mirror of
https://github.com/aicodix/code.git
synced 2026-04-27 14:30:36 +00:00
598 lines
13 KiB
C++
598 lines
13 KiB
C++
/*
|
|
Soft decoder for Simplex codes
|
|
|
|
Copyright 2020 Ahmet Inan <inan@aicodix.de>
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
namespace CODE {
|
|
|
|
template <int K>
|
|
class SimplexDecoder
|
|
{
|
|
static const int W = 1 << K;
|
|
static const int N = (1 << K) - 1;
|
|
int8_t mod[W*N];
|
|
|
|
static bool parity(unsigned x)
|
|
{
|
|
x ^= x >> 16;
|
|
x ^= x >> 8;
|
|
x ^= x >> 4;
|
|
x ^= x >> 2;
|
|
x ^= x >> 1;
|
|
return x & 1;
|
|
}
|
|
public:
|
|
SimplexDecoder()
|
|
{
|
|
for (int msg = 0; msg < W; ++msg)
|
|
for (int i = 0; i < N; ++i)
|
|
mod[msg*N+i] = 1 - 2 * parity(msg&(i+1));
|
|
}
|
|
int operator()(const int8_t *code)
|
|
{
|
|
int word = 0, best = 0, next = 0;
|
|
for (int msg = 0; msg < W; ++msg) {
|
|
int sum = 0;
|
|
for (int i = 0; i < N; ++i)
|
|
sum += mod[msg*N+i] * code[i];
|
|
if (sum > best) {
|
|
next = best;
|
|
best = sum;
|
|
word = msg;
|
|
} else if (sum > next) {
|
|
next = sum;
|
|
}
|
|
}
|
|
if (best == next)
|
|
return -1;
|
|
return word;
|
|
}
|
|
};
|
|
|
|
template <>
|
|
class SimplexDecoder<2>
|
|
{
|
|
static const int K = 2;
|
|
static const int W = 1 << K;
|
|
public:
|
|
int operator()(const int8_t *code)
|
|
{
|
|
int tmp[4] = {
|
|
code[0], -code[0],
|
|
code[1] + code[2], code[1] - code[2],
|
|
};
|
|
int sum[W] = {
|
|
tmp[0] + tmp[2],
|
|
tmp[1] + tmp[3],
|
|
tmp[0] - tmp[2],
|
|
tmp[1] - tmp[3],
|
|
};
|
|
int word = 0, best = 0, next = 0;
|
|
for (int msg = 0 ; msg < W; ++msg) {
|
|
if (sum[msg] > best) {
|
|
next = best;
|
|
best = sum[msg];
|
|
word = msg;
|
|
} else if (sum[msg] > next) {
|
|
next = sum[msg];
|
|
}
|
|
}
|
|
if (best == next)
|
|
return -1;
|
|
return word;
|
|
}
|
|
};
|
|
|
|
template <>
|
|
class SimplexDecoder<3>
|
|
{
|
|
static const int K = 3;
|
|
static const int W = 1 << K;
|
|
public:
|
|
int operator()(const int8_t *c)
|
|
{
|
|
int d[8] = {
|
|
c[0], -c[0],
|
|
c[1] + c[2], c[1] - c[2],
|
|
c[3] + c[4], c[3] - c[4],
|
|
c[5] + c[6], c[5] - c[6],
|
|
};
|
|
int e[8] = {
|
|
d[0] + d[2], d[0] - d[2],
|
|
d[1] + d[3], d[1] - d[3],
|
|
d[4] + d[6], d[4] - d[6],
|
|
d[5] + d[7], d[5] - d[7],
|
|
};
|
|
int sum[W] = {
|
|
e[0] + e[4],
|
|
e[2] + e[6],
|
|
e[1] + e[5],
|
|
e[3] + e[7],
|
|
e[0] - e[4],
|
|
e[2] - e[6],
|
|
e[1] - e[5],
|
|
e[3] - e[7],
|
|
};
|
|
int word = 0, best = 0, next = 0;
|
|
for (int msg = 0 ; msg < W; ++msg) {
|
|
if (sum[msg] > best) {
|
|
next = best;
|
|
best = sum[msg];
|
|
word = msg;
|
|
} else if (sum[msg] > next) {
|
|
next = sum[msg];
|
|
}
|
|
}
|
|
if (best == next)
|
|
return -1;
|
|
return word;
|
|
}
|
|
};
|
|
|
|
template <>
|
|
class SimplexDecoder<4>
|
|
{
|
|
static const int K = 4;
|
|
static const int W = 1 << K;
|
|
public:
|
|
int operator()(const int8_t *c)
|
|
{
|
|
int d[16] = {
|
|
c[0], -c[0],
|
|
c[1] + c[2], c[1] - c[2],
|
|
c[3] + c[4], c[3] - c[4],
|
|
c[5] + c[6], c[5] - c[6],
|
|
c[7] + c[8], c[7] - c[8],
|
|
c[9] + c[10], c[9] - c[10],
|
|
c[11] + c[12], c[11] - c[12],
|
|
c[13] + c[14], c[13] - c[14],
|
|
};
|
|
int e[16] = {
|
|
d[0] + d[2], d[0] - d[2],
|
|
d[1] + d[3], d[1] - d[3],
|
|
d[4] + d[6], d[4] - d[6],
|
|
d[5] + d[7], d[5] - d[7],
|
|
d[8] + d[10], d[8] - d[10],
|
|
d[9] + d[11], d[9] - d[11],
|
|
d[12] + d[14], d[12] - d[14],
|
|
d[13] + d[15], d[13] - d[15],
|
|
};
|
|
int f[16] = {
|
|
e[0] + e[4], e[0] - e[4],
|
|
e[1] + e[5], e[1] - e[5],
|
|
e[2] + e[6], e[2] - e[6],
|
|
e[3] + e[7], e[3] - e[7],
|
|
e[8] + e[12], e[8] - e[12],
|
|
e[9] + e[13], e[9] - e[13],
|
|
e[10] + e[14], e[10] - e[14],
|
|
e[11] + e[15], e[11] - e[15],
|
|
};
|
|
int sum[W] = {
|
|
f[0] + f[8],
|
|
f[4] + f[12],
|
|
f[2] + f[10],
|
|
f[6] + f[14],
|
|
f[1] + f[9],
|
|
f[5] + f[13],
|
|
f[3] + f[11],
|
|
f[7] + f[15],
|
|
f[0] - f[8],
|
|
f[4] - f[12],
|
|
f[2] - f[10],
|
|
f[6] - f[14],
|
|
f[1] - f[9],
|
|
f[5] - f[13],
|
|
f[3] - f[11],
|
|
f[7] - f[15],
|
|
};
|
|
int word = 0, best = 0, next = 0;
|
|
for (int msg = 0 ; msg < W; ++msg) {
|
|
if (sum[msg] > best) {
|
|
next = best;
|
|
best = sum[msg];
|
|
word = msg;
|
|
} else if (sum[msg] > next) {
|
|
next = sum[msg];
|
|
}
|
|
}
|
|
if (best == next)
|
|
return -1;
|
|
return word;
|
|
}
|
|
};
|
|
|
|
template <>
|
|
class SimplexDecoder<5>
|
|
{
|
|
static const int K = 5;
|
|
static const int W = 1 << K;
|
|
public:
|
|
int operator()(const int8_t *c)
|
|
{
|
|
int d[32] = {
|
|
c[0], -c[0],
|
|
c[1] + c[2], c[1] - c[2],
|
|
c[3] + c[4], c[3] - c[4],
|
|
c[5] + c[6], c[5] - c[6],
|
|
c[7] + c[8], c[7] - c[8],
|
|
c[9] + c[10], c[9] - c[10],
|
|
c[11] + c[12], c[11] - c[12],
|
|
c[13] + c[14], c[13] - c[14],
|
|
c[15] + c[16], c[15] - c[16],
|
|
c[17] + c[18], c[17] - c[18],
|
|
c[19] + c[20], c[19] - c[20],
|
|
c[21] + c[22], c[21] - c[22],
|
|
c[23] + c[24], c[23] - c[24],
|
|
c[25] + c[26], c[25] - c[26],
|
|
c[27] + c[28], c[27] - c[28],
|
|
c[29] + c[30], c[29] - c[30],
|
|
};
|
|
int e[32] = {
|
|
d[0] + d[2], d[0] - d[2],
|
|
d[1] + d[3], d[1] - d[3],
|
|
d[4] + d[6], d[4] - d[6],
|
|
d[5] + d[7], d[5] - d[7],
|
|
d[8] + d[10], d[8] - d[10],
|
|
d[9] + d[11], d[9] - d[11],
|
|
d[12] + d[14], d[12] - d[14],
|
|
d[13] + d[15], d[13] - d[15],
|
|
d[16] + d[18], d[16] - d[18],
|
|
d[17] + d[19], d[17] - d[19],
|
|
d[20] + d[22], d[20] - d[22],
|
|
d[21] + d[23], d[21] - d[23],
|
|
d[24] + d[26], d[24] - d[26],
|
|
d[25] + d[27], d[25] - d[27],
|
|
d[28] + d[30], d[28] - d[30],
|
|
d[29] + d[31], d[29] - d[31],
|
|
};
|
|
int f[32] = {
|
|
e[0] + e[4], e[0] - e[4],
|
|
e[1] + e[5], e[1] - e[5],
|
|
e[2] + e[6], e[2] - e[6],
|
|
e[3] + e[7], e[3] - e[7],
|
|
e[8] + e[12], e[8] - e[12],
|
|
e[9] + e[13], e[9] - e[13],
|
|
e[10] + e[14], e[10] - e[14],
|
|
e[11] + e[15], e[11] - e[15],
|
|
e[16] + e[20], e[16] - e[20],
|
|
e[17] + e[21], e[17] - e[21],
|
|
e[18] + e[22], e[18] - e[22],
|
|
e[19] + e[23], e[19] - e[23],
|
|
e[24] + e[28], e[24] - e[28],
|
|
e[25] + e[29], e[25] - e[29],
|
|
e[26] + e[30], e[26] - e[30],
|
|
e[27] + e[31], e[27] - e[31],
|
|
};
|
|
int g[32] = {
|
|
f[0] + f[8], f[0] - f[8],
|
|
f[1] + f[9], f[1] - f[9],
|
|
f[2] + f[10], f[2] - f[10],
|
|
f[3] + f[11], f[3] - f[11],
|
|
f[4] + f[12], f[4] - f[12],
|
|
f[5] + f[13], f[5] - f[13],
|
|
f[6] + f[14], f[6] - f[14],
|
|
f[7] + f[15], f[7] - f[15],
|
|
f[16] + f[24], f[16] - f[24],
|
|
f[17] + f[25], f[17] - f[25],
|
|
f[18] + f[26], f[18] - f[26],
|
|
f[19] + f[27], f[19] - f[27],
|
|
f[20] + f[28], f[20] - f[28],
|
|
f[21] + f[29], f[21] - f[29],
|
|
f[22] + f[30], f[22] - f[30],
|
|
f[23] + f[31], f[23] - f[31],
|
|
};
|
|
int sum[W] = {
|
|
g[0] + g[16],
|
|
g[8] + g[24],
|
|
g[4] + g[20],
|
|
g[12] + g[28],
|
|
g[2] + g[18],
|
|
g[10] + g[26],
|
|
g[6] + g[22],
|
|
g[14] + g[30],
|
|
g[1] + g[17],
|
|
g[9] + g[25],
|
|
g[5] + g[21],
|
|
g[13] + g[29],
|
|
g[3] + g[19],
|
|
g[11] + g[27],
|
|
g[7] + g[23],
|
|
g[15] + g[31],
|
|
g[0] - g[16],
|
|
g[8] - g[24],
|
|
g[4] - g[20],
|
|
g[12] - g[28],
|
|
g[2] - g[18],
|
|
g[10] - g[26],
|
|
g[6] - g[22],
|
|
g[14] - g[30],
|
|
g[1] - g[17],
|
|
g[9] - g[25],
|
|
g[5] - g[21],
|
|
g[13] - g[29],
|
|
g[3] - g[19],
|
|
g[11] - g[27],
|
|
g[7] - g[23],
|
|
g[15] - g[31],
|
|
};
|
|
int word = 0, best = 0, next = 0;
|
|
for (int msg = 0 ; msg < W; ++msg) {
|
|
if (sum[msg] > best) {
|
|
next = best;
|
|
best = sum[msg];
|
|
word = msg;
|
|
} else if (sum[msg] > next) {
|
|
next = sum[msg];
|
|
}
|
|
}
|
|
if (best == next)
|
|
return -1;
|
|
return word;
|
|
}
|
|
};
|
|
|
|
template <>
|
|
class SimplexDecoder<6>
|
|
{
|
|
static const int K = 6;
|
|
static const int W = 1 << K;
|
|
public:
|
|
int operator()(const int8_t *c)
|
|
{
|
|
int d[64] = {
|
|
c[0], -c[0],
|
|
c[1] + c[2], c[1] - c[2],
|
|
c[3] + c[4], c[3] - c[4],
|
|
c[5] + c[6], c[5] - c[6],
|
|
c[7] + c[8], c[7] - c[8],
|
|
c[9] + c[10], c[9] - c[10],
|
|
c[11] + c[12], c[11] - c[12],
|
|
c[13] + c[14], c[13] - c[14],
|
|
c[15] + c[16], c[15] - c[16],
|
|
c[17] + c[18], c[17] - c[18],
|
|
c[19] + c[20], c[19] - c[20],
|
|
c[21] + c[22], c[21] - c[22],
|
|
c[23] + c[24], c[23] - c[24],
|
|
c[25] + c[26], c[25] - c[26],
|
|
c[27] + c[28], c[27] - c[28],
|
|
c[29] + c[30], c[29] - c[30],
|
|
c[31] + c[32], c[31] - c[32],
|
|
c[33] + c[34], c[33] - c[34],
|
|
c[35] + c[36], c[35] - c[36],
|
|
c[37] + c[38], c[37] - c[38],
|
|
c[39] + c[40], c[39] - c[40],
|
|
c[41] + c[42], c[41] - c[42],
|
|
c[43] + c[44], c[43] - c[44],
|
|
c[45] + c[46], c[45] - c[46],
|
|
c[47] + c[48], c[47] - c[48],
|
|
c[49] + c[50], c[49] - c[50],
|
|
c[51] + c[52], c[51] - c[52],
|
|
c[53] + c[54], c[53] - c[54],
|
|
c[55] + c[56], c[55] - c[56],
|
|
c[57] + c[58], c[57] - c[58],
|
|
c[59] + c[60], c[59] - c[60],
|
|
c[61] + c[62], c[61] - c[62],
|
|
};
|
|
int e[64] = {
|
|
d[0] + d[2], d[0] - d[2],
|
|
d[1] + d[3], d[1] - d[3],
|
|
d[4] + d[6], d[4] - d[6],
|
|
d[5] + d[7], d[5] - d[7],
|
|
d[8] + d[10], d[8] - d[10],
|
|
d[9] + d[11], d[9] - d[11],
|
|
d[12] + d[14], d[12] - d[14],
|
|
d[13] + d[15], d[13] - d[15],
|
|
d[16] + d[18], d[16] - d[18],
|
|
d[17] + d[19], d[17] - d[19],
|
|
d[20] + d[22], d[20] - d[22],
|
|
d[21] + d[23], d[21] - d[23],
|
|
d[24] + d[26], d[24] - d[26],
|
|
d[25] + d[27], d[25] - d[27],
|
|
d[28] + d[30], d[28] - d[30],
|
|
d[29] + d[31], d[29] - d[31],
|
|
d[32] + d[34], d[32] - d[34],
|
|
d[33] + d[35], d[33] - d[35],
|
|
d[36] + d[38], d[36] - d[38],
|
|
d[37] + d[39], d[37] - d[39],
|
|
d[40] + d[42], d[40] - d[42],
|
|
d[41] + d[43], d[41] - d[43],
|
|
d[44] + d[46], d[44] - d[46],
|
|
d[45] + d[47], d[45] - d[47],
|
|
d[48] + d[50], d[48] - d[50],
|
|
d[49] + d[51], d[49] - d[51],
|
|
d[52] + d[54], d[52] - d[54],
|
|
d[53] + d[55], d[53] - d[55],
|
|
d[56] + d[58], d[56] - d[58],
|
|
d[57] + d[59], d[57] - d[59],
|
|
d[60] + d[62], d[60] - d[62],
|
|
d[61] + d[63], d[61] - d[63],
|
|
};
|
|
int f[64] = {
|
|
e[0] + e[4], e[0] - e[4],
|
|
e[1] + e[5], e[1] - e[5],
|
|
e[2] + e[6], e[2] - e[6],
|
|
e[3] + e[7], e[3] - e[7],
|
|
e[8] + e[12], e[8] - e[12],
|
|
e[9] + e[13], e[9] - e[13],
|
|
e[10] + e[14], e[10] - e[14],
|
|
e[11] + e[15], e[11] - e[15],
|
|
e[16] + e[20], e[16] - e[20],
|
|
e[17] + e[21], e[17] - e[21],
|
|
e[18] + e[22], e[18] - e[22],
|
|
e[19] + e[23], e[19] - e[23],
|
|
e[24] + e[28], e[24] - e[28],
|
|
e[25] + e[29], e[25] - e[29],
|
|
e[26] + e[30], e[26] - e[30],
|
|
e[27] + e[31], e[27] - e[31],
|
|
e[32] + e[36], e[32] - e[36],
|
|
e[33] + e[37], e[33] - e[37],
|
|
e[34] + e[38], e[34] - e[38],
|
|
e[35] + e[39], e[35] - e[39],
|
|
e[40] + e[44], e[40] - e[44],
|
|
e[41] + e[45], e[41] - e[45],
|
|
e[42] + e[46], e[42] - e[46],
|
|
e[43] + e[47], e[43] - e[47],
|
|
e[48] + e[52], e[48] - e[52],
|
|
e[49] + e[53], e[49] - e[53],
|
|
e[50] + e[54], e[50] - e[54],
|
|
e[51] + e[55], e[51] - e[55],
|
|
e[56] + e[60], e[56] - e[60],
|
|
e[57] + e[61], e[57] - e[61],
|
|
e[58] + e[62], e[58] - e[62],
|
|
e[59] + e[63], e[59] - e[63],
|
|
};
|
|
int g[64] = {
|
|
f[0] + f[8], f[0] - f[8],
|
|
f[1] + f[9], f[1] - f[9],
|
|
f[2] + f[10], f[2] - f[10],
|
|
f[3] + f[11], f[3] - f[11],
|
|
f[4] + f[12], f[4] - f[12],
|
|
f[5] + f[13], f[5] - f[13],
|
|
f[6] + f[14], f[6] - f[14],
|
|
f[7] + f[15], f[7] - f[15],
|
|
f[16] + f[24], f[16] - f[24],
|
|
f[17] + f[25], f[17] - f[25],
|
|
f[18] + f[26], f[18] - f[26],
|
|
f[19] + f[27], f[19] - f[27],
|
|
f[20] + f[28], f[20] - f[28],
|
|
f[21] + f[29], f[21] - f[29],
|
|
f[22] + f[30], f[22] - f[30],
|
|
f[23] + f[31], f[23] - f[31],
|
|
f[32] + f[40], f[32] - f[40],
|
|
f[33] + f[41], f[33] - f[41],
|
|
f[34] + f[42], f[34] - f[42],
|
|
f[35] + f[43], f[35] - f[43],
|
|
f[36] + f[44], f[36] - f[44],
|
|
f[37] + f[45], f[37] - f[45],
|
|
f[38] + f[46], f[38] - f[46],
|
|
f[39] + f[47], f[39] - f[47],
|
|
f[48] + f[56], f[48] - f[56],
|
|
f[49] + f[57], f[49] - f[57],
|
|
f[50] + f[58], f[50] - f[58],
|
|
f[51] + f[59], f[51] - f[59],
|
|
f[52] + f[60], f[52] - f[60],
|
|
f[53] + f[61], f[53] - f[61],
|
|
f[54] + f[62], f[54] - f[62],
|
|
f[55] + f[63], f[55] - f[63],
|
|
};
|
|
int h[64] = {
|
|
g[0] + g[16], g[0] - g[16],
|
|
g[1] + g[17], g[1] - g[17],
|
|
g[2] + g[18], g[2] - g[18],
|
|
g[3] + g[19], g[3] - g[19],
|
|
g[4] + g[20], g[4] - g[20],
|
|
g[5] + g[21], g[5] - g[21],
|
|
g[6] + g[22], g[6] - g[22],
|
|
g[7] + g[23], g[7] - g[23],
|
|
g[8] + g[24], g[8] - g[24],
|
|
g[9] + g[25], g[9] - g[25],
|
|
g[10] + g[26], g[10] - g[26],
|
|
g[11] + g[27], g[11] - g[27],
|
|
g[12] + g[28], g[12] - g[28],
|
|
g[13] + g[29], g[13] - g[29],
|
|
g[14] + g[30], g[14] - g[30],
|
|
g[15] + g[31], g[15] - g[31],
|
|
g[32] + g[48], g[32] - g[48],
|
|
g[33] + g[49], g[33] - g[49],
|
|
g[34] + g[50], g[34] - g[50],
|
|
g[35] + g[51], g[35] - g[51],
|
|
g[36] + g[52], g[36] - g[52],
|
|
g[37] + g[53], g[37] - g[53],
|
|
g[38] + g[54], g[38] - g[54],
|
|
g[39] + g[55], g[39] - g[55],
|
|
g[40] + g[56], g[40] - g[56],
|
|
g[41] + g[57], g[41] - g[57],
|
|
g[42] + g[58], g[42] - g[58],
|
|
g[43] + g[59], g[43] - g[59],
|
|
g[44] + g[60], g[44] - g[60],
|
|
g[45] + g[61], g[45] - g[61],
|
|
g[46] + g[62], g[46] - g[62],
|
|
g[47] + g[63], g[47] - g[63],
|
|
};
|
|
int sum[W] = {
|
|
h[0] + h[32],
|
|
h[16] + h[48],
|
|
h[8] + h[40],
|
|
h[24] + h[56],
|
|
h[4] + h[36],
|
|
h[20] + h[52],
|
|
h[12] + h[44],
|
|
h[28] + h[60],
|
|
h[2] + h[34],
|
|
h[18] + h[50],
|
|
h[10] + h[42],
|
|
h[26] + h[58],
|
|
h[6] + h[38],
|
|
h[22] + h[54],
|
|
h[14] + h[46],
|
|
h[30] + h[62],
|
|
h[1] + h[33],
|
|
h[17] + h[49],
|
|
h[9] + h[41],
|
|
h[25] + h[57],
|
|
h[5] + h[37],
|
|
h[21] + h[53],
|
|
h[13] + h[45],
|
|
h[29] + h[61],
|
|
h[3] + h[35],
|
|
h[19] + h[51],
|
|
h[11] + h[43],
|
|
h[27] + h[59],
|
|
h[7] + h[39],
|
|
h[23] + h[55],
|
|
h[15] + h[47],
|
|
h[31] + h[63],
|
|
h[0] - h[32],
|
|
h[16] - h[48],
|
|
h[8] - h[40],
|
|
h[24] - h[56],
|
|
h[4] - h[36],
|
|
h[20] - h[52],
|
|
h[12] - h[44],
|
|
h[28] - h[60],
|
|
h[2] - h[34],
|
|
h[18] - h[50],
|
|
h[10] - h[42],
|
|
h[26] - h[58],
|
|
h[6] - h[38],
|
|
h[22] - h[54],
|
|
h[14] - h[46],
|
|
h[30] - h[62],
|
|
h[1] - h[33],
|
|
h[17] - h[49],
|
|
h[9] - h[41],
|
|
h[25] - h[57],
|
|
h[5] - h[37],
|
|
h[21] - h[53],
|
|
h[13] - h[45],
|
|
h[29] - h[61],
|
|
h[3] - h[35],
|
|
h[19] - h[51],
|
|
h[11] - h[43],
|
|
h[27] - h[59],
|
|
h[7] - h[39],
|
|
h[23] - h[55],
|
|
h[15] - h[47],
|
|
h[31] - h[63],
|
|
};
|
|
int word = 0, best = 0, next = 0;
|
|
for (int msg = 0 ; msg < W; ++msg) {
|
|
if (sum[msg] > best) {
|
|
next = best;
|
|
best = sum[msg];
|
|
word = msg;
|
|
} else if (sum[msg] > next) {
|
|
next = sum[msg];
|
|
}
|
|
}
|
|
if (best == next)
|
|
return -1;
|
|
return word;
|
|
}
|
|
};
|
|
|
|
}
|
|
|