47 for (
j = 0;
j <
n;
j++) {
50 for (
i = 0;
i <
K;
i++) {
69 for (
j = 0;
j <
n;
j++) {
72 for (
i = 0;
i <
K;
i++) {
92 for (
j = 0;
j <
n;
j++) {
96 for (
i = 0;
i <
m;
i++) {
116 for (
j = 0;
j <
n;
j++) {
120 for (
i = 0;
i <
m;
i++) {
139 for (
j = 0;
j <
n;
j++) {
157 for (
j = 0;
j <
n;
j++) {
177 for (
j = 0;
j <
n;
j++) {
200 for (
int j = 0;
j <
n;
j++) {
224 for (
int j =
n - 1;
j >= 0;
j--) {
242 for (
int j = 0;
j <
n;
j++) {
290int Conv_Code_MFD_3[15][3] = {
301 {0117, 01365, 01633},
302 {02353, 02671, 03175},
303 {04767, 05723, 06265},
304 {010533, 010675, 017661},
305 {021645, 035661, 037133},
309int Conv_Code_MFD_4[15][4] = {
314 {013, 015, 015, 017},
315 {025, 027, 033, 037},
316 {053, 067, 071, 075},
317 {0135, 0135, 0147, 0163},
318 {0235, 0275, 0313, 0357},
319 {0463, 0535, 0733, 0745},
320 {0117, 01365, 01633, 01653},
321 {02327, 02353, 02671, 03175},
322 {04767, 05723, 06265, 07455},
323 {011145, 012477, 015573, 016727},
324 {021113, 023175, 035527, 035537},
329int Conv_Code_MFD_5[9][5] = {
333 {07, 07, 07, 05, 05},
334 {017, 017, 013, 015, 015},
335 {037, 027, 033, 025, 035},
336 {075, 071, 073, 065, 057},
337 {0175, 0131, 0135, 0135, 0147},
338 {0257, 0233, 0323, 0271, 0357},
342int Conv_Code_MFD_6[9][6] = {
346 {07, 07, 07, 07, 05, 05},
347 {017, 017, 013, 013, 015, 015},
348 {037, 035, 027, 033, 025, 035},
349 {073, 075, 055, 065, 047, 057},
350 {0173, 0151, 0135, 0135, 0163, 0137},
351 {0253, 0375, 0331, 0235, 0313, 0357},
355int Conv_Code_MFD_7[9][7] = {
356 {0, 0, 0, 0, 0, 0, 0},
357 {0, 0, 0, 0, 0, 0, 0},
358 {0, 0, 0, 0, 0, 0, 0},
359 {07, 07, 07, 07, 05, 05, 05},
360 {017, 017, 013, 013, 013, 015, 015},
361 {035, 027, 025, 027, 033, 035, 037},
362 {053, 075, 065, 075, 047, 067, 057},
363 {0165, 0145, 0173, 0135, 0135, 0147, 0137},
364 {0275, 0253, 0375, 0331, 0235, 0313, 0357},
368int Conv_Code_MFD_8[9][8] = {
369 {0, 0, 0, 0, 0, 0, 0, 0},
370 {0, 0, 0, 0, 0, 0, 0, 0},
371 {0, 0, 0, 0, 0, 0, 0, 0},
372 {07, 07, 05, 05, 05, 07, 07, 07},
373 {017, 017, 013, 013, 013, 015, 015, 017},
374 {037, 033, 025, 025, 035, 033, 027, 037},
375 {057, 073, 051, 065, 075, 047, 067, 057},
376 {0153, 0111, 0165, 0173, 0135, 0135, 0147, 0137},
377 {0275, 0275, 0253, 0371, 0331, 0235, 0313, 0357},
380int maxK_Conv_Code_MFD[9] = {0, 0, 14, 14, 14, 8, 8, 8, 8};
382void get_MFD_gen_pol(
int n,
int K, ivec & gen)
388 it_assert(K >= 3 && K <= maxK_Conv_Code_MFD[2],
"This convolutional code doesn't exist in the tables");
389 gen(0) = Conv_Code_MFD_2[K][0];
390 gen(1) = Conv_Code_MFD_2[K][1];
393 it_assert(K >= 3 && K <= maxK_Conv_Code_MFD[3],
"This convolutional code doesn't exist in the tables");
394 gen(0) = Conv_Code_MFD_3[K][0];
395 gen(1) = Conv_Code_MFD_3[K][1];
396 gen(2) = Conv_Code_MFD_3[K][2];
399 it_assert(K >= 3 && K <= maxK_Conv_Code_MFD[4],
"This convolutional code doesn't exist in the tables");
400 gen(0) = Conv_Code_MFD_4[K][0];
401 gen(1) = Conv_Code_MFD_4[K][1];
402 gen(2) = Conv_Code_MFD_4[K][2];
403 gen(3) = Conv_Code_MFD_4[K][3];
406 it_assert(K >= 3 && K <= maxK_Conv_Code_MFD[5],
"This convolutional code doesn't exist in the tables");
407 gen(0) = Conv_Code_MFD_5[K][0];
408 gen(1) = Conv_Code_MFD_5[K][1];
409 gen(2) = Conv_Code_MFD_5[K][2];
410 gen(3) = Conv_Code_MFD_5[K][3];
411 gen(4) = Conv_Code_MFD_5[K][4];
414 it_assert(K >= 3 && K <= maxK_Conv_Code_MFD[6],
"This convolutional code doesn't exist in the tables");
415 gen(0) = Conv_Code_MFD_6[K][0];
416 gen(1) = Conv_Code_MFD_6[K][1];
417 gen(2) = Conv_Code_MFD_6[K][2];
418 gen(3) = Conv_Code_MFD_6[K][3];
419 gen(4) = Conv_Code_MFD_6[K][4];
420 gen(5) = Conv_Code_MFD_6[K][5];
423 it_assert(K >= 3 && K <= maxK_Conv_Code_MFD[7],
"This convolutional code doesn't exist in the tables");
424 gen(0) = Conv_Code_MFD_7[K][0];
425 gen(1) = Conv_Code_MFD_7[K][1];
426 gen(2) = Conv_Code_MFD_7[K][2];
427 gen(3) = Conv_Code_MFD_7[K][3];
428 gen(4) = Conv_Code_MFD_7[K][4];
429 gen(5) = Conv_Code_MFD_7[K][5];
430 gen(6) = Conv_Code_MFD_7[K][6];
433 it_assert(K >= 3 && K <= maxK_Conv_Code_MFD[8],
"This convolutional code doesn't exist in the tables");
434 gen(0) = Conv_Code_MFD_8[K][0];
435 gen(1) = Conv_Code_MFD_8[K][1];
436 gen(2) = Conv_Code_MFD_8[K][2];
437 gen(3) = Conv_Code_MFD_8[K][3];
438 gen(4) = Conv_Code_MFD_8[K][4];
439 gen(5) = Conv_Code_MFD_8[K][5];
440 gen(6) = Conv_Code_MFD_8[K][6];
441 gen(7) = Conv_Code_MFD_8[K][7];
444 it_assert(
false,
"This convolutional code doesn't exist in the tables");
449int Conv_Code_ODS_2[17][2] = {
470int Conv_Code_ODS_3[14][3] = {
481 {01233, 01375, 01671},
482 {02335, 02531, 03477},
483 {05745, 06471, 07553},
484 {013261, 015167, 017451},
488int Conv_Code_ODS_4[12][4] = {
493 {013, 015, 015, 017},
494 {025, 027, 033, 037},
495 {051, 055, 067, 077},
496 {0117, 0127, 0155, 0171},
497 {0231, 0273, 0327, 0375},
498 {0473, 0513, 0671, 0765},
499 {01173, 01325, 01467, 01751},
500 {02565, 02747, 03311, 03723},
503int maxK_Conv_Code_ODS[5] = {0, 0, 16, 13, 11};
505void get_ODS_gen_pol(
int n,
int K, ivec & gen)
511 it_assert(K >= 3 && K <= maxK_Conv_Code_ODS[2],
"This convolutional code doesn't exist in the tables");
512 gen(0) = Conv_Code_ODS_2[K][0];
513 gen(1) = Conv_Code_ODS_2[K][1];
516 it_assert(K >= 3 && K <= maxK_Conv_Code_ODS[3],
"This convolutional code doesn't exist in the tables");
517 gen(0) = Conv_Code_ODS_3[K][0];
518 gen(1) = Conv_Code_ODS_3[K][1];
519 gen(2) = Conv_Code_ODS_3[K][2];
522 it_assert(K >= 3 && K <= maxK_Conv_Code_ODS[4],
"This convolutional code doesn't exist in the tables");
523 gen(0) = Conv_Code_ODS_4[K][0];
524 gen(1) = Conv_Code_ODS_4[K][1];
525 gen(2) = Conv_Code_ODS_4[K][2];
526 gen(3) = Conv_Code_ODS_4[K][3];
529 it_assert(
false,
"This convolutional code doesn't exist in the tables");
547 it_assert(
false,
"This convolutional code doesn't exist in the tables");
561 it_error_if(
n <= 0,
"Convolutional_Code::set_generator_polynomials(): Invalid code rate");
578 for (
int i = 0;
i <
n;
i++) {
645 output.
set_size(input.size() *
n,
false);
647 for (
int i = 0;
i < input.
size();
i++) {
649 for (
int j = 0;
j <
n;
j++) {
665 output.
set_size((input.size() +
m) *
n,
false);
670 for (
int i = 0;
i < input.
size();
i++) {
672 for (
int j = 0;
j <
n;
j++) {
681 for (
int j = 0;
j <
n;
j++) {
695 output.
set_size(input.size() *
n,
false);
700 for (
int i = 0;
i <
m;
i++) {
705 for (
int i = 0;
i < input.
size();
i++) {
707 for (
int j = 0;
j <
n;
j++) {
725 for (
int j = 0;
j <
n;
j++) {
737 it_error(
"Convolutional_Code::decode(): Hard-decision decoding not implemented");
742 it_error(
"Convolutional_Code::decode(): Hard-decision decoding not implemented");
775 "Convolutional_Code::decode_tail(): Input sequence to short");
793 for (
int l = 0; l <
m; l++) {
884 "Convolutional_Code::decode_tailbite(): Input sequence to short");
889 double best_metric = std::numeric_limits<double>::max();
970 "Convolutional_Code::decode_trunc(): Input sequence to short");
1066 for (
j = 0;
j <
n;
j++) {
1092 int start,
S,
W0,
W1, S0, S1;
1095 for (start = 1; start <
no_states; start++) {
1104 if (S1 < start)
goto node0;
1114 if (S0 < start)
continue;
1115 if (
W0 > 0)
continue;
1186 if (t ==
m)
goto stack;
1201 if (t ==
m)
goto stack;
1312 for (
i = 0;
i <
K;
i++) {
1353 if (
mf <
m)
goto F6;
1464 w += (
in & (1 <<
i)) >>
i;
1480 else if (
v1(
i) >
v2(
i)) {
1494 double t1 = 0,
t2 = 0;
1499 if (
t1 <
t2)
return 1;
1500 else if (
t1 >
t2)
return 0;
Array< T > mid(int pos, int n) const
Get n elements of the array starting from pos.
int size() const
Returns the number of data elements in the array object.
void set_size(int n, bool copy=false)
Resizing an Array<T>.
Array< T > right(int n) const
Get n right elements of the array.
int get_input(const int state)
Returns the input that results in state, that is the MSB of state.
int encoder_state
The current encoder state.
double rate
The rate of the code.
vec sum_metric
Metrics accumulator.
imat path_memory
Path memory (trellis)
int next_state(const int instate, const int input)
Next state from instate given the input.
void encode_tailbite(const bvec &input, bvec &output)
Encode an input binary vector using tailbiting.
void calculate_spectrum(Array< ivec > &spectrum, int dmax, int no_terms)
Calculate spectrum.
void encode_tail(const bvec &input, bvec &output)
Encoding that starts and ends in the zero state.
int trunc_length
The decoder truncation length.
void calc_metric_reverse(const int state, const vec &rx_codeword, double &zero_metric, double &one_metric)
Calculate delta metrics for 0 and 1 input branches reaching state.
bool inverse_tail(const bvec coded_sequence, bvec &input)
Calculate the inverse sequence.
ITPP_EXPORT int reverse_int(int length, int in)
Reverses the bitrepresentation of in (of size length) and converts to an integer.
void reset()
Reset encoder and decoder states.
void calc_metric(const vec &rx_codeword, vec &delta_metrics)
Calculate delta metrics for all possible codewords.
int previous_state(const int state, const int input)
The previous state from state given the input.
int start_state
The encoder start state.
imat output_reverse_int
output in int format for a given state and input
bool catastrophic(void)
Check if catastrophic. Returns true if catastrophic.
int fast(Array< ivec > &spectrum, const int dfree, const int no_terms, const int Cdfree=1000000, const bool test_catastrophic=false)
Cederwall's fast algorithm.
int trunc_ptr
Truncated path memory pointer.
int no_states
Number of states.
virtual void decode_tailbite(const vec &received_signal, bvec &output)
Decode a block of encoded data where encode_tailbite has been used.
void set_code(const CONVOLUTIONAL_CODE_TYPE type_of_code, int inverse_rate, int constraint_length)
Set the code according to built-in tables.
void init_encoder()
Initialise internal encoder state with start state. Has no effect on Tail and Tailbite methods.
virtual void decode_tail(const vec &received_signal, bvec &output)
Decode a block of encoded data where encode_tail has been used.
void encode_bit(const bin &input, bvec &output)
Encode a binary bit starting from the internal encoder state.
void encode_trunc(const bvec &input, bvec &output)
Encode a binary vector starting from the previous encoder state.
int n
Number of generators.
void set_generator_polynomials(const ivec &gen, int constraint_length)
Set generator polynomials. Given in Proakis integer form.
int m
Memory of the encoder.
ITPP_EXPORT int weight_int(int length, int in)
Calculate the Hamming weight of the binary representation of in of size length.
int weight(const int state, const int input)
The weight of the transition from given state with the input given.
ivec gen_pol_rev
Generator polynomials for the reverse code.
int trunc_state
Truncated memory fill state.
virtual void decode_trunc(const vec &received_signal, bvec &output)
Viterbi decoding using truncation of memory (default = 5*K)
CONVOLUTIONAL_CODE_METHOD cc_method
encoding and decoding method
bvec xor_int_table
Auxilary table used by the codec.
ivec gen_pol
Generator polynomials.
Array< bool > visited_state
Visited states.
void distance_profile(ivec &dist_prof, int dmax=100000, bool reverse=false)
Calculate distance profile. If reverse = true calculate for the reverse code instead.
bvec output_reverse(const int state, const int input)
Output on transition (backwards) with input from state.
virtual void decode(const bvec &coded_bits, bvec &decoded_bits)
Decode a bvec of coded data.
int weight_reverse(const int state, const int input)
The weight (of the reverse code) of the transition from given state with the input given.
virtual void encode(const bvec &input, bvec &output)
Encode an input binary vector using specified method (Tail by default)
Binary arithmetic (boolean) class.
Definition of a binary convolutional encoder class.
#define it_error_if(t, s)
Abort if t is true.
#define it_error(s)
Abort unconditionally.
#define it_assert_debug(t, s)
Abort if t is not true and NDEBUG is not defined.
#define it_assert(t, s)
Abort if t is not true.
CONVOLUTIONAL_CODE_TYPE
Type of Convolutional Code.
int pow2i(int x)
Calculate two to the power of x (2^x); x is integer.
int length(const Vec< T > &v)
Length of vector.
int min_index(const Vec< T > &in)
Return the postion of the minimum element in the vector.
Vec< T > reverse(const Vec< T > &in)
Reverse the input vector.
vec spectrum(const vec &v, int nfft, int noverlap)
Power spectrum calculation.
Various functions on vectors and matrices - header file.
int weight_int(int length, int in)
int compare_spectra(ivec v1, ivec v2)
int reverse_int(int length, int in)
Mat< Num_T > elem_mult(const Mat< Num_T > &m1, const Mat< Num_T > &m2)
Element wise multiplication of two matrices.