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 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258
|
/*
* Copyright 2008, 2009 Free Software Foundation, Inc.
*
* SPDX-License-Identifier: AGPL-3.0+
*
* This software is distributed under the terms of the GNU Affero Public License.
* See the COPYING file in the main directory for details.
*
* This use of this software may be subject to additional restrictions.
* See the LEGAL file in the main directory for details.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program 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 Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef FECVECTORS_H
#define FECVECTORS_H
#include "Vector.h"
#include <stdint.h>
class BitVector : public Vector<char> {
public:
/**@name Constructors. */
//@{
/**@name Casts of Vector constructors. */
//@{
BitVector(char* wData, char* wStart, char* wEnd)
:Vector<char>(wData,wStart,wEnd)
{ }
BitVector(size_t len=0):Vector<char>(len) {}
BitVector(const Vector<char>& source):Vector<char>(source) {}
BitVector(Vector<char>& source):Vector<char>(source) {}
BitVector(const Vector<char>& source1, const Vector<char> source2):Vector<char>(source1,source2) {}
//@}
/** Construct from a string of "0" and "1". */
BitVector(const char* valString);
//@}
/** Index a single bit. */
bool bit(size_t index) const
{
// We put this code in .h for fast inlining.
const char *dp = mStart+index;
assert(dp<mEnd);
return (*dp) & 0x01;
}
/**@name Casts and overrides of Vector operators. */
//@{
BitVector segment(size_t start, size_t span)
{
char* wStart = mStart + start;
char* wEnd = wStart + span;
assert(wEnd<=mEnd);
return BitVector(NULL,wStart,wEnd);
}
BitVector alias()
{ return segment(0,size()); }
const BitVector segment(size_t start, size_t span) const
{ return (BitVector)(Vector<char>::segment(start,span)); }
BitVector head(size_t span) { return segment(0,span); }
const BitVector head(size_t span) const { return segment(0,span); }
BitVector tail(size_t start) { return segment(start,size()-start); }
const BitVector tail(size_t start) const { return segment(start,size()-start); }
//@}
void zero() { fill(0); }
/** Invert 0<->1. */
void invert();
/**@name Byte-wise operations. */
//@{
/** Reverse an 8-bit vector. */
void reverse8();
/** Reverse groups of 8 within the vector (byte reversal). */
void LSB8MSB();
//@}
/**@name Serialization and deserialization. */
//@{
uint64_t peekField(size_t readIndex, unsigned length) const;
uint64_t peekFieldReversed(size_t readIndex, unsigned length) const;
uint64_t readField(size_t& readIndex, unsigned length) const;
uint64_t readFieldReversed(size_t& readIndex, unsigned length) const;
void fillField(size_t writeIndex, uint64_t value, unsigned length);
void fillFieldReversed(size_t writeIndex, uint64_t value, unsigned length);
void writeField(size_t& writeIndex, uint64_t value, unsigned length);
void writeFieldReversed(size_t& writeIndex, uint64_t value, unsigned length);
void write0(size_t& writeIndex) { writeField(writeIndex,0,1); }
void write1(size_t& writeIndex) { writeField(writeIndex,1,1); }
//@}
/** Sum of bits. */
unsigned sum() const;
/** Reorder bits, dest[i] = this[map[i]]. */
void map(const unsigned *map, size_t mapSize, BitVector& dest) const;
/** Reorder bits, dest[map[i]] = this[i]. */
void unmap(const unsigned *map, size_t mapSize, BitVector& dest) const;
/** Pack into a char array. */
void pack(unsigned char*) const;
/** Unpack from a char array. */
void unpack(const unsigned char*);
/** Make a hexdump string. */
void hex(std::ostream&) const;
std::string hexstr() const;
/** Unpack from a hexdump string.
* @returns true on success, false on error. */
bool unhex(const char*);
void set(BitVector other) // That's right. No ampersand.
{
clear();
mData=other.mData;
mStart=other.mStart;
mEnd=other.mEnd;
other.mData=NULL;
}
void settfb(int i, int j) const
{
mStart[i] = j;
}
};
std::ostream& operator<<(std::ostream&, const BitVector&);
/**
The SoftVector class is used to represent a soft-decision signal.
Values 0..1 represent probabilities that a bit is "true".
*/
class SoftVector: public Vector<float> {
public:
/** Build a SoftVector of a given length. */
SoftVector(size_t wSize=0):Vector<float>(wSize) {}
/** Construct a SoftVector from a C string of "0", "1", and "X". */
SoftVector(const char* valString);
/** Construct a SoftVector from a BitVector. */
SoftVector(const BitVector& source);
/**
Wrap a SoftVector around a block of floats.
The block will be delete[]ed upon desctuction.
*/
SoftVector(float *wData, unsigned length)
:Vector<float>(wData,length)
{}
SoftVector(float* wData, float* wStart, float* wEnd)
:Vector<float>(wData,wStart,wEnd)
{ }
/**
Casting from a Vector<float>.
Note that this is NOT pass-by-reference.
*/
SoftVector(Vector<float> source)
:Vector<float>(source)
{}
/**@name Casts and overrides of Vector operators. */
//@{
SoftVector segment(size_t start, size_t span)
{
float* wStart = mStart + start;
float* wEnd = wStart + span;
assert(wEnd<=mEnd);
return SoftVector(NULL,wStart,wEnd);
}
SoftVector alias()
{ return segment(0,size()); }
const SoftVector segment(size_t start, size_t span) const
{ return (SoftVector)(Vector<float>::segment(start,span)); }
SoftVector head(size_t span) { return segment(0,span); }
const SoftVector head(size_t span) const { return segment(0,span); }
SoftVector tail(size_t start) { return segment(start,size()-start); }
const SoftVector tail(size_t start) const { return segment(start,size()-start); }
//@}
// How good is the SoftVector in the sense of the bits being solid?
// Result of 1 is perfect and 0 means all the bits were 0.0
// If plow is non-NULL, also return the lowest energy bit.
float getEnergy(float *low=0) const;
/** Fill with "unknown" values. */
void unknown() { fill(0.0F); }
/** Return a hard bit value from a given index by slicing. */
bool bit(size_t index) const
{
const float *dp = mStart+index;
assert(dp<mEnd);
return (*dp)>0.0F;
}
/** Slice the whole signal into bits. */
BitVector sliced() const;
};
std::ostream& operator<<(std::ostream&, const SoftVector&);
#endif
// vim: ts=4 sw=4
|