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