Project
Loading...
Searching...
No Matches
dc_primitives.h
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
12/* Local Variables: */
13/* mode: c++ */
14/* End: */
15
16#ifndef DC_PRIMITIVES_H
17#define DC_PRIMITIVES_H
18
23
32#include <map>
33//#define BOOST_MPL_LIMIT_STRING_SIZE 32
34#include <boost/mpl/size.hpp>
35#include <boost/mpl/range_c.hpp>
36#include <boost/mpl/string.hpp>
37
38namespace o2
39{
40namespace data_compression
41{
42
44//
45// General meta programming tools
46//
47// All meta programs are evaluated at compile time
48
54template <typename T, std::size_t nbits>
55struct getmax {
56 static T const value = getmax<T, nbits - 1>::value << 1 | 1;
57};
58// template specialization for termination of the meta program
59template <typename T>
60struct getmax<T, 0> {
61 static T const value = 0;
62};
63
71template <typename T, T _min, T _max>
73 static std::size_t const value = boost::mpl::size<boost::mpl::range_c<T, _min, _max>>::value + 1;
74};
75
82template <std::size_t n>
84 static std::size_t const value = upperbinarybound<(n >> 1)>::value + 1;
85};
86// template specialization for termination of the meta program
87template <>
89 static std::size_t const value = 0;
90};
91
93//
94// DataCompression tools
95//
96// The Alphabet: for every parameter to be stored in a compressed format, there
97// is a range of valid symbols referred to be an alphabet. The DataCompression
98// framework requires an implementation of an alphabet which is then used with
99// the probability model and codecs. The alphabet class needs to implement a
100// check function (isValid), and a forward iterator together with begin and end
101// function to hook it up to the framework.
102//
103// Default Alphabet implementations: most of the alphabets will describe a range
104// of contiguous values, which is implemented by the class ContiguousAlphabet.
105// Two specializations describe symbols in a range from 0 to a max value and
106// within a certain bit range, respectively
107// ZeroBoundContiguousAlphabet and BitRangeContiguousAlphabet
108
109/******************************************************************************
110 * @class ExampleAlphabet
111 * @brief An example for an Alphabet definition.
112 *
113 * A class definition for an alphabet. Note that the functions are only defined,
114 * not implemented. The class is required to support the following functions to
115 * hook it up onto the DataCompression framework:
116 * - isValid validity of a value
117 * - getIndex get index from value
118 * - getSymbol get symbol from index
119 * - forward iterator class to walk through elements of alphabet
120 * - begin start iteration over elements
121 * - end end marker for iteration
122 *
123 * The alphabet has to provide an index for the symbol range such that the
124 * framework can build a one to one relation between symbols and index values
125 * used for internal mapping of the symbols.
126 */
127template <typename T>
129{
130 public:
133
134 using value_type = T;
135
137 static bool isValid(value_type v);
138
140 static unsigned getIndex(value_type symbol);
141
143 static value_type getSymbol(unsigned index);
144
146 constexpr unsigned getIndexRange();
147
148
150 template <typename ValueT>
152 {
153 public:
156
158 using value_type = ValueT;
159 using reference = ValueT&;
160 using pointer = ValueT*;
161 using difference_type = std::ptrdiff_t;
162 using iterator_category = std::forward_iterator_tag;
163
164 // prefix increment
166 // postfix increment
167 self_type operator++(int /*unused*/);
168 // addition
169 // self_type operator+(size_type n) const;
170 // reference
172 // comparison
173 bool operator==(const self_type& other) const;
174 // comparison
175 bool operator!=(const self_type& other) const;
176
177 private:
178 };
179
182
191
192 private:
193};
194
195/******************************************************************************
196 * Definition of a contiguous alphabet
197 *
198 * The contiguous alphabet defines integer number elements of the specified
199 * type in a given range.
200 *
201 * TODO: the mpl string length is limited and can be configured with the
202 * define BOOST_MPL_LIMIT_STRING_SIZE (somehow the number of allowed
203 * template arguments is given by this number divided by four)
204 */
205template <typename T, T _min, T _max, //
206 typename NameT = boost::mpl::string<'U', 'n', 'n', 'a', 'm', 'e', 'd'>::type //
207 >
209{
210 public:
213
214 using value_type = T;
215 using size_type = T;
216 using range = boost::mpl::range_c<T, _min, _max>;
217 using size = boost::mpl::plus<boost::mpl::size<range>, boost::mpl::int_<1>>;
218
220 static bool isValid(value_type v) { return v >= _min && v <= _max; }
221
227 static unsigned getIndex(value_type symbol)
228 {
229 int index = symbol;
230 if (_min < 0) {
231 index += -_min;
232 } else if (_min > 0) {
233 index -= _min;
234 }
235 return index;
236 }
237
239 static value_type getSymbol(unsigned index) { return _min + index; }
240
242 constexpr unsigned getIndexRange() { return _max - _min; }
243
247 constexpr const char* getName() const { return boost::mpl::c_str<NameT>::value; }
248
250 template <typename ValueT>
252 {
253 public:
254 Iterator() : mValue(_max), mIsEnd(true) {}
255 Iterator(T value, bool isEnd) : mValue(value), mIsEnd(isEnd) {}
256 ~Iterator() = default;
257
259 using value_type = ValueT;
260 using reference = ValueT&;
261 using pointer = ValueT*;
262 using difference_type = std::ptrdiff_t;
263 using iterator_category = std::forward_iterator_tag;
264
265 // prefix increment
267 {
268 if (mValue < _max) {
269 mValue++;
270 } else {
271 mIsEnd = true;
272 }
273 return *this;
274 }
275
276 // postfix increment
277 self_type operator++(int /*unused*/)
278 {
279 self_type copy(*this);
280 ++*this;
281 return copy;
282 }
283
284 // addition
286 {
287 self_type copy(*this);
288 if (!copy.mIsEnd) {
289 if ((n > _max) || (_max - n < mValue)) {
290 copy.mIsEnd = true;
291 copy.mValue = _max;
292 } else {
293 copy.mValue += n;
294 }
295 }
296 return copy;
297 }
298
299 reference operator*() { return mValue; }
300 // pointer operator->() const {return &mValue;}
301 // reference operator[](size_type n) const;
302
303 bool operator==(const self_type& other) const { return mValue == other.mValue && mIsEnd == other.mIsEnd; }
304 bool operator!=(const self_type& other) const { return not(*this == other); }
305
306 private:
307 value_type mValue;
308 bool mIsEnd;
309 };
310
313
315 const_iterator begin() const { return iterator(_min, false); }
316
318 const_iterator end() const { return iterator(_max, true); }
319
321 iterator begin() { return iterator(_min, false); }
322
324 iterator end() { return iterator(_max, true); }
325
326 private:
327};
328
329/******************************************************************************
330 * Definition of a zero-bound contiguous alphabet
331 *
332 * The zero-bound contiguous alphabet defines integer number elements of the
333 * specified type between 0 and a maximum value.
334 */
335template <typename T, T _max, //
336 typename NameT = boost::mpl::string<'U', 'n', 'n', 'a', 'm', 'e', 'd'>::type //
337 >
338class ZeroBoundContiguousAlphabet : public ContiguousAlphabet<T, 0, _max, NameT>
339{
340};
341
342/******************************************************************************
343 * Definition of a bit-range contiguous alphabet
344 *
345 * The bit-range contiguous alphabet defines integer number elements between
346 * 0 and the maximum number allowed by bit-range
347 */
348template <typename T, std::size_t _nbits, typename NameT = boost::mpl::string<'U', 'n', 'n', 'a', 'm', 'e', 'd'>::type>
349class BitRangeContiguousAlphabet : public ZeroBoundContiguousAlphabet<T, getmax<T, _nbits>::value, NameT>
350{
351};
352
353/******************************************************************************
354 * Probability model class collecting statistics for an alphabet
355 *
356 */
357template <class Alphabet, typename WeightType = double>
359{
360 public:
361 using alphabet_type = Alphabet;
362 using value_type = typename Alphabet::value_type;
363 using weight_type = WeightType;
364 using TableType = std::map<value_type, WeightType>;
365
366 // TODO: check if this is the correct way for WeightType defaults
367 static const value_type _default0 = 0;
368 static const value_type _default1 = _default0 + 1;
369
370 ProbabilityModel() : mProbabilityTable(), mTotalWeight(_default0) {}
371 ~ProbabilityModel() = default;
372
373 constexpr const char* getName() const
374 {
375 Alphabet tmp;
376 return tmp.getName();
377 }
378
380 {
381 mProbabilityTable[value] += weight;
382 mTotalWeight += weight;
383 return 0;
384 }
385
386 int initWeight(Alphabet& alphabet, WeightType weight = _default1)
387 {
388 mProbabilityTable.clear();
389 mTotalWeight = _default0;
390 for (auto i : alphabet) {
392 }
393 return 0;
394 }
395
396 WeightType normalize()
397 {
398 WeightType totalWeight = _default0;
399 // TODO: handle division by zero, although that should not occur at all
400 for (typename TableType::iterator i = mProbabilityTable.begin(); i != mProbabilityTable.end(); i++) {
401 totalWeight += i->second;
402 i->second /= mTotalWeight;
403 }
404 // TODO: verify total weight
405 // if (mTotalWeight - verifyTotalWeight > some small value)
406 mTotalWeight = totalWeight / mTotalWeight;
407 return totalWeight;
408 }
409
410 // const reference only to avoid changes in the weight count
411 // without registering in the total weight as well
412 const WeightType& operator[](value_type v) const
413 {
414 typename TableType::const_iterator i = mProbabilityTable.find(v);
415 if (i != mProbabilityTable.end()) {
416 return i->second;
417 }
418 static WeightType dummy = _default0;
419 return dummy;
420 }
421
422 typename TableType::const_iterator begin() const { return mProbabilityTable.begin(); }
423
424 typename TableType::const_iterator end() const { return mProbabilityTable.end(); }
425
426 typename TableType::iterator begin() { return mProbabilityTable.begin(); }
427
428 typename TableType::iterator end() { return mProbabilityTable.end(); }
429
430 void print() const {}
431
432 private:
433 TableType mProbabilityTable;
434 WeightType mTotalWeight;
435};
436
437} // namespace data_compression
438} // namespace o2
439#endif
int32_t i
a forward iterator to access the list of elements
bool operator!=(const self_type &other) const
bool operator==(const self_type &other) const
constexpr const char * getName() const
constexpr unsigned getIndexRange()
get the range of indices aka number of indices
iterator begin()
return forward iterator to begin of element list
static unsigned getIndex(value_type symbol)
const_iterator begin() const
return forward iterator to begin of element list
static bool isValid(value_type v)
check for valid value within range
iterator end()
the end of element list
const_iterator end() const
the end of element list
boost::mpl::plus< boost::mpl::size< range >, boost::mpl::int_< 1 > > size
boost::mpl::range_c< T, _min, _max > range
static value_type getSymbol(unsigned index)
get symbol from index
a forward iterator to access the list of elements
bool operator!=(const self_type &other) const
bool operator==(const self_type &other) const
iterator begin()
return forward iterator to begin of element list
const_iterator end() const
the end of element list
const_iterator begin() const
return forward iterator to begin of element list
iterator end()
the end of element list
static unsigned getIndex(value_type symbol)
get index of value
static value_type getSymbol(unsigned index)
get symbol from index
constexpr unsigned getIndexRange()
get the range of indices aka number of indices
static bool isValid(value_type v)
check for valid value within range
TableType::const_iterator end() const
std::map< value_type, WeightType > TableType
typename Alphabet::value_type value_type
int addWeight(value_type value, weight_type weight=_default1)
const WeightType & operator[](value_type v) const
constexpr const char * getName() const
TableType::const_iterator begin() const
int initWeight(Alphabet &alphabet, WeightType weight=_default1)
GLdouble n
Definition glcorearb.h:1982
const GLdouble * v
Definition glcorearb.h:832
GLuint index
Definition glcorearb.h:781
GLuint GLuint GLfloat weight
Definition glcorearb.h:5477
GLsizei const GLfloat * value
Definition glcorearb.h:819
GLint GLint GLsizei GLint GLenum GLenum type
Definition glcorearb.h:275
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
Get maximum of an n-bit number.
Get number of elements in a sequence of integral types This redirects to the size meta program of the...
Get the upper binary bound of a number The gives the number of bits required to present a number.
VectorOfTObjectPtrs other