diff options
Diffstat (limited to 'linden/indra/llmath/llrand.h')
-rw-r--r-- | linden/indra/llmath/llrand.h | 134 |
1 files changed, 87 insertions, 47 deletions
diff --git a/linden/indra/llmath/llrand.h b/linden/indra/llmath/llrand.h index db9f353..47b5651 100644 --- a/linden/indra/llmath/llrand.h +++ b/linden/indra/llmath/llrand.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /** | 1 | /** |
2 | * @file llrand.h | 2 | * @file llrand.h |
3 | * @brief Some useful math functions. | 3 | * @brief Information, functions, and typedefs for randomness. |
4 | * | 4 | * |
5 | * Copyright (c) 2000-2007, Linden Research, Inc. | 5 | * Copyright (c) 2000-2007, Linden Research, Inc. |
6 | * | 6 | * |
@@ -28,61 +28,101 @@ | |||
28 | #ifndef LL_LLRAND_H | 28 | #ifndef LL_LLRAND_H |
29 | #define LL_LLRAND_H | 29 | #define LL_LLRAND_H |
30 | 30 | ||
31 | // As long as you #include "llviewerprecompiledheaders.h", | 31 | #include "boost/random/lagged_fibonacci.hpp" |
32 | // you can use "gLindenLabRandomNumber.llfrand( range );" which returns a | 32 | #include "boost/random/mersenne_twister.hpp" |
33 | // random number F32 ranging from 0.0f to range. | ||
34 | // -Ventrella - Sept 30, 2005 | ||
35 | 33 | ||
36 | // Slams Intel processors into Single Precision FP mode | 34 | /** |
37 | // (which is not any faster on modern hardware) | 35 | * Use the boost random number generators if you want a stateful |
38 | void slamFPCW( void ); | 36 | * random numbers. If you want more random numbers, use the |
39 | 37 | * c-functions since they will generate faster/better randomness | |
40 | class LLRand | 38 | * across the process. |
41 | { | 39 | * |
42 | public: | 40 | * I tested some of the boost random engines, and picked a good double |
43 | LLRand(U32 seed) : mSeed(seed) {} | 41 | * generator and a good integer generator. I also took some timings |
44 | ~LLRand() {} | 42 | * for them on linux using gcc 3.3.5. The harness also did some other |
45 | 43 | * fairly trivial operations to try to limit compiler optimizations, | |
46 | void seed(U32 seed) { mSeed = seed; } | 44 | * so these numbers are only good for relative comparisons. |
45 | * | ||
46 | * usec/inter algorithm | ||
47 | * 0.21 boost::minstd_rand0 | ||
48 | * 0.039 boost:lagged_fibonacci19937 | ||
49 | * 0.036 boost:lagged_fibonacci607 | ||
50 | * 0.44 boost::hellekalek1995 | ||
51 | * 0.44 boost::ecuyer1988 | ||
52 | * 0.042 boost::rand48 | ||
53 | * 0.043 boost::mt11213b | ||
54 | * 0.028 stdlib random() | ||
55 | * 0.05 stdlib lrand48() | ||
56 | * 0.034 stdlib rand() | ||
57 | * 0.020 the old & lame LLRand | ||
58 | */ | ||
47 | 59 | ||
48 | U32 llrand() | 60 | /** |
49 | { | 61 | *@brief Generate a float from [0, RAND_MAX). |
50 | mSeed = U64L(1664525) * mSeed + U64L(1013904223); | 62 | */ |
51 | return (U32)mSeed; | 63 | S32 ll_rand(); |
52 | } | ||
53 | 64 | ||
54 | U32 llrand(U32 val) | 65 | /** |
55 | { | 66 | *@brief Generate a float from [0, val). |
56 | mSeed = U64L(1664525) * mSeed + U64L(1013904223); | 67 | */ |
57 | return (U32)(mSeed) % val; | 68 | S32 ll_rand(S32 val); |
58 | } | ||
59 | 69 | ||
60 | // val is the maximum | 70 | /** |
61 | F32 llfrand(F32 val) | 71 | *@brief Generate a float from [0, 1.0). |
62 | { | 72 | */ |
63 | const U32 FP_ONE = 0x3f800000; | 73 | F32 ll_frand(); |
64 | const U32 FP_MASK = 0x007fffff; | ||
65 | U32 ir = llrand(); | ||
66 | 74 | ||
67 | ir = FP_ONE | (FP_MASK & ir); | 75 | /** |
68 | 76 | *@brief Generate a float from [0, val). | |
69 | // generate random float | 77 | */ |
70 | F32 fr = (*(F32 *)&ir); | 78 | F32 ll_frand(F32 val); |
71 | 79 | ||
72 | // correct to [0..1) | 80 | /** |
73 | fr -= 1.f; | 81 | *@brief Generate a double from [0, 1.0). |
82 | */ | ||
83 | F64 ll_drand(); | ||
74 | 84 | ||
75 | fr *= val; | 85 | /** |
86 | *@brief Generate a double from [0, val). | ||
87 | */ | ||
88 | F64 ll_drand(F64 val); | ||
76 | 89 | ||
77 | return fr; | 90 | /** |
78 | } | 91 | * @brief typedefs for good boost lagged fibonacci. |
79 | 92 | * @see boost::lagged_fibonacci | |
80 | public: | 93 | * |
81 | U64 mSeed; | 94 | * These generators will quickly generate doubles. Note the memory |
82 | }; | 95 | * requirements, because they are somewhat high. I chose the smallest |
96 | * one, and one comparable in speed but higher periodicity without | ||
97 | * outrageous memory requirements. | ||
98 | * To use: | ||
99 | * LLRandLagFib607 foo((U32)time(NULL)); | ||
100 | * double bar = foo(); | ||
101 | */ | ||
83 | 102 | ||
84 | F32 frand(F32 val); | 103 | typedef boost::lagged_fibonacci607 LLRandLagFib607; |
104 | /**< | ||
105 | * lengh of cycle: 2^32,000 | ||
106 | * memory: 607*sizeof(double) (about 5K) | ||
107 | */ | ||
85 | 108 | ||
86 | extern LLRand gLindenLabRandomNumber; | 109 | typedef boost::lagged_fibonacci2281 LLRandLagFib2281; |
110 | /**< | ||
111 | * lengh of cycle: 2^120,000 | ||
112 | * memory: 2281*sizeof(double) (about 17K) | ||
113 | */ | ||
87 | 114 | ||
115 | /** | ||
116 | * @breif typedefs for a good boost mersenne twister implementation. | ||
117 | * @see boost::mersenne_twister | ||
118 | * | ||
119 | * This fairly quickly generates U32 values | ||
120 | * To use: | ||
121 | * LLRandMT19937 foo((U32)time(NULL)); | ||
122 | * U32 bar = foo(); | ||
123 | * | ||
124 | * lengh of cycle: 2^19,937-1 | ||
125 | * memory: about 2496 bytes | ||
126 | */ | ||
127 | typedef boost::mt11213b LLRandMT19937; | ||
88 | #endif | 128 | #endif |