00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef TRNG_GSL_H
00020 #define TRNG_GSL_H
00021
00022 #include <vector>
00023 #include <trng.h>
00024 #include <gsl/gsl_rng.h>
00025
00026
00027 namespace TRNG {
00028
00030
00038 class trng_gsl : public TRNG::RNG<trng_gsl> {
00039 gsl_rng *r;
00040 unsigned long Min_val, Max_val;
00041 long steps;
00042 const gsl_rng_type* T;
00043
00044 long hash_func(const char *key) {
00045 const long prime=1021;
00046 long hash=0l;
00047 long i=0;
00048 while (key[i]!=0) {
00049 hash+=key[i];
00050 ++i;
00051 }
00052 return hash%prime;
00053 }
00054
00055 public:
00056
00057 static const TRNG::RNG_type type=TRNG::trng_gsl_t;
00058
00059 const char * name(void) {
00060 return gsl_rng_name(r);
00061 }
00062
00063 void reset(void) {
00064 steps=1l;
00065 Max_val=gsl_rng_max(r);
00066 Min_val=gsl_rng_min(r);
00067 if (Max_val>=0x80000000)
00068 max_val=Max_val/2;
00069 else
00070 max_val=Max_val;
00071 max_val2=max_val/2l;
00072 }
00073
00074 void seed(long s=0) {
00075 gsl_rng_set(r, s);
00076 }
00077
00078 long rand(void) {
00079 unsigned long t;
00080 t=gsl_rng_get(r);
00081 for (long i=1l; i<steps; ++i)
00082 gsl_rng_get(r);
00083 if (Max_val>=0x80000000)
00084 return (t-Min_val)/2;
00085 else
00086 return t-Min_val;
00087 }
00088
00089 void split(long s, long n) {
00090 if (s<1l || n>s || n<0l)
00091 throw TRNG::error("invalid arguments for trng_gsl::split");
00092 if (s>1l) {
00093 for (long i=0l; i<n; ++i)
00094 rand();
00095 steps*=s;
00096 }
00097 }
00098
00099 void jump2(long s) {
00100 if (s<0l || s>63l)
00101 throw TRNG::error("invalid argument for trng_gsl::split");
00102 unsigned long long to=1ull<<s;
00103 for (unsigned long long i=0ull; i<to; ++i)
00104 rand();
00105 }
00106
00107 void save_status(std::vector<long> &s) {
00108 void *state=gsl_rng_state(r);
00109 size_t n=gsl_rng_size(r);
00110 s.resize(n+6);
00111 s[0]=type;
00112 s[1]=hash_func(gsl_rng_name(r));
00113 s[2]=steps;
00114 s[3]=Max_val;
00115 s[4]=Min_val;
00116 s[5]=max_val;
00117 for (size_t i=0; i<n; ++i)
00118 s[i+6]=*(static_cast<unsigned char *>(state)+i);
00119 }
00120
00121 void load_status(const std::vector<long> &s) {
00122 if (s[0]!=type)
00123 throw TRNG::error("trng_gsl::load_status wrong parameter");
00124 gsl_rng_free(r);
00125 const gsl_rng_type **t0=gsl_rng_types_setup ();
00126 for (const gsl_rng_type **t=t0; *t!=0; t++)
00127 if (hash_func((*t)->name)==s[1]) {
00128 steps=s[2];
00129 Max_val=s[3];
00130 Min_val=s[4];
00131 max_val=s[5];
00132 r=gsl_rng_alloc(*t);
00133 if (r==NULL)
00134 throw TRNG::error("trng_gsl::load_status not enough memory");
00135 void *state=gsl_rng_state(r);
00136 size_t n=gsl_rng_size(r);
00137 for (size_t i=0; i<n; ++i)
00138 *(static_cast<unsigned char *>(state)+i)=
00139 static_cast<unsigned char>(s[i+6]);
00140 break;
00141 }
00142 }
00143
00144 trng_gsl & trng_gsl::operator=(TRNG::RNG<trng_gsl> &other) {
00145 if (this!=&other) {
00146 std::vector<long> s;
00147 other.save_status(s);
00148 load_status(s);
00149 }
00150 return *this;
00151 }
00152
00154
00161 trng_gsl(const gsl_rng_type * T_=gsl_rng_mt19937, long seed_=0l) : T(T_) {
00162 r=gsl_rng_alloc(T);
00163 if (r==NULL)
00164 throw TRNG::error("trng_gsl::trng_gsl not enough memory");
00165 reset();
00166 seed(seed_);
00167 }
00168
00169 trng_gsl(trng_gsl &other) {
00170 r=gsl_rng_alloc(gsl_rng_mt19937);
00171 if (r==NULL)
00172 throw TRNG::error("trng_gsl::trng_gsl not enough memory");
00173 std::vector<long> s;
00174 other.save_status(s);
00175 load_status(s);
00176 }
00177
00178 virtual ~trng_gsl() {
00179 gsl_rng_free(r);
00180 }
00181
00182 };
00183
00184 }
00185
00186 #endif