From 30b1a603b5f353fc5b1e853740775d1577755add Mon Sep 17 00:00:00 2001 From: Ahmet Inan Date: Wed, 14 Jul 2021 01:31:26 +0200 Subject: [PATCH] simplified branches where all but the last bit is frozen --- polar_decoder.hh | 30 ++++++++++++++++++++++++++ polar_list_decoder.hh | 50 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) diff --git a/polar_decoder.hh b/polar_decoder.hh index c50ad86..7090dc0 100644 --- a/polar_decoder.hh +++ b/polar_decoder.hh @@ -39,6 +39,16 @@ struct PolarNode trans(*message, hard); *message += N; } + static void rep(TYPE **message, TYPE *hard, TYPE *soft) + { + for (int h = N; h; h /= 2) + for (int i = 0; i < h/2; ++i) + soft[i+h/2] = PH::qadd(soft[i+h], soft[i+h/2+h]); + TYPE hrd = PH::signum(soft[1]); + for (int i = 0; i < N; ++i) + hard[i] = hrd; + *(*message)++ = hrd; + } }; template @@ -86,6 +96,8 @@ struct PolarTree soft[i+N/2] = PH::prod(soft[i+N], soft[i+N/2+N]); if (frozen[0] == 0xffffffff) PolarNode::rate0(hard); + else if (frozen[0] == 0x7fffffff) + PolarNode::rep(message, hard, soft); else if (frozen[0] == 0) PolarNode::rate1(message, hard, soft); else @@ -94,6 +106,8 @@ struct PolarTree soft[i+N/2] = PH::madd(hard[i], soft[i+N], soft[i+N/2+N]); if (frozen[1] == 0xffffffff) PolarNode::rate0(hard+N/2); + else if (frozen[1] == 0x7fffffff) + PolarNode::rep(message, hard+N/2, soft); else if (frozen[1] == 0) PolarNode::rate1(message, hard+N/2, soft); else @@ -115,6 +129,8 @@ struct PolarTree soft[i+N/2] = PH::prod(soft[i+N], soft[i+N/2+N]); if ((frozen & ((1<<(1<<(M-1)))-1)) == ((1<<(1<<(M-1)))-1)) PolarNode::rate0(hard); + else if ((frozen & ((1<<(1<<(M-1)))-1)) == ((1<<((1<<(M-1))-1))-1)) + PolarNode::rep(message, hard, soft); else if ((frozen & ((1<<(1<<(M-1)))-1)) == 0) PolarNode::rate1(message, hard, soft); else @@ -123,6 +139,8 @@ struct PolarTree soft[i+N/2] = PH::madd(hard[i], soft[i+N], soft[i+N/2+N]); if (frozen >> (N/2) == ((1<<(1<<(M-1)))-1)) PolarNode::rate0(hard+N/2); + else if (frozen >> (N/2) == ((1<<((1<<(M-1))-1))-1)) + PolarNode::rep(message, hard+N/2, soft); else if (frozen >> (N/2) == 0) PolarNode::rate1(message, hard+N/2, soft); else @@ -144,6 +162,8 @@ struct PolarTree soft[i+N/2] = PH::prod(soft[i+N], soft[i+N/2+N]); if ((frozen & ((1<<(1<<(M-1)))-1)) == ((1<<(1<<(M-1)))-1)) PolarNode::rate0(hard); + else if ((frozen & ((1<<(1<<(M-1)))-1)) == ((1<<((1<<(M-1))-1))-1)) + PolarNode::rep(message, hard, soft); else if ((frozen & ((1<<(1<<(M-1)))-1)) == 0) PolarNode::rate1(message, hard, soft); else @@ -152,6 +172,8 @@ struct PolarTree soft[i+N/2] = PH::madd(hard[i], soft[i+N], soft[i+N/2+N]); if (frozen >> (N/2) == ((1<<(1<<(M-1)))-1)) PolarNode::rate0(hard+N/2); + else if (frozen >> (N/2) == ((1<<((1<<(M-1))-1))-1)) + PolarNode::rep(message, hard+N/2, soft); else if (frozen >> (N/2) == 0) PolarNode::rate1(message, hard+N/2, soft); else @@ -173,6 +195,8 @@ struct PolarTree soft[i+N/2] = PH::prod(soft[i+N], soft[i+N/2+N]); if ((frozen & ((1<<(1<<(M-1)))-1)) == ((1<<(1<<(M-1)))-1)) PolarNode::rate0(hard); + else if ((frozen & ((1<<(1<<(M-1)))-1)) == ((1<<((1<<(M-1))-1))-1)) + PolarNode::rep(message, hard, soft); else if ((frozen & ((1<<(1<<(M-1)))-1)) == 0) PolarNode::rate1(message, hard, soft); else @@ -181,6 +205,8 @@ struct PolarTree soft[i+N/2] = PH::madd(hard[i], soft[i+N], soft[i+N/2+N]); if (frozen >> (N/2) == ((1<<(1<<(M-1)))-1)) PolarNode::rate0(hard+N/2); + else if (frozen >> (N/2) == ((1<<((1<<(M-1))-1))-1)) + PolarNode::rep(message, hard+N/2, soft); else if (frozen >> (N/2) == 0) PolarNode::rate1(message, hard+N/2, soft); else @@ -202,6 +228,8 @@ struct PolarTree soft[i+N/2] = PH::prod(soft[i+N], soft[i+N/2+N]); if ((frozen & ((1<<(1<<(M-1)))-1)) == ((1<<(1<<(M-1)))-1)) PolarNode::rate0(hard); + else if ((frozen & ((1<<(1<<(M-1)))-1)) == ((1<<((1<<(M-1))-1))-1)) + PolarNode::rep(message, hard, soft); else if ((frozen & ((1<<(1<<(M-1)))-1)) == 0) PolarNode::rate1(message, hard, soft); else @@ -210,6 +238,8 @@ struct PolarTree soft[i+N/2] = PH::madd(hard[i], soft[i+N], soft[i+N/2+N]); if (frozen >> (N/2) == ((1<<(1<<(M-1)))-1)) PolarNode::rate0(hard+N/2); + else if (frozen >> (N/2) == ((1<<((1<<(M-1))-1))-1)) + PolarNode::rep(message, hard+N/2, soft); else if (frozen >> (N/2) == 0) PolarNode::rate1(message, hard+N/2, soft); else diff --git a/polar_list_decoder.hh b/polar_list_decoder.hh index a558c72..aa98980 100644 --- a/polar_list_decoder.hh +++ b/polar_list_decoder.hh @@ -31,6 +31,36 @@ struct PolarListNode map.v[k] = k; return map; } + static MAP rep(PATH *metric, TYPE *message, MAP *maps, int *count, TYPE *hard, TYPE *soft) + { + PATH fork[2*TYPE::SIZE]; + for (int k = 0; k < TYPE::SIZE; ++k) + fork[k] = fork[k+TYPE::SIZE] = metric[k]; + for (int i = 0; i < N; ++i) + for (int k = 0; k < TYPE::SIZE; ++k) + if (soft[i+N].v[k] < 0) + fork[k] -= soft[i+N].v[k]; + else + fork[k+TYPE::SIZE] += soft[i+N].v[k]; + int perm[2*TYPE::SIZE]; + for (int k = 0; k < 2*TYPE::SIZE; ++k) + perm[k] = k; + std::nth_element(perm, perm+TYPE::SIZE, perm+2*TYPE::SIZE, [fork](int a, int b){ return fork[a] < fork[b]; }); + for (int k = 0; k < TYPE::SIZE; ++k) + metric[k] = fork[perm[k]]; + MAP map; + for (int k = 0; k < TYPE::SIZE; ++k) + map.v[k] = perm[k] % TYPE::SIZE; + TYPE hrd; + for (int k = 0; k < TYPE::SIZE; ++k) + hrd.v[k] = perm[k] < TYPE::SIZE ? 1 : -1; + for (int i = 0; i < N; ++i) + hard[i] = hrd; + message[*count] = hrd; + maps[*count] = map; + ++*count; + return map; + } }; template @@ -117,12 +147,16 @@ struct PolarListTree MAP lmap, rmap; if (frozen[0] == 0xffffffff) lmap = PolarListNode::rate0(metric, hard, soft); + else if (frozen[0] == 0x7fffffff) + lmap = PolarListNode::rep(metric, message, maps, count, hard, soft); 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 if (frozen[1] == 0x7fffffff) + rmap = PolarListNode::rep(metric, message, maps, count, hard+N/2, soft); else rmap = PolarListTree::decode(metric, message, maps, count, hard+N/2, soft, frozen[1]); for (int i = 0; i < N/2; ++i) @@ -146,12 +180,16 @@ struct PolarListTree MAP lmap, rmap; if ((frozen & ((1<<(1<<(M-1)))-1)) == ((1<<(1<<(M-1)))-1)) lmap = PolarListNode::rate0(metric, hard, soft); + else if ((frozen & ((1<<(1<<(M-1)))-1)) == ((1<<((1<<(M-1))-1))-1)) + lmap = PolarListNode::rep(metric, message, maps, count, hard, soft); 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 if (frozen >> (N/2) == ((1<<((1<<(M-1))-1))-1)) + rmap = PolarListNode::rep(metric, message, maps, count, hard+N/2, soft); else rmap = PolarListTree::decode(metric, message, maps, count, hard+N/2, soft, frozen >> (N/2)); for (int i = 0; i < N/2; ++i) @@ -175,12 +213,16 @@ struct PolarListTree MAP lmap, rmap; if ((frozen & ((1<<(1<<(M-1)))-1)) == ((1<<(1<<(M-1)))-1)) lmap = PolarListNode::rate0(metric, hard, soft); + else if ((frozen & ((1<<(1<<(M-1)))-1)) == ((1<<((1<<(M-1))-1))-1)) + lmap = PolarListNode::rep(metric, message, maps, count, hard, soft); 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 if (frozen >> (N/2) == ((1<<((1<<(M-1))-1))-1)) + rmap = PolarListNode::rep(metric, message, maps, count, hard+N/2, soft); else rmap = PolarListTree::decode(metric, message, maps, count, hard+N/2, soft, frozen >> (N/2)); for (int i = 0; i < N/2; ++i) @@ -204,12 +246,16 @@ struct PolarListTree MAP lmap, rmap; if ((frozen & ((1<<(1<<(M-1)))-1)) == ((1<<(1<<(M-1)))-1)) lmap = PolarListNode::rate0(metric, hard, soft); + else if ((frozen & ((1<<(1<<(M-1)))-1)) == ((1<<((1<<(M-1))-1))-1)) + lmap = PolarListNode::rep(metric, message, maps, count, hard, soft); 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 if (frozen >> (N/2) == ((1<<((1<<(M-1))-1))-1)) + rmap = PolarListNode::rep(metric, message, maps, count, hard+N/2, soft); else rmap = PolarListTree::decode(metric, message, maps, count, hard+N/2, soft, frozen >> (N/2)); for (int i = 0; i < N/2; ++i) @@ -233,12 +279,16 @@ struct PolarListTree MAP lmap, rmap; if ((frozen & ((1<<(1<<(M-1)))-1)) == ((1<<(1<<(M-1)))-1)) lmap = PolarListNode::rate0(metric, hard, soft); + else if ((frozen & ((1<<(1<<(M-1)))-1)) == ((1<<((1<<(M-1))-1))-1)) + lmap = PolarListNode::rep(metric, message, maps, count, hard, soft); 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 if (frozen >> (N/2) == ((1<<((1<<(M-1))-1))-1)) + rmap = PolarListNode::rep(metric, message, maps, count, hard+N/2, soft); else rmap = PolarListTree::decode(metric, message, maps, count, hard+N/2, soft, frozen >> (N/2)); for (int i = 0; i < N/2; ++i)