00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #if !defined TRNG_H
00020
00021 #define TRNG_H
00022
00023 #include <iostream>
00024 #include <cmath>
00025 #include <climits>
00026 #include <vector>
00027 #include <trnglib.h>
00028
00029 #define TRNG_VERSION "3"
00030 #define TRNG_REVISION "0"
00031
00032
00034
00037 namespace TRNG {
00038
00040
00044 enum RNG_type {
00045 RNG_t,
00046 generic_MLCG_t,
00047 ParkMiller_t,
00048 LCG32_t,
00049 LCG64_t,
00050 MRG2_t,
00051 MRG3_t,
00052 MRG4_t,
00053 MRG5_t,
00054 YARNLCG64_t,
00055 YARN2_t,
00056 YARN3_t,
00057 YARN4_t,
00058 YARN5_t,
00059 CLCG2_t,
00060 CLCG3_t,
00061 CLCG4_t,
00062 EINV_t,
00063 EINVLCG64_t,
00064 trng_gsl_t,
00065 user1_t=1001,
00066 user2_t=1002,
00067 user3_t=1003,
00068 user4_t=1004,
00069 user5_t=1005
00070 };
00071
00073 struct vector2d_struct {
00075 double x1;
00077 double x2;
00078 };
00079
00081
00085 typedef struct vector2d_struct vector2d;
00086
00088 struct vector3d_struct {
00090 double x1;
00092 double x2;
00094 double x3;
00095 };
00096
00098
00102 typedef struct vector3d_struct vector3d;
00103
00105 struct vector4d_struct {
00107 double x1;
00109 double x2;
00111 double x3;
00113 double x4;
00114 };
00115
00117
00121 typedef struct vector4d_struct vector4d;
00122
00123
00124
00126
00135 template<class RNG_type> class RNG {
00136 private:
00137 RNG_type & derived(void) {
00138 return static_cast<RNG_type &>(*this);
00139 }
00140
00141 protected:
00143 long max_val;
00145 long max_val2;
00146 public:
00148
00151 static const TRNG::RNG_type type=RNG_t;
00152
00154
00159 const char * name(void) {
00160 return derived().name();
00161 }
00162
00164
00168 void reset(void) {
00169 derived().reset();
00170 }
00171
00173
00181 void seed(long s=0l) {
00182 derived().seed(s);
00183 }
00184
00186
00193 long rand(void) {
00194 return derived().rand();
00195 }
00196
00198
00201 long max(void) {
00202 return max_val;
00203 };
00204
00206
00210 bool boolean(void) {
00211 return (rand()<=max_val2) ? true : false;
00212 }
00213
00215
00219 bool boolean(const double p) {
00220 return (rand()<static_cast<long>(p*max())+1.0) ? true : false;
00221 }
00222
00224
00227 double uniform(void) {
00228 return uniformco();
00229 }
00230
00232
00237 double uniform(const double a, const double b) {
00238 return uniformco(a, b);
00239 }
00240
00242
00245 double uniformco(void) {
00246 return static_cast<double>(rand())/
00247 (static_cast<double>(max())+1.0);
00248 }
00249
00251
00256 double uniformco(const double a, const double b) {
00257 return a+(b-a)*static_cast<double>(rand())/
00258 (static_cast<double>(max())+1.0);
00259 }
00260
00262
00265 double uniformcc(void) {
00266 return static_cast<double>(rand())/
00267 static_cast<double>(max());
00268 }
00269
00271
00276 double uniformcc(const double a, const double b) {
00277 return a+(b-a)*static_cast<double>(rand())/
00278 static_cast<double>(max());
00279 }
00280
00282
00285 double uniformoc(void) {
00286 return (static_cast<double>(rand())+1.0)/
00287 (static_cast<double>(max())+1.0);
00288 }
00289
00291
00296 double uniformoc(const double a, const double b) {
00297 return a+(b-a)*(static_cast<double>(rand())+1.0)/
00298 (static_cast<double>(max())+1.0);
00299 }
00300
00302
00305 double uniformoo(void) {
00306 return (static_cast<double>(rand())+1.0)/
00307 (static_cast<double>(max())+2.0);
00308 }
00309
00311
00316 double uniformoo(const double a, const double b) {
00317 return a+(b-a)*(static_cast<double>(rand())+1.0)/
00318 (static_cast<double>(max())+2.0);
00319 }
00320
00322
00326 long uniforml(const long b) {
00327 return static_cast<long>(uniform(0.0, static_cast<double>(b)));
00328 }
00329
00331
00336 long uniforml(const long a, const long b) {
00337 return static_cast<long>(uniform(static_cast<double>(a),
00338 static_cast<double>(b)));
00339 }
00340
00342
00356 double normal_dist(const double sigma=1.0, const double mu=0.0) {
00357 double s, t1, t2;
00358 if (sigma<=0.0)
00359 throw error("negative or zero standard deviation in TRNG::RNG::normal_dist");
00360 do {
00361 t1=uniformoo(-1.0, 1.0);
00362 t2=uniformoo(-1.0, 1.0);
00363 s=t1*t1+t2*t2;
00364 } while (s>=1.0);
00365 s=std::sqrt(-2.0*std::log(s)/s);
00366 return t1*s*sigma+mu;
00367 }
00368
00370
00389 double exp_dist(const double mu=1.0) {
00390 if (mu<=0.0)
00391 throw error("negative or zero parameter in TRNG::RNG::exp_dist");
00392 double t=uniformoc();
00393 return -mu*std::log(t);
00394 }
00395
00397
00411 double laplace_dist(const double a=1.0) {
00412 if (a<=0.0)
00413 throw error("parameter less or equal zero in TRNG::RNG::laplace_dist");
00414 double u;
00415 do {
00416 u=uniformoo(-1.0, 1.0);
00417 } while (u==0.0);
00418 return u<0.0 ? a*std::log(-u) : -a*std::log(u);
00419 }
00420
00422
00442 double tent_dist(const double a=1.0) {
00443 if (a<=0.0)
00444 throw error("parameter less or equal zero in TRNG::RNG::tent_dist");
00445 double y=uniformoo();
00446 if (y<0.5)
00447 return (-1.0+std::sqrt(2*y))*a;
00448 else
00449 return (1.0-std::sqrt(2.0-2.0*y))*a;
00450 }
00451
00453
00472 double Gamma_dist(const double a, const double b) {
00473 if (a<=0.0 || b<=0.0)
00474 throw error("parameter less or equal zero in TRNG::RNG::Gamma_dist");
00475 double a_int=std::floor(a);
00476 if (a_int==a) {
00477
00478 if (a<12) {
00479 double prod=1.0;
00480 for (int i=0; i<a; ++i)
00481 prod*=uniformoo();
00482
00483
00484
00485
00486 return -b*std::log(prod);
00487 } else {
00488
00489
00490
00491
00492 double sqa, x, y, v;
00493 sqa=std::sqrt(2.0*a-1.0);
00494 do {
00495 do {
00496 const double pi=3.14159265358979324;
00497 y=std::tan(pi*uniformco());
00498 x=sqa*y+a-1.0;
00499 }
00500 while (x<=0.0);
00501 v=uniformco();
00502 }
00503 while (v>(1.0+y*y)*std::exp((a-1.0)*log(x/(a-1))-sqa*y));
00504 return b*x;
00505 }
00506 }
00507 if (a_int==0.0) {
00508
00509
00510
00511 const double e=2.71828182844;
00512 double p, q, x, u, v;
00513 p=e/(a+e);
00514 do {
00515 u=uniformco();
00516 v=uniformoo();
00517 if (u<p) {
00518 x=std::exp((1.0/a)*std::log(v));
00519 q=std::exp(-x);
00520 } else {
00521 x=1.0-std::log(v);
00522 q=std::exp((a-1.0)*std::log(x));
00523 }
00524 } while (uniformco()>=q);
00525 return b*x;
00526 }
00527 return Gamma_dist(a_int, b)+Gamma_dist(a-a_int, b);
00528 }
00529
00531
00550 double Beta_dist(const double a, const double b) {
00551 if (a<=0.0 || b<=0.0)
00552 throw error("negative or zero parameter in TRNG::RNG::Beta_dist");
00553 double t1=Gamma_dist(a, 1.0);
00554 double t2=Gamma_dist(b, 1.0);
00555 return t1/(t1+t2);
00556 }
00557
00559
00575 double chi_square_dist(const double nu) {
00576 if (nu<1.0)
00577 throw error("parameter less than one in TRNG::RNG::chi_square_dist");
00578 return 2.0*Gamma_dist(0.5*nu, 1.0);
00579 }
00580
00582
00597 long binomial_dist(long n, double p=0.5) {
00598 if (p<=0.0 || p>1.0)
00599 throw error("probability <=0.0 or >1.0 in TRNG::RNG::binomial_dist");
00600 if (n<1l)
00601 throw error("less than one trail TRNG::RNG::binomial_dist");
00602 long i, a, b, k=0;
00603 while (n>12l) {
00604 double X;
00605 a=1l+(n/2l);
00606 b=1l+n-a;
00607 X=Beta_dist(static_cast<double>(a), static_cast<double>(b));
00608 if (X>=p) {
00609 n=a-1l;
00610 p/=X;
00611 } else {
00612 k+=a;
00613 n=b-1l;
00614 p=(p-X)/(1l-X);
00615 }
00616 }
00617 for (i=0l; i<n; i++)
00618 if (uniformco()<p)
00619 k++;
00620 return k;
00621 }
00622
00624
00637 long binomial_dist_tab(long n, double p=0.5) {
00638 if (p<=0.0 || p>1.0)
00639 throw error("probability <=0.0 or >1.0 in TRNG::RNG::binomial_dist_tab");
00640 if (n<1l)
00641 throw error("less than one trail TRNG::RNG::binomial_dist_tab");
00642 static long n_=0l;
00643 static double p_=0.0;
00644 static std::vector<double> prob;
00645 if (n!=n_ || p!=p_) {
00646 n_=n;
00647 p_=p;
00648 prob.resize(n_);
00649
00650
00651
00652
00653 double b=1.0;
00654 for (int k=0l; k<n_; ++k) {
00655 prob[k]=b*std::pow(p_, static_cast<double>(k))*
00656 std::pow(1.0-p_, static_cast<double>(n_-k));
00657 if (k>0l)
00658 prob[k]+=prob[k-1l];
00659 b=std::floor(b*static_cast<double>(n_-k)/
00660 static_cast<double>(k+1l)+0.5);
00661 }
00662 }
00663 return find_interval(prob, uniformco());
00664 }
00665
00667
00683 double Student_t_dist(const double nu) {
00684 if (nu<=0.0)
00685 throw error("parameter less than or equal zero in TRNG::RNG::Student_t_dist");
00686 if (nu<=2.0)
00687 return normal_dist()/std::sqrt(chi_square_dist(nu)/nu);
00688 else {
00689 double y1, y2, z;
00690 do {
00691 y1=normal_dist();
00692 y2=exp_dist(1.0/(0.5*nu-1.0));
00693 z=y1*y1/(nu-2.0);
00694 } while (1.0-z<0.0 || std::exp(-y2-z)>(1.0-z));
00695
00696
00697
00698 return y1/std::sqrt((1.0-2.0/nu)*(1.0-z));
00699 }
00700 }
00701
00703
00715 long poisson_dist(double mu=1.0) {
00716 if (mu<=0)
00717 throw error("parameter less than 0 in TRNG::RNG::poisson_dist");
00718 double emu;
00719 double prod=1.0;
00720 long k=0;
00721 while (mu>10.0) {
00722 long m=static_cast<long>(mu*(7.0/8.0));
00723 double X=Gamma_dist(static_cast<long>(m), 1.0);
00724 if (X>=mu) {
00725 return k+binomial_dist(m-1l, mu/X);
00726 } else {
00727 k+=m;
00728 mu-=X;
00729 }
00730 }
00731
00732 emu=std::exp(-mu);
00733 do {
00734 prod*=uniformco();
00735 k++;
00736 } while (prod>emu);
00737 return k-1l;
00738 }
00739
00741
00753 long geometric_dist(double q) {
00754 if (q<=0.0 ||q>1.0)
00755 throw error("parameter out of range in TRNG::RNG::geometric_dist");
00756 if (q==1.0)
00757 return 1l;
00758 return static_cast<long>
00759 (std::log(uniformoo())/std::log(1.0-p))+1l;
00760 }
00761
00763
00789 template<class t_function>
00790 double rejection(t_function p, double a1, double a2, double p_max) {
00791 double t1, t2;
00792 do {
00793 t1=uniformco(a1, a2);
00794 t2=uniformco(0.0, p_max);
00795 } while (p(t1)<t2);
00796 return t1;
00797 }
00798
00800
00812 long discrete_dist(const std::vector<double> p) {
00813 if (p.empty())
00814 throw error("empty vector in TRNG::discrete_dist");
00815 double x=uniformco();
00816 if (x<p[0])
00817 return 0l;
00818 long i1=0l;
00819 long i2=p.size()-1l;
00820 while (i2-i1>1l) {
00821 long i3=(i2+i1)/2;
00822 if (x<=p[i3])
00823 i2=i3;
00824 else
00825 i1=i3;
00826 }
00827 return i2;
00828 }
00829
00831
00839 vector2d spherical2d(void) {
00840 double r2, t1, t2, t12, t22;
00841 vector2d vec;
00842 do {
00843 t1=2.0*uniformco()-1.0;
00844 t2=uniformco();
00845 t12=t1*t1;
00846 t22=t2*t2;
00847 r2=t12+t22;
00848 } while (r2>1.0);
00849 vec.x1=2.0*t1*t2/r2;
00850 vec.x2=(t12-t22)/r2;
00851 return vec;
00852 }
00853
00855
00863 vector3d spherical3d(void) {
00864 double q, r2, t1, t2;
00865 vector3d vec;
00866 do {
00867 t1=2.0*uniformco()-1.0;
00868 t2=2.0*uniformco()-1.0;
00869 r2=t1*t1+t2*t2;
00870 } while (r2>1.0);
00871 q=2.0*sqrt(1.0-r2);
00872 vec.x1=t1*q;
00873 vec.x2=t2*q;
00874 vec.x3=1-2*r2;
00875 return vec;
00876 }
00877
00879
00887 vector4d spherical4d(void) {
00888 double q, r21, r22, t1, t2, t3, t4;
00889 vector4d vec;
00890 do {
00891 t1=2.0*uniformco()-1.0;
00892 t2=2.0*uniformco()-1.0;
00893 r21=t1*t1+t2*t2;
00894 } while (r21>1.0);
00895 do {
00896 t3=2.0*uniformco()-1.0;
00897 t4=2.0*uniformco()-1.0;
00898 r22=t3*t3+t4*t4;
00899 } while (r22>1.0);
00900 q=sqrt((1.0-r21)/r22);
00901 vec.x1=t1;
00902 vec.x2=t2;
00903 vec.x3=t3*q;
00904 vec.x4=t4*q;
00905 return(vec);
00906 }
00907
00909
00918 void split(long s, long n) {
00919 derived().split(s, n);
00920 }
00921
00923
00929 void jump(long long s) {
00930 if (s<0ll)
00931 throw error("invalid argument for TRNG::RNG::jump");
00932 long i=0l;
00933 while (s>0ll) {
00934 if (s%2==1)
00935 jump2(i);
00936 ++i;
00937 s>>=1;
00938 }
00939 }
00940
00942
00950 void jump(long long s, long n) {
00951 if (s<0ll || n<0l)
00952 throw error("invalid argument for TRNG::RNG::jump");
00953 while (n>0l) {
00954 jump(s);
00955 --n;
00956 }
00957 }
00958
00960
00966 void jump2(long s) {
00967 derived().jump2(s);
00968 }
00969
00971
00978 void jump2(long s, long n) {
00979 if (s<0l || n<0l)
00980 throw error("invalid argument for TRNG::RNG::jump2");
00981 while (n>0l) {
00982 if (n%2l==1l)
00983 jump2(s);
00984 s+=1l;
00985 n>>=1;
00986 }
00987 }
00988
00990
00995 void save_status(std::vector<long> &s) {
00996 derived().save_status(s);
00997 }
00998
01000
01005 void load_status(const std::vector<long> &s) {
01006 derived().load_status(s);
01007 }
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023 };
01024
01025
01026
01028
01044 class generic_MLCG : public RNG<generic_MLCG> {
01045
01046
01047 private:
01048 long a, a_save;
01049 long modulus, modulus_save;
01050 long r;
01051 void backward(void);
01052 public:
01053 static const RNG_type type=generic_MLCG_t;
01054 const char * name(void);
01055 void reset(void);
01056 void seed(long s=0l);
01057 long rand(void);
01058 void split(long s, long n);
01059 void jump2(long s);
01060 void save_status(std::vector<long> &s);
01061 void load_status(const std::vector<long> &s);
01062 generic_MLCG & generic_MLCG::operator=(RNG<generic_MLCG> &other);
01063 generic_MLCG(long a_=16807l, long modulus_=2147483647l, long seed_=0l);
01064 };
01065
01066 inline long generic_MLCG::rand(void) {
01067 if (modulus==2147483647l) {
01068 unsigned long long t=
01069 static_cast<unsigned long long>(a)*static_cast<unsigned long long>(r);
01070 t=(t&0x7fffffffull)+(t>>31);
01071 r=(t>=2147483647ul) ? (t-2147483647ul) : t;
01072 return r;
01073 } else {
01074 r=static_cast<long>
01075 ((static_cast<long long>(a)*static_cast<long long>(r))%modulus);
01076 return r;
01077 }
01078 }
01079
01080
01081
01083
01091 class ParkMiller_param {
01092 public:
01093 const long a;
01094 const long modulus;
01095
01101 ParkMiller_param(long a_, long modulus_) :
01102 a(a_), modulus(modulus_) { };
01103 };
01104
01106 namespace ParkMiller_param_sets {
01108 const ParkMiller_param mindstd=ParkMiller_param(16807l, 2147483647l);
01110 const ParkMiller_param Fishman1=ParkMiller_param(742938285l, 2147483647l);
01112 const ParkMiller_param Fishman2=ParkMiller_param(950706376l, 2147483647l);
01114 const ParkMiller_param Fishman3=ParkMiller_param(1226874159l, 2147483647l);
01116 const ParkMiller_param Fishman4=ParkMiller_param(62089911l, 2147483647l);
01118 const ParkMiller_param Fishman5=ParkMiller_param(1343714438l, 2147483647l);
01119 }
01120
01122
01137 class ParkMiller : public RNG<ParkMiller> {
01138 private:
01139 generic_MLCG R;
01140 public:
01141 static const RNG_type type=ParkMiller_t;
01142 const char * name(void);
01143 void reset(void);
01144 void seed(long s=0l);
01145 long rand(void);
01146 void split(long s, long n);
01147 void jump2(long s);
01148 void save_status(std::vector<long> &s);
01149 void load_status(const std::vector<long> &s);
01150 ParkMiller & ParkMiller::operator=(RNG<ParkMiller> &other);
01152
01161 ParkMiller(ParkMiller_param param=ParkMiller_param_sets::mindstd,
01162 long seed_=0l);
01163 };
01164
01165 inline long ParkMiller::rand(void) {
01166 return R.rand()-1l;
01167 }
01168
01169
01170
01172
01180 class LCG32_param {
01181 public:
01182 const unsigned long a;
01183 const unsigned long b;
01184
01190 LCG32_param(unsigned long a_, unsigned long b_) :
01191 a(a_), b(b_) { };
01192 };
01193
01195 namespace LCG32_param_sets {
01197 const LCG32_param VAX=LCG32_param(69069ul, 1ul);
01199 const LCG32_param SuperDuper=LCG32_param(69069ul, 0ul);
01201 const LCG32_param Derive=LCG32_param(3141592653ul, 1ul);
01203 const LCG32_param LEcuyer1=LCG32_param(2891336453ul, 1ul);
01205 const LCG32_param LEcuyer2=LCG32_param(29943829ul, 1ul);
01207 const LCG32_param LEcuyer3=LCG32_param(32310901ul, 1ul);
01208 }
01209
01211
01227 class LCG32 : public RNG<LCG32> {
01228 private:
01229 unsigned long a, a_save;
01230 unsigned long b, b_save;
01231 unsigned long r;
01232 void backward(void);
01233 public:
01234 static const RNG_type type=LCG32_t;
01235 const char * name(void);
01236 void reset(void);
01237 void seed(long s=0l);
01238 long rand(void);
01239 void split(long s, long n);
01240 void jump2(long s);
01241 void save_status(std::vector<long> &s);
01242 void load_status(const std::vector<long> &s);
01243 LCG32 & LCG32::operator=(RNG<LCG32> &other);
01245
01253 LCG32(LCG32_param param=LCG32_param_sets::VAX, long seed_=0l);
01254 };
01255
01256 inline long LCG32::rand(void) {
01257 r=a*r+b;
01258 #if ULONG_MAX == 0xfffffffful
01259 #else
01260 r&=0xfffffffful;
01261 #endif
01262 return static_cast<long>(r>>1);
01263 }
01264
01265
01266
01268
01276 class LCG64_param {
01277 public:
01278 const unsigned long long a;
01279 const unsigned long long b;
01280
01286 LCG64_param(unsigned long long a_, unsigned long long b_) :
01287 a(a_), b(b_) { };
01288 };
01289
01291 namespace LCG64_param_sets {
01293 const LCG64_param TRNG=LCG64_param(18145460002477866997ull, 1ull);
01295 const LCG64_param LEcuyer1=LCG64_param(2862933555777941757ull, 1ull);
01297 const LCG64_param LEcuyer2=LCG64_param(3202034522624059733ull, 1ull);
01299 const LCG64_param LEcuyer3=LCG64_param(3935559000370003845ull, 1ull);
01300 }
01301
01303
01317 class LCG64 : public RNG<LCG64> {
01318 private:
01319 unsigned long long a, a_save;
01320 unsigned long long b, b_save;
01321 unsigned long long r;
01322 void backward(void);
01323 public:
01324 static const RNG_type type=LCG64_t;
01325 const char * name(void);
01326 void reset(void);
01327 void seed(long s=0l);
01328 long rand(void);
01329 void split(long s, long n);
01330 void jump2(long s);
01331 void save_status(std::vector<long> &s);
01332 void load_status(const std::vector<long> &s);
01333 LCG64 & LCG64::operator=(RNG<LCG64> &other);
01335
01343 LCG64(LCG64_param param=LCG64_param_sets::TRNG, long seed_=0l);
01344 };
01345
01346 inline long LCG64::rand(void) {
01347 r=a*r+b;
01348 return static_cast<long>(r>>33);
01349 }
01350
01351
01352
01354
01362 class MRG2_param {
01363 public:
01364 const long a1;
01365 const long a2;
01366 const long modulus;
01367
01374 MRG2_param(long a1_, long a2_, long modulus_) :
01375 a1(a1_), a2(a2_), modulus(modulus_) { };
01376 };
01377
01379 namespace MRG2_param_sets {
01381 const MRG2_param LEcuyer1=MRG2_param(1498809829l, 1160990996l, 2147483647l);
01383 const MRG2_param LEcuyer2=MRG2_param(46325l, 1084587l, 2147483647l);
01384 }
01385
01387
01395 class MRG2 : public RNG<MRG2> {
01396 private:
01397 long a1, a2, a1_save, a2_save;
01398 long r1, r2;
01399 long modulus, modulus_save;
01400 void backward(void);
01401 public:
01402 static const RNG_type type=MRG2_t;
01403 const char * name(void);
01404 void reset(void);
01405 void seed(long s=0l);
01406 long rand(void);
01407 void split(long s, long n);
01408 void jump2(long s);
01409 void save_status(std::vector<long> &s);
01410 void load_status(const std::vector<long> &s);
01411 MRG2 & MRG2::operator=(RNG<MRG2> &other);
01413
01423 MRG2(MRG2_param param=MRG2_param_sets::LEcuyer1, long seed_=0l);
01424 };
01425
01426 inline long MRG2::rand(void) {
01427 unsigned long long t=
01428 static_cast<unsigned long long>(a1)*static_cast<unsigned long long>(r1)+
01429 static_cast<unsigned long long>(a2)*static_cast<unsigned long long>(r2);
01430 if (modulus==2147483647l) {
01431 t=(t&0x7fffffffull)+(t>>31);
01432 if (t>=2ull*2147483647ull)
01433 t-=2ull*2147483647ull;
01434 if (t>=2147483647ull)
01435 t-=2147483647ull;
01436 } else
01437 t%=modulus;
01438 r2=r1; r1=t;
01439 return r1;
01440 }
01441
01442
01443
01445
01453 class MRG3_param {
01454 public:
01455 const long a1;
01456 const long a2;
01457 const long a3;
01458 const long modulus;
01459
01467 MRG3_param(long a1_, long a2_, long a3_, long modulus_) :
01468 a1(a1_), a2(a2_), a3(a3_), modulus(modulus_) { };
01469 };
01470
01472 namespace MRG3_param_sets {
01474 const MRG3_param LEcuyer1=MRG3_param(2021422057l, 1826992351l, 1977753457l, 2147483647l);
01476 const MRG3_param LEcuyer2=MRG3_param(1476728729l, 0l, 1155643113l, 2147483647l);
01478 const MRG3_param LEcuyer3=MRG3_param(65338l, 0l, 64636l, 2147483647l);
01479 }
01480
01482
01490 class MRG3 : public RNG<MRG3> {
01491 private:
01492 long a1, a2, a3, a1_save, a2_save, a3_save;
01493 long r1, r2, r3;
01494 long modulus, modulus_save;
01495 void backward(void);
01496 public:
01497 static const RNG_type type=MRG3_t;
01498 const char * name(void);
01499 void reset(void);
01500 void seed(long s=0l);
01501 long rand(void);
01502 void split(long s, long n);
01503 void jump2(long s);
01504 void save_status(std::vector<long> &s);
01505 void load_status(const std::vector<long> &s);
01506 MRG3 & MRG3::operator=(RNG<MRG3> &other);
01508
01518 MRG3(MRG3_param param=MRG3_param_sets::LEcuyer1, long seed_=0l);
01519 };
01520
01521 inline long MRG3::rand(void) {
01522 unsigned long long t=
01523 static_cast<unsigned long long>(a1)*static_cast<unsigned long long>(r1)+
01524 static_cast<unsigned long long>(a2)*static_cast<unsigned long long>(r2)+
01525 static_cast<unsigned long long>(a3)*static_cast<unsigned long long>(r3);
01526 if (modulus==2147483647l) {
01527 t=(t&0x7fffffffull)+(t>>31);
01528 if (t>=2ull*2147483647ull)
01529 t-=2ull*2147483647ull;
01530 if (t>=2147483647ull)
01531 t-=2147483647ull;
01532 } else
01533 t%=modulus;
01534 r3=r2; r2=r1; r1=t;
01535 return r1;
01536 }
01537
01538
01539
01541
01549 class MRG4_param {
01550 public:
01551 const long a1;
01552 const long a2;
01553 const long a3;
01554 const long a4;
01555 const long modulus;
01556
01565 MRG4_param(long a1_, long a2_, long a3_, long a4_, long modulus_) :
01566 a1(a1_), a2(a2_), a3(a3_), a4(a4_), modulus(modulus_) { };
01567 };
01568
01570 namespace MRG4_param_sets {
01572 const MRG4_param LEcuyer1=MRG4_param(2001982722l, 1412284257l, 1155380217l, 1668339922l, 2147483647l);
01574 const MRG4_param LEcuyer2=MRG4_param(64886l, 0l, 0l, 64322l, 2147483647l);
01575 }
01576
01578
01587 class MRG4 : public RNG<MRG4> {
01588 private:
01589 long a1, a2, a3, a4, a1_save, a2_save, a3_save, a4_save;
01590 long r1, r2, r3, r4;
01591 long modulus, modulus_save;
01592 void backward(void);
01593 public:
01594 static const RNG_type type=MRG4_t;
01595 const char * name(void);
01596 void reset(void);
01597 void seed(long s=0l);
01598 long rand(void);
01599 void split(long s, long n);
01600 void jump2(long s);
01601 void save_status(std::vector<long> &s);
01602 void load_status(const std::vector<long> &s);
01603 MRG4 & MRG4::operator=(RNG<MRG4> &other);
01605
01616 MRG4(MRG4_param param=MRG4_param_sets::LEcuyer1, long seed_=0l);
01617 };
01618
01619 inline long MRG4::rand(void) {
01620 unsigned long long t=
01621 static_cast<unsigned long long>(a1)*static_cast<unsigned long long>(r1)+
01622 static_cast<unsigned long long>(a2)*static_cast<unsigned long long>(r2)+
01623 static_cast<unsigned long long>(a3)*static_cast<unsigned long long>(r3)+
01624 static_cast<unsigned long long>(a4)*static_cast<unsigned long long>(r4);
01625 if (modulus==2147483647l) {
01626 t=(t&0x7fffffffull)+(t>>31);
01627 if (t>=4ull*2147483647ull)
01628 t-=4ull*2147483647ull;
01629 if (t>=2ull*2147483647ull)
01630 t-=2ull*2147483647ull;
01631 if (t>=2147483647ull)
01632 t-=2147483647ull;
01633 } else
01634 t%=modulus;
01635 r4=r3; r3=r2; r2=r1; r1=t;
01636 return r1;
01637 }
01638
01639
01640
01642
01651 class MRG5_param {
01652 public:
01653 const long a1;
01654 const long a2;
01655 const long a3;
01656 const long a4;
01657 const long a5;
01658 const long modulus;
01659
01669 MRG5_param(long a1_, long a2_, long a3_, long a4_, long a5_, long modulus_) :
01670 a1(a1_), a2(a2_), a3(a3_), a4(a4_), a5(a5_), modulus(modulus_) { };
01671 };
01672
01674 namespace MRG5_param_sets {
01676 const MRG5_param LEcuyer1=MRG5_param(177786l, 0l, 0l, 0l, 64654l, 2147483647l);
01677 }
01678
01680
01689 class MRG5 : public RNG<MRG5> {
01690 private:
01691 long a1, a2, a3, a4, a5, a1_save, a2_save, a3_save, a4_save, a5_save;
01692 long r1, r2, r3, r4, r5;
01693 long modulus, modulus_save;
01694 unsigned long long m2_2;
01695 void backward(void);
01696 public:
01697 static const RNG_type type=MRG5_t;
01698 const char * name(void);
01699 void reset(void);
01700 void seed(long s=0l);
01701 long rand(void);
01702 void split(long s, long n);
01703 void jump2(long s);
01704 void save_status(std::vector<long> &s);
01705 void load_status(const std::vector<long> &s);
01706 MRG5 & MRG5::operator=(RNG<MRG5> &other);
01708
01719 MRG5(MRG5_param param=MRG5_param_sets::LEcuyer1, long seed_=0l);
01720 };
01721
01722 inline long MRG5::rand(void) {
01723 unsigned long long t=
01724 static_cast<unsigned long long>(a1)*static_cast<unsigned long long>(r1)+
01725 static_cast<unsigned long long>(a2)*static_cast<unsigned long long>(r2)+
01726 static_cast<unsigned long long>(a3)*static_cast<unsigned long long>(r3)+
01727 static_cast<unsigned long long>(a4)*static_cast<unsigned long long>(r4);
01728 if (t>=m2_2)
01729 t-=m2_2;
01730 t+=static_cast<unsigned long long>(a5)*static_cast<unsigned long long>(r5);
01731 if (modulus==2147483647l) {
01732 t=(t&0x7fffffffull)+(t>>31);
01733 if (t>=2ull*2147483647ull)
01734 t-=2ull*2147483647ull;
01735 if (t>=2147483647ull)
01736 t-=2147483647ull;
01737 } else
01738 t%=modulus;
01739 r5=r4; r4=r3; r3=r2; r2=r1; r1=t;
01740 return r1;
01741 }
01742
01743
01744
01746
01754 class YARNLCG64_param {
01755 public:
01756 const unsigned long long a;
01757 const unsigned long long b;
01758 const long g;
01759
01766 YARNLCG64_param(unsigned long long a_, unsigned long long b_, long g_) :
01767 a(a_), b(b_), g(g_) { };
01768 };
01769
01771 namespace YARNLCG64_param_sets {
01773 const YARNLCG64_param TRNG=YARNLCG64_param(18145460002477866997ull, 1ull, 123567893l);
01775 const YARNLCG64_param LEcuyer1=YARNLCG64_param(2862933555777941757ull, 1ull, 123567893l);
01777 const YARNLCG64_param LEcuyer2=YARNLCG64_param(3202034522624059733ull, 1ull, 123567893l);
01779 const YARNLCG64_param LEcuyer3=YARNLCG64_param(3935559000370003845ull, 1ull, 123567893l);
01780 }
01781
01783
01806 class YARNLCG64 : public RNG<YARNLCG64> {
01807 private:
01808 LCG64 R;
01809 power g;
01810 long g_save;
01811 public:
01812 static const RNG_type type=YARNLCG64_t;
01813 const char * name(void);
01814 void reset(void);
01815 void seed(long s=0l);
01816 long rand(void);
01817 void split(long s, long n);
01818 void jump2(long s);
01819 void save_status(std::vector<long> &s);
01820 void load_status(const std::vector<long> &s);
01821 YARNLCG64 & YARNLCG64::operator=(RNG<YARNLCG64> &other);
01823
01831 YARNLCG64(YARNLCG64_param param=YARNLCG64_param_sets::TRNG, long seed_=0l);
01832 };
01833
01834 inline long YARNLCG64::rand(void) {
01835 long t=R.rand();
01836 return (t==0 || t==2147483647l) ? t : g(t);
01837 }
01838
01839
01840
01842
01857 class YARN2_param {
01858 public:
01859 const long a1;
01860 const long a2;
01861 const long modulus;
01862 const long g;
01863
01871 YARN2_param(long a1_, long a2_, long modulus_, long g_) :
01872 a1(a1_), a2(a2_), modulus(modulus_), g(g_) { };
01873 };
01874
01876 namespace YARN2_param_sets {
01878 const YARN2_param LEcuyer1=YARN2_param(1498809829l, 1160990996l, 2147483647l, 123567893l);
01880 const YARN2_param LEcuyer2=YARN2_param(46325l, 1084587l, 2147483647l, 123567893l);
01881 }
01882
01884
01901 class YARN2 : public RNG<YARN2> {
01902 private:
01903 MRG2 R;
01904 power g;
01905 long g_save;
01906 public:
01907 static const RNG_type type=YARN2_t;
01908 const char * name(void);
01909 void reset(void);
01910 void seed(long s=0l);
01911 long rand(void);
01912 void split(long s, long n);
01913 void jump2(long s);
01914 void save_status(std::vector<long> &s);
01915 void load_status(const std::vector<long> &s);
01916 YARN2 & YARN2::operator=(RNG<YARN2> &other);
01918
01929 YARN2(YARN2_param param=YARN2_param_sets::LEcuyer1, long seed_=0l);
01930 };
01931
01932 inline long YARN2::rand(void) {
01933 long t=R.rand();
01934 return (t==0) ? 0 : g(t);
01935 }
01936
01937
01938
01940
01955 class YARN3_param {
01956 public:
01957 const long a1;
01958 const long a2;
01959 const long a3;
01960 const long modulus;
01961 const long g;
01962
01971 YARN3_param(long a1_, long a2_, long a3_, long modulus_, long g_) :
01972 a1(a1_), a2(a2_), a3(a3_), modulus(modulus_), g(g_) { };
01973 };
01974
01976 namespace YARN3_param_sets {
01978 const YARN3_param LEcuyer1=YARN3_param(2021422057l, 1826992351l, 1977753457l, 2147483647l, 123567893l);
01980 const YARN3_param LEcuyer2=YARN3_param(1476728729l, 0l, 1155643113l, 2147483647l, 123567893l);
01982 const YARN3_param LEcuyer3=YARN3_param(65338l, 0l, 64636l, 2147483647l, 123567893l);
01983 }
01984
01986
02003 class YARN3 : public RNG<YARN3> {
02004 private:
02005 MRG3 R;
02006 power g;
02007 long g_save;
02008 public:
02009 static const RNG_type type=YARN3_t;
02010 const char * name(void);
02011 void reset(void);
02012 void seed(long s=0l);
02013 long rand(void);
02014 void split(long s, long n);
02015 void jump2(long s);
02016 void save_status(std::vector<long> &s);
02017 void load_status(const std::vector<long> &s);
02018 YARN3 & YARN3::operator=(RNG<YARN3> &other);
02020
02031 YARN3(YARN3_param param=YARN3_param_sets::LEcuyer1, long seed_=0l);
02032 };
02033
02034 inline long YARN3::rand(void) {
02035 long t=R.rand();
02036 return (t==0) ? 0 : g(t);
02037 }
02038
02039
02040
02042
02058 class YARN4_param {
02059 public:
02060 const long a1;
02061 const long a2;
02062 const long a3;
02063 const long a4;
02064 const long modulus;
02065 const long g;
02066
02076 YARN4_param(long a1_, long a2_, long a3_, long a4_, long modulus_, long g_) :
02077 a1(a1_), a2(a2_), a3(a3_), a4(a4_), modulus(modulus_), g(g_) { };
02078 };
02079
02081 namespace YARN4_param_sets {
02083 const YARN4_param LEcuyer1=YARN4_param(2001982722l, 1412284257l, 1155380217l, 1668339922l, 2147483647l, 123567893l);
02085 const YARN4_param LEcuyer2=YARN4_param(64886l, 0l, 0l, 64322l, 2147483647l, 123567893l);
02086 }
02087
02089
02107 class YARN4 : public RNG<YARN4> {
02108 private:
02109 MRG4 R;
02110 power g;
02111 long g_save;
02112 public:
02113 static const RNG_type type=YARN4_t;
02114 const char * name(void);
02115 void reset(void);
02116 void seed(long s=0l);
02117 long rand(void);
02118 void split(long s, long n);
02119 void jump2(long s);
02120 void save_status(std::vector<long> &s);
02121 void load_status(const std::vector<long> &s);
02122 YARN4 & YARN4::operator=(RNG<YARN4> &other);
02124
02136 YARN4(YARN4_param param=YARN4_param_sets::LEcuyer1, long seed_=0l);
02137 };
02138
02139 inline long YARN4::rand(void) {
02140 long t=R.rand();
02141 return (t==0) ? 0 : g(t);
02142 }
02143
02144
02145
02147
02163 class YARN5_param {
02164 public:
02165 const long a1;
02166 const long a2;
02167 const long a3;
02168 const long a4;
02169 const long a5;
02170 const long modulus;
02171 const long g;
02172
02183 YARN5_param(long a1_, long a2_, long a3_, long a4_, long a5_, long modulus_, long g_) :
02184 a1(a1_), a2(a2_), a3(a3_), a4(a4_), a5(a5_), modulus(modulus_), g(g_) { };
02185 };
02186
02188 namespace YARN5_param_sets {
02190 const YARN5_param LEcuyer1=YARN5_param(177786l, 0l, 0l, 0l, 64654l, 2147483647l, 123567893l);
02191 }
02192
02194
02212 class YARN5 : public RNG<YARN5> {
02213 private:
02214 MRG5 R;
02215 power g;
02216 long g_save;
02217 public:
02218 static const RNG_type type=YARN4_t;
02219 const char * name(void);
02220 void reset(void);
02221 void seed(long s=0l);
02222 long rand(void);
02223 void split(long s, long n);
02224 void jump2(long s);
02225 void save_status(std::vector<long> &s);
02226 void load_status(const std::vector<long> &s);
02227 YARN5 & YARN5::operator=(RNG<YARN5> &other);
02229
02241 YARN5(YARN5_param param=YARN5_param_sets::LEcuyer1, long seed_=0l);
02242 };
02243
02244 inline long YARN5::rand(void) {
02245 long t=R.rand();
02246 return (t==0) ? 0 : g(t);
02247 }
02248
02249
02250
02252
02257 class CLCG2_param {
02258 public:
02259 const long a1;
02260 const long modulus1;
02261 const long a2;
02262 const long modulus2;
02263
02271 CLCG2_param(long a1_, long modulus1_, long a2_, long modulus2_) :
02272 a1(a1_), modulus1(modulus1_),
02273 a2(a2_), modulus2(modulus2_) { };
02274 };
02275
02277 namespace CLCG2_param_sets {
02279 const CLCG2_param TRNG=CLCG2_param(376555083l, 2147482951l, 1028879659l, 2147482949l);
02280 }
02281
02283
02296 class CLCG2 : public RNG<CLCG2> {
02297 private:
02298 generic_MLCG R1;
02299 generic_MLCG R2;
02300 long modulus;
02301 public:
02302 static const RNG_type type=CLCG2_t;
02303 const char * name(void);
02304 void reset(void);
02305 void seed(long s=0l);
02306 long rand(void);
02307 void split(long s, long n);
02308 void jump2(long s);
02309 void save_status(std::vector<long> &s);
02310 void load_status(const std::vector<long> &s);
02311 CLCG2 & CLCG2::operator=(RNG<CLCG2> &other);
02313
02330 CLCG2(CLCG2_param param=CLCG2_param_sets::TRNG, long seed_=0l);
02331 };
02332
02333 inline long CLCG2::rand(void) {
02334 unsigned long t=
02335 static_cast<unsigned long>(R1.rand())+
02336 static_cast<unsigned long>(R2.rand());
02337 return (t>=modulus) ? (t-modulus) : t;
02338 }
02339
02340
02341
02343
02348 class CLCG3_param {
02349 public:
02350 const long a1;
02351 const long modulus1;
02352 const long a2;
02353 const long modulus2;
02354 const long a3;
02355 const long modulus3;
02356
02366 CLCG3_param(long a1_, long modulus1_, long a2_, long modulus2_, long a3_, long modulus3_) :
02367 a1(a1_), modulus1(modulus1_),
02368 a2(a2_), modulus2(modulus2_),
02369 a3(a3_), modulus3(modulus3_) { };
02370 };
02371
02373 namespace CLCG3_param_sets {
02375 const CLCG3_param TRNG=CLCG3_param(376555083l, 2147482951l,1028879659l, 2147482949l, 225802979l, 2147482943l);
02376 }
02377
02379
02393 class CLCG3 : public RNG<CLCG3> {
02394 private:
02395 generic_MLCG R1;
02396 generic_MLCG R2;
02397 generic_MLCG R3;
02398 long modulus;
02399 public:
02400 static const RNG_type type=CLCG3_t;
02401 const char * name(void);
02402 void reset(void);
02403 void seed(long s=0l);
02404 long rand(void);
02405 void split(long s, long n);
02406 void jump2(long s);
02407 void save_status(std::vector<long> &s);
02408 void load_status(const std::vector<long> &s);
02409 CLCG3 & CLCG3::operator=(RNG<CLCG3> &other);
02411
02430 CLCG3(CLCG3_param param=CLCG3_param_sets::TRNG, long seed_=0l);
02431 };
02432
02433 inline long CLCG3::rand(void) {
02434 unsigned long t=
02435 static_cast<unsigned long>(R1.rand())+
02436 static_cast<unsigned long>(R2.rand());
02437 if (t>=modulus)
02438 t-=modulus;
02439 t+=static_cast<unsigned long>(R3.rand());
02440 return (t>=modulus) ? (t-modulus) : t;
02441 }
02442
02443
02444
02446
02451 class CLCG4_param {
02452 public:
02453 const long a1;
02454 const long modulus1;
02455 const long a2;
02456 const long modulus2;
02457 const long a3;
02458 const long modulus3;
02459 const long a4;
02460 const long modulus4;
02461
02473 CLCG4_param(long a1_, long modulus1_, long a2_, long modulus2_, long a3_, long modulus3_, long a4_, long modulus4_) :
02474 a1(a1_), modulus1(modulus1_),
02475 a2(a2_), modulus2(modulus2_),
02476 a3(a3_), modulus3(modulus3_),
02477 a4(a4_), modulus4(modulus4_) { };
02478 };
02479
02481 namespace CLCG4_param_sets {
02483 const CLCG4_param TRNG=CLCG4_param(376555083l, 2147482951l, 1028879659l, 2147482949l, 225802979l, 2147482943l,2028073966l, 2147482859l);
02484 }
02485
02487
02502 class CLCG4 : public RNG<CLCG4> {
02503 private:
02504 generic_MLCG R1;
02505 generic_MLCG R2;
02506 generic_MLCG R3;
02507 generic_MLCG R4;
02508 long modulus;
02509 public:
02510 static const RNG_type type=CLCG4_t;
02511 const char * name(void);
02512 void reset(void);
02513 void seed(long s=0l);
02514 long rand(void);
02515 void split(long s, long n);
02516 void jump2(long s);
02517 void save_status(std::vector<long> &s);
02518 void load_status(const std::vector<long> &s);
02519 CLCG4 & CLCG4::operator=(RNG<CLCG4> &other);
02521
02542 CLCG4(CLCG4_param param=CLCG4_param_sets::TRNG, long seed_=0l);
02543 };
02544
02545 inline long CLCG4::rand(void) {
02546 unsigned long t=
02547 static_cast<unsigned long>(R1.rand())+
02548 static_cast<unsigned long>(R2.rand());
02549 if (t>=modulus)
02550 t-=modulus;
02551 t+=static_cast<unsigned long>(R3.rand());
02552 if (t>=modulus)
02553 t-=modulus;
02554 t+=static_cast<unsigned long>(R4.rand());
02555 return (t>=modulus) ? (t-modulus) : t;
02556 }
02557
02558
02559
02561
02569 class EINV_param {
02570 public:
02571 const long a;
02572 const long b;
02573 const long modulus;
02574
02581 EINV_param(long a_, long b_, long modulus_) :
02582 a(a_), b(b_), modulus(modulus_) { };
02583 };
02584
02586 namespace EINV_param_sets {
02588 const EINV_param TRNG=EINV_param(1073741831l, 0l, 1342177283l);
02589 }
02590
02592
02604 class EINV : public RNG<EINV> {
02605 private:
02606 long a, b, i, di, modulus, a_save, b_save, modulus_save;
02607 public:
02608 static const RNG_type type=EINV_t;
02609 const char * name(void);
02610 void reset(void);
02611 void seed(long s=0l);
02612 long rand(void);
02613 void split(long s, long n);
02614 void jump2(long s);
02615 void save_status(std::vector<long> &s);
02616 void load_status(const std::vector<long> &s);
02617 EINV & EINV::operator=(RNG<EINV> &other);
02619
02625 EINV(EINV_param param=EINV_param_sets::TRNG, long seed_=0l);
02626 };
02627
02628 inline long EINV::rand(void) {
02629 i-=modulus;
02630 i+=di;
02631 if (i<0)
02632 i+=modulus;
02633 long x=static_cast<long>((static_cast<long long>(a)*
02634 static_cast<long long>(i))%modulus)-modulus;
02635 x+=b;
02636 if (x<0)
02637 x+=modulus;
02638
02639 long temp, q, flast=0, f=1, m=modulus;
02640 while (x>1) {
02641 temp=m%x;
02642 q=m/x;
02643 m=x;
02644 x=temp;
02645 temp=f;
02646 f=flast-q*f;
02647 flast=temp;
02648 }
02649 return (a==0) ? 0 : ( (f<0) ? (f+modulus) : f );
02650 }
02651
02652
02653
02655
02666 class EINVLCG64_param {
02667 public:
02668 const long a;
02669 const long b;
02670 const long modulus;
02671 const unsigned long long c;
02672 const unsigned long long d;
02673
02685 EINVLCG64_param(long a_, long b_, long modulus_, unsigned long long c_, unsigned long long d_) :
02686 a(a_), b(b_), modulus(modulus_), c(c_), d(d_) { };
02687 };
02688
02690 namespace EINVLCG64_param_sets {
02692 const EINVLCG64_param TRNG=EINVLCG64_param(1073741831l, 0l, 1342177283l, 18145460002477866997ull, 1ull);
02693 }
02694
02696
02707 class EINVLCG64 : public RNG<EINVLCG64> {
02708 private:
02709 LCG64 R1;
02710 EINV R2;
02711 public:
02712 static const RNG_type type=EINVLCG64_t;
02713 const char * name(void);
02714 void reset(void);
02715 void seed(long s=0l);
02716 long rand(void);
02717 void split(long s, long n);
02718 void jump2(long s);
02719 void save_status(std::vector<long> &s);
02720 void load_status(const std::vector<long> &s);
02721 EINVLCG64 & EINVLCG64::operator=(RNG<EINVLCG64> &other);
02723
02736 EINVLCG64(EINVLCG64_param param=EINVLCG64_param_sets::TRNG, long seed_=0l);
02737 };
02738
02739 inline long EINVLCG64::rand(void) {
02740 return (R1.rand()+R2.rand())&0x7fffffffl;
02741 }
02742
02743 }
02744
02745
02746 #endif