1 #ifndef RANDOM_CUSTOM_DISTR_H 2 #define RANDOM_CUSTOM_DISTR_H 4 #if defined(_MSC_VER) && (_MSC_VER >= 1400) 6 #pragma warning(disable:4512) 8 #pragma warning(disable:4127) 21 #include <boost/tuple/tuple.hpp> 22 #include <boost/tuple/tuple_comparison.hpp> 23 #include <boost/bind.hpp> 24 #include <boost/math/distributions/normal.hpp> 37 : impl_( (
std::min)(from, to), (
std::max)(from, to), value)
50 double getFrom()
const {
return boost::get<0>(impl_); }
52 double getTo()
const {
return boost::get<1>(impl_); }
54 double getValue()
const {
return boost::get<2>(impl_); }
56 void setValue(
double val) { boost::get<2>(impl_) = val; }
59 bool operator==(
const DistrValue& v)
const {
return impl_ == v.impl_; }
69 boost::tuple<double, double, double> impl_;
73 inline std::ostream& operator<<(std::ostream& os,
const DistrValue& v) {
79 typedef std::vector<DistrValue> DistrValues;
92 double getVariationTerm(
const DistrValue& v,
const double mi) {
94 double b = v.
getTo() - mi;
95 return v.
getValue()* ( pow(b, 3.0) - pow(a, 3.0) )/ 3.0;
102 inline DistrValues makeProbabilityDensity(
const DistrValues& in) {
103 typedef std::list<DistrValue> Val;
104 Val val(in.begin(), in.end() );
108 Val::iterator curr = val.begin();
109 Val::iterator next = curr;
110 if( next != val.end() )
112 while( next != val.end() ) {
113 if(next->getFrom() < curr->getTo() ) {
114 if( next->getTo() <= curr->getTo() ) {
116 Val::iterator it = next;
123 *next =
DistrValue( curr->getTo(), next->getTo(), next->getValue() );
126 else if(next->getFrom() > curr->getTo() ) {
127 val.insert(next,
DistrValue( curr->getTo(), next->getFrom(), 0.0 ) );
133 double sum = std::accumulate( val.begin(), val.end(), 0.0,
134 boost::bind( std::plus<double>(), _1,
135 boost::bind(&getArea, _2) ) );
137 if(sum == 0.0) sum = 1.0;
140 for(Val::iterator i = val.begin(); i != val.end(); ++i ) {
141 i->setValue( i->getValue() / sum );
143 return DistrValues( val.begin(), val.end() );
147 inline std::ostream& operator<<(std::ostream& os,
const DistrValues& v) {
148 std::copy(v.begin(), v.end(), std::ostream_iterator<DistrValue>(os,
"; ") );
156 values_.push_back(
DistrValue(0.0, 1.0, 1.0) );
159 : values_( makeProbabilityDensity(values) ), gen_()
172 const DistrValues&
getValues()
const {
return values_; }
176 return getQuantile( gen_() );
181 return std::accumulate( values_.begin(), values_.end(), 0.0,
182 boost::bind( std::plus<double>(), _1,
183 boost::bind(&getMeanTerm, _2) ) );
188 double mi = getMean();
189 double variation = std::accumulate( values_.begin(), values_.end(), 0.0,
190 boost::bind( std::plus<double>(), _1,
191 boost::bind(&getVariationTerm, _2, mi) ) );
192 return std::sqrt(variation);
197 if( values_.empty() )
198 return std::numeric_limits<double>::quiet_NaN();
201 for(DistrValues::const_iterator it = values_.begin(); it != values_.end(); ++it ) {
202 double area = getArea(*it);
203 if( k >= sum && k < sum + area) {
205 return getLength(*it) * ( k - sum ) / area + it->getFrom();
210 return values_.back().getTo();
213 double getProbabilityDensity(
double x)
const;
216 double getDistribution(
double x)
const;
238 const double SIG = sigma;
239 const double N = num_steps >= 0 ?
static_cast<double>(num_steps) : 1.0;
240 boost::math::normal normal01(0.0,1.0);
241 const double EPSILON = 0.5 * SIG / (boost::math::pdf(normal01, 3.0) * sqrt(N) );
250 : epsilon_(c.epsilon_), histogram_(c.histogram_), numValues_(c.numValues_)
257 double addValue(
double value) {
261 double key = floor(value/epsilon_)*epsilon_;
263 Histogram::iterator it = histogram_.find(key);
264 if(it != histogram_.end() )
267 histogram_.insert( std::make_pair( key, 1L ) );
277 const double epsilon2 = epsilon_/2.0;
279 for(Histogram::const_iterator it = histogram_.begin(); it != histogram_.end(); ++it) {
280 values.push_back(
DistrValue( it->first - epsilon2,
281 it->first + epsilon2,
282 static_cast<double>(it->second) ) );
292 typedef std::map<double,long> Histogram;
293 Histogram histogram_;
308 DistrValues::const_iterator it =
309 std::lower_bound( values_.begin(), values_.end(), v, rangeLessThanValue );
310 if( it == values_.end() )
312 if( it == values_.begin() && x < it->getFrom() )
314 return it->getValue();
321 DistrValues::const_iterator it =
322 std::lower_bound( values_.begin(), values_.end(), v, rangeLessThanValue );
324 double sum = std::accumulate( values_.begin(), it, 0.0, boost::bind( std::plus<double>(), _1, boost::bind(&getArea, _2) ) );
325 if( it != values_.end() )
326 if(it->getFrom() <= x && x <= it->getTo() )
327 sum += ( x - it->getFrom() ) * it->getValue();
333 #endif //RANDOM_CUSTOM_DISTR_H long getNumValues() const
Definition: RandomCustomDistr.hpp:273
double getQuantile(double k) const
Definition: RandomCustomDistr.hpp:196
virtual ~RandomCustomCreator()
Definition: RandomCustomDistr.hpp:254
static double calculateEpsilon(double sigma, long num_steps)
Definition: RandomCustomDistr.hpp:237
DistrValue(double from, double to, double value)
c-tor
Definition: RandomCustomDistr.hpp:36
double getTo() const
Definition: RandomCustomDistr.hpp:52
double getFrom() const
Definition: RandomCustomDistr.hpp:50
RandomCustomCreator(double e)
Definition: RandomCustomDistr.hpp:246
double getMean() const
Definition: RandomCustomDistr.hpp:180
DistrValue(const DistrValue &v)
copy c-tor
Definition: RandomCustomDistr.hpp:41
Definition: RandomCustomDistr.hpp:226
RandomCustomDistr getRandomCustomDistr() const
Definition: RandomCustomDistr.hpp:276
the uniform distribution for double, in given range, e.g. <0,1), uses RandomSingleton ...
Definition: Random.hpp:74
~DistrValue()
d-tor
Definition: RandomCustomDistr.hpp:48
double getProbabilityDensity(double x) const
Definition: RandomCustomDistr.hpp:305
double getValue() const
Definition: RandomCustomDistr.hpp:54
DistrValue & operator=(const DistrValue &v)
assignment
Definition: RandomCustomDistr.hpp:43
the distribution described by histogram (sum of ranges)
Definition: RandomCustomDistr.hpp:153
Definition: RandomCustomDistr.hpp:33
double getDistribution(double x) const
Definition: RandomCustomDistr.hpp:318
void setValue(double val)
Definition: RandomCustomDistr.hpp:56
double getStandardDeviation() const
Definition: RandomCustomDistr.hpp:187
double operator()()
the method to generate the random variable with given distribution
Definition: RandomCustomDistr.hpp:175
RandomCustomDistr & operator=(const RandomCustomDistr &h)
Definition: RandomCustomDistr.hpp:163
const DistrValues & getValues() const
Definition: RandomCustomDistr.hpp:172
RandomCustomCreator(const RandomCustomCreator &c)
Definition: RandomCustomDistr.hpp:249