From a772aabdb8a52457b9b086e8843deb30021038a9 Mon Sep 17 00:00:00 2001 From: Ahmet Inan Date: Tue, 20 Jan 2026 12:52:34 +0100 Subject: [PATCH 1/5] skip permutation and shuffling for rate0 nodes --- polar_list_decoder.hh | 204 +++++++++++++++++++++++++++--------------- 1 file changed, 130 insertions(+), 74 deletions(-) diff --git a/polar_list_decoder.hh b/polar_list_decoder.hh index 07a1cb1..ab47cbf 100644 --- a/polar_list_decoder.hh +++ b/polar_list_decoder.hh @@ -18,7 +18,7 @@ struct PolarListNode typedef typename PH::PATH PATH; typedef typename PH::MAP MAP; static const int N = 1 << M; - static MAP rate0(PATH *metric, TYPE *hard, TYPE *soft) + static void rate0(PATH *metric, TYPE *hard, TYPE *soft) { for (int i = 0; i < N; ++i) hard[i] = PH::one(); @@ -26,10 +26,6 @@ struct PolarListNode for (int k = 0; k < TYPE::SIZE; ++k) if (soft[i+N].v[k] < 0) metric[k] -= soft[i+N].v[k]; - MAP map; - for (int k = 0; k < TYPE::SIZE; ++k) - map.v[k] = k; - return map; } }; @@ -39,16 +35,12 @@ struct PolarListNode typedef PolarHelper PH; typedef typename PH::PATH PATH; typedef typename PH::MAP MAP; - static MAP rate0(PATH *metric, TYPE *hard, TYPE *soft) + static void rate0(PATH *metric, TYPE *hard, TYPE *soft) { *hard = PH::one(); for (int k = 0; k < TYPE::SIZE; ++k) if (soft[1].v[k] < 0) metric[k] -= soft[1].v[k]; - MAP map; - for (int k = 0; k < TYPE::SIZE; ++k) - map.v[k] = k; - return map; } static MAP rate1(PATH *metric, TYPE *message, MAP *maps, int *count, TYPE *hard, TYPE *soft) { @@ -112,19 +104,30 @@ struct PolarListTree { for (int i = 0; i < N/2; ++i) soft[i+N/2] = PH::prod(soft[i+N], soft[i+N/2+N]); - MAP lmap, rmap; - if (frozen[0] == 0xffffffff) - lmap = PolarListNode::rate0(metric, hard, soft); - else + MAP lmap; + if (frozen[0] == 0xffffffff) { + PolarListNode::rate0(metric, hard, soft); + for (int i = 0; i < N/2; ++i) + soft[i+N/2] = PH::madd(hard[i], soft[i+N], soft[i+N/2+N]); + for (int k = 0; k < TYPE::SIZE; ++k) + lmap.v[k] = k; + } else { lmap = PolarListTree::decode(metric, message, maps, count, hard, soft, frozen[0]); - for (int i = 0; i < N/2; ++i) - soft[i+N/2] = PH::madd(hard[i], vshuf(soft[i+N], lmap), vshuf(soft[i+N/2+N], lmap)); - if (frozen[1] == 0xffffffff) - rmap = PolarListNode::rate0(metric, hard+N/2, soft); - else + for (int i = 0; i < N/2; ++i) + soft[i+N/2] = PH::madd(hard[i], vshuf(soft[i+N], lmap), vshuf(soft[i+N/2+N], lmap)); + } + MAP rmap; + if (frozen[1] == 0xffffffff) { + PolarListNode::rate0(metric, hard+N/2, soft); + for (int i = 0; i < N/2; ++i) + hard[i] = PH::qmul(hard[i], hard[i+N/2]); + for (int k = 0; k < TYPE::SIZE; ++k) + rmap.v[k] = k; + } else { rmap = PolarListTree::decode(metric, message, maps, count, hard+N/2, soft, frozen[1]); - for (int i = 0; i < N/2; ++i) - hard[i] = PH::qmul(vshuf(hard[i], rmap), hard[i+N/2]); + for (int i = 0; i < N/2; ++i) + hard[i] = PH::qmul(vshuf(hard[i], rmap), hard[i+N/2]); + } return vshuf(lmap, rmap); } }; @@ -141,19 +144,30 @@ struct PolarListTree { for (int i = 0; i < N/2; ++i) soft[i+N/2] = PH::prod(soft[i+N], soft[i+N/2+N]); - MAP lmap, rmap; - if ((frozen & ((1<<(1<<(M-1)))-1)) == ((1<<(1<<(M-1)))-1)) - lmap = PolarListNode::rate0(metric, hard, soft); - else + MAP lmap; + if ((frozen & ((1<<(1<<(M-1)))-1)) == ((1<<(1<<(M-1)))-1)) { + PolarListNode::rate0(metric, hard, soft); + for (int i = 0; i < N/2; ++i) + soft[i+N/2] = PH::madd(hard[i], soft[i+N], soft[i+N/2+N]); + for (int k = 0; k < TYPE::SIZE; ++k) + lmap.v[k] = k; + } else { lmap = PolarListTree::decode(metric, message, maps, count, hard, soft, frozen & ((1<<(1<<(M-1)))-1)); - for (int i = 0; i < N/2; ++i) - soft[i+N/2] = PH::madd(hard[i], vshuf(soft[i+N], lmap), vshuf(soft[i+N/2+N], lmap)); - if (frozen >> (N/2) == ((1<<(1<<(M-1)))-1)) - rmap = PolarListNode::rate0(metric, hard+N/2, soft); - else + for (int i = 0; i < N/2; ++i) + soft[i+N/2] = PH::madd(hard[i], vshuf(soft[i+N], lmap), vshuf(soft[i+N/2+N], lmap)); + } + MAP rmap; + if (frozen >> (N/2) == ((1<<(1<<(M-1)))-1)) { + PolarListNode::rate0(metric, hard+N/2, soft); + for (int i = 0; i < N/2; ++i) + hard[i] = PH::qmul(hard[i], hard[i+N/2]); + for (int k = 0; k < TYPE::SIZE; ++k) + rmap.v[k] = k; + } else { rmap = PolarListTree::decode(metric, message, maps, count, hard+N/2, soft, frozen >> (N/2)); - for (int i = 0; i < N/2; ++i) - hard[i] = PH::qmul(vshuf(hard[i], rmap), hard[i+N/2]); + for (int i = 0; i < N/2; ++i) + hard[i] = PH::qmul(vshuf(hard[i], rmap), hard[i+N/2]); + } return vshuf(lmap, rmap); } }; @@ -170,19 +184,30 @@ struct PolarListTree { for (int i = 0; i < N/2; ++i) soft[i+N/2] = PH::prod(soft[i+N], soft[i+N/2+N]); - MAP lmap, rmap; - if ((frozen & ((1<<(1<<(M-1)))-1)) == ((1<<(1<<(M-1)))-1)) - lmap = PolarListNode::rate0(metric, hard, soft); - else + MAP lmap; + if ((frozen & ((1<<(1<<(M-1)))-1)) == ((1<<(1<<(M-1)))-1)) { + PolarListNode::rate0(metric, hard, soft); + for (int i = 0; i < N/2; ++i) + soft[i+N/2] = PH::madd(hard[i], soft[i+N], soft[i+N/2+N]); + for (int k = 0; k < TYPE::SIZE; ++k) + lmap.v[k] = k; + } else { lmap = PolarListTree::decode(metric, message, maps, count, hard, soft, frozen & ((1<<(1<<(M-1)))-1)); - for (int i = 0; i < N/2; ++i) - soft[i+N/2] = PH::madd(hard[i], vshuf(soft[i+N], lmap), vshuf(soft[i+N/2+N], lmap)); - if (frozen >> (N/2) == ((1<<(1<<(M-1)))-1)) - rmap = PolarListNode::rate0(metric, hard+N/2, soft); - else + for (int i = 0; i < N/2; ++i) + soft[i+N/2] = PH::madd(hard[i], vshuf(soft[i+N], lmap), vshuf(soft[i+N/2+N], lmap)); + } + MAP rmap; + if (frozen >> (N/2) == ((1<<(1<<(M-1)))-1)) { + PolarListNode::rate0(metric, hard+N/2, soft); + for (int i = 0; i < N/2; ++i) + hard[i] = PH::qmul(hard[i], hard[i+N/2]); + for (int k = 0; k < TYPE::SIZE; ++k) + rmap.v[k] = k; + } else { rmap = PolarListTree::decode(metric, message, maps, count, hard+N/2, soft, frozen >> (N/2)); - for (int i = 0; i < N/2; ++i) - hard[i] = PH::qmul(vshuf(hard[i], rmap), hard[i+N/2]); + for (int i = 0; i < N/2; ++i) + hard[i] = PH::qmul(vshuf(hard[i], rmap), hard[i+N/2]); + } return vshuf(lmap, rmap); } }; @@ -199,19 +224,30 @@ struct PolarListTree { for (int i = 0; i < N/2; ++i) soft[i+N/2] = PH::prod(soft[i+N], soft[i+N/2+N]); - MAP lmap, rmap; - if ((frozen & ((1<<(1<<(M-1)))-1)) == ((1<<(1<<(M-1)))-1)) - lmap = PolarListNode::rate0(metric, hard, soft); - else + MAP lmap; + if ((frozen & ((1<<(1<<(M-1)))-1)) == ((1<<(1<<(M-1)))-1)) { + PolarListNode::rate0(metric, hard, soft); + for (int i = 0; i < N/2; ++i) + soft[i+N/2] = PH::madd(hard[i], soft[i+N], soft[i+N/2+N]); + for (int k = 0; k < TYPE::SIZE; ++k) + lmap.v[k] = k; + } else { lmap = PolarListTree::decode(metric, message, maps, count, hard, soft, frozen & ((1<<(1<<(M-1)))-1)); - for (int i = 0; i < N/2; ++i) - soft[i+N/2] = PH::madd(hard[i], vshuf(soft[i+N], lmap), vshuf(soft[i+N/2+N], lmap)); - if (frozen >> (N/2) == ((1<<(1<<(M-1)))-1)) - rmap = PolarListNode::rate0(metric, hard+N/2, soft); - else + for (int i = 0; i < N/2; ++i) + soft[i+N/2] = PH::madd(hard[i], vshuf(soft[i+N], lmap), vshuf(soft[i+N/2+N], lmap)); + } + MAP rmap; + if (frozen >> (N/2) == ((1<<(1<<(M-1)))-1)) { + PolarListNode::rate0(metric, hard+N/2, soft); + for (int i = 0; i < N/2; ++i) + hard[i] = PH::qmul(hard[i], hard[i+N/2]); + for (int k = 0; k < TYPE::SIZE; ++k) + rmap.v[k] = k; + } else { rmap = PolarListTree::decode(metric, message, maps, count, hard+N/2, soft, frozen >> (N/2)); - for (int i = 0; i < N/2; ++i) - hard[i] = PH::qmul(vshuf(hard[i], rmap), hard[i+N/2]); + for (int i = 0; i < N/2; ++i) + hard[i] = PH::qmul(vshuf(hard[i], rmap), hard[i+N/2]); + } return vshuf(lmap, rmap); } }; @@ -228,19 +264,30 @@ struct PolarListTree { for (int i = 0; i < N/2; ++i) soft[i+N/2] = PH::prod(soft[i+N], soft[i+N/2+N]); - MAP lmap, rmap; - if ((frozen & ((1<<(1<<(M-1)))-1)) == ((1<<(1<<(M-1)))-1)) - lmap = PolarListNode::rate0(metric, hard, soft); - else + MAP lmap; + if ((frozen & ((1<<(1<<(M-1)))-1)) == ((1<<(1<<(M-1)))-1)) { + PolarListNode::rate0(metric, hard, soft); + for (int i = 0; i < N/2; ++i) + soft[i+N/2] = PH::madd(hard[i], soft[i+N], soft[i+N/2+N]); + for (int k = 0; k < TYPE::SIZE; ++k) + lmap.v[k] = k; + } else { lmap = PolarListTree::decode(metric, message, maps, count, hard, soft, frozen & ((1<<(1<<(M-1)))-1)); - for (int i = 0; i < N/2; ++i) - soft[i+N/2] = PH::madd(hard[i], vshuf(soft[i+N], lmap), vshuf(soft[i+N/2+N], lmap)); - if (frozen >> (N/2) == ((1<<(1<<(M-1)))-1)) - rmap = PolarListNode::rate0(metric, hard+N/2, soft); - else + for (int i = 0; i < N/2; ++i) + soft[i+N/2] = PH::madd(hard[i], vshuf(soft[i+N], lmap), vshuf(soft[i+N/2+N], lmap)); + } + MAP rmap; + if (frozen >> (N/2) == ((1<<(1<<(M-1)))-1)) { + PolarListNode::rate0(metric, hard+N/2, soft); + for (int i = 0; i < N/2; ++i) + hard[i] = PH::qmul(hard[i], hard[i+N/2]); + for (int k = 0; k < TYPE::SIZE; ++k) + rmap.v[k] = k; + } else { rmap = PolarListTree::decode(metric, message, maps, count, hard+N/2, soft, frozen >> (N/2)); - for (int i = 0; i < N/2; ++i) - hard[i] = PH::qmul(vshuf(hard[i], rmap), hard[i+N/2]); + for (int i = 0; i < N/2; ++i) + hard[i] = PH::qmul(vshuf(hard[i], rmap), hard[i+N/2]); + } return vshuf(lmap, rmap); } }; @@ -254,17 +301,26 @@ struct PolarListTree static MAP decode(PATH *metric, TYPE *message, MAP *maps, int *count, TYPE *hard, TYPE *soft, uint32_t frozen) { soft[1] = PH::prod(soft[2], soft[3]); - MAP lmap, rmap; - if (frozen & 1) - lmap = PolarListNode::rate0(metric, hard, soft); - else + MAP lmap; + if (frozen & 1) { + PolarListNode::rate0(metric, hard, soft); + soft[1] = PH::madd(hard[0], soft[2], soft[3]); + for (int k = 0; k < TYPE::SIZE; ++k) + lmap.v[k] = k; + } else { lmap = PolarListNode::rate1(metric, message, maps, count, hard, soft); - soft[1] = PH::madd(hard[0], vshuf(soft[2], lmap), vshuf(soft[3], lmap)); - if (frozen >> 1) - rmap = PolarListNode::rate0(metric, hard+1, soft); - else + soft[1] = PH::madd(hard[0], vshuf(soft[2], lmap), vshuf(soft[3], lmap)); + } + MAP rmap; + if (frozen >> 1) { + PolarListNode::rate0(metric, hard+1, soft); + hard[0] = PH::qmul(hard[0], hard[1]); + for (int k = 0; k < TYPE::SIZE; ++k) + rmap.v[k] = k; + } else { rmap = PolarListNode::rate1(metric, message, maps, count, hard+1, soft); - hard[0] = PH::qmul(vshuf(hard[0], rmap), hard[1]); + hard[0] = PH::qmul(vshuf(hard[0], rmap), hard[1]); + } return vshuf(lmap, rmap); } }; From 467122ac634872e379015633f1755f83fa7b887e Mon Sep 17 00:00:00 2001 From: Ahmet Inan Date: Tue, 20 Jan 2026 13:08:18 +0100 Subject: [PATCH 2/5] skip redundant operations --- polar_list_decoder.hh | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/polar_list_decoder.hh b/polar_list_decoder.hh index ab47cbf..307b6e5 100644 --- a/polar_list_decoder.hh +++ b/polar_list_decoder.hh @@ -108,7 +108,7 @@ struct PolarListTree if (frozen[0] == 0xffffffff) { PolarListNode::rate0(metric, hard, soft); for (int i = 0; i < N/2; ++i) - soft[i+N/2] = PH::madd(hard[i], soft[i+N], soft[i+N/2+N]); + soft[i+N/2] = PH::qadd(soft[i+N], soft[i+N/2+N]); for (int k = 0; k < TYPE::SIZE; ++k) lmap.v[k] = k; } else { @@ -119,8 +119,6 @@ struct PolarListTree MAP rmap; if (frozen[1] == 0xffffffff) { PolarListNode::rate0(metric, hard+N/2, soft); - for (int i = 0; i < N/2; ++i) - hard[i] = PH::qmul(hard[i], hard[i+N/2]); for (int k = 0; k < TYPE::SIZE; ++k) rmap.v[k] = k; } else { @@ -148,7 +146,7 @@ struct PolarListTree if ((frozen & ((1<<(1<<(M-1)))-1)) == ((1<<(1<<(M-1)))-1)) { PolarListNode::rate0(metric, hard, soft); for (int i = 0; i < N/2; ++i) - soft[i+N/2] = PH::madd(hard[i], soft[i+N], soft[i+N/2+N]); + soft[i+N/2] = PH::qadd(soft[i+N], soft[i+N/2+N]); for (int k = 0; k < TYPE::SIZE; ++k) lmap.v[k] = k; } else { @@ -159,8 +157,6 @@ struct PolarListTree MAP rmap; if (frozen >> (N/2) == ((1<<(1<<(M-1)))-1)) { PolarListNode::rate0(metric, hard+N/2, soft); - for (int i = 0; i < N/2; ++i) - hard[i] = PH::qmul(hard[i], hard[i+N/2]); for (int k = 0; k < TYPE::SIZE; ++k) rmap.v[k] = k; } else { @@ -188,7 +184,7 @@ struct PolarListTree if ((frozen & ((1<<(1<<(M-1)))-1)) == ((1<<(1<<(M-1)))-1)) { PolarListNode::rate0(metric, hard, soft); for (int i = 0; i < N/2; ++i) - soft[i+N/2] = PH::madd(hard[i], soft[i+N], soft[i+N/2+N]); + soft[i+N/2] = PH::qadd(soft[i+N], soft[i+N/2+N]); for (int k = 0; k < TYPE::SIZE; ++k) lmap.v[k] = k; } else { @@ -199,8 +195,6 @@ struct PolarListTree MAP rmap; if (frozen >> (N/2) == ((1<<(1<<(M-1)))-1)) { PolarListNode::rate0(metric, hard+N/2, soft); - for (int i = 0; i < N/2; ++i) - hard[i] = PH::qmul(hard[i], hard[i+N/2]); for (int k = 0; k < TYPE::SIZE; ++k) rmap.v[k] = k; } else { @@ -228,7 +222,7 @@ struct PolarListTree if ((frozen & ((1<<(1<<(M-1)))-1)) == ((1<<(1<<(M-1)))-1)) { PolarListNode::rate0(metric, hard, soft); for (int i = 0; i < N/2; ++i) - soft[i+N/2] = PH::madd(hard[i], soft[i+N], soft[i+N/2+N]); + soft[i+N/2] = PH::qadd(soft[i+N], soft[i+N/2+N]); for (int k = 0; k < TYPE::SIZE; ++k) lmap.v[k] = k; } else { @@ -239,8 +233,6 @@ struct PolarListTree MAP rmap; if (frozen >> (N/2) == ((1<<(1<<(M-1)))-1)) { PolarListNode::rate0(metric, hard+N/2, soft); - for (int i = 0; i < N/2; ++i) - hard[i] = PH::qmul(hard[i], hard[i+N/2]); for (int k = 0; k < TYPE::SIZE; ++k) rmap.v[k] = k; } else { @@ -268,7 +260,7 @@ struct PolarListTree if ((frozen & ((1<<(1<<(M-1)))-1)) == ((1<<(1<<(M-1)))-1)) { PolarListNode::rate0(metric, hard, soft); for (int i = 0; i < N/2; ++i) - soft[i+N/2] = PH::madd(hard[i], soft[i+N], soft[i+N/2+N]); + soft[i+N/2] = PH::qadd(soft[i+N], soft[i+N/2+N]); for (int k = 0; k < TYPE::SIZE; ++k) lmap.v[k] = k; } else { @@ -279,8 +271,6 @@ struct PolarListTree MAP rmap; if (frozen >> (N/2) == ((1<<(1<<(M-1)))-1)) { PolarListNode::rate0(metric, hard+N/2, soft); - for (int i = 0; i < N/2; ++i) - hard[i] = PH::qmul(hard[i], hard[i+N/2]); for (int k = 0; k < TYPE::SIZE; ++k) rmap.v[k] = k; } else { @@ -304,7 +294,7 @@ struct PolarListTree MAP lmap; if (frozen & 1) { PolarListNode::rate0(metric, hard, soft); - soft[1] = PH::madd(hard[0], soft[2], soft[3]); + soft[1] = PH::qadd(soft[2], soft[3]); for (int k = 0; k < TYPE::SIZE; ++k) lmap.v[k] = k; } else { @@ -314,7 +304,6 @@ struct PolarListTree MAP rmap; if (frozen >> 1) { PolarListNode::rate0(metric, hard+1, soft); - hard[0] = PH::qmul(hard[0], hard[1]); for (int k = 0; k < TYPE::SIZE; ++k) rmap.v[k] = k; } else { From cae677eeb1f95b0d0a202467f82aff1f17d5f965 Mon Sep 17 00:00:00 2001 From: Ahmet Inan Date: Wed, 21 Jan 2026 10:28:45 +0100 Subject: [PATCH 3/5] skip redundant mixing of maps --- polar_list_decoder.hh | 168 ++++++++++++++++++++++++------------------ 1 file changed, 96 insertions(+), 72 deletions(-) diff --git a/polar_list_decoder.hh b/polar_list_decoder.hh index 307b6e5..696c3d4 100644 --- a/polar_list_decoder.hh +++ b/polar_list_decoder.hh @@ -104,29 +104,33 @@ struct PolarListTree { for (int i = 0; i < N/2; ++i) soft[i+N/2] = PH::prod(soft[i+N], soft[i+N/2+N]); - MAP lmap; - if (frozen[0] == 0xffffffff) { + MAP map; + bool left_frozen = frozen[0] == 0xffffffff; + if (left_frozen) { PolarListNode::rate0(metric, hard, soft); for (int i = 0; i < N/2; ++i) soft[i+N/2] = PH::qadd(soft[i+N], soft[i+N/2+N]); - for (int k = 0; k < TYPE::SIZE; ++k) - lmap.v[k] = k; } else { - lmap = PolarListTree::decode(metric, message, maps, count, hard, soft, frozen[0]); + map = PolarListTree::decode(metric, message, maps, count, hard, soft, frozen[0]); for (int i = 0; i < N/2; ++i) - soft[i+N/2] = PH::madd(hard[i], vshuf(soft[i+N], lmap), vshuf(soft[i+N/2+N], lmap)); + soft[i+N/2] = PH::madd(hard[i], vshuf(soft[i+N], map), vshuf(soft[i+N/2+N], map)); } - MAP rmap; - if (frozen[1] == 0xffffffff) { + bool right_frozen = frozen[1] == 0xffffffff; + if (right_frozen) { PolarListNode::rate0(metric, hard+N/2, soft); - for (int k = 0; k < TYPE::SIZE; ++k) - rmap.v[k] = k; + if (left_frozen) + for (int k = 0; k < TYPE::SIZE; ++k) + map.v[k] = k; } else { - rmap = PolarListTree::decode(metric, message, maps, count, hard+N/2, soft, frozen[1]); + MAP rmap = PolarListTree::decode(metric, message, maps, count, hard+N/2, soft, frozen[1]); for (int i = 0; i < N/2; ++i) hard[i] = PH::qmul(vshuf(hard[i], rmap), hard[i+N/2]); + if (left_frozen) + map = rmap; + else + map = vshuf(map, rmap); } - return vshuf(lmap, rmap); + return map; } }; @@ -142,29 +146,33 @@ struct PolarListTree { for (int i = 0; i < N/2; ++i) soft[i+N/2] = PH::prod(soft[i+N], soft[i+N/2+N]); - MAP lmap; - if ((frozen & ((1<<(1<<(M-1)))-1)) == ((1<<(1<<(M-1)))-1)) { + MAP map; + bool left_frozen = (frozen & ((1<<(1<<(M-1)))-1)) == ((1<<(1<<(M-1)))-1); + if (left_frozen) { PolarListNode::rate0(metric, hard, soft); for (int i = 0; i < N/2; ++i) soft[i+N/2] = PH::qadd(soft[i+N], soft[i+N/2+N]); - for (int k = 0; k < TYPE::SIZE; ++k) - lmap.v[k] = k; } else { - lmap = PolarListTree::decode(metric, message, maps, count, hard, soft, frozen & ((1<<(1<<(M-1)))-1)); + map = PolarListTree::decode(metric, message, maps, count, hard, soft, frozen & ((1<<(1<<(M-1)))-1)); for (int i = 0; i < N/2; ++i) - soft[i+N/2] = PH::madd(hard[i], vshuf(soft[i+N], lmap), vshuf(soft[i+N/2+N], lmap)); + soft[i+N/2] = PH::madd(hard[i], vshuf(soft[i+N], map), vshuf(soft[i+N/2+N], map)); } - MAP rmap; - if (frozen >> (N/2) == ((1<<(1<<(M-1)))-1)) { + bool right_frozen = frozen >> (N/2) == ((1<<(1<<(M-1)))-1); + if (right_frozen) { PolarListNode::rate0(metric, hard+N/2, soft); - for (int k = 0; k < TYPE::SIZE; ++k) - rmap.v[k] = k; + if (left_frozen) + for (int k = 0; k < TYPE::SIZE; ++k) + map.v[k] = k; } else { - rmap = PolarListTree::decode(metric, message, maps, count, hard+N/2, soft, frozen >> (N/2)); + MAP rmap = PolarListTree::decode(metric, message, maps, count, hard+N/2, soft, frozen >> (N/2)); for (int i = 0; i < N/2; ++i) hard[i] = PH::qmul(vshuf(hard[i], rmap), hard[i+N/2]); + if (left_frozen) + map = rmap; + else + map = vshuf(map, rmap); } - return vshuf(lmap, rmap); + return map; } }; @@ -180,29 +188,33 @@ struct PolarListTree { for (int i = 0; i < N/2; ++i) soft[i+N/2] = PH::prod(soft[i+N], soft[i+N/2+N]); - MAP lmap; - if ((frozen & ((1<<(1<<(M-1)))-1)) == ((1<<(1<<(M-1)))-1)) { + MAP map; + bool left_frozen = (frozen & ((1<<(1<<(M-1)))-1)) == ((1<<(1<<(M-1)))-1); + if (left_frozen) { PolarListNode::rate0(metric, hard, soft); for (int i = 0; i < N/2; ++i) soft[i+N/2] = PH::qadd(soft[i+N], soft[i+N/2+N]); - for (int k = 0; k < TYPE::SIZE; ++k) - lmap.v[k] = k; } else { - lmap = PolarListTree::decode(metric, message, maps, count, hard, soft, frozen & ((1<<(1<<(M-1)))-1)); + map = PolarListTree::decode(metric, message, maps, count, hard, soft, frozen & ((1<<(1<<(M-1)))-1)); for (int i = 0; i < N/2; ++i) - soft[i+N/2] = PH::madd(hard[i], vshuf(soft[i+N], lmap), vshuf(soft[i+N/2+N], lmap)); + soft[i+N/2] = PH::madd(hard[i], vshuf(soft[i+N], map), vshuf(soft[i+N/2+N], map)); } - MAP rmap; - if (frozen >> (N/2) == ((1<<(1<<(M-1)))-1)) { + bool right_frozen = frozen >> (N/2) == ((1<<(1<<(M-1)))-1); + if (right_frozen) { PolarListNode::rate0(metric, hard+N/2, soft); - for (int k = 0; k < TYPE::SIZE; ++k) - rmap.v[k] = k; + if (left_frozen) + for (int k = 0; k < TYPE::SIZE; ++k) + map.v[k] = k; } else { - rmap = PolarListTree::decode(metric, message, maps, count, hard+N/2, soft, frozen >> (N/2)); + MAP rmap = PolarListTree::decode(metric, message, maps, count, hard+N/2, soft, frozen >> (N/2)); for (int i = 0; i < N/2; ++i) hard[i] = PH::qmul(vshuf(hard[i], rmap), hard[i+N/2]); + if (left_frozen) + map = rmap; + else + map = vshuf(map, rmap); } - return vshuf(lmap, rmap); + return map; } }; @@ -218,29 +230,33 @@ struct PolarListTree { for (int i = 0; i < N/2; ++i) soft[i+N/2] = PH::prod(soft[i+N], soft[i+N/2+N]); - MAP lmap; - if ((frozen & ((1<<(1<<(M-1)))-1)) == ((1<<(1<<(M-1)))-1)) { + MAP map; + bool left_frozen = (frozen & ((1<<(1<<(M-1)))-1)) == ((1<<(1<<(M-1)))-1); + if (left_frozen) { PolarListNode::rate0(metric, hard, soft); for (int i = 0; i < N/2; ++i) soft[i+N/2] = PH::qadd(soft[i+N], soft[i+N/2+N]); - for (int k = 0; k < TYPE::SIZE; ++k) - lmap.v[k] = k; } else { - lmap = PolarListTree::decode(metric, message, maps, count, hard, soft, frozen & ((1<<(1<<(M-1)))-1)); + map = PolarListTree::decode(metric, message, maps, count, hard, soft, frozen & ((1<<(1<<(M-1)))-1)); for (int i = 0; i < N/2; ++i) - soft[i+N/2] = PH::madd(hard[i], vshuf(soft[i+N], lmap), vshuf(soft[i+N/2+N], lmap)); + soft[i+N/2] = PH::madd(hard[i], vshuf(soft[i+N], map), vshuf(soft[i+N/2+N], map)); } - MAP rmap; - if (frozen >> (N/2) == ((1<<(1<<(M-1)))-1)) { + bool right_frozen = frozen >> (N/2) == ((1<<(1<<(M-1)))-1); + if (right_frozen) { PolarListNode::rate0(metric, hard+N/2, soft); - for (int k = 0; k < TYPE::SIZE; ++k) - rmap.v[k] = k; + if (left_frozen) + for (int k = 0; k < TYPE::SIZE; ++k) + map.v[k] = k; } else { - rmap = PolarListTree::decode(metric, message, maps, count, hard+N/2, soft, frozen >> (N/2)); + MAP rmap = PolarListTree::decode(metric, message, maps, count, hard+N/2, soft, frozen >> (N/2)); for (int i = 0; i < N/2; ++i) hard[i] = PH::qmul(vshuf(hard[i], rmap), hard[i+N/2]); + if (left_frozen) + map = rmap; + else + map = vshuf(map, rmap); } - return vshuf(lmap, rmap); + return map; } }; @@ -256,29 +272,33 @@ struct PolarListTree { for (int i = 0; i < N/2; ++i) soft[i+N/2] = PH::prod(soft[i+N], soft[i+N/2+N]); - MAP lmap; - if ((frozen & ((1<<(1<<(M-1)))-1)) == ((1<<(1<<(M-1)))-1)) { + MAP map; + bool left_frozen = (frozen & ((1<<(1<<(M-1)))-1)) == ((1<<(1<<(M-1)))-1); + if (left_frozen) { PolarListNode::rate0(metric, hard, soft); for (int i = 0; i < N/2; ++i) soft[i+N/2] = PH::qadd(soft[i+N], soft[i+N/2+N]); - for (int k = 0; k < TYPE::SIZE; ++k) - lmap.v[k] = k; } else { - lmap = PolarListTree::decode(metric, message, maps, count, hard, soft, frozen & ((1<<(1<<(M-1)))-1)); + map = PolarListTree::decode(metric, message, maps, count, hard, soft, frozen & ((1<<(1<<(M-1)))-1)); for (int i = 0; i < N/2; ++i) - soft[i+N/2] = PH::madd(hard[i], vshuf(soft[i+N], lmap), vshuf(soft[i+N/2+N], lmap)); + soft[i+N/2] = PH::madd(hard[i], vshuf(soft[i+N], map), vshuf(soft[i+N/2+N], map)); } - MAP rmap; - if (frozen >> (N/2) == ((1<<(1<<(M-1)))-1)) { + bool right_frozen = frozen >> (N/2) == ((1<<(1<<(M-1)))-1); + if (right_frozen) { PolarListNode::rate0(metric, hard+N/2, soft); - for (int k = 0; k < TYPE::SIZE; ++k) - rmap.v[k] = k; + if (left_frozen) + for (int k = 0; k < TYPE::SIZE; ++k) + map.v[k] = k; } else { - rmap = PolarListTree::decode(metric, message, maps, count, hard+N/2, soft, frozen >> (N/2)); + MAP rmap = PolarListTree::decode(metric, message, maps, count, hard+N/2, soft, frozen >> (N/2)); for (int i = 0; i < N/2; ++i) hard[i] = PH::qmul(vshuf(hard[i], rmap), hard[i+N/2]); + if (left_frozen) + map = rmap; + else + map = vshuf(map, rmap); } - return vshuf(lmap, rmap); + return map; } }; @@ -291,26 +311,30 @@ struct PolarListTree static MAP decode(PATH *metric, TYPE *message, MAP *maps, int *count, TYPE *hard, TYPE *soft, uint32_t frozen) { soft[1] = PH::prod(soft[2], soft[3]); - MAP lmap; - if (frozen & 1) { + MAP map; + bool left_frozen = frozen & 1; + if (left_frozen) { PolarListNode::rate0(metric, hard, soft); soft[1] = PH::qadd(soft[2], soft[3]); - for (int k = 0; k < TYPE::SIZE; ++k) - lmap.v[k] = k; } else { - lmap = PolarListNode::rate1(metric, message, maps, count, hard, soft); - soft[1] = PH::madd(hard[0], vshuf(soft[2], lmap), vshuf(soft[3], lmap)); + map = PolarListNode::rate1(metric, message, maps, count, hard, soft); + soft[1] = PH::madd(hard[0], vshuf(soft[2], map), vshuf(soft[3], map)); } - MAP rmap; - if (frozen >> 1) { + bool right_frozen = frozen >> 1; + if (right_frozen) { PolarListNode::rate0(metric, hard+1, soft); - for (int k = 0; k < TYPE::SIZE; ++k) - rmap.v[k] = k; + if (left_frozen) + for (int k = 0; k < TYPE::SIZE; ++k) + map.v[k] = k; } else { - rmap = PolarListNode::rate1(metric, message, maps, count, hard+1, soft); + MAP rmap = PolarListNode::rate1(metric, message, maps, count, hard+1, soft); hard[0] = PH::qmul(vshuf(hard[0], rmap), hard[1]); + if (left_frozen) + map = rmap; + else + map = vshuf(map, rmap); } - return vshuf(lmap, rmap); + return map; } }; From 831e17d878cdb244436347e4dd77aebd6f9a8154 Mon Sep 17 00:00:00 2001 From: Ahmet Inan Date: Sat, 24 Jan 2026 12:52:07 +0100 Subject: [PATCH 4/5] skip permutation and shuffling for rate0 leafs --- pac_list_decoder.hh | 43 ++++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/pac_list_decoder.hh b/pac_list_decoder.hh index ec4eae8..1896e04 100644 --- a/pac_list_decoder.hh +++ b/pac_list_decoder.hh @@ -28,7 +28,7 @@ struct PACListLeaf *state = ((*state & 126) << 1) | (input ? 2 : 0) | (output ? 1 : 0); return output; } - static MAP rate0(PATH *metric, int *state, TYPE *hard, TYPE *soft) + static void rate0(PATH *metric, int *state, TYPE *hard, TYPE *soft) { TYPE sft = soft[1]; for (int k = 0; k < TYPE::SIZE; ++k) @@ -38,10 +38,6 @@ struct PACListLeaf for (int k = 0; k < TYPE::SIZE; ++k) hrd.v[k] = 1 - 2 * (state[k] & 1); *hard = hrd; - MAP map; - for (int k = 0; k < TYPE::SIZE; ++k) - map.v[k] = k; - return map; } static MAP rate1(PATH *metric, TYPE *message, MAP *maps, int *count, int *state, TYPE *hard, TYPE *soft) { @@ -218,18 +214,31 @@ struct PACListTree static MAP decode(PATH *metric, TYPE *message, MAP *maps, int *count, int *state, TYPE *hard, TYPE *soft, uint32_t frozen) { soft[1] = PH::prod(soft[2], soft[3]); - MAP lmap, rmap; - if (frozen & 1) - lmap = PACListLeaf::rate0(metric, state, hard, soft); - else - lmap = PACListLeaf::rate1(metric, message, maps, count, state, hard, soft); - soft[1] = PH::madd(hard[0], vshuf(soft[2], lmap), vshuf(soft[3], lmap)); - if (frozen >> 1) - rmap = PACListLeaf::rate0(metric, state, hard+1, soft); - else - rmap = PACListLeaf::rate1(metric, message, maps, count, state, hard+1, soft); - hard[0] = PH::qmul(vshuf(hard[0], rmap), hard[1]); - return vshuf(lmap, rmap); + MAP map; + bool left_frozen = frozen & 1; + if (left_frozen) { + PACListLeaf::rate0(metric, state, hard, soft); + soft[1] = PH::madd(hard[0], soft[2], soft[3]); + } else { + map = PACListLeaf::rate1(metric, message, maps, count, state, hard, soft); + soft[1] = PH::madd(hard[0], vshuf(soft[2], map), vshuf(soft[3], map)); + } + bool right_frozen = frozen >> 1; + if (right_frozen) { + PACListLeaf::rate0(metric, state, hard+1, soft); + hard[0] = PH::qmul(hard[0], hard[1]); + if (left_frozen) + for (int k = 0; k < TYPE::SIZE; ++k) + map.v[k] = k; + } else { + MAP rmap = PACListLeaf::rate1(metric, message, maps, count, state, hard+1, soft); + hard[0] = PH::qmul(vshuf(hard[0], rmap), hard[1]); + if (left_frozen) + map = rmap; + else + map = vshuf(map, rmap); + } + return map; } }; From 40e6a9013698c18be2610e16041b751abdd7aa56 Mon Sep 17 00:00:00 2001 From: Ahmet Inan Date: Mon, 26 Jan 2026 00:47:25 +0100 Subject: [PATCH 5/5] skip decoding frozen bits when no message bits yet --- pac_list_decoder.hh | 198 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 158 insertions(+), 40 deletions(-) diff --git a/pac_list_decoder.hh b/pac_list_decoder.hh index 1896e04..30e26dd 100644 --- a/pac_list_decoder.hh +++ b/pac_list_decoder.hh @@ -11,8 +11,26 @@ Copyright 2025 Ahmet Inan namespace CODE { +template +struct PACListNode +{ + typedef PolarHelper PH; + typedef typename PH::PATH PATH; + typedef typename PH::MAP MAP; + static const int N = 1 << M; + static void rate0(PATH *metric, TYPE *hard, TYPE *soft) + { + for (int i = 0; i < N; ++i) + hard[i] = PH::one(); + for (int i = 0; i < N; ++i) + for (int k = 0; k < TYPE::SIZE; ++k) + if (soft[i+N].v[k] < 0) + metric[k] -= soft[i+N].v[k]; + } +}; + template -struct PACListLeaf +struct PACListNode { typedef PolarHelper PH; typedef typename PH::PATH PATH; @@ -107,13 +125,33 @@ struct PACListTree { for (int i = 0; i < N/2; ++i) soft[i+N/2] = PH::prod(soft[i+N], soft[i+N/2+N]); - MAP lmap = PACListTree::decode(metric, message, maps, count, state, hard, soft, frozen[0]); - for (int i = 0; i < N/2; ++i) - soft[i+N/2] = PH::madd(hard[i], vshuf(soft[i+N], lmap), vshuf(soft[i+N/2+N], lmap)); - MAP rmap = PACListTree::decode(metric, message, maps, count, state, hard+N/2, soft, frozen[1]); - for (int i = 0; i < N/2; ++i) - hard[i] = PH::qmul(vshuf(hard[i], rmap), hard[i+N/2]); - return vshuf(lmap, rmap); + MAP map; + bool left_frozen = frozen[0] == 0xffffffff && !*count; + if (left_frozen) { + PACListNode::rate0(metric, hard, soft); + for (int i = 0; i < N/2; ++i) + soft[i+N/2] = PH::qadd(soft[i+N], soft[i+N/2+N]); + } else { + map = PACListTree::decode(metric, message, maps, count, state, hard, soft, frozen[0]); + for (int i = 0; i < N/2; ++i) + soft[i+N/2] = PH::madd(hard[i], vshuf(soft[i+N], map), vshuf(soft[i+N/2+N], map)); + } + bool right_frozen = frozen[1] == 0xffffffff && !*count; + if (right_frozen) { + PACListNode::rate0(metric, hard+N/2, soft); + if (left_frozen) + for (int k = 0; k < TYPE::SIZE; ++k) + map.v[k] = k; + } else { + MAP rmap = PACListTree::decode(metric, message, maps, count, state, hard+N/2, soft, frozen[1]); + for (int i = 0; i < N/2; ++i) + hard[i] = PH::qmul(vshuf(hard[i], rmap), hard[i+N/2]); + if (left_frozen) + map = rmap; + else + map = vshuf(map, rmap); + } + return map; } }; @@ -129,13 +167,33 @@ struct PACListTree { for (int i = 0; i < N/2; ++i) soft[i+N/2] = PH::prod(soft[i+N], soft[i+N/2+N]); - MAP lmap = PACListTree::decode(metric, message, maps, count, state, hard, soft, frozen & ((1<<(1<<(M-1)))-1)); - for (int i = 0; i < N/2; ++i) - soft[i+N/2] = PH::madd(hard[i], vshuf(soft[i+N], lmap), vshuf(soft[i+N/2+N], lmap)); - MAP rmap = PACListTree::decode(metric, message, maps, count, state, hard+N/2, soft, frozen >> (N/2)); - for (int i = 0; i < N/2; ++i) - hard[i] = PH::qmul(vshuf(hard[i], rmap), hard[i+N/2]); - return vshuf(lmap, rmap); + MAP map; + bool left_frozen = (frozen & ((1<<(1<<(M-1)))-1)) == ((1<<(1<<(M-1)))-1) && !*count; + if (left_frozen) { + PACListNode::rate0(metric, hard, soft); + for (int i = 0; i < N/2; ++i) + soft[i+N/2] = PH::qadd(soft[i+N], soft[i+N/2+N]); + } else { + map = PACListTree::decode(metric, message, maps, count, state, hard, soft, frozen & ((1<<(1<<(M-1)))-1)); + for (int i = 0; i < N/2; ++i) + soft[i+N/2] = PH::madd(hard[i], vshuf(soft[i+N], map), vshuf(soft[i+N/2+N], map)); + } + bool right_frozen = frozen >> (N/2) == ((1<<(1<<(M-1)))-1) && !*count; + if (right_frozen) { + PACListNode::rate0(metric, hard+N/2, soft); + if (left_frozen) + for (int k = 0; k < TYPE::SIZE; ++k) + map.v[k] = k; + } else { + MAP rmap = PACListTree::decode(metric, message, maps, count, state, hard+N/2, soft, frozen >> (N/2)); + for (int i = 0; i < N/2; ++i) + hard[i] = PH::qmul(vshuf(hard[i], rmap), hard[i+N/2]); + if (left_frozen) + map = rmap; + else + map = vshuf(map, rmap); + } + return map; } }; @@ -151,13 +209,33 @@ struct PACListTree { for (int i = 0; i < N/2; ++i) soft[i+N/2] = PH::prod(soft[i+N], soft[i+N/2+N]); - MAP lmap = PACListTree::decode(metric, message, maps, count, state, hard, soft, frozen & ((1<<(1<<(M-1)))-1)); - for (int i = 0; i < N/2; ++i) - soft[i+N/2] = PH::madd(hard[i], vshuf(soft[i+N], lmap), vshuf(soft[i+N/2+N], lmap)); - MAP rmap = PACListTree::decode(metric, message, maps, count, state, hard+N/2, soft, frozen >> (N/2)); - for (int i = 0; i < N/2; ++i) - hard[i] = PH::qmul(vshuf(hard[i], rmap), hard[i+N/2]); - return vshuf(lmap, rmap); + MAP map; + bool left_frozen = (frozen & ((1<<(1<<(M-1)))-1)) == ((1<<(1<<(M-1)))-1) && !*count; + if (left_frozen) { + PACListNode::rate0(metric, hard, soft); + for (int i = 0; i < N/2; ++i) + soft[i+N/2] = PH::qadd(soft[i+N], soft[i+N/2+N]); + } else { + map = PACListTree::decode(metric, message, maps, count, state, hard, soft, frozen & ((1<<(1<<(M-1)))-1)); + for (int i = 0; i < N/2; ++i) + soft[i+N/2] = PH::madd(hard[i], vshuf(soft[i+N], map), vshuf(soft[i+N/2+N], map)); + } + bool right_frozen = frozen >> (N/2) == ((1<<(1<<(M-1)))-1) && !*count; + if (right_frozen) { + PACListNode::rate0(metric, hard+N/2, soft); + if (left_frozen) + for (int k = 0; k < TYPE::SIZE; ++k) + map.v[k] = k; + } else { + MAP rmap = PACListTree::decode(metric, message, maps, count, state, hard+N/2, soft, frozen >> (N/2)); + for (int i = 0; i < N/2; ++i) + hard[i] = PH::qmul(vshuf(hard[i], rmap), hard[i+N/2]); + if (left_frozen) + map = rmap; + else + map = vshuf(map, rmap); + } + return map; } }; @@ -173,13 +251,33 @@ struct PACListTree { for (int i = 0; i < N/2; ++i) soft[i+N/2] = PH::prod(soft[i+N], soft[i+N/2+N]); - MAP lmap = PACListTree::decode(metric, message, maps, count, state, hard, soft, frozen & ((1<<(1<<(M-1)))-1)); - for (int i = 0; i < N/2; ++i) - soft[i+N/2] = PH::madd(hard[i], vshuf(soft[i+N], lmap), vshuf(soft[i+N/2+N], lmap)); - MAP rmap = PACListTree::decode(metric, message, maps, count, state, hard+N/2, soft, frozen >> (N/2)); - for (int i = 0; i < N/2; ++i) - hard[i] = PH::qmul(vshuf(hard[i], rmap), hard[i+N/2]); - return vshuf(lmap, rmap); + MAP map; + bool left_frozen = (frozen & ((1<<(1<<(M-1)))-1)) == ((1<<(1<<(M-1)))-1) && !*count; + if (left_frozen) { + PACListNode::rate0(metric, hard, soft); + for (int i = 0; i < N/2; ++i) + soft[i+N/2] = PH::qadd(soft[i+N], soft[i+N/2+N]); + } else { + map = PACListTree::decode(metric, message, maps, count, state, hard, soft, frozen & ((1<<(1<<(M-1)))-1)); + for (int i = 0; i < N/2; ++i) + soft[i+N/2] = PH::madd(hard[i], vshuf(soft[i+N], map), vshuf(soft[i+N/2+N], map)); + } + bool right_frozen = frozen >> (N/2) == ((1<<(1<<(M-1)))-1) && !*count; + if (right_frozen) { + PACListNode::rate0(metric, hard+N/2, soft); + if (left_frozen) + for (int k = 0; k < TYPE::SIZE; ++k) + map.v[k] = k; + } else { + MAP rmap = PACListTree::decode(metric, message, maps, count, state, hard+N/2, soft, frozen >> (N/2)); + for (int i = 0; i < N/2; ++i) + hard[i] = PH::qmul(vshuf(hard[i], rmap), hard[i+N/2]); + if (left_frozen) + map = rmap; + else + map = vshuf(map, rmap); + } + return map; } }; @@ -195,13 +293,33 @@ struct PACListTree { for (int i = 0; i < N/2; ++i) soft[i+N/2] = PH::prod(soft[i+N], soft[i+N/2+N]); - MAP lmap = PACListTree::decode(metric, message, maps, count, state, hard, soft, frozen & ((1<<(1<<(M-1)))-1)); - for (int i = 0; i < N/2; ++i) - soft[i+N/2] = PH::madd(hard[i], vshuf(soft[i+N], lmap), vshuf(soft[i+N/2+N], lmap)); - MAP rmap = PACListTree::decode(metric, message, maps, count, state, hard+N/2, soft, frozen >> (N/2)); - for (int i = 0; i < N/2; ++i) - hard[i] = PH::qmul(vshuf(hard[i], rmap), hard[i+N/2]); - return vshuf(lmap, rmap); + MAP map; + bool left_frozen = (frozen & ((1<<(1<<(M-1)))-1)) == ((1<<(1<<(M-1)))-1) && !*count; + if (left_frozen) { + PACListNode::rate0(metric, hard, soft); + for (int i = 0; i < N/2; ++i) + soft[i+N/2] = PH::qadd(soft[i+N], soft[i+N/2+N]); + } else { + map = PACListTree::decode(metric, message, maps, count, state, hard, soft, frozen & ((1<<(1<<(M-1)))-1)); + for (int i = 0; i < N/2; ++i) + soft[i+N/2] = PH::madd(hard[i], vshuf(soft[i+N], map), vshuf(soft[i+N/2+N], map)); + } + bool right_frozen = frozen >> (N/2) == ((1<<(1<<(M-1)))-1) && !*count; + if (right_frozen) { + PACListNode::rate0(metric, hard+N/2, soft); + if (left_frozen) + for (int k = 0; k < TYPE::SIZE; ++k) + map.v[k] = k; + } else { + MAP rmap = PACListTree::decode(metric, message, maps, count, state, hard+N/2, soft, frozen >> (N/2)); + for (int i = 0; i < N/2; ++i) + hard[i] = PH::qmul(vshuf(hard[i], rmap), hard[i+N/2]); + if (left_frozen) + map = rmap; + else + map = vshuf(map, rmap); + } + return map; } }; @@ -217,21 +335,21 @@ struct PACListTree MAP map; bool left_frozen = frozen & 1; if (left_frozen) { - PACListLeaf::rate0(metric, state, hard, soft); + PACListNode::rate0(metric, state, hard, soft); soft[1] = PH::madd(hard[0], soft[2], soft[3]); } else { - map = PACListLeaf::rate1(metric, message, maps, count, state, hard, soft); + map = PACListNode::rate1(metric, message, maps, count, state, hard, soft); soft[1] = PH::madd(hard[0], vshuf(soft[2], map), vshuf(soft[3], map)); } bool right_frozen = frozen >> 1; if (right_frozen) { - PACListLeaf::rate0(metric, state, hard+1, soft); + PACListNode::rate0(metric, state, hard+1, soft); hard[0] = PH::qmul(hard[0], hard[1]); if (left_frozen) for (int k = 0; k < TYPE::SIZE; ++k) map.v[k] = k; } else { - MAP rmap = PACListLeaf::rate1(metric, message, maps, count, state, hard+1, soft); + MAP rmap = PACListNode::rate1(metric, message, maps, count, state, hard+1, soft); hard[0] = PH::qmul(vshuf(hard[0], rmap), hard[1]); if (left_frozen) map = rmap;