00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef RANDOM_H
00021 #define RANDOM_H
00022
00023 #include "common.h"
00024 #include "Vector.h"
00025
00026 #ifdef _MSC_VER
00027 #define INT64_LITERAL(X) X ## i64
00028 #else
00029 #define INT64_LITERAL(X) X ## LL
00030 #endif
00031
00032 #define RAND48_SEED INT64_LITERAL(0x00001234abcd330e)
00033 #define RAND48_MULT INT64_LITERAL(0x00000005deece66d)
00034 #define RAND48_ADD INT64_LITERAL(0x000000000000000b)
00035 #define RAND48_MASK INT64_LITERAL(0x0000ffffffffffff)
00036
00037 class Random {
00038
00039 private:
00040
00041 double second_gaussian;
00042 int64 second_gaussian_waiting;
00043 int64 rand48_seed;
00044 int64 rand48_mult;
00045 int64 rand48_add;
00046
00047 public:
00048
00049
00050 Random(void) {
00051 init(0);
00052 rand48_seed = RAND48_SEED;
00053 }
00054
00055
00056 Random(unsigned long seed) {
00057 init(seed);
00058 }
00059
00060
00061 void init(unsigned long seed) {
00062 second_gaussian = 0;
00063 second_gaussian_waiting = 0;
00064 rand48_seed = seed & INT64_LITERAL(0x00000000ffffffff);
00065 rand48_seed = rand48_seed << 16;
00066 rand48_seed |= RAND48_SEED & INT64_LITERAL(0x0000ffff);
00067 rand48_mult = RAND48_MULT;
00068 rand48_add = RAND48_ADD;
00069 }
00070
00071
00072 void skip(void) {
00073 rand48_seed = ( rand48_seed * rand48_mult + rand48_add ) & RAND48_MASK;
00074 }
00075
00076
00077 void split(int iStream, int numStreams) {
00078
00079 int i;
00080
00081
00082 numStreams |= 1;
00083
00084
00085 for ( i = 0; i < iStream; ++i ) skip();
00086
00087
00088 int64 save_seed = rand48_seed;
00089
00090
00091 rand48_seed = rand48_add;
00092 for ( i = 1; i < numStreams; ++i ) skip();
00093 int64 new_add = rand48_seed;
00094
00095
00096 rand48_seed = rand48_mult;
00097 rand48_add = 0;
00098 for ( i = 1; i < numStreams; ++i ) skip();
00099 rand48_mult = rand48_seed;
00100
00101 rand48_add = new_add;
00102 rand48_seed = save_seed;
00103
00104 second_gaussian = 0;
00105 second_gaussian_waiting = 0;
00106 }
00107
00108
00109 BigReal uniform(void) {
00110 skip();
00111 const double exp48 = ( 1.0 / (double)(INT64_LITERAL(1) << 48) );
00112 return ( (double) rand48_seed * exp48 );
00113 }
00114
00115
00116 BigReal gaussian(void) {
00117 BigReal fac, r, v1, v2;
00118
00119 if (second_gaussian_waiting) {
00120 second_gaussian_waiting = 0;
00121 return second_gaussian;
00122 } else {
00123 r = 2.;
00124 while (r >=1. || r < 1.523e-8) {
00125 v1 = 2.0 * uniform() - 1.0;
00126 v2 = 2.0 * uniform() - 1.0;
00127 r = v1*v1 + v2*v2;
00128 }
00129 fac = sqrt(-2.0 * log(r)/r);
00130
00131
00132 second_gaussian_waiting = 1;
00133 second_gaussian = v1 * fac;
00134 return v2 * fac;
00135 }
00136 }
00137
00138
00139 Vector gaussian_vector(void) {
00140 return Vector( gaussian(), gaussian(), gaussian() );
00141 }
00142
00143
00144 long integer(void) {
00145 skip();
00146 return ( ( rand48_seed >> 17 ) & INT64_LITERAL(0x000000007fffffff) );
00147 }
00148
00149
00150 template <class Elem> void reorder(Elem *a, int n) {
00151 for ( int i = 0; i < (n-1); ++i ) {
00152 int ie = i + ( integer() % (n-i) );
00153 if ( ie == i ) continue;
00154 const Elem e = a[ie];
00155 a[ie] = a[i];
00156 a[i] = e;
00157 }
00158 }
00159
00160 };
00161
00162 #endif // RANDOM_H
00163