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,
46 bool gaussianMapping = true);
47
48 static StochasticEncoder StudentTEncoder(size_t quantCount, double nu,
49 double rms) {
50 StochasticEncoder<ValueType> encoder(quantCount);
51 encoder.initializeStudentT(nu, rms);
52 return encoder;
53 }
54
55 static StochasticEncoder TruncatedGausEncoder(size_t quantCount, double trunc,
56 double rms) {
57 StochasticEncoder<ValueType> encoder(quantCount);
58 encoder.initializeTruncatedGaussian(trunc, rms);
59 return encoder;
60 }
61
65 typedef unsigned symbol_t;
66
71 typedef ValueType value_t;
72
81 symbol_t Encode(ValueType value) const {
82 if (std::isfinite(value))
84 else
85 return QuantizationCount() - 1;
86 }
87
88 static std::uniform_int_distribution<unsigned> GetDitherDistribution() {
89 return std::uniform_int_distribution<unsigned>(0, ((1u << 31) - 1));
90 }
91
103 symbol_t EncodeWithDithering(ValueType value, unsigned ditherValue) const {
104 if (std::isfinite(value)) {
105 const typename Dictionary::const_iterator lowerBound =
107 if (lowerBound == _decDictionary.begin())
108 return _decDictionary.symbol(lowerBound);
109 if (lowerBound == _decDictionary.end())
110 return _decDictionary.symbol(lowerBound - 1);
111 const ValueType rightValue = _decDictionary.value(lowerBound);
112 const ValueType leftValue = _decDictionary.value(lowerBound - 1);
113
114 ValueType ditherMark =
115 ValueType(1u << 31) * (value - leftValue) / (rightValue - leftValue);
116 if (ditherMark > ditherValue)
117 return _decDictionary.symbol(lowerBound);
118 else
119 return _decDictionary.symbol(lowerBound - 1);
120 } else {
121 return _encDictionary.size();
122 }
123 }
124
132 if (symbol != _encDictionary.size())
133 return _encDictionary.value(symbol);
134 else
135 return 0.0;
136 }
137
143 ValueType Decode(symbol_t symbol) const {
144 return _decDictionary.value(symbol);
145 }
146
147 size_t QuantizationCount() const { return _decDictionary.size() + 1; }
148
149 ValueType MaxQuantity() const { return _decDictionary.largest_value(); }
150
151 ValueType MinQuantity() const { return _decDictionary.smallest_value(); }
152
153 private:
154 explicit StochasticEncoder(size_t quantCount)
155 : _encDictionary(quantCount - 1), _decDictionary(quantCount - 1) {}
156
157 void initializeStudentT(double nu, double rms);
158
159 void initializeTruncatedGaussian(double truncationValue, double rms);
160
162 public:
164 typedef const value_t *const_iterator;
165
167
168 explicit Dictionary(size_t size) : _values(size) {}
169
170 void reserve(size_t size) { _values.reserve(size); }
171
172 void resize(size_t size) { _values.resize(size); }
173
183 size_t p = 0, q = _values.size();
184 size_t m = (p + q) / 2;
185 if (_values[m] <= val)
186 p = m;
187 else
188 q = m;
189 while (p + 1 != q) {
190 size_t m = (p + q) / 2;
191 if (_values[m] <= val)
192 p = m;
193 else
194 q = m;
195 }
196 return (_values[p] < val) ? (&_values[q]) : (&_values[p]);
197 }
198
210 size_t p = 0, q = _values.size();
211 while (p + 1 != q) {
212 size_t m = (p + q) / 2;
213 if (_values[m] <= val)
214 p = m;
215 else
216 q = m;
217 }
218 return (_values[p] < val) ? (&_values[q]) : (&_values[p]);
219 }
220
228 const value_t *p = &*_values.begin(), *q = p + _values.size();
229 while (p + 1 != q) {
230 // This is a bit inefficient, but (p + q)/2 was not allowed, because
231 // operator+(ptr,ptr) is not allowed.
232 const value_t *m = p + (q - p) / 2;
233 if (*m <= val)
234 p = m;
235 else
236 q = m;
237 }
238 return p;
239 }
240
241 iterator begin() { return &*_values.begin(); }
242 const_iterator begin() const { return &*_values.begin(); }
243 const_iterator end() const { return &*_values.end(); }
244 symbol_t symbol(const_iterator iter) const { return (iter - begin()); }
245 symbol_t largest_symbol() const { return _values.size() - 1; }
246 value_t value(const_iterator iter) const { return *iter; }
247 value_t value(symbol_t sym) const { return _values[sym]; }
248 value_t largest_value() const { return _values.back(); }
249 value_t smallest_value() const { return _values.front(); }
250 size_t size() const { return _values.size(); }
251 size_t capacity(size_t) const { return _values.capacity(); }
252
253 private:
255 };
256
257 typedef long double num_t;
258
260 static num_t invCumulative(num_t c, num_t err = num_t(1e-13));
261
264};
265
266} // namespace dyscostman
267
268#endif
A container similar to std::vector, but one that allows construction without initializing its element...
Definition uvector.h:74
size_t capacity() const noexcept
Get the number of elements the container can currently hold without reallocating storage.
Definition uvector.h:354
size_t size() const noexcept
Get number of elements in container.
Definition uvector.h:300
void resize(size_t n)
Change the number of elements in the container.
Definition uvector.h:314
void reserve(size_t n)
Reserve space for a number of elements, to prevent the overhead of extra reallocations.
Definition uvector.h:369
Tp & back() noexcept
Get reference to last element in container.
Definition uvector.h:440
iterator begin() noexcept
Get iterator to first element.
Definition uvector.h:264
iterator end() noexcept
Get iterator to element past last element.
Definition uvector.h:270
Tp & front() noexcept
Get reference to first element in container.
Definition uvector.h:434
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....
Lossy encoder for stochastic values.
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.