Project
Loading...
Searching...
No Matches
DataGenerator.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#ifndef DATAGENERATOR_H
13#define DATAGENERATOR_H
18
19#include <stdexcept> // exeptions, range_error
20#include <utility> // std::forward
21#include <random> // random distribution
22#include <cmath> // exp
23//#include <iostream> // lets see if needed, or keep class fre from output
24//#include <iomanip> // lets see if needed, or keep class fre from output
25
26namespace o2
27{
28namespace test
29{
30
52template <typename ValueT, typename ModelT>
54{
55 public:
56 using size_type = std::size_t;
57 using value_type = ValueT;
60
61 template <typename... Args>
62 DataGenerator(result_type _min, result_type _max, result_type _step, Args&&... args)
63 : min(_min), max(_max), step(_step), nbins((max - min) / step), mGenerator(), mModel(std::forward<Args>(args)...)
64 {
65 }
66 ~DataGenerator() = default;
67 DataGenerator(const DataGenerator&) = default;
69
74
75 using random_engine = std::default_random_engine;
76
78 // TODO: can it be const?
80 {
82 int trials = 0;
83 while ((v = mModel(mGenerator)) < min || v >= max) {
84 if (trials++ > 1000) {
85 // this is a protection, just picked a reasonable threshold for number of trials
86 throw std::range_error("random value outside configured range for too many trials");
87 }
88 }
89 int bin = (v - min) / step;
90 return min + bin * step + 0.5 * step;
91 }
92
94 value_type getRandom() const { return (*this)(); }
95
97 value_type getMin() const { return ModelT::min; }
98
100 value_type getMax() const { return ModelT::max; }
101
103 double getProbability(value_type v) const { return mModel.getProbability(v); }
104
111 template <class ContainerT>
113 {
114 public:
115 iterator(const ContainerT& parent, size_type count = 0) : mParent(parent), mCount(count) {}
116 ~iterator() = default;
117
119 using reference = typename ContainerT::value_type&;
120 using pointer = typename ContainerT::value_type*;
121 using difference_type = typename std::iterator_traits<pointer>::difference_type;
122 using iterator_category = std::forward_iterator_tag;
123
124 // prefix increment
126 {
127 if (mCount < mParent.nbins) {
128 mCount++;
129 }
130 return *this;
131 }
132
133 // postfix increment
134 self_type operator++(int /*unused*/)
135 {
136 self_type copy(*this);
137 ++*this;
138 return copy;
139 }
140
141 // addition
143 {
144 self_type copy(*this);
145 if (copy.mCount + n < mParent.nbins) {
146 copy.mCount += n;
147 } else {
148 copy.mCount = mParent.nbins;
149 }
150 return copy;
151 }
152
153 value_type operator*() { return mParent.min + mCount * mParent.step + .5 * mParent.step; }
154 // pointer operator->() const {return &mValue;}
155 // reference operator[](size_type n) const;
156
157 bool operator==(const self_type& other) const { return mCount == other.mCount; }
158 bool operator!=(const self_type& other) const { return not(*this == other); }
159
160 private:
161 const ContainerT& mParent;
162 size_type mCount;
163 };
164
167
170
171 private:
172 random_engine mGenerator;
173 ModelT mModel;
174};
175
181template <class RealType = double, class _BASE = std::normal_distribution<RealType>>
183{
184 public:
185 using result_type = typename _BASE::result_type;
186
187 normal_distribution(result_type _mean, result_type _stddev) : _BASE(_mean, _stddev), mean(_mean), stddev(_stddev) {}
188
189 const double sqrt2pi = 2.5066283;
192
194 // if value_type is an integral type we want to have the probability
195 // that the result value is in the range [v, v+1) whereas the step
196 // can be something else than 1
197 // also the values outside the specified range should be excluded
198 // and the probability for intervals in the range has to be scaled
199 template <typename value_type>
200 double getProbability(value_type v) const
201 {
202 return (exp(-(v - mean) * (v - mean) / (2 * stddev * stddev))) / (stddev * sqrt2pi);
203 }
204};
205
211template <class IntType = int, class _BASE = std::poisson_distribution<IntType>>
213{
214 public:
215 using result_type = typename _BASE::result_type;
216
217 poisson_distribution(result_type _mean) : _BASE(_mean), mean(_mean) {}
219
221
222 int factorial(unsigned int n) const { return (n <= 1) ? 1 : factorial(n - 1) * n; }
223
225 template <typename value_type>
226 double getProbability(value_type v) const
227 {
228 if (v < 0) {
229 return 0.;
230 }
231 return pow(mean, v) * exp(-mean) / factorial(v);
232 }
233};
234
240template <class IntType = int, class _BASE = std::geometric_distribution<IntType>>
242{
243 public:
244 geometric_distribution(float _parameter) : _BASE(_parameter), parameter(_parameter) {}
245
246 const float parameter;
247
249 template <typename value_type>
250 double getProbability(value_type v) const
251 {
252 if (v < 0) {
253 return 0.;
254 }
255 return parameter * pow((1 - parameter), v);
256 }
257};
258
259}; // namespace test
260}; // namespace o2
261#endif
uint64_t exp(uint64_t base, uint8_t exp) noexcept
bool operator==(const self_type &other) const
iterator(const ContainerT &parent, size_type count=0)
bool operator!=(const self_type &other) const
typename std::iterator_traits< pointer >::difference_type difference_type
typename ContainerT::value_type * pointer
std::forward_iterator_tag iterator_category
self_type operator+(size_type n) const
typename ContainerT::value_type & reference
A simple data generator.
value_type operator()()
get next random value
const result_type step
std::default_random_engine random_engine
const size_type nbins
double getProbability(value_type v) const
get theoretical probability of a value
value_type getMax() const
get maximum value
value_type getRandom() const
get next random value
iterator< self_type > end()
return forward iterator to the end of bins
iterator< self_type > begin()
return forward iterator to begin of bins
DataGenerator & operator=(const DataGenerator &)=default
const result_type min
DataGenerator(result_type _min, result_type _max, result_type _step, Args &&... args)
DataGenerator(const DataGenerator &)=default
const result_type max
value_type getMin() const
get minimum value
specialization of std::geometric_distribution which implements also the analytic formula.
geometric_distribution(float _parameter)
double getProbability(value_type v) const
get theoretical probability of a value
specialization of std::normal_distribution which implements also the analytic formula.
typename _BASE::result_type result_type
normal_distribution(result_type _mean, result_type _stddev)
double getProbability(value_type v) const
get theoretical probability of a value
specialization of std::poisson_distribution which implements also the analytic formula.
double getProbability(value_type v) const
get theoretical probability of a value
int factorial(unsigned int n) const
typename _BASE::result_type result_type
poisson_distribution(result_type _mean)
GLdouble n
Definition glcorearb.h:1982
GLint GLsizei count
Definition glcorearb.h:399
const GLdouble * v
Definition glcorearb.h:832
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
Defining DataPointCompositeObject explicitly as copiable.
FIXME: do not use data model tables.
VectorOfTObjectPtrs other