-
Notifications
You must be signed in to change notification settings - Fork 4
/
dec_vector.hh
115 lines (110 loc) · 3.42 KB
/
dec_vector.hh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/*
vector IRA-LDPC decoder reference code
Copyright 2019 Ahmet Inan <inan@aicodix.de>
*/
#pragma once
#include "cnp_vector.hh"
void nul_vector(int *output)
{
for (int i = 0; i < VECTOR_SCALARS; ++i)
output[i] = 0;
}
void cpy_vector(int *output, const int *input)
{
for (int i = 0; i < VECTOR_SCALARS; ++i)
output[i] = input[i];
}
void rot_vector(int *output, const int *input, int shift)
{
for (int i = 0; i < VECTOR_SCALARS; ++i)
output[(i + shift + VECTOR_SCALARS) % VECTOR_SCALARS] = input[i];
}
void add_vector(int *o, const int *a, const int *b)
{
for (int i = 0; i < VECTOR_SCALARS; ++i)
o[i] = min_scalar(max_scalar(a[i] + b[i], -VMAG_MAX), VMAG_MAX);
}
void sub_vector(int *o, const int *a, const int *b)
{
for (int i = 0; i < VECTOR_SCALARS; ++i)
o[i] = min_scalar(max_scalar(a[i] - b[i], -VMAG_MAX), VMAG_MAX);
}
void dec_vector(int *output, const int *input)
{
int vars[CODE_VECTORS][VECTOR_SCALARS];
int q = parities / BLOCK_VECTORS;
for (int i = 0; i < CODE_BLOCKS - q; ++i)
for (int j = 0; j < BLOCK_VECTORS; ++j)
for (int n = 0; n < VECTOR_SCALARS; ++n)
vars[BLOCK_VECTORS*i+j][n] = min_scalar(max_scalar(input[BLOCK_SCALARS*i+BLOCK_VECTORS*n+j], -VMAG_MAX), VMAG_MAX);
int R = parities * VECTOR_SCALARS;
int K = CODE_SCALARS - R;
int messages = CODE_VECTORS - parities;
for (int i = 0; i < q; ++i)
for (int j = 0; j < BLOCK_VECTORS; ++j)
for (int n = 0; n < VECTOR_SCALARS; ++n)
vars[messages+BLOCK_VECTORS*i+j][n] = min_scalar(max_scalar(input[K+q*(BLOCK_VECTORS*n+j)+i], -VMAG_MAX), VMAG_MAX);
int wd_flags[VECTOR_LOCATIONS_MAX];
int bnls[VECTOR_LOCATIONS_MAX][VECTOR_SCALARS] = { { 0 } };
for (int seq = 0; seq < ITERATIONS_MAX; ++seq) {
int loc = 0;
for (int pty = 0; pty < parities; ++pty) {
int cnt = counts[pty];
int *off = offsets + loc;
int *shi = shifts + loc;
int *wdf = wd_flags + loc;
int (*bnl)[VECTOR_SCALARS] = bnls + loc;
int tmp[COUNT_MAX][VECTOR_SCALARS];
int inp[COUNT_MAX][VECTOR_SCALARS];
int prev_val;
for (int num = 0; num < cnt; ++num) {
if (!seq) {
if (num)
wdf[num] = off[num-1] == off[num];
else
wdf[num] = 0;
}
rot_vector(tmp[num], vars[off[num]], -shi[num]);
if (off[num] == CODE_VECTORS-1 && shi[num] == VECTOR_SCALARS-1) {
prev_val = tmp[num][0];
tmp[num][0] = VMAG_MAX;
}
sub_vector(inp[num], tmp[num], bnl[num]);
}
int out[COUNT_MAX][VECTOR_SCALARS];
cnp_vector(out, inp, bnl, cnt, 1);
int first_wdf;
for (int num = 0; num < cnt; ++num) {
add_vector(tmp[num], inp[num], out[num]);
if (off[num] == CODE_VECTORS-1 && shi[num] == VECTOR_SCALARS-1)
tmp[num][0] = prev_val;
if (!wdf[num]) {
cpy_vector(bnl[num], out[num]);
rot_vector(vars[off[num]], tmp[num], shi[num]);
} else if (!seq) {
nul_vector(bnl[num]);
}
if (num) {
if (off[num-1] == off[num]) {
wdf[num-1] = wdf[num];
} else {
wdf[num-1] = first_wdf;
first_wdf = wdf[num];
}
} else {
first_wdf = wdf[num];
}
}
wdf[cnt-1] = first_wdf;
loc += cnt;
}
}
for (int i = 0; i < CODE_BLOCKS - q; ++i)
for (int j = 0; j < BLOCK_VECTORS; ++j)
for (int n = 0; n < VECTOR_SCALARS; ++n)
output[BLOCK_SCALARS*i+BLOCK_VECTORS*n+j] = vars[BLOCK_VECTORS*i+j][n];
for (int i = 0; i < q; ++i)
for (int j = 0; j < BLOCK_VECTORS; ++j)
for (int n = 0; n < VECTOR_SCALARS; ++n)
output[K+q*(BLOCK_VECTORS*n+j)+i] = vars[messages+BLOCK_VECTORS*i+j][n];
}