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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
/* -*- c++ -*- */
/*
* Copyright 2013-2014 Free Software Foundation, Inc.
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 3, or (at your
* option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <ldpc_R_U_encoder_impl.h>
#include <sstream>
namespace gr {
namespace fec {
namespace code {
generic_encoder::sptr
ldpc_R_U_encoder::make(ldpc_par_chk_mtrx *H_obj)
{
return generic_encoder::sptr
(new ldpc_R_U_encoder_impl(H_obj));
}
ldpc_R_U_encoder_impl::ldpc_R_U_encoder_impl(ldpc_par_chk_mtrx *H_obj)
: generic_encoder("ldpc_R_U_encoder")
{
// LDPC parity check matrix to use for encoding
d_H = H_obj;
// Set frame size to k, the # of bits in the information word
// All buffers and settings will be based on this value.
set_frame_size(d_H->k());
}
ldpc_R_U_encoder_impl::~ldpc_R_U_encoder_impl()
{
}
int
ldpc_R_U_encoder_impl::get_output_size()
{
return d_H->n();
}
int
ldpc_R_U_encoder_impl::get_input_size()
{
return d_frame_size;
}
bool
ldpc_R_U_encoder_impl::set_frame_size(unsigned int frame_size)
{
bool ret = true;
// TODO add some bounds check here? The frame size is
// constant and specified by the size of the parity check
// matrix used for encoding.
d_frame_size = frame_size;
return ret;
}
double
ldpc_R_U_encoder_impl::rate()
{
return (d_H->n())/static_cast<double>(d_frame_size);
}
void
ldpc_R_U_encoder_impl::generic_work(void *inbuffer,
void *outbuffer)
{
// Populate the information word
const unsigned char *in = (const unsigned char *)inbuffer;
unsigned int index, k = d_H->k();
gsl_matrix *s = gsl_matrix_alloc(k, 1);
for (index = 0; index < k; index++) {
double value = static_cast<double>(in[index]);
gsl_matrix_set(s, index, 0, value);
}
// Solve for p2 (parity part)
const gsl_matrix *A = d_H->A();
const gsl_matrix *B = d_H->B();
const gsl_matrix *D = d_H->D();
const gsl_matrix *E = d_H->E();
const gsl_matrix *inv_T = d_H->T_inverse();
const gsl_matrix *inv_p = d_H->phi_inverse();
const gsl_matrix *temp1 = d_H->mult_matrices_mod2(B, s);
const gsl_matrix *temp2 = d_H->mult_matrices_mod2(inv_T,
temp1);
const gsl_matrix *temp3 = d_H->mult_matrices_mod2(E, temp2);
const gsl_matrix *temp4 = d_H->mult_matrices_mod2(D, s);
const gsl_matrix *temp5 = d_H->add_matrices_mod2(temp4,
temp3);
const gsl_matrix *p2 = d_H->mult_matrices_mod2(inv_p, temp5);
// Solve for p1 (parity part)
const gsl_matrix *temp6 = d_H->mult_matrices_mod2(A, p2);
const gsl_matrix *temp7 = d_H->add_matrices_mod2(temp6,
temp1);
const gsl_matrix *p1 = d_H->mult_matrices_mod2(inv_T, temp7);
// Populate the codeword to be output
unsigned int p1_length = (*p1).size1;
unsigned int p2_length = (*p2).size1;
unsigned char *out = (unsigned char*)outbuffer;
for (index = 0; index < p1_length; index++) {
int value = gsl_matrix_get(p1, index, 0);
out[index] = value;
}
for (index = 0; index < p2_length; index++) {
int value = gsl_matrix_get(p2, index, 0);
out[p1_length+index] = value;
}
for (index = 0; index < k; index++) {
int value = gsl_matrix_get(s, index, 0);
out[p1_length+p2_length+index] = value;
}
}
} /* namespace code */
} /* namespace fec */
} /* namespace gr */
|