[221] | 1 | /***************************************************************************
|
---|
| 2 | * blitz/rand-uniform.h Uniform class, which provides uniformly
|
---|
| 3 | * distributed random numbers.
|
---|
| 4 | *
|
---|
| 5 | * $Id: rand-uniform.h,v 1.1.1.1 1999-04-09 17:58:59 ansari Exp $
|
---|
| 6 | *
|
---|
| 7 | * Copyright (C) 1997,1998 Todd Veldhuizen <tveldhui@seurat.uwaterloo.ca>
|
---|
| 8 | *
|
---|
| 9 | * This program is free software; you can redistribute it and/or
|
---|
| 10 | * modify it under the terms of the GNU General Public License
|
---|
| 11 | * as published by the Free Software Foundation; either version 2
|
---|
| 12 | * of the License, or (at your option) any later version.
|
---|
| 13 | *
|
---|
| 14 | * This program is distributed in the hope that it will be useful,
|
---|
| 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
| 17 | * GNU General Public License for more details.
|
---|
| 18 | *
|
---|
| 19 | * Suggestions: blitz-suggest@cybervision.com
|
---|
| 20 | * Bugs: blitz-bugs@cybervision.com
|
---|
| 21 | *
|
---|
| 22 | * For more information, please see the Blitz++ Home Page:
|
---|
| 23 | * http://seurat.uwaterloo.ca/blitz/
|
---|
| 24 | *
|
---|
| 25 | ***************************************************************************
|
---|
| 26 | *
|
---|
| 27 | * This random number generator is based on the LAPACK auxilliary
|
---|
| 28 | * routine DLARAN by Jack Dongarra. It's a multiplicative congruential
|
---|
| 29 | * generator with modulus 2^48 and multiplier 33952834046453.
|
---|
| 30 | *
|
---|
| 31 | * See also: G. S. Fishman, Multiplicative congruential random number
|
---|
| 32 | * generators with modulus 2^b: an exhaustive analysis for b=32 and
|
---|
| 33 | * a partial analysis for b=48, Math. Comp. 189, pp 331-344, 1990.
|
---|
| 34 | *
|
---|
| 35 | * This routine requires 32-bit integers.
|
---|
| 36 | *
|
---|
| 37 | * The generated number lies in the open interval (low,high). i.e. low and
|
---|
| 38 | * high themselves will never be generated.
|
---|
| 39 | *
|
---|
| 40 | ***************************************************************************
|
---|
| 41 | *
|
---|
| 42 | * $Log: not supported by cvs2svn $
|
---|
| 43 | * Revision 1.4 1998/03/14 00:04:47 tveldhui
|
---|
| 44 | * 0.2-alpha-05
|
---|
| 45 | *
|
---|
| 46 | * Revision 1.3 1997/07/16 14:51:20 tveldhui
|
---|
| 47 | * Update: Alpha release 0.2 (Arrays)
|
---|
| 48 | *
|
---|
| 49 | * Revision 1.2 1997/01/24 14:42:00 tveldhui
|
---|
| 50 | * Periodic RCS update
|
---|
| 51 | *
|
---|
| 52 | */
|
---|
| 53 |
|
---|
| 54 | #ifndef BZ_RAND_UNIFORM_H
|
---|
| 55 | #define BZ_RAND_UNIFORM_H
|
---|
| 56 |
|
---|
| 57 | #ifndef BZ_RANDOM_H
|
---|
| 58 | #include <blitz/random.h>
|
---|
| 59 | #endif
|
---|
| 60 |
|
---|
| 61 | BZ_NAMESPACE(blitz)
|
---|
| 62 |
|
---|
| 63 | class Uniform {
|
---|
| 64 |
|
---|
| 65 | public:
|
---|
| 66 | typedef double T_numtype;
|
---|
| 67 |
|
---|
| 68 | Uniform(double low = 0.0, double high = 1.0, double = 0.0)
|
---|
| 69 | : low_(low), length_(high-low)
|
---|
| 70 | {
|
---|
| 71 | BZPRECONDITION(sizeof(int) >= 4); // Need 32 bit integers!
|
---|
| 72 |
|
---|
| 73 | seed[0] = 24; // All seeds in the range [0,4095]
|
---|
| 74 | seed[1] = 711;
|
---|
| 75 | seed[2] = 3;
|
---|
| 76 | seed[3] = 3721; // The last seed must be odd
|
---|
| 77 | }
|
---|
| 78 |
|
---|
| 79 | void randomize()
|
---|
| 80 | {
|
---|
| 81 | BZ_NOT_IMPLEMENTED(); // NEEDS_WORK
|
---|
| 82 |
|
---|
| 83 | BZPOSTCONDITION(seed[3] % 2 == 1);
|
---|
| 84 | }
|
---|
| 85 |
|
---|
| 86 | // I'm trying to avoid having a compiled
|
---|
| 87 | // portion of the library, so this is inline until I
|
---|
| 88 | // figure out a better way to do this or I change my mind.
|
---|
| 89 | // -- TV
|
---|
| 90 | // NEEDS_WORK
|
---|
| 91 | double random()
|
---|
| 92 | {
|
---|
| 93 | BZPRECONDITION(seed[3] % 2 == 1);
|
---|
| 94 |
|
---|
| 95 | int it0, it1, it2, it3;
|
---|
| 96 | it3 = seed[3] * 2549;
|
---|
| 97 | it2 = it3 / 4096;
|
---|
| 98 | it3 -= it2 << 12;
|
---|
| 99 | it2 += seed[2] * 2549 + seed[3] * 2508;
|
---|
| 100 | it1 = it2 / 4096;
|
---|
| 101 | it2 -= it1 << 12;
|
---|
| 102 | it1 += seed[1] * 2549 + seed[2] * 2508 + seed[3] * 322;
|
---|
| 103 | it0 = it1 / 4096;
|
---|
| 104 | it1 -= it0 << 12;
|
---|
| 105 | it0 += seed[0] * 2549 + seed[1] * 2508 + seed[2] * 322 + seed[3] * 494;
|
---|
| 106 | it0 %= 4096;
|
---|
| 107 | seed[0] = it0;
|
---|
| 108 | seed[1] = it1;
|
---|
| 109 | seed[2] = it2;
|
---|
| 110 | seed[3] = it3;
|
---|
| 111 |
|
---|
| 112 | const double z = 1 / 4096.;
|
---|
| 113 | return low_ + length_ * (it0 + (it1 + (it2 + it3 * z) * z) * z) * z;
|
---|
| 114 | }
|
---|
| 115 |
|
---|
| 116 | operator double()
|
---|
| 117 | { return random(); }
|
---|
| 118 |
|
---|
| 119 | private:
|
---|
| 120 | double low_, length_;
|
---|
| 121 |
|
---|
| 122 | int seed[4];
|
---|
| 123 | };
|
---|
| 124 |
|
---|
| 125 | BZ_NAMESPACE_END
|
---|
| 126 |
|
---|
| 127 | #endif // BZ_RAND_UNIFORM_H
|
---|
| 128 |
|
---|