casacore
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 
10 namespace dyscostman {
11 
31 template <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 
161  class Dictionary {
162  public:
163  typedef value_t *iterator;
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 
259  static num_t cumulative(num_t x);
260  static num_t invCumulative(num_t c, num_t err = num_t(1e-13));
261 
264 };
265 
266 } // namespace dyscostman
267 
268 #endif
Tp & back() noexcept
Get reference to last element in container.
Definition: uvector.h:439
size_t capacity() const noexcept
Get the number of elements the container can currently hold without reallocating storage.
Definition: uvector.h:353
size_t size() const noexcept
Get number of elements in container.
Definition: uvector.h:299
void resize(size_t n)
Change the number of elements in the container.
Definition: uvector.h:313
void reserve(size_t n)
Reserve space for a number of elements, to prevent the overhead of extra reallocations.
Definition: uvector.h:368
iterator begin() noexcept
Get iterator to first element.
Definition: uvector.h:263
iterator end() noexcept
Get iterator to element past last element.
Definition: uvector.h:269
Tp & front() noexcept
Get reference to first element in container.
Definition: uvector.h:433
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)
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)
const Double c
Fundamental physical constants (SI units):
const Double e
e and functions thereof:
bool isfinite(const std::complex< T > &val)
LatticeExprNode stddev(const LatticeExprNode &expr)
LatticeExprNode value(const LatticeExprNode &expr)
This function returns the value of the expression without a mask.
TableExprNode rms(const TableExprNode &array)
Definition: ExprNode.h:1680
Header file for uvector and its relational and swap functions.