-
Notifications
You must be signed in to change notification settings - Fork 0
/
bmsa-decoding.hpp
243 lines (197 loc) · 7.72 KB
/
bmsa-decoding.hpp
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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
/*
* bmsa-decoding.hpp
*
* Created on: 29.06.2011
* Author: ulysses
*/
#ifndef BMSA_DECODING_HPP_
#define BMSA_DECODING_HPP_
#include <array>
#include <functional>
#include <map>
#include <vector>
#include <boost/iterator/transform_iterator.hpp>
#include <boost/range/adaptor/map.hpp>
#include <boost/range/iterator_range.hpp>
#include <glog/logging.h>
#include "Point.hpp"
#include "bmsa.hpp"
#include "mv_poly.hpp"
#include "CurveArithmetic.hpp"
#include "NtlPolynomials.hpp"
namespace mv_poly {
template<
int Dim,
typename ECCodeParams
>
class BMSDecoding {
public:
typedef typename ECCodeParams::Field Field;
typedef typename ECCodeParams::BasisElem BasisElem;
typedef BasisElem PointT;
typedef typename ECCodeParams::CurvePoint CurvePoint;
typedef std::vector< CurvePoint > CurvePointsCollection;
typedef std::vector<Field> FieldElemsCollection;
private:
/******************** Private typedef's *********************/
typedef std::map< BasisElem, Field> SyndromeType;
typedef typename ECCodeParams::OrderPolicyHolder OrderPolicyHolder;
typedef BMSAlgorithm< SyndromeType,
typename MVPolyType<Dim, Field>::type,
OrderPolicyHolder::template impl
> BmsaT;
typedef typename BmsaT::PolynomialCollection PolynomialCollection;
typedef std::vector<int> ErrorPositions;
/******************** Private fields *********************/
size_t l;
CurvePointsCollection curvePoints;
// compute common roots of elements in F
ErrorPositions
getErrorLocations(PolynomialCollection const & polys) {
typedef typename PolynomialCollection::value_type PolyT;
typedef CoefficientTraits<typename PolyT::CoefT> CoefTr;
ErrorPositions result;
int idx = 0;
std::for_each(curvePoints.begin(), curvePoints.end(),
[&result,&idx,&polys](CurvePoint const & cp) {
bool root_for_all = std::accumulate(polys.begin(),
polys.end(), true,
[&cp](bool val, PolyT const & p){
return val && p(cp) == CoefTr::addId();
});
if (root_for_all)
result.push_back(idx);
++idx;
});
// ********** logging
std::ostringstream log_oss;
std::copy(result.begin(), result.end(),
std::ostream_iterator<int>(log_oss, " "));
LOG(INFO) << "Error positions: " << log_oss.str();
// ********** ENF OF logging
return result;
}
FieldElemsCollection
getErrorValues(
FieldElemsCollection const & r,
CurvePointsCollection const & locations) {
// Not Implemented Yet
}
// Feng-Rao majority voting: partially implemented
void frmv(BmsaT & bmsa) {
typedef std::map<PointT, PointT> PointToPointMap;
PointToPointMap voters; // Г_k with support points from \sigma_k attached
PointT k = bmsa.getSeqLen(); // k - kurrent step :)
// 1. Compute Г_k
for (
auto it = bmsa.getF().begin();
it != bmsa.getF().end();
++it
) {
PointT const & s = it->first;
for (PointT t = s; t < k; ++t) {
// we assume tha going from s to k following monomial order
// yields all points t s.t. s <= t <= k where <= stands for
// by-coordinate comparison (natural partial order)
bool l1 = byCoordinateLess(s, t);
bool l2 = byCoordinateLess(t, k);
bool g = byCoordinateGreaterThenAny(k - t, bmsa.getF() | boost::adaptors::map_keys);
if (
l1 &&
l2 &&
g) {
voters[t] = s;
}
}
}
// ********** logging (Г_k)
LOG(INFO) << "Gamma_k has " << voters.size() << " elements";
std::ostringstream log_oss;
std::copy(voters.begin(), voters.end(),
std::ostream_iterator<typename PointToPointMap::value_type>(log_oss, " "));
LOG(INFO) << "Gamma_k: " << log_oss.str();
// ********** ENF OF logging
// 2. Compute votes and choose winner
// Not implemented yet
}
PolynomialCollection
computeErrorLocatorPolynomials(FieldElemsCollection const & received) {
SyndromeType syn;
auto basis = ECCodeParams::getCodeBasis(l);
// ********** logging
std::ostringstream log_oss;
std::copy(basis.begin(), basis.end(),
std::ostream_iterator<BasisElem>(log_oss, " "));
LOG(INFO) << "Basis for evaluation code: " << log_oss.str();
// ********** ENF OF logging
// computing "known" syndroms
using namespace std::placeholders;
auto syndromComponentAtBasisElem =
[this,&received](BasisElem const & be) -> typename SyndromeType::value_type {
auto tit = boost::make_transform_iterator(this->curvePoints.begin(),
std::bind(
computeMonomAtPoint<Field, BasisElem, CurvePoint>,
be,
_1));
return typename SyndromeType::value_type(
be,
std::inner_product(received.begin(), received.end(),
tit, FieldElemTraits<Field>::addId()));
};
std::transform(basis.begin(), basis.end(),
std::inserter(syn, syn.begin()), syndromComponentAtBasisElem);
// END OF computing "known" syndroms
// ********** logging
log_oss.str("");
std::for_each(syn.begin(), syn.end(),
[&log_oss](typename SyndromeType::value_type const & s) {
log_oss << makeNtlPowerPrinter(s.second) << " ";
}
);
LOG(INFO) << "Known syndroms: " << log_oss.str();
// ********** ENF OF logging
// compute error locators for the known syndroms
BmsaT bmsa(syn, ++basis.back());
auto minset = bmsa.computeMinimalSet();
// ********** logging
for_each(minset.begin(), minset.end(),
[](typename BmsaT::PolynomialCollection::value_type const & p) {
LOG(INFO) << "Error locator: " <<
makePowerPrinter< OrderPolicyHolder::template impl >(p)
<< std::endl;
}
);
// ********** ENF OF logging
// while(true) { // TODO: define stop condition
// frmv(bmsa);
// ++bmsa; // TODO: ++ should be correctly implemented for given OrderPolicy
// }
return minset;
}
public:
BMSDecoding(
size_t l)
: l(l) {
curvePoints = ECCodeParams::getRationalPoints();
// Logging
LOG(INFO) << "Curve points";
for (auto cpt : curvePoints) {
LOG(INFO) << "("
<< makeNtlPowerPrinter(cpt[0]) << ", "
<< makeNtlPowerPrinter(cpt[1]) << ")";
}
}
// Should return FieldElemsCollection but getErrorValues NIY
ErrorPositions decode(FieldElemsCollection const & r) {
FieldElemsCollection result;
ErrorPositions locations =
getErrorLocations(
computeErrorLocatorPolynomials(r));
// FieldElemsCollection values = getErrorValues(locations);
// correct r with locators and values...
// return result;
return locations;
}
}; // BMSDecoding
} // namespace mv_poly
#endif /* BMSA_DECODING_HPP_ */