casacore
Loading...
Searching...
No Matches
stochasticencoder.h
Go to the documentation of this file.
1#ifndef DYSCO_STOCHASTIC_ENCODER_H
2#define DYSCO_STOCHASTIC_ENCODER_H
3
4#include "uvector.h"
5
6#include <algorithm>
7#include <cmath>
8#include <cstring>
9
10namespace dyscostman {
11
31template <typename ValueType = float>
33 public:
45 StochasticEncoder(size_t quantCount, ValueType stddev, bool gaussianMapping = true);
46
47 static StochasticEncoder StudentTEncoder(size_t quantCount, double nu, double rms) {
48 StochasticEncoder<ValueType> encoder(quantCount);
49 encoder.initializeStudentT(nu, rms);
50 return encoder;
51 }
52
53 static StochasticEncoder TruncatedGausEncoder(size_t quantCount, double trunc, double rms) {
54 StochasticEncoder<ValueType> encoder(quantCount);
55 encoder.initializeTruncatedGaussian(trunc, rms);
56 return encoder;
57 }
58
62 typedef unsigned symbol_t;
63
68 typedef ValueType value_t;
69
78 symbol_t Encode(ValueType value) const {
79 if (std::isfinite(value))
80 return _encDictionary.symbol(_encDictionary.lower_bound(value));
81 else
82 return QuantizationCount() - 1;
83 }
84
85 static std::uniform_int_distribution<unsigned> GetDitherDistribution() {
86 return std::uniform_int_distribution<unsigned>(0, ((1u << 31) - 1));
87 }
88
100 symbol_t EncodeWithDithering(ValueType value, unsigned ditherValue) const {
101 if (std::isfinite(value)) {
102 const typename Dictionary::const_iterator lowerBound = _decDictionary.lower_bound(value);
103 if (lowerBound == _decDictionary.begin()) return _decDictionary.symbol(lowerBound);
104 if (lowerBound == _decDictionary.end()) return _decDictionary.symbol(lowerBound - 1);
105 const ValueType rightValue = _decDictionary.value(lowerBound);
106 const ValueType leftValue = _decDictionary.value(lowerBound - 1);
107
108 ValueType ditherMark = ValueType(1u << 31) * (value - leftValue) / (rightValue - leftValue);
109 if (ditherMark > ditherValue)
110 return _decDictionary.symbol(lowerBound);
111 else
112 return _decDictionary.symbol(lowerBound - 1);
113 } else {
114 return _encDictionary.size();
115 }
116 }
117
125 if (symbol != _encDictionary.size())
126 return _encDictionary.value(symbol);
127 else
128 return 0.0;
129 }
130
136 ValueType Decode(symbol_t symbol) const { return _decDictionary.value(symbol); }
137
138 size_t QuantizationCount() const { return _decDictionary.size() + 1; }
139
140 ValueType MaxQuantity() const { return _decDictionary.largest_value(); }
141
142 ValueType MinQuantity() const { return _decDictionary.smallest_value(); }
143
144 private:
145 explicit StochasticEncoder(size_t quantCount)
146 : _encDictionary(quantCount - 1), _decDictionary(quantCount - 1) {}
147
148 void initializeStudentT(double nu, double rms);
149
150 void initializeTruncatedGaussian(double truncationValue, double rms);
151
153 public:
155 typedef const value_t *const_iterator;
156
158
159 explicit Dictionary(size_t size) : _values(size) {}
160
161 void reserve(size_t size) { _values.reserve(size); }
162
163 void resize(size_t size) { _values.resize(size); }
164
174 size_t p = 0, q = _values.size();
175 size_t m = (p + q) / 2;
176 if (_values[m] <= val)
177 p = m;
178 else
179 q = m;
180 while (p + 1 != q) {
181 size_t m = (p + q) / 2;
182 if (_values[m] <= val)
183 p = m;
184 else
185 q = m;
186 }
187 return (_values[p] < val) ? (&_values[q]) : (&_values[p]);
188 }
189
201 size_t p = 0, q = _values.size();
202 while (p + 1 != q) {
203 size_t m = (p + q) / 2;
204 if (_values[m] <= val)
205 p = m;
206 else
207 q = m;
208 }
209 return (_values[p] < val) ? (&_values[q]) : (&_values[p]);
210 }
211
219 const value_t *p = &*_values.begin(), *q = p + _values.size();
220 while (p + 1 != q) {
221 // This is a bit inefficient, but (p + q)/2 was not allowed, because
222 // operator+(ptr,ptr) is not allowed.
223 const value_t *m = p + (q - p) / 2;
224 if (*m <= val)
225 p = m;
226 else
227 q = m;
228 }
229 return p;
230 }
231
232 iterator begin() { return &*_values.begin(); }
233 const_iterator begin() const { return &*_values.begin(); }
234 const_iterator end() const { return &*_values.end(); }
235 symbol_t symbol(const_iterator iter) const { return (iter - begin()); }
236 symbol_t largest_symbol() const { return _values.size() - 1; }
237 value_t value(const_iterator iter) const { return *iter; }
238 value_t value(symbol_t sym) const { return _values[sym]; }
239 value_t largest_value() const { return _values.back(); }
240 value_t smallest_value() const { return _values.front(); }
241 size_t size() const { return _values.size(); }
242 size_t capacity(size_t) const { return _values.capacity(); }
243
244 private:
246 };
247
248 typedef long double num_t;
249
251 static num_t invCumulative(num_t c, num_t err = num_t(1e-13));
252
255};
256
257} // namespace dyscostman
258
259#endif
A container similar to std::vector, but one that allows construction without initializing its element...
Definition uvector.h:77
const_iterator lower_bound(value_t val) const
Returns an iterator pointing to the first element in the dictionary that is not less than (i....
value_t value(const_iterator iter) const
symbol_t symbol(const_iterator iter) const
const_iterator lower_bound_slow(value_t val) const
Below is the first failed result of an attempt to beat the STL in performance.
const_iterator lower_bound_fast(value_t val) const
Returns an iterator pointing to the first element in the dictionary that is not less than (i....
value_t RightBoundary(symbol_t symbol) const
Will return the right boundary of the given symbol.
static num_t cumulative(num_t x)
static num_t invCumulative(num_t c, num_t err=num_t(1e-13))
void initializeTruncatedGaussian(double truncationValue, double rms)
static std::uniform_int_distribution< unsigned > GetDitherDistribution()
symbol_t Encode(ValueType value) const
Get the quantized symbol for the given floating point value.
void initializeStudentT(double nu, double rms)
StochasticEncoder(size_t quantCount, ValueType stddev, bool gaussianMapping=true)
Construct encoder for given dictionary size and Gaussian stddev.
static StochasticEncoder StudentTEncoder(size_t quantCount, double nu, double rms)
symbol_t EncodeWithDithering(ValueType value, unsigned ditherValue) const
Get the quantized symbol for the given floating point value.
ValueType value_t
Template type used for representing floating point values that are to be encoded.
unsigned symbol_t
Unsigned integer type used for representing the encoded symbols.
ValueType Decode(symbol_t symbol) const
Get the centroid value that belongs to the given symbol.
static StochasticEncoder TruncatedGausEncoder(size_t quantCount, double trunc, double rms)
Header file for UVector and its relational and swap functions.