gb_rand.hxx
Go to the documentation of this file.00001
00002
00003 #ifndef CH_TOOLS__GB_RAND_HXX
00004 #define CH_TOOLS__GB_RAND_HXX
00005
00006 #include <iostream>
00007
00018 namespace CH_Tools {
00019
00023
00028 class GB_rand
00029 {
00030 private:
00031 long A[56];
00032 int ind;
00033
00035 long mod_diff(long x,long y){return ((x-y)&0x7fffffff);}
00036
00038 long flip_cycle ()
00039 {
00040 register long *ii, *jj;
00041 for (ii = &A[1], jj = &A[32]; jj <= &A[55]; ii++, jj++)
00042 *ii = ((*ii-*jj) & 0x7fffffff);
00043 for (jj = &A[1]; ii <= &A[55]; ii++, jj++)
00044 *ii = ((*ii-*jj) & 0x7fffffff);
00045 ind = 54;
00046 return A[55];
00047 }
00048
00049 public:
00051 void init(long seed=1)
00052 {
00053 register long i;
00054 register long prev = seed, next = 1;
00055 seed = prev = (prev & 0x7fffffff);
00056 A[55] = prev;
00057 for (i = 21; i; i = (i + 21) % 55) {
00058 A[i] = next;
00059
00060 next = ((prev-next) & 0x7fffffff);
00061 if (seed & 1)
00062 seed = 0x40000000 + (seed >> 1);
00063 else
00064 seed >>= 1;
00065 next = ((next- seed) & 0x7fffffff);
00066
00067 prev = A[i];
00068 }
00069
00070 (void) flip_cycle ();
00071 (void) flip_cycle ();
00072 (void) flip_cycle ();
00073 (void) flip_cycle ();
00074 (void) flip_cycle ();
00075
00076 }
00077
00079 GB_rand(long seed=1)
00080 {ind=0;A[0]=-1;init(seed);}
00081
00083 ~GB_rand(){}
00084
00086 long unif_long(long m)
00087 {
00088 const unsigned long two_to_the_31 = (unsigned long)0x80000000;
00089 register unsigned long t = two_to_the_31 - (two_to_the_31 % m);
00090 register long r;
00091 do {
00092 r = (A[ind]>=0?(A[ind--]):flip_cycle());
00093 } while (t <= (unsigned long) r);
00094 return r % m;
00095 }
00096
00098 double next()
00099 {
00100 long r=unif_long(0x40000000);
00101 return (double(r)+.5)/double(0x40000000);
00102 }
00103
00105 std::ostream& save(std::ostream& out) const
00106 {
00107 for(int i=0;i<56;i++) out<<A[i]<<"\n";
00108 out<<ind<<"\n"; return out;
00109 }
00110
00112 std::istream& restore(std::istream& in)
00113 {
00114 for(int i=0;i<56;i++)
00115 in>>A[i];
00116 in>>ind; return in;
00117 }
00118
00119 };
00120
00122
00123 }
00124
00125 #endif
00126