1 /* -*- c++ -*- */
2 /*
3  * Copyright 2015 Free Software Foundation, Inc.
4  *
5  * This file is part of GNU Radio
6  *
7  * GNU Radio is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3, or (at your option)
10  * any later version.
11  *
12  * GNU Radio is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with GNU Radio; see the file COPYING.  If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street,
20  * Boston, MA 02110-1301, USA.
21  */
22 
23 #include <gnuradio/fec/cldpc.h>
24 #include <stdexcept>
25 
cldpc(const GF2Mat X)26 cldpc::cldpc(const GF2Mat X)
27 {
28     H = X;
29     M = H.get_M();
30     N = H.get_N();
31     G = H.get_G(permute, rank_H);
32     K = N - rank_H;
33 }
34 
cldpc(const alist _list)35 cldpc::cldpc(const alist _list)
36 {
37     H = GF2Mat(_list);
38     M = H.get_M();
39     N = H.get_N();
40     G = H.get_G(permute, rank_H);
41     K = N - rank_H;
42 }
43 
set_alist(const alist _list)44 void cldpc::set_alist(const alist _list)
45 {
46     H = GF2Mat(_list);
47     M = H.get_M();
48     N = H.get_N();
49     G = H.get_G(permute, rank_H);
50     K = N - rank_H;
51 }
52 
get_systematic_bits(std::vector<char> in)53 std::vector<char> cldpc::get_systematic_bits(std::vector<char> in)
54 {
55     std::vector<char> data;
56     data.resize(K);
57     int index;
58     for (size_t i = 0; i < K; i++) {
59         index = permute[i + rank_H];
60         data[i] = in[index];
61     }
62     return data;
63 }
64 
print_permute()65 void cldpc::print_permute()
66 {
67     for (size_t i = 0; i < permute.size(); i++) {
68         std::cout << permute[i] << ", ";
69     }
70     std::cout << "\n";
71 }
72 
syndrome(const std::vector<char> in)73 std::vector<char> cldpc::syndrome(const std::vector<char> in)
74 {
75     std::vector<char> synd;
76     synd.resize(rank_H);
77     GF2Vec in_bvec;
78     in_bvec.set_vec(in);
79     for (int i = 0; i < rank_H; i++) {
80         synd[i] = H[i] * in_bvec;
81     }
82     return synd;
83 }
84 
is_codeword(const std::vector<char> in)85 bool cldpc::is_codeword(const std::vector<char> in)
86 {
87     std::vector<char> synd;
88     synd = syndrome(in);
89     bool is_code;
90     is_code = true;
91     for (int i = 0; i < rank_H; i++) {
92         if (synd[i] != char(0)) {
93             is_code = false;
94         }
95     }
96     return is_code;
97 }
98 
encode(std::vector<char> dataword)99 std::vector<char> cldpc::encode(std::vector<char> dataword)
100 {
101     if (dataword.size() == K) {
102         GF2Vec x(N);
103         GF2Vec data(K);
104         data.set_vec(dataword);
105         for (int i = rank_H; i < N; i++) {
106             x[i] = dataword[i - rank_H];
107         }
108         for (int i = 0; i < rank_H; i++) {
109             x[i] = G[i].sub_vector(N - K, N) * data;
110         }
111         GF2Vec y(N);
112         for (int i = 0; i < N; i++) {
113             y[permute[i]] = x[i];
114         }
115         return y.get_vec();
116     } else {
117         throw std::runtime_error("bad vector length!");
118         return std::vector<char>();
119     }
120 }
121 
dimension()122 int cldpc::dimension() { return K; }
123 
get_M()124 int cldpc::get_M() { return M; }
125 
get_N()126 int cldpc::get_N() { return N; }
127 
get_H()128 GF2Mat cldpc::get_H() { return H; }
129 
get_G()130 GF2Mat cldpc::get_G() { return G; }
131