Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members  

trng_gsl.h

00001 // ---------------------------------------------------------------------
00002 // Time-stamp: <Tuesday, 10.12.2002, 13:29:33; edited by bauke>
00003 // 
00004 // Tina's random number generators TRNG
00005 //
00006 // Copyright (C) 2001, 2002 Heiko Bauke
00007 //
00008 // heiko.bauke@physik.uni-magdeburg.de
00009 //
00010 // TRNG is free software; you can redistribute it and/or
00011 // modify it under the terms of the GNU General Public License
00012 // as published by the Free Software Foundation. This program
00013 // is distributed WITHOUT ANY WARRANTY; without even the implied
00014 // warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00015 // See the GNU General Public License for more details.
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     // TRNG::user1_t for a user implemeneted rng
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

Generated on Wed Feb 19 02:00:03 2003 for Tina's Random Number Generators by doxygen1.2.15