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 

Generated on Tue May 3 16:52:53 2011 for ConicBundle by  doxygen 1.5.6