1 /*---------------------------------------------------------------------------* 2 Project: Horizon 3 File: math_MersenneTwister.h 4 5 Copyright (C)2009-2012 Nintendo Co., Ltd. All rights reserved. 6 7 These coded instructions, statements, and computer programs contain 8 proprietary information of Nintendo of America Inc. and/or Nintendo 9 Company Ltd., and are protected by Federal copyright law. They may 10 not be disclosed to third parties or copied or duplicated in any form, 11 in whole or in part, without the prior written consent of Nintendo. 12 13 $Rev: 47802 $ 14 *---------------------------------------------------------------------------*/ 15 16 /* Please see man pages for details 17 18 19 20 */ 21 22 #ifndef NN_MATH_MATH_MERSENNETWISTER_H_ 23 #define NN_MATH_MATH_MERSENNETWISTER_H_ 24 25 #include <nn/types.h> 26 27 namespace nn { namespace math { 28 29 /* ------------------------------------------------------------------------ 30 Class definitions 31 ------------------------------------------------------------------------ */ 32 33 //---------------------------------------------------------------------- 34 // 35 // 36 // 37 // 38 // 39 // 40 // 41 // 42 // 43 // 44 // 45 // 46 // 47 // 48 // 49 //---------------------------------------------------------------------- 50 class MersenneTwister 51 { 52 private: 53 static const int PARAMETER_W = 32; 54 static const int PARAMETER_N = 624; 55 static const int PARAMETER_M = 397; 56 static const int PARAMETER_R = 31; 57 static const int PARAMETER_U = 11; 58 static const int PARAMETER_S = 7; 59 static const int PARAMETER_T = 15; 60 static const int PARAMETER_L = 18; 61 62 static const bit32 PARAMETER_A = 0x9908b0df; 63 static const bit32 PARAMETER_B = 0x9d2c5680; 64 static const bit32 PARAMETER_C = 0xefc60000; 65 66 static const bit32 MIX_MASK = (~0u << PARAMETER_R); 67 68 public: 69 //---------------------------------------------------------------------- 70 // 71 //---------------------------------------------------------------------- 72 struct State 73 { 74 //---------------------------------------------------------------------- 75 // 76 //---------------------------------------------------------------------- 77 int index; 78 79 //---------------------------------------------------------------------- 80 // 81 //---------------------------------------------------------------------- 82 bit32 state[PARAMETER_N]; 83 }; 84 85 private: 86 int m_Index; 87 bit32 m_State[PARAMETER_N]; 88 89 public: 90 91 // 92 // 93 94 //---------------------------------------------------------------------- 95 // 96 // 97 // 98 // 99 // 100 //---------------------------------------------------------------------- 101 void Initialize(); 102 103 //---------------------------------------------------------------------- 104 // 105 // 106 // 107 // 108 // 109 //---------------------------------------------------------------------- 110 void Initialize(bit32 seed); 111 112 //---------------------------------------------------------------------- 113 // 114 // 115 // 116 // 117 // 118 // 119 //---------------------------------------------------------------------- 120 void Initialize(const bit32* pSeed, int numSeed); 121 122 //---------------------------------------------------------------------- 123 // 124 //---------------------------------------------------------------------- Finalize()125 void Finalize(){} 126 127 // 128 129 // 130 // 131 132 //---------------------------------------------------------------------- 133 // 134 // 135 // 136 // 137 // 138 // 139 // 140 // 141 // 142 // 143 // 144 //---------------------------------------------------------------------- 145 void SaveState(MersenneTwister::State* pStateBuffer); 146 147 //---------------------------------------------------------------------- 148 // 149 // 150 // 151 // 152 // 153 // 154 // 155 // 156 //---------------------------------------------------------------------- 157 void RestoreState(const MersenneTwister::State* pStateBuffer); 158 159 // 160 161 // 162 // 163 164 //---------------------------------------------------------------------- 165 // 166 // 167 // 168 // 169 // 170 //---------------------------------------------------------------------- 171 u32 GenerateRandomU32(); 172 173 //---------------------------------------------------------------------- 174 // 175 // 176 // 177 // 178 // 179 //---------------------------------------------------------------------- 180 u64 GenerateRandomU64(); 181 182 //---------------------------------------------------------------------- 183 // 184 // 185 // 186 //---------------------------------------------------------------------- 187 f32 GenerateRandomF32(); 188 189 //---------------------------------------------------------------------- 190 // 191 // 192 // 193 //---------------------------------------------------------------------- 194 f64 GenerateRandomF64(); 195 196 //---------------------------------------------------------------------- 197 // 198 // 199 // 200 // 201 // 202 // 203 // 204 // 205 // 206 // 207 // 208 // 209 // 210 // 211 // 212 // 213 // 214 // 215 // 216 // 217 // 218 // 219 //---------------------------------------------------------------------- 220 u32 GenerateRandomN(u16 num); 221 222 //---------------------------------------------------------------------- 223 // 224 // 225 // 226 // 227 // 228 // 229 // 230 //---------------------------------------------------------------------- 231 void GenerateRandomBytes(void* p, size_t size); 232 233 // 234 235 236 private: GenerateRandomU24()237 u32 GenerateRandomU24() 238 { 239 return GenerateRandomU32() >> 8; 240 } 241 242 static inline bit32 MixBits(bit32 u, bit32 l); 243 static inline bit32 GenerateXkn(bit32 xkm, bit32 xk, bit32 xk1); 244 }; 245 246 247 248 /* ------------------------------------------------------------------------ 249 Inline member function definitions 250 ------------------------------------------------------------------------ */ 251 GenerateRandomU64()252 inline u64 MersenneTwister::GenerateRandomU64() 253 { 254 const u32 lo = GenerateRandomU32(); 255 const u32 hi = GenerateRandomU32(); 256 return (static_cast<u64>(hi) << 32) | lo; 257 } 258 GenerateRandomF32()259 inline f32 MersenneTwister::GenerateRandomF32() 260 { 261 return GenerateRandomU24() * (1.0f / (1ull << 24)); 262 } 263 GenerateRandomF64()264 inline f64 MersenneTwister::GenerateRandomF64() 265 { 266 static const int RESOLUTION = 53; 267 static const int U32_BITS = 32; 268 static const int A_SHIFT = (2 * U32_BITS - RESOLUTION) / 2; 269 static const int B_SHIFT = (2 * U32_BITS - RESOLUTION) - A_SHIFT; 270 //static const int A_BITS = U32_BITS - A_SHIFT; 271 static const int B_BITS = U32_BITS - B_SHIFT; 272 273 u32 a = (GenerateRandomU32() >> A_SHIFT); 274 u32 b = (GenerateRandomU32() >> B_SHIFT); 275 276 return (1.0 * a * (1u << B_BITS) + b) * (1.0 / (1ull << RESOLUTION)); 277 } 278 GenerateRandomN(u16 max)279 inline u32 MersenneTwister::GenerateRandomN(u16 max) 280 { 281 return static_cast<u32>((static_cast<u64>(GenerateRandomU32()) * max) >> 32); 282 } 283 284 285 286 }} 287 288 289 /* NN_MATH_MATH_MERSENNETWISTER_H_ */ 290 #endif 291