155 lines
3.6 KiB
Plaintext
155 lines
3.6 KiB
Plaintext
// Copyright (C) 2010, Guy Barrand. All rights reserved.
|
|
// See the file tools.license for terms.
|
|
|
|
#ifndef tools_randT
|
|
#define tools_randT
|
|
|
|
#include "cmathT"
|
|
|
|
#include "mathd"
|
|
|
|
namespace tools {
|
|
|
|
template <class FLAT,class REAL>
|
|
class rgauss {
|
|
public:
|
|
rgauss(FLAT& a_flat,REAL a_mean = 0,REAL a_std_dev = 1)
|
|
:m_flat(a_flat),m_mean(a_mean),m_std_dev(a_std_dev){}
|
|
virtual ~rgauss(){}
|
|
public:
|
|
rgauss(const rgauss& a_from):m_flat(a_from.m_flat),m_mean(a_from.m_mean),m_std_dev(a_from.m_std_dev){}
|
|
rgauss& operator=(const rgauss& a_from) {
|
|
m_mean = a_from.m_mean;
|
|
m_std_dev = a_from.m_std_dev;
|
|
return *this;
|
|
}
|
|
public:
|
|
REAL shoot() {
|
|
// Shoot random numbers according a
|
|
// rgaussian distribution of mean 0 and sigma 1.
|
|
REAL v1,v2,r,fac;
|
|
do {
|
|
v1 = REAL(2) * m_flat.shoot() - REAL(1);
|
|
v2 = REAL(2) * m_flat.shoot() - REAL(1);
|
|
r = v1*v1 + v2*v2;
|
|
} while (r>REAL(1));
|
|
fac = _sqrt(-REAL(2)*_log(r)/r);
|
|
return (v2 * fac) * m_std_dev + m_mean;
|
|
}
|
|
FLAT& flat() {return m_flat;}
|
|
protected:
|
|
FLAT& m_flat;
|
|
REAL m_mean;
|
|
REAL m_std_dev;
|
|
};
|
|
|
|
template <class FLAT,class REAL>
|
|
class rbw {
|
|
public:
|
|
rbw(FLAT& a_flat,REAL a_mean = 0,REAL a_gamma = 1)
|
|
:m_flat(a_flat),m_mean(a_mean),m_gamma(a_gamma){
|
|
_half_pi(m_half_pi);
|
|
}
|
|
virtual ~rbw(){}
|
|
public:
|
|
rbw(const rbw& a_from):m_flat(a_from.m_flat),m_mean(a_from.m_mean),m_gamma(a_from.m_gamma),m_half_pi(a_from.m_half_pi){}
|
|
rbw& operator=(const rbw& a_from) {
|
|
m_mean = a_from.m_mean;
|
|
m_gamma = a_from.m_gamma;
|
|
m_half_pi = a_from.m_half_pi;
|
|
return *this;
|
|
}
|
|
public:
|
|
REAL shoot() const {
|
|
REAL rval = REAL(2) * m_flat.shoot() - REAL(1);
|
|
REAL displ = (REAL(1)/REAL(2)) * m_gamma * _tan(rval * m_half_pi);
|
|
return m_mean + displ;
|
|
}
|
|
FLAT& flat() {return m_flat;}
|
|
protected:
|
|
FLAT& m_flat;
|
|
REAL m_mean;
|
|
REAL m_gamma;
|
|
REAL m_half_pi;
|
|
};
|
|
|
|
template <class FLAT,class REAL>
|
|
class rexp {
|
|
public:
|
|
rexp(FLAT& a_flat,REAL a_rate = 1):m_flat(a_flat),m_rate(a_rate){}
|
|
virtual ~rexp(){}
|
|
public:
|
|
rexp(const rexp& a_from):m_flat(a_from.m_flat),m_rate(a_from.m_rate){}
|
|
rexp& operator=(const rexp& a_from) {m_rate = a_from.m_rate;return *this;}
|
|
public:
|
|
REAL shoot() const {
|
|
REAL v;
|
|
do {
|
|
v = m_flat.shoot();
|
|
} while(v<=REAL(0));
|
|
return -_log(v)/m_rate;
|
|
}
|
|
FLAT& flat() {return m_flat;}
|
|
protected:
|
|
FLAT& m_flat;
|
|
REAL m_rate;
|
|
};
|
|
|
|
template <class FLAT,class REAL>
|
|
class rdir2 {
|
|
public:
|
|
rdir2(FLAT& a_flat):m_flat(a_flat){}
|
|
virtual ~rdir2(){}
|
|
public:
|
|
rdir2(const rdir2& a_from):m_flat(a_from.m_flat){}
|
|
rdir2& operator=(const rdir2&) {return *this;}
|
|
public:
|
|
void shoot(REAL& a_x,REAL& a_y) const {
|
|
// from gsl_ran_dir_2d.
|
|
REAL u,v,s;
|
|
do {
|
|
u = REAL(2) * m_flat.shoot()-REAL(1);
|
|
v = REAL(2) * m_flat.shoot()-REAL(1);
|
|
s = u * u + v * v;
|
|
}
|
|
while ( (s > REAL(1)) || (s==REAL(0)) );
|
|
a_x = (u * u - v * v) / s;
|
|
a_y = REAL(2) * u * v / s;
|
|
}
|
|
FLAT& flat() {return m_flat;}
|
|
protected:
|
|
FLAT& m_flat;
|
|
};
|
|
|
|
template <class FLAT,class REAL>
|
|
class rdir3 {
|
|
public:
|
|
rdir3(FLAT& a_flat):m_flat(a_flat){}
|
|
virtual ~rdir3(){}
|
|
public:
|
|
rdir3(const rdir3& a_from):m_flat(a_from.m_flat){}
|
|
rdir3& operator=(const rdir3&) {return *this;}
|
|
public:
|
|
void shoot(REAL& a_x,REAL& a_y,REAL& a_z) const {
|
|
// from gsl_ran_dir_3d.
|
|
REAL s;
|
|
do {
|
|
a_x = REAL(2) * m_flat.shoot() - REAL(1);
|
|
a_y = REAL(2) * m_flat.shoot() - REAL(1);
|
|
s = (a_x) * (a_x) + (a_y) * (a_y);
|
|
}
|
|
while (s > REAL(1));
|
|
a_z = REAL(2) * s - REAL(1);
|
|
REAL a = REAL(2) * _sqrt(REAL(1) - s);
|
|
a_x *= a;
|
|
a_y *= a;
|
|
}
|
|
FLAT& flat() {return m_flat;}
|
|
protected:
|
|
FLAT& m_flat;
|
|
};
|
|
|
|
}
|
|
|
|
#endif
|