blob: 3b556b998f25447957e3d1ac9b2c7864656000ff [file] [log] [blame]
dburgess82c46ff2011-10-07 02:40:51 +00001/*
2* Copyright 2008, 2009 Free Software Foundation, Inc.
3*
4*
5* This software is distributed under the terms of the GNU Affero Public License.
6* See the COPYING file in the main directory for details.
7*
8* This use of this software may be subject to additional restrictions.
9* See the LEGAL file in the main directory for details.
10
11 This program is free software: you can redistribute it and/or modify
12 it under the terms of the GNU Affero General Public License as published by
13 the Free Software Foundation, either version 3 of the License, or
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU Affero General Public License for more details.
20
21 You should have received a copy of the GNU Affero General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
23
24*/
25
26
27
28
29#include "BitVector.h"
30#include <iostream>
31#include <stdio.h>
kurtis.heimerl5a872472013-05-31 21:47:25 +000032#include <sstream>
Alexander Chemeris38b69872017-03-17 18:20:09 -070033#include <math.h>
dburgess82c46ff2011-10-07 02:40:51 +000034
35using namespace std;
36
37
38/**
39 Apply a Galois polymonial to a binary seqeunce.
40 @param val The input sequence.
41 @param poly The polynomial.
42 @param order The order of the polynomial.
43 @return Single-bit result.
44*/
45unsigned applyPoly(uint64_t val, uint64_t poly, unsigned order)
46{
47 uint64_t prod = val & poly;
48 unsigned sum = prod;
49 for (unsigned i=1; i<order; i++) sum ^= prod>>i;
50 return sum & 0x01;
51}
52
53
54
55
56
57
58BitVector::BitVector(const char *valString)
59 :Vector<char>(strlen(valString))
60{
61 uint32_t accum = 0;
62 for (size_t i=0; i<size(); i++) {
63 accum <<= 1;
64 if (valString[i]=='1') accum |= 0x01;
65 mStart[i] = accum;
66 }
67}
68
69
70
71
72
73uint64_t BitVector::peekField(size_t readIndex, unsigned length) const
74{
75 uint64_t accum = 0;
76 char *dp = mStart + readIndex;
77 assert(dp+length <= mEnd);
78 for (unsigned i=0; i<length; i++) {
79 accum = (accum<<1) | ((*dp++) & 0x01);
80 }
81 return accum;
82}
83
84
85
86
87uint64_t BitVector::peekFieldReversed(size_t readIndex, unsigned length) const
88{
89 uint64_t accum = 0;
90 char *dp = mStart + readIndex + length - 1;
91 assert(dp<mEnd);
92 for (int i=(length-1); i>=0; i--) {
93 accum = (accum<<1) | ((*dp--) & 0x01);
94 }
95 return accum;
96}
97
98
99
100
101uint64_t BitVector::readField(size_t& readIndex, unsigned length) const
102{
103 const uint64_t retVal = peekField(readIndex,length);
104 readIndex += length;
105 return retVal;
106}
107
108
109uint64_t BitVector::readFieldReversed(size_t& readIndex, unsigned length) const
110{
111 const uint64_t retVal = peekFieldReversed(readIndex,length);
112 readIndex += length;
113 return retVal;
114}
115
116
117
118
119
120void BitVector::fillField(size_t writeIndex, uint64_t value, unsigned length)
121{
122 char *dpBase = mStart + writeIndex;
123 char *dp = dpBase + length - 1;
124 assert(dp < mEnd);
125 while (dp>=dpBase) {
126 *dp-- = value & 0x01;
127 value >>= 1;
128 }
129}
130
131
132void BitVector::fillFieldReversed(size_t writeIndex, uint64_t value, unsigned length)
133{
134 char *dp = mStart + writeIndex;
135 char *dpEnd = dp + length - 1;
136 assert(dpEnd < mEnd);
137 while (dp<=dpEnd) {
138 *dp++ = value & 0x01;
139 value >>= 1;
140 }
141}
142
143
144
145
146void BitVector::writeField(size_t& writeIndex, uint64_t value, unsigned length)
147{
148 fillField(writeIndex,value,length);
149 writeIndex += length;
150}
151
152
153void BitVector::writeFieldReversed(size_t& writeIndex, uint64_t value, unsigned length)
154{
155 fillFieldReversed(writeIndex,value,length);
156 writeIndex += length;
157}
158
159
160void BitVector::invert()
161{
162 for (size_t i=0; i<size(); i++) {
163 mStart[i] = ~mStart[i];
164 }
165}
166
167
168
169
170void BitVector::reverse8()
171{
172 assert(size()>=8);
173
174 char tmp0 = mStart[0];
175 mStart[0] = mStart[7];
176 mStart[7] = tmp0;
177
178 char tmp1 = mStart[1];
179 mStart[1] = mStart[6];
180 mStart[6] = tmp1;
181
182 char tmp2 = mStart[2];
183 mStart[2] = mStart[5];
184 mStart[5] = tmp2;
185
186 char tmp3 = mStart[3];
187 mStart[3] = mStart[4];
188 mStart[4] = tmp3;
189}
190
191
192
193void BitVector::LSB8MSB()
194{
195 if (size()<8) return;
196 size_t size8 = 8*(size()/8);
197 size_t iTop = size8 - 8;
198 for (size_t i=0; i<=iTop; i+=8) segment(i,8).reverse8();
199}
200
201
202
203uint64_t BitVector::syndrome(Generator& gen) const
204{
205 gen.clear();
206 const char *dp = mStart;
207 while (dp<mEnd) gen.syndromeShift(*dp++);
208 return gen.state();
209}
210
211
212uint64_t BitVector::parity(Generator& gen) const
213{
214 gen.clear();
215 const char *dp = mStart;
216 while (dp<mEnd) gen.encoderShift(*dp++);
217 return gen.state();
218}
219
220
dburgess82c46ff2011-10-07 02:40:51 +0000221
222unsigned BitVector::sum() const
223{
224 unsigned sum = 0;
225 for (size_t i=0; i<size(); i++) sum += mStart[i] & 0x01;
226 return sum;
227}
228
229
230
231
232void BitVector::map(const unsigned *map, size_t mapSize, BitVector& dest) const
233{
234 for (unsigned i=0; i<mapSize; i++) {
235 dest.mStart[i] = mStart[map[i]];
236 }
237}
238
239
240
241
242void BitVector::unmap(const unsigned *map, size_t mapSize, BitVector& dest) const
243{
244 for (unsigned i=0; i<mapSize; i++) {
245 dest.mStart[map[i]] = mStart[i];
246 }
247}
248
249
250
251
252
253
254
dburgess82c46ff2011-10-07 02:40:51 +0000255ostream& operator<<(ostream& os, const BitVector& hv)
256{
257 for (size_t i=0; i<hv.size(); i++) {
258 if (hv.bit(i)) os << '1';
259 else os << '0';
260 }
261 return os;
262}
263
264
265
266
dburgess82c46ff2011-10-07 02:40:51 +0000267SoftVector::SoftVector(const BitVector& source)
268{
269 resize(source.size());
270 for (size_t i=0; i<size(); i++) {
271 if (source.bit(i)) mStart[i]=1.0F;
Alexander Chemeris38b69872017-03-17 18:20:09 -0700272 else mStart[i]=-1.0F;
dburgess82c46ff2011-10-07 02:40:51 +0000273 }
274}
275
276
277BitVector SoftVector::sliced() const
278{
279 size_t sz = size();
280 BitVector newSig(sz);
281 for (size_t i=0; i<sz; i++) {
Alexander Chemeris38b69872017-03-17 18:20:09 -0700282 if (mStart[i]>0.0F) newSig[i]=1;
dburgess82c46ff2011-10-07 02:40:51 +0000283 else newSig[i] = 0;
284 }
285 return newSig;
286}
287
288
kurtis.heimerl5a872472013-05-31 21:47:25 +0000289float SoftVector::getEnergy(float *plow) const
290{
291 const SoftVector &vec = *this;
292 int len = vec.size();
293 float avg = 0; float low = 1;
294 for (int i = 0; i < len; i++) {
Alexander Chemeris38b69872017-03-17 18:20:09 -0700295 float energy = fabsf(vec[i]);
kurtis.heimerl5a872472013-05-31 21:47:25 +0000296 if (energy < low) low = energy;
297 avg += energy/len;
298 }
299 if (plow) { *plow = low; }
300 return avg;
301}
302
dburgess82c46ff2011-10-07 02:40:51 +0000303
304ostream& operator<<(ostream& os, const SoftVector& sv)
305{
306 for (size_t i=0; i<sv.size(); i++) {
Alexander Chemeris38b69872017-03-17 18:20:09 -0700307 if (sv[i]<-0.5) os << "0";
308 else if (sv[i]<-0.25) os << "o";
309 else if (sv[i]<0.0) os << ".";
310 else if (sv[i]>0.5) os << "1";
311 else if (sv[i]>0.25) os << "|";
312 else if (sv[i]>0.0) os << "'";
dburgess82c46ff2011-10-07 02:40:51 +0000313 else os << "-";
314 }
315 return os;
316}
317
318
319
320void BitVector::pack(unsigned char* targ) const
321{
322 // Assumes MSB-first packing.
323 unsigned bytes = size()/8;
324 for (unsigned i=0; i<bytes; i++) {
325 targ[i] = peekField(i*8,8);
326 }
327 unsigned whole = bytes*8;
328 unsigned rem = size() - whole;
329 if (rem==0) return;
330 targ[bytes] = peekField(whole,rem) << (8-rem);
331}
332
333
334void BitVector::unpack(const unsigned char* src)
335{
336 // Assumes MSB-first packing.
337 unsigned bytes = size()/8;
338 for (unsigned i=0; i<bytes; i++) {
339 fillField(i*8,src[i],8);
340 }
341 unsigned whole = bytes*8;
342 unsigned rem = size() - whole;
343 if (rem==0) return;
kurtis.heimerl7645fca2012-03-08 07:13:15 +0000344 fillField(whole,src[bytes] >> (8-rem),rem);
dburgess82c46ff2011-10-07 02:40:51 +0000345}
346
347void BitVector::hex(ostream& os) const
348{
349 os << std::hex;
350 unsigned digits = size()/4;
351 size_t wp=0;
352 for (unsigned i=0; i<digits; i++) {
353 os << readField(wp,4);
354 }
355 os << std::dec;
356}
357
kurtis.heimerl5a872472013-05-31 21:47:25 +0000358std::string BitVector::hexstr() const
359{
360 std::ostringstream ss;
361 hex(ss);
362 return ss.str();
363}
364
365
dburgess82c46ff2011-10-07 02:40:51 +0000366bool BitVector::unhex(const char* src)
367{
368 // Assumes MSB-first packing.
369 unsigned int val;
370 unsigned digits = size()/4;
371 for (unsigned i=0; i<digits; i++) {
372 if (sscanf(src+i, "%1x", &val) < 1) {
373 return false;
374 }
375 fillField(i*4,val,4);
376 }
377 unsigned whole = digits*4;
378 unsigned rem = size() - whole;
379 if (rem>0) {
380 if (sscanf(src+digits, "%1x", &val) < 1) {
381 return false;
382 }
383 fillField(whole,val,rem);
384 }
385 return true;
386}
387
388// vim: ts=4 sw=4