00001 #ifndef BZ_RANDOM_UNIFORM_H
00002 #define BZ_RANDOM_UNIFORM_H
00003
00004 #include <random/default.h>
00005
00006 #ifndef FLT_MANT_DIG
00007 #include <float.h>
00008 #endif
00009
00010 BZ_NAMESPACE(ranlib)
00011
00012
00013
00014
00015
00016 template<typename T = defaultType, typename IRNG = defaultIRNG,
00017 typename stateTag = defaultState>
00018 class UniformClosedOpen { };
00019
00020
00021 const long double norm32open = .2328306436538696289062500000000000000000E-9L;
00022 const long double norm64open = .5421010862427522170037264004349708557129E-19L;
00023 const long double norm96open = .1262177448353618888658765704452457967477E-28L;
00024 const long double norm128open = .2938735877055718769921841343055614194547E-38L;
00025
00026
00027 template<typename IRNG, typename stateTag>
00028 class UniformClosedOpen<float,IRNG,stateTag>
00029 : public IRNGWrapper<IRNG,stateTag>
00030 {
00031
00032 public:
00033 typedef float T_numtype;
00034
00035 UniformClosedOpen() {};
00036 UniformClosedOpen(unsigned int i) :
00037 IRNGWrapper<IRNG,stateTag>::IRNGWrapper(i) {};
00038
00039 float random()
00040 {
00041 #if FLT_MANT_DIG > 96
00042 #if (FLT_MANT_DIG > 128) && !defined(BZ_IGNORE_RNG_ERRORS)
00043 #error RNG code assumes float mantissa is <= 128 bits (not true for your platform). Use -DBZ_IGNORE_RNG_ERRORS to ignore this warning.
00044 #endif
00045 IRNG_int i1 = this->irng_.random();
00046 IRNG_int i2 = this->irng_.random();
00047 IRNG_int i3 = this->irng_.random();
00048 IRNG_int i4 = this->irng_.random();
00049 return i1 * norm128open + i2 * norm96open + i3 * norm64open
00050 + i4 * norm32open;
00051 #elif FLT_MANT_DIG > 64
00052 IRNG_int i1 = this->irng_.random();
00053 IRNG_int i2 = this->irng_.random();
00054 IRNG_int i3 = this->irng_.random();
00055 return i1 * norm96open + i2 * norm64open + i3 * norm32open;
00056 #elif FLT_MANT_DIG > 32
00057 IRNG_int i1 = this->irng_.random();
00058 IRNG_int i2 = this->irng_.random();
00059 return i1 * norm64open + i2 * norm32open;
00060 #else
00061 IRNG_int i1 = this->irng_.random();
00062 return i1 * norm32open;
00063 #endif
00064 }
00065
00066 float getUniform()
00067 { return random(); }
00068 };
00069
00070 template<typename IRNG, typename stateTag>
00071 class UniformClosedOpen<double,IRNG,stateTag>
00072 : public IRNGWrapper<IRNG,stateTag>
00073 {
00074 public:
00075 typedef double T_numtype;
00076
00077 UniformClosedOpen() {}
00078 UniformClosedOpen(unsigned int i) :
00079 IRNGWrapper<IRNG,stateTag>::IRNGWrapper(i) {};
00080
00081 double random()
00082 {
00083 #if DBL_MANT_DIG > 96
00084 #if (DBL_MANT_DIG > 128) && !defined(BZ_IGNORE_RNG_ERRORS)
00085 #error RNG code assumes double mantissa is <= 128 bits (not true for your platform). Use -DBZ_IGNORE_RNG_ERRORS to ignore this warning.
00086 #endif
00087
00088 IRNG_int i1 = this->irng_.random();
00089 IRNG_int i2 = this->irng_.random();
00090 IRNG_int i3 = this->irng_.random();
00091 IRNG_int i4 = this->irng_.random();
00092 return i1 * norm128open + i2 * norm96open + i3 * norm64open
00093 + i4 * norm32open;
00094 #elif DBL_MANT_DIG > 64
00095 IRNG_int i1 = this->irng_.random();
00096 IRNG_int i2 = this->irng_.random();
00097 IRNG_int i3 = this->irng_.random();
00098 return i1 * norm96open + i2 * norm64open + i3 * norm32open;
00099 #elif DBL_MANT_DIG > 32
00100 IRNG_int i1 = this->irng_.random();
00101 IRNG_int i2 = this->irng_.random();
00102 return i1 * norm64open + i2 * norm32open;
00103 #else
00104 IRNG_int i1 = this->irng_.random();
00105 return i1 * norm32open;
00106 #endif
00107
00108 }
00109
00110 double getUniform() { return random(); }
00111 };
00112
00113 template<typename IRNG, typename stateTag>
00114 class UniformClosedOpen<long double,IRNG,stateTag>
00115 : public IRNGWrapper<IRNG,stateTag>
00116 {
00117 public:
00118 typedef long double T_numtype;
00119
00120 UniformClosedOpen() {};
00121 UniformClosedOpen(unsigned int i) :
00122 IRNGWrapper<IRNG,stateTag>::IRNGWrapper(i) {};
00123
00124 long double random()
00125 {
00126 #if LDBL_MANT_DIG > 96
00127 #if (LDBL_MANT_DIG > 128) && !defined(BZ_IGNORE_RNG_ERRORS)
00128 #error RNG code assumes long double mantissa is <= 128 bits (not true for your platform). Use -DBZ_IGNORE_RNG_ERRORS to ignore this warning.
00129 #endif
00130
00131 IRNG_int i1 = this->irng_.random();
00132 IRNG_int i2 = this->irng_.random();
00133 IRNG_int i3 = this->irng_.random();
00134 IRNG_int i4 = this->irng_.random();
00135 return i1 * norm128open + i2 * norm96open + i3 * norm64open
00136 + i4 * norm32open;
00137 #elif LDBL_MANT_DIG > 64
00138 IRNG_int i1 = this->irng_.random();
00139 IRNG_int i2 = this->irng_.random();
00140 IRNG_int i3 = this->irng_.random();
00141 return i1 * norm96open + i2 * norm64open + i3 * norm32open;
00142 #elif LDBL_MANT_DIG > 32
00143 IRNG_int i1 = this->irng_.random();
00144 IRNG_int i2 = this->irng_.random();
00145 return i1 * norm64open + i2 * norm32open;
00146 #else
00147 IRNG_int i1 = this->irng_.random();
00148 return i1 * norm32open;
00149 #endif
00150 }
00151
00152 long double getUniform() { return random(); }
00153 };
00154
00155
00156
00157
00158 template<class T, typename IRNG = defaultIRNG,
00159 typename stateTag = defaultState>
00160 class Uniform : public UniformClosedOpen<T,IRNG,stateTag>
00161 {
00162 public:
00163 Uniform() {};
00164 Uniform(unsigned int i) :
00165 UniformClosedOpen<T,IRNG,stateTag>::UniformClosedOpen(i) {}
00166 };
00167
00168
00169
00170
00171
00172
00173 const long double norm32closed = .2328306437080797375431469961868475648078E-9L;
00174
00175
00176
00177 const long double norm64closed1 =
00178 .23283064365386962891887177448353618888727188481031E-9L;
00179 const long double norm64closed2 =
00180 .54210108624275221703311375920552804341370213034169E-19L;
00181
00182
00183 const long double norm96closed1 = .2328306436538696289062500000029387358771E-9L;
00184 const long double norm96closed2 =
00185 .5421010862427522170037264004418131333707E-19L;
00186 const long double norm96closed3 =
00187 .1262177448353618888658765704468388886588E-28L;
00188
00189
00190
00191 const long double norm128clos1 = .2328306436538696289062500000000000000007E-9L;
00192 const long double norm128clos2 = .5421010862427522170037264004349708557145E-19L;
00193 const long double norm128clos3 = .1262177448353618888658765704452457967481E-28L;
00194 const long double norm128clos4 = .2938735877055718769921841343055614194555E-38L;
00195
00196
00197 template<typename T = double, typename IRNG = defaultIRNG,
00198 typename stateTag = defaultState>
00199 class UniformClosed { };
00200
00201 template<typename IRNG, typename stateTag>
00202 class UniformClosed<float,IRNG,stateTag> : public IRNGWrapper<IRNG,stateTag> {
00203
00204 public:
00205 typedef float T_numtype;
00206
00207 UniformClosed() {};
00208 UniformClosed(unsigned int i) :
00209 IRNGWrapper<IRNG,stateTag>::IRNGWrapper(i) {};
00210
00211 float random()
00212 {
00213 #if FLTMANT_DIG > 96
00214 #if (FLT_MANT_DIG > 128) && !defined(BZ_IGNORE_RNG_ERRORS)
00215 #error RNG code assumes float mantissa is <= 128 bits (not true for your platform). Use -DBZ_IGNORE_RNG_ERRORS to ignore this warning.
00216 #endif
00217 IRNG_int i1 = this->irng_.random();
00218 IRNG_int i2 = this->irng_.random();
00219 IRNG_int i3 = this->irng_.random();
00220 IRNG_int i4 = this->irng_.random();
00221
00222 return i1 * norm128clos1 + i2 * norm128clos2
00223 + i3 * norm128clos3 + i4 * norm128clos4;
00224 #elif FLT_MANT_DIG > 64
00225 IRNG_int i1 = this->irng_.random();
00226 IRNG_int i2 = this->irng_.random();
00227 IRNG_int i3 = this->irng_.random();
00228
00229 return i1 * norm96closed1 + i2 * norm96closed2
00230 + i3 * norm96closed3;
00231 #elif FLT_MANT_DIG > 32
00232 IRNG_int i1 = this->irng_.random();
00233 IRNG_int i2 = this->irng_.random();
00234
00235 return i1 * norm64closed1 + i2 * norm64closed2;
00236 #else
00237 IRNG_int i = this->irng_.random();
00238 return i * norm32closed;
00239 #endif
00240
00241 }
00242
00243 float getUniform()
00244 { return random(); }
00245 };
00246
00247 template<typename IRNG, typename stateTag>
00248 class UniformClosed<double,IRNG,stateTag> : public IRNGWrapper<IRNG,stateTag> {
00249
00250 public:
00251 typedef double T_numtype;
00252
00253 UniformClosed() {};
00254 UniformClosed(unsigned int i) :
00255 IRNGWrapper<IRNG,stateTag>::IRNGWrapper(i) {};
00256
00257 double random()
00258 {
00259 #if DBL_MANT_DIG > 96
00260 #if (DBL_MANT_DIG > 128) && !defined(BZ_IGNORE_RNG_ERRORS)
00261 #error RNG code assumes double mantissa is <= 128 bits (not true for your platform). Use -DBZ_IGNORE_RNG_ERRORS to ignore this warning.
00262 #endif
00263 IRNG_int i1 = this->irng_.random();
00264 IRNG_int i2 = this->irng_.random();
00265 IRNG_int i3 = this->irng_.random();
00266 IRNG_int i4 = this->irng_.random();
00267
00268 return i1 * norm128clos1 + i2 * norm128clos2
00269 + i3 * norm128clos3 + i4 * norm128clos4;
00270 #elif DBL_MANT_DIG > 64
00271 IRNG_int i1 = this->irng_.random();
00272 IRNG_int i2 = this->irng_.random();
00273 IRNG_int i3 = this->irng_.random();
00274
00275 return i1 * norm96closed1 + i2 * norm96closed2
00276 + i3 * norm96closed3;
00277 #elif DBL_MANT_DIG > 32
00278 IRNG_int i1 = this->irng_.random();
00279 IRNG_int i2 = this->irng_.random();
00280
00281 return i1 * norm64closed1 + i2 * norm64closed2;
00282 #else
00283 IRNG_int i = this->irng_.random();
00284 return i * norm32closed;
00285 #endif
00286
00287 }
00288
00289 double getUniform()
00290 { return random(); }
00291 };
00292
00293 template<typename IRNG, typename stateTag>
00294 class UniformClosed<long double,IRNG,stateTag>
00295 : public IRNGWrapper<IRNG,stateTag> {
00296
00297 public:
00298 typedef long double T_numtype;
00299
00300 UniformClosed() {};
00301 UniformClosed(unsigned int i) :
00302 IRNGWrapper<IRNG,stateTag>::IRNGWrapper(i) {};
00303
00304 long double random()
00305 {
00306 #if LDBL_MANT_DIG > 96
00307 #if (LDBL_MANT_DIG > 128) && !defined(BZ_IGNORE_RNG_ERRORS)
00308 #error RNG code assumes long double mantissa is <= 128 bits (not true for your platform). Use -DBZ_IGNORE_RNG_ERRORS to ignore this warning.
00309 #endif
00310 IRNG_int i1 = this->irng_.random();
00311 IRNG_int i2 = this->irng_.random();
00312 IRNG_int i3 = this->irng_.random();
00313 IRNG_int i4 = this->irng_.random();
00314
00315 return i1 * norm128clos1 + i2 * norm128clos2
00316 + i3 * norm128clos3 + i4 * norm128clos4;
00317 #elif LDBL_MANT_DIG > 64
00318 IRNG_int i1 = this->irng_.random();
00319 IRNG_int i2 = this->irng_.random();
00320 IRNG_int i3 = this->irng_.random();
00321
00322 return i1 * norm96closed1 + i2 * norm96closed2
00323 + i3 * norm96closed3;
00324 #elif LDBL_MANT_DIG > 32
00325 IRNG_int i1 = this->irng_.random();
00326 IRNG_int i2 = this->irng_.random();
00327
00328 return i1 * norm64closed1 + i2 * norm64closed2;
00329 #else
00330 IRNG_int i = this->irng_.random();
00331 return i * norm32closed;
00332 #endif
00333 }
00334
00335 long double getUniform()
00336 { return random(); }
00337
00338 };
00339
00340
00341
00342
00343
00344 template<typename T = double, typename IRNG = defaultIRNG,
00345 typename stateTag = defaultState>
00346 class UniformOpen : public UniformClosedOpen<T,IRNG,stateTag> {
00347 public:
00348 typedef T T_numtype;
00349
00350 UniformOpen() {};
00351 UniformOpen(unsigned int i) :
00352 UniformClosedOpen<T,IRNG,stateTag>(i) {};
00353
00354 T random()
00355 {
00356
00357
00358 T x;
00359 do {
00360 x = UniformClosedOpen<T,IRNG,stateTag>::random();
00361 } while (x == 0.0L);
00362
00363 return x;
00364 }
00365
00366 T getUniform()
00367 { return random(); }
00368
00369 };
00370
00371
00372
00373
00374
00375 template<typename T = double, typename IRNG = defaultIRNG,
00376 typename stateTag = defaultState>
00377 class UniformOpenClosed : public UniformClosedOpen<T,IRNG,stateTag> {
00378
00379 public:
00380 typedef T T_numtype;
00381
00382 UniformOpenClosed() {};
00383 UniformOpenClosed(unsigned int i) :
00384 UniformClosedOpen<T,IRNG,stateTag>(i) {};
00385
00386
00387 T random()
00388 {
00389
00390
00391 return 1.0 - UniformClosedOpen<T,IRNG,stateTag>::random();
00392 }
00393
00394 T getUniform()
00395 { return random(); }
00396 };
00397
00398 BZ_NAMESPACE_END
00399
00400 #endif // BZ_RANDOM_UNIFORM_H