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 "2"
00030 #define TRNG_REVISION "2"
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 YARNLCG64_t,
00054 YARN2_t,
00055 YARN3_t,
00056 YARN4_t,
00057 CLCG2_t,
00058 CLCG3_t,
00059 CLCG4_t,
00060 EINV_t,
00061 EINVLCG64_t,
00062 trng_gsl_t,
00063 user1_t=1001,
00064 user2_t=1002,
00065 user3_t=1003,
00066 user4_t=1004,
00067 user5_t=1005
00068 };
00069
00071 struct vector2d_struct {
00073 double x1;
00075 double x2;
00076 };
00077
00079
00083 typedef struct vector2d_struct vector2d;
00084
00086 struct vector3d_struct {
00088 double x1;
00090 double x2;
00092 double x3;
00093 };
00094
00096
00100 typedef struct vector3d_struct vector3d;
00101
00103 struct vector4d_struct {
00105 double x1;
00107 double x2;
00109 double x3;
00111 double x4;
00112 };
00113
00115
00119 typedef struct vector4d_struct vector4d;
00120
00121
00122
00124
00133 template<class RNG_type> class RNG {
00134 private:
00135 RNG_type & derived(void) {
00136 return static_cast<RNG_type &>(*this);
00137 }
00138
00139 protected:
00141 long max_val;
00143 long max_val2;
00144 public:
00146
00149 static const TRNG::RNG_type type=RNG_t;
00150
00152
00157 const char * name(void) {
00158 return derived().name();
00159 }
00160
00162
00166 void reset(void) {
00167 derived().reset();
00168 }
00169
00171
00179 void seed(long s=0l) {
00180 derived().seed(s);
00181 }
00182
00184
00191 long rand(void) {
00192 return derived().rand();
00193 }
00194
00196
00199 long max(void) {
00200 return max_val;
00201 };
00202
00204
00208 bool boolean(void) {
00209 return (rand()<=max_val2) ? true : false;
00210 }
00211
00213
00217 bool boolean(const double p) {
00218 return (rand()<static_cast<long>(p*max())+1.0) ? true : false;
00219 }
00220
00222
00225 double uniform(void) {
00226 return uniformco();
00227 }
00228
00230
00235 double uniform(const double a, const double b) {
00236 return uniformco(a, b);
00237 }
00238
00240
00243 double uniformco(void) {
00244 return static_cast<double>(rand())/
00245 (static_cast<double>(max())+1.0);
00246 }
00247
00249
00254 double uniformco(const double a, const double b) {
00255 return a+(b-a)*static_cast<double>(rand())/
00256 (static_cast<double>(max())+1.0);
00257 }
00258
00260
00263 double uniformcc(void) {
00264 return static_cast<double>(rand())/
00265 static_cast<double>(max());
00266 }
00267
00269
00274 double uniformcc(const double a, const double b) {
00275 return a+(b-a)*static_cast<double>(rand())/
00276 static_cast<double>(max());
00277 }
00278
00280
00283 double uniformoc(void) {
00284 return (static_cast<double>(rand())+1.0)/
00285 (static_cast<double>(max())+1.0);
00286 }
00287
00289
00294 double uniformoc(const double a, const double b) {
00295 return a+(b-a)*(static_cast<double>(rand())+1.0)/
00296 (static_cast<double>(max())+1.0);
00297 }
00298
00300
00303 double uniformoo(void) {
00304 return (static_cast<double>(rand())+1.0)/
00305 (static_cast<double>(max())+2.0);
00306 }
00307
00309
00314 double uniformoo(const double a, const double b) {
00315 return a+(b-a)*(static_cast<double>(rand())+1.0)/
00316 (static_cast<double>(max())+2.0);
00317 }
00318
00320
00324 long uniforml(const long b) {
00325 return static_cast<long>(uniform(0.0, static_cast<double>(b)));
00326 }
00327
00329
00334 long uniforml(const long a, const long b) {
00335 return static_cast<long>(uniform(static_cast<double>(a),
00336 static_cast<double>(b)));
00337 }
00338
00340
00354 double normal_dist(const double sigma=1.0, const double mu=0.0) {
00355
00356 double s, t1, t2;
00357
00358 if (sigma<=0.0)
00359 throw error("negative or zero standard deviation in TRNG::RNG::normal_dist");
00360
00361
00362 do {
00363 t1=uniformoo(-1.0, 1.0);
00364 t2=uniformoo(-1.0, 1.0);
00365 s=t1*t1+t2*t2;
00366 } while (s>=1.0);
00367 s=std::sqrt(-2.0*std::log(s)/s);
00368 return t1*s*sigma+mu;
00369
00370
00371
00372
00373 }
00374
00376
00395 double exp_dist(const double mu=1.0) {
00396 if (mu<=0.0)
00397 throw error("negative or zero parameter in TRNG::RNG::exp_dist");
00398 double t=uniformoc();
00399 return -mu*std::log(t);
00400 }
00401
00403
00417 double laplace_dist(const double a=1.0) {
00418 if (a<=0.0)
00419 throw error("parameter less or equal zero in TRNG::RNG::laplace_dist");
00420 double u;
00421 do {
00422 u=uniformoo(-1.0, 1.0);
00423 } while (u==0.0);
00424 return u<0.0 ? a*std::log(-u) : -a*std::log(u);
00425 }
00426
00428
00448 double tent_dist(const double a=1.0) {
00449 if (a<=0.0)
00450 throw error("parameter less or equal zero in TRNG::RNG::tent_dist");
00451 double y=uniformoo();
00452 if (y<0.5)
00453 return (-1.0+std::sqrt(2*y))*a;
00454 else
00455 return (1.0-std::sqrt(2.0-2.0*y))*a;
00456 }
00457
00459
00478 double Gamma_dist(const double a, const double b) {
00479 if (a<=0.0 || b<=0.0)
00480 throw error("parameter less or equal zero in TRNG::RNG::Gamma_dist");
00481 double a_int=std::floor(a);
00482 if (a_int==a) {
00483
00484 if (a<12) {
00485 double prod=1.0;
00486 for (int i=0; i<a; ++i)
00487 prod*=uniformoo();
00488
00489
00490
00491
00492 return -b*std::log(prod);
00493 } else {
00494
00495
00496
00497
00498 double sqa, x, y, v;
00499 sqa=std::sqrt(2.0*a-1.0);
00500 do {
00501 do {
00502 const double pi=3.14159265358979324;
00503 y=std::tan(pi*uniformco());
00504 x=sqa*y+a-1.0;
00505 }
00506 while (x<=0.0);
00507 v=uniformco();
00508 }
00509 while (v>(1.0+y*y)*std::exp((a-1.0)*log(x/(a-1))-sqa*y));
00510 return b*x;
00511 }
00512 }
00513 if (a_int==0.0) {
00514
00515
00516
00517 const double e=2.71828182844;
00518 double p, q, x, u, v;
00519 p=e/(a+e);
00520 do {
00521 u=uniformco();
00522 v=uniformoo();
00523 if (u<p) {
00524 x=std::exp((1.0/a)*std::log(v));
00525 q=std::exp(-x);
00526 } else {
00527 x=1.0-std::log(v);
00528 q=std::exp((a-1.0)*std::log(x));
00529 }
00530 } while (uniformco()>=q);
00531 return b*x;
00532 }
00533 return Gamma_dist(a_int, b)+Gamma_dist(a-a_int, b);
00534 }
00535
00537
00556 double Beta_dist(const double a, const double b) {
00557 if (a<=0.0 || b<=0.0)
00558 throw error("negative or zero parameter in TRNG::RNG::Beta_dist");
00559 double t1=Gamma_dist(a, 1.0);
00560 double t2=Gamma_dist(b, 1.0);
00561 return t1/(t1+t2);
00562 }
00563
00565
00581 double chi_square_dist(const double nu) {
00582 if (nu<1.0)
00583 throw error("parameter less than one in TRNG::RNG::chi_square_dist");
00584 return 2.0*Gamma_dist(0.5*nu, 1.0);
00585 }
00586
00588
00603 long binomial_dist(long n, double p=0.5) {
00604 if (p<=0.0 || p>1.0)
00605 throw error("probability <=0.0 or >1.0 in TRNG::RNG::binomial_dist");
00606 if (n<1l)
00607 throw error("less than one trail TRNG::RNG::binomial_dist");
00608 long i, a, b, k=0;
00609 while (n>12l) {
00610 double X;
00611 a=1l+(n/2l);
00612 b=1l+n-a;
00613 X=Beta_dist(static_cast<double>(a), static_cast<double>(b));
00614 if (X>=p) {
00615 n=a-1l;
00616 p/=X;
00617 } else {
00618 k+=a;
00619 n=b-1l;
00620 p=(p-X)/(1l-X);
00621 }
00622 }
00623 for (i=0l; i<n; i++)
00624 if (uniformco()<p)
00625 k++;
00626 return k;
00627 }
00628
00630
00643 long binomial_dist_tab(long n, double p=0.5) {
00644 if (p<=0.0 || p>1.0)
00645 throw error("probability <=0.0 or >1.0 in TRNG::RNG::binomial_dist_tab");
00646 if (n<1l)
00647 throw error("less than one trail TRNG::RNG::binomial_dist_tab");
00648 static long n_=0l;
00649 static double p_=0.0;
00650 static std::vector<double> prob;
00651 if (n!=n_ || p!=p_) {
00652 n_=n;
00653 p_=p;
00654 prob.resize(n_);
00655
00656
00657
00658
00659 double b=1.0;
00660 for (int k=0l; k<n_; ++k) {
00661 prob[k]=b*std::pow(p_, static_cast<double>(k))*
00662 std::pow(1.0-p_, static_cast<double>(n_-k));
00663 if (k>0l)
00664 prob[k]+=prob[k-1l];
00665 b=std::floor(b*static_cast<double>(n_-k)/
00666 static_cast<double>(k+1l)+0.5);
00667 }
00668 }
00669 return find_interval(prob, uniformco());
00670 }
00671
00673
00689 double Student_t_dist(const double nu) {
00690 if (nu<=0.0)
00691 throw error("parameter less than or equal zero in TRNG::RNG::Student_t_dist");
00692 if (nu<=2.0)
00693 return normal_dist()/std::sqrt(chi_square_dist(nu)/nu);
00694 else {
00695 double y1, y2, z;
00696 do {
00697 y1=normal_dist();
00698 y2=exp_dist(1.0/(0.5*nu-1.0));
00699 z=y1*y1/(nu-2.0);
00700 } while (1.0-z<0.0 || std::exp(-y2-z)>(1.0-z));
00701
00702
00703
00704 return y1/std::sqrt((1.0-2.0/nu)*(1.0-z));
00705 }
00706 }
00707
00709
00721 long poisson_dist(double mu=1.0) {
00722 if (mu<=0)
00723 throw error("parameter less than 0 in TRNG::RNG::poisson_dist");
00724 double emu;
00725 double prod=1.0;
00726 long k=0;
00727 while (mu>10.0) {
00728 long m=static_cast<long>(mu*(7.0/8.0));
00729 double X=Gamma_dist(static_cast<long>(m), 1.0);
00730 if (X>=mu) {
00731 return k+binomial_dist(m-1l, mu/X);
00732 } else {
00733 k+=m;
00734 mu-=X;
00735 }
00736 }
00737
00738 emu=std::exp(-mu);
00739 do {
00740 prod*=uniformco();
00741 k++;
00742 } while (prod>emu);
00743 return k-1l;
00744 }
00745
00747
00759 long geometric_dist(double q) {
00760 if (q<=0.0 ||q>1.0)
00761 throw error("parameter out of range in TRNG::RNG::geometric_dist");
00762 if (q==1.0)
00763 return 1l;
00764 return static_cast<long>
00765 (std::log(uniformoo())/std::log(1.0-p))+1l;
00766 }
00767
00769
00795 template<class t_function>
00796 double rejection(t_function p, double a1, double a2, double p_max) {
00797 double t1, t2;
00798 do {
00799 t1=uniformco(a1, a2);
00800 t2=uniformco(0.0, p_max);
00801 } while (p(t1)<t2);
00802 return t1;
00803 }
00804
00806
00818 long discrete_dist(const std::vector<double> p) {
00819 if (p.empty())
00820 throw error("empty vector in TRNG::discrete_dist");
00821 double x=uniformco();
00822 if (x<p[0])
00823 return 0l;
00824 long i1=0l;
00825 long i2=p.size()-1l;
00826 while (i2-i1>1l) {
00827 long i3=(i2+i1)/2;
00828 if (x<=p[i3])
00829 i2=i3;
00830 else
00831 i1=i3;
00832 }
00833 return i2;
00834 }
00835
00837
00845 vector2d spherical2d(void) {
00846 double r2, t1, t2, t12, t22;
00847 vector2d vec;
00848 do {
00849 t1=2.0*uniformco()-1.0;
00850 t2=uniformco();
00851 t12=t1*t1;
00852 t22=t2*t2;
00853 r2=t12+t22;
00854 } while (r2>1.0);
00855 vec.x1=2.0*t1*t2/r2;
00856 vec.x2=(t12-t22)/r2;
00857 return vec;
00858 }
00859
00861
00869 vector3d spherical3d(void) {
00870 double q, r2, t1, t2;
00871 vector3d vec;
00872 do {
00873 t1=2.0*uniformco()-1.0;
00874 t2=2.0*uniformco()-1.0;
00875 r2=t1*t1+t2*t2;
00876 } while (r2>1.0);
00877 q=2.0*sqrt(1.0-r2);
00878 vec.x1=t1*q;
00879 vec.x2=t2*q;
00880 vec.x3=1-2*r2;
00881 return vec;
00882 }
00883
00885
00893 vector4d spherical4d(void) {
00894 double q, r21, r22, t1, t2, t3, t4;
00895 vector4d vec;
00896 do {
00897 t1=2.0*uniformco()-1.0;
00898 t2=2.0*uniformco()-1.0;
00899 r21=t1*t1+t2*t2;
00900 } while (r21>1.0);
00901 do {
00902 t3=2.0*uniformco()-1.0;
00903 t4=2.0*uniformco()-1.0;
00904 r22=t3*t3+t4*t4;
00905 } while (r22>1.0);
00906 q=sqrt((1.0-r21)/r22);
00907 vec.x1=t1;
00908 vec.x2=t2;
00909 vec.x3=t3*q;
00910 vec.x4=t4*q;
00911 return(vec);
00912 }
00913
00915
00924 void split(long s, long n) {
00925 derived().split(s, n);
00926 }
00927
00929
00935 void jump(long long s) {
00936 if (s<0ll)
00937 throw error("invalid argument for TRNG::RNG::jump");
00938 long i=0l;
00939 while (s>0ll) {
00940 if (s%2==1)
00941 jump2(i);
00942 ++i;
00943 s>>=1;
00944 }
00945 }
00946
00948
00956 void jump(long long s, long n) {
00957 if (s<0ll || n<0l)
00958 throw error("invalid argument for TRNG::RNG::jump");
00959 while (n>0l) {
00960 jump(s);
00961 --n;
00962 }
00963 }
00964
00966
00972 void jump2(long s) {
00973 derived().jump2(s);
00974 }
00975
00977
00984 void jump2(long s, long n) {
00985 if (s<0l || n<0l)
00986 throw error("invalid argument for TRNG::RNG::jump2");
00987 while (n>0l) {
00988 if (n%2l==1l)
00989 jump2(s);
00990 s+=1l;
00991 n>>=1;
00992 }
00993 }
00994
00996
01001 void save_status(std::vector<long> &s) {
01002 derived().save_status(s);
01003 }
01004
01006
01011 void load_status(const std::vector<long> &s) {
01012 derived().load_status(s);
01013 }
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029 };
01030
01031
01032
01034
01050 class generic_MLCG : public RNG<generic_MLCG> {
01051
01052
01053 private:
01054 long a, a_save;
01055 long modulus, modulus_save;
01056 long r;
01057 void backward(void);
01058 public:
01059 static const RNG_type type=generic_MLCG_t;
01060 const char * name(void);
01061 void reset(void);
01062 void seed(long s=0l);
01063 long rand(void);
01064 void split(long s, long n);
01065 void jump2(long s);
01066 void save_status(std::vector<long> &s);
01067 void load_status(const std::vector<long> &s);
01068 generic_MLCG & generic_MLCG::operator=(RNG<generic_MLCG> &other);
01069 generic_MLCG(long a_=16807l, long modulus_=2147483647l, long seed_=0l);
01070 };
01071
01072 inline long generic_MLCG::rand(void) {
01073 r=static_cast<long>
01074 ((static_cast<long long>(a)*static_cast<long long>(r))%modulus);
01075 return r;
01076 }
01077
01078
01079
01081
01096 class ParkMiller : public RNG<ParkMiller> {
01097 private:
01098 generic_MLCG R;
01099 public:
01100 static const RNG_type type=ParkMiller_t;
01101 const char * name(void);
01102 void reset(void);
01103 void seed(long s=0l);
01104 long rand(void);
01105 void split(long s, long n);
01106 void jump2(long s);
01107 void save_status(std::vector<long> &s);
01108 void load_status(const std::vector<long> &s);
01109 ParkMiller & ParkMiller::operator=(RNG<ParkMiller> &other);
01111
01120 ParkMiller(long a_=16807l, long modulus_=2147483647l, long seed_=0l);
01121 };
01122
01123 inline long ParkMiller::rand(void) {
01124 return R.rand()-1l;
01125 }
01126
01127
01128
01129
01131
01145 class LCG32 : public RNG<LCG32> {
01146 private:
01147 unsigned long a, a_save;
01148 unsigned long b, b_save;
01149 unsigned long r;
01150 void backward(void);
01151 public:
01152 static const RNG_type type=LCG32_t;
01153 const char * name(void);
01154 void reset(void);
01155 void seed(long s=0l);
01156 long rand(void);
01157 void split(long s, long n);
01158 void jump2(long s);
01159 void save_status(std::vector<long> &s);
01160 void load_status(const std::vector<long> &s);
01161 LCG32 & LCG32::operator=(RNG<LCG32> &other);
01163
01172 LCG32(unsigned long a_=69069ul, unsigned long b_=1ul, long seed_=0l);
01173 };
01174
01175 inline long LCG32::rand(void) {
01176 r=a*r+b;
01177 #if ULONG_MAX == 0xfffffffful
01178 #else
01179 r&=0xfffffffful;
01180 #endif
01181 return static_cast<long>(r>>1);
01182 }
01183
01184
01185
01187
01201 class LCG64 : public RNG<LCG64> {
01202 private:
01203 unsigned long long a, a_save;
01204 unsigned long long b, b_save;
01205 unsigned long long r;
01206 void backward(void);
01207 public:
01208 static const RNG_type type=LCG64_t;
01209 const char * name(void);
01210 void reset(void);
01211 void seed(long s=0l);
01212 long rand(void);
01213 void split(long s, long n);
01214 void jump2(long s);
01215 void save_status(std::vector<long> &s);
01216 void load_status(const std::vector<long> &s);
01217 LCG64 & LCG64::operator=(RNG<LCG64> &other);
01219
01228 LCG64(unsigned long long a_=18145460002477866997ull,
01229 unsigned long long b_=1ul,
01230 long seed_=0ul);
01231 };
01232
01233 inline long LCG64::rand(void) {
01234 r=a*r+b;
01235 return static_cast<long>(r>>33);
01236 }
01237
01238
01239
01241
01249 class MRG2 : public RNG<MRG2> {
01250 private:
01251 long a0, a1, a0_save, a1_save;
01252 long r0, r1;
01253 long modulus, modulus_save;
01254 void backward(void);
01255 public:
01256 static const RNG_type type=MRG2_t;
01257 const char * name(void);
01258 void reset(void);
01259 void seed(long s=0l);
01260 long rand(void);
01261 void split(long s, long n);
01262 void jump2(long s);
01263 void save_status(std::vector<long> &s);
01264 void load_status(const std::vector<long> &s);
01265 MRG2 & MRG2::operator=(RNG<MRG2> &other);
01267
01279 MRG2(long a0_=1498809829l, long a1_=1160990996l,
01280 long modulus_=2147483647l, long seed_=0l);
01281 };
01282
01283 inline long MRG2::rand(void) {
01284 long t=static_cast<long>((static_cast<long long>(a0)*
01285 static_cast<long long>(r0)+
01286 static_cast<long long>(a1)*
01287 static_cast<long long>(r1))%modulus);
01288 r1=r0; r0=t;
01289 return r0;
01290 }
01291
01292
01293
01295
01303 class MRG3 : public RNG<MRG3> {
01304 private:
01305 long a0, a1, a2, a0_save, a1_save, a2_save;
01306 long r0, r1, r2;
01307 long modulus, modulus_save;
01308 void backward(void);
01309 public:
01310 static const RNG_type type=MRG3_t;
01311 const char * name(void);
01312 void reset(void);
01313 void seed(long s=0l);
01314 long rand(void);
01315 void split(long s, long n);
01316 void jump2(long s);
01317 void save_status(std::vector<long> &s);
01318 void load_status(const std::vector<long> &s);
01319 MRG3 & MRG3::operator=(RNG<MRG3> &other);
01321
01334 MRG3(long a0_=2021422057l, long a1_=1826992351l,
01335 long a2_=1977753457l, long modulus_=2147483647l,
01336 long seed_=0l);
01337 };
01338
01339 inline long MRG3::rand(void) {
01340 long t=static_cast<long>((static_cast<unsigned long long>(a0)*
01341 static_cast<unsigned long long>(r0)+
01342 static_cast<unsigned long long>(a1)*
01343 static_cast<unsigned long long>(r1)+
01344 static_cast<unsigned long long>(a2)*
01345 static_cast<unsigned long long>(r2))%modulus);
01346 r2=r1; r1=r0; r0=t;
01347 return r0;
01348 }
01349
01350
01351
01353
01362 class MRG4 : public RNG<MRG4> {
01363 private:
01364 long a0, a1, a2, a3, a0_save, a1_save, a2_save, a3_save;
01365 long r0, r1, r2, r3;
01366 long modulus, modulus_save;
01367 void backward(void);
01368 public:
01369 static const RNG_type type=MRG4_t;
01370 const char * name(void);
01371 void reset(void);
01372 void seed(long s=0l);
01373 long rand(void);
01374 void split(long s, long n);
01375 void jump2(long s);
01376 void save_status(std::vector<long> &s);
01377 void load_status(const std::vector<long> &s);
01378 MRG4 & MRG4::operator=(RNG<MRG4> &other);
01380
01395 MRG4(long a0_=2001982722l, long a1_=1412284257l,
01396 long a2_=1155380217l, long a3_=1668339922l,
01397 long modulus_=2147483647l, long seed_=0l);
01398 };
01399
01400 inline long MRG4::rand(void) {
01401 long t=static_cast<long>((static_cast<unsigned long long>(a0)*
01402 static_cast<unsigned long long>(r0)+
01403 static_cast<unsigned long long>(a1)*
01404 static_cast<unsigned long long>(r1)+
01405 static_cast<unsigned long long>(a2)*
01406 static_cast<unsigned long long>(r2)+
01407 static_cast<unsigned long long>(a3)*
01408 static_cast<unsigned long long>(r3))%modulus);
01409 r3=r2; r2=r1; r1=r0; r0=t;
01410 return r0;
01411 }
01412
01413
01414
01416
01439 class YARNLCG64 : public RNG<YARNLCG64> {
01440 private:
01441 LCG64 R;
01442 power b;
01443 long b_save;
01444 public:
01445 static const RNG_type type=YARNLCG64_t;
01446 const char * name(void);
01447 void reset(void);
01448 void seed(long s=0l);
01449 long rand(void);
01450 void split(long s, long n);
01451 void jump2(long s);
01452 void save_status(std::vector<long> &s);
01453 void load_status(const std::vector<long> &s);
01454 YARNLCG64 & YARNLCG64::operator=(RNG<YARNLCG64> &other);
01456
01465 YARNLCG64(unsigned long long a_=18145460002477866997ull,
01466 unsigned long long b_=1ul,
01467 long seed_=0ul, long c_=123567893l);
01468 };
01469
01470 inline long YARNLCG64::rand(void) {
01471 long t=R.rand();
01472 return (t==0 || t==2147483647l) ? t : b(t);
01473 }
01474
01475
01476
01478
01495 class YARN2 : public RNG<YARN2> {
01496 private:
01497 MRG2 R;
01498 power b;
01499 long b_save;
01500 public:
01501 static const RNG_type type=YARN2_t;
01502 const char * name(void);
01503 void reset(void);
01504 void seed(long s=0l);
01505 long rand(void);
01506 void split(long s, long n);
01507 void jump2(long s);
01508 void save_status(std::vector<long> &s);
01509 void load_status(const std::vector<long> &s);
01510 YARN2 & YARN2::operator=(RNG<YARN2> &other);
01512
01526 YARN2(long a0_=1498809829l, long a1_=1160990996l,
01527 long modulus_=2147483647l,
01528 long seed_=0l, long b_=123567893l);
01529 };
01530
01531 inline long YARN2::rand(void) {
01532 long t=R.rand();
01533 return (t==0) ? 0 : b(t);
01534 }
01535
01536
01537
01539
01556 class YARN3 : public RNG<YARN3> {
01557 private:
01558 MRG3 R;
01559 power b;
01560 long b_save;
01561 public:
01562 static const RNG_type type=YARN3_t;
01563 const char * name(void);
01564 void reset(void);
01565 void seed(long s=0l);
01566 long rand(void);
01567 void split(long s, long n);
01568 void jump2(long s);
01569 void save_status(std::vector<long> &s);
01570 void load_status(const std::vector<long> &s);
01571 YARN3 & YARN3::operator=(RNG<YARN3> &other);
01573
01588 YARN3(long a0_=2021422057l, long a1_=1826992351l,
01589 long a2_=1977753457l, long modulus_=2147483647l,
01590 long seed_=0l, long b_=123567893l);
01591 };
01592
01593 inline long YARN3::rand(void) {
01594 long t=R.rand();
01595 return (t==0) ? 0 : b(t);
01596 }
01597
01598
01599
01601
01619 class YARN4 : public RNG<YARN4> {
01620 private:
01621 MRG4 R;
01622 power b;
01623 long b_save;
01624 public:
01625 static const RNG_type type=YARN4_t;
01626 const char * name(void);
01627 void reset(void);
01628 void seed(long s=0l);
01629 long rand(void);
01630 void split(long s, long n);
01631 void jump2(long s);
01632 void save_status(std::vector<long> &s);
01633 void load_status(const std::vector<long> &s);
01634 YARN4 & YARN4::operator=(RNG<YARN4> &other);
01636
01653 YARN4(long a0_=2001982722l, long a1_=1412284257l,
01654 long a2_=1155380217l, long a3_=1668339922l,
01655 long modulus_=2147483647l, long seed_=0l, long b_=123567893l);
01656 };
01657
01658 inline long YARN4::rand(void) {
01659 long t=R.rand();
01660 return (t==0) ? 0 : b(t);
01661 }
01662
01663
01664
01666
01679 class CLCG2 : public RNG<CLCG2> {
01680 private:
01681 generic_MLCG R1;
01682 generic_MLCG R2;
01683 long modulus;
01684 public:
01685 static const RNG_type type=CLCG2_t;
01686 const char * name(void);
01687 void reset(void);
01688 void seed(long s=0l);
01689 long rand(void);
01690 void split(long s, long n);
01691 void jump2(long s);
01692 void save_status(std::vector<long> &s);
01693 void load_status(const std::vector<long> &s);
01694 CLCG2 & CLCG2::operator=(RNG<CLCG2> &other);
01696
01716 CLCG2(long a1= 376555083l, long m1=2147482951l,
01717 long a2=1028879659l, long m2=2147482949l,
01718 long seed_=0l);
01719 };
01720
01721 inline long CLCG2::rand(void) {
01722 return static_cast<long>((static_cast<long long>(R1.rand())+
01723 static_cast<long long>(R2.rand()))%
01724 modulus);
01725 }
01726
01727
01728
01730
01744 class CLCG3 : public RNG<CLCG3> {
01745 private:
01746 generic_MLCG R1;
01747 generic_MLCG R2;
01748 generic_MLCG R3;
01749 long modulus;
01750 public:
01751 static const RNG_type type=CLCG3_t;
01752 const char * name(void);
01753 void reset(void);
01754 void seed(long s=0l);
01755 long rand(void);
01756 void split(long s, long n);
01757 void jump2(long s);
01758 void save_status(std::vector<long> &s);
01759 void load_status(const std::vector<long> &s);
01760 CLCG3 & CLCG3::operator=(RNG<CLCG3> &other);
01762
01786 CLCG3(long a1= 376555083l, long m1=2147482951l,
01787 long a2=1028879659l, long m2=2147482949l,
01788 long a3= 225802979l, long m3=2147482943l,
01789 long seed_=0l);
01790 };
01791
01792 inline long CLCG3::rand(void) {
01793 return static_cast<long>((static_cast<long long>(R1.rand())+
01794 static_cast<long long>(R2.rand())+
01795 static_cast<long long>(R3.rand()))%
01796 modulus);
01797 }
01798
01799
01800
01802
01817 class CLCG4 : public RNG<CLCG4> {
01818 private:
01819 generic_MLCG R1;
01820 generic_MLCG R2;
01821 generic_MLCG R3;
01822 generic_MLCG R4;
01823 long modulus;
01824 public:
01825 static const RNG_type type=CLCG4_t;
01826 const char * name(void);
01827 void reset(void);
01828 void seed(long s=0l);
01829 long rand(void);
01830 void split(long s, long n);
01831 void jump2(long s);
01832 void save_status(std::vector<long> &s);
01833 void load_status(const std::vector<long> &s);
01834 CLCG4 & CLCG4::operator=(RNG<CLCG4> &other);
01836
01864 CLCG4(long a1= 376555083l, long m1=2147482951l,
01865 long a2=1028879659l, long m2=2147482949l,
01866 long a3= 225802979l, long m3=2147482943l,
01867 long a4=2028073966l, long m4=2147482859l,
01868 long seed_=0l);
01869 };
01870
01871 inline long CLCG4::rand(void) {
01872 return static_cast<long>((static_cast<long long>(R1.rand())+
01873 static_cast<long long>(R2.rand())+
01874 static_cast<long long>(R3.rand())+
01875 static_cast<long long>(R4.rand()))%
01876 modulus);
01877 }
01878
01879
01880
01882
01895 class EINV : public RNG<EINV> {
01896 private:
01897 long a, i, di, modulus, a_save;
01898 long modulo_invers(const long a);
01899 public:
01900 static const RNG_type type=EINV_t;
01901 const char * name(void);
01902 void reset(void);
01903 void seed(long s=0l);
01904 long rand(void);
01905 void split(long s, long n);
01906 void jump2(long s);
01907 void save_status(std::vector<long> &s);
01908 void load_status(const std::vector<long> &s);
01909 EINV & EINV::operator=(RNG<EINV> &other);
01911
01916 EINV(long a_=1073741831l, long seed_=0l);
01917 };
01918
01919 inline long EINV::rand(void) {
01920 i=static_cast<long>
01921 ((static_cast<long long>(i)+
01922 static_cast<long long>(di))%modulus);
01923 long x=static_cast<long>((static_cast<long long>(a)*
01924 static_cast<long long>(i))%modulus);
01925
01926 long temp, q, flast=0, f=1, m=modulus;
01927 while (x>1) {
01928 temp=m%x;
01929 q=m/x;
01930 m=x;
01931 x=temp;
01932 temp=f;
01933 f=flast-q*f;
01934 flast=temp;
01935 }
01936 return a==0 ? 0 : f>=0 ? f : f+modulus;
01937 }
01938
01939
01940
01942
01954 class EINVLCG64 : public RNG<EINVLCG64> {
01955 private:
01956 LCG64 R1;
01957 EINV R2;
01958 public:
01959 static const RNG_type type=EINVLCG64_t;
01960 const char * name(void);
01961 void reset(void);
01962 void seed(long s=0l);
01963 long rand(void);
01964 void split(long s, long n);
01965 void jump2(long s);
01966 void save_status(std::vector<long> &s);
01967 void load_status(const std::vector<long> &s);
01968 EINVLCG64 & EINVLCG64::operator=(RNG<EINVLCG64> &other);
01970
01973 EINVLCG64(long seed_=0l);
01974 };
01975
01976 inline long EINVLCG64::rand(void) {
01977 return (R1.rand()+R2.rand())&0x7fffffffl;
01978 }
01979
01980 }
01981
01982
01983 #endif