1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     math_TinyMt.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_TINY_MT_H_
23 #define NN_MATH_MATH_TINY_MT_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 TinyMt
51     {
52     private:
53         static const int   PARAMETER_N   =  4;
54         static const bit32 PARAMETER_MAT1 = 0x8f7011ee;
55         static const bit32 PARAMETER_MAT2 = 0xfc78ff1f;
56         static const bit32 PARAMETER_TMAT = 0x3793fdff;
57 
58         static const int MIN_LOOP = 8;
59         static const int NUM_SKIP = 8;
60 
61         static const bit32 BIT31_MASK = ~0u >> 1;
62 
63     public:
64         //----------------------------------------------------------------------
65         //
66         //----------------------------------------------------------------------
67         struct State
68         {
69             //----------------------------------------------------------------------
70             //
71             //----------------------------------------------------------------------
72             bit32 state[PARAMETER_N];
73         };
74 
75     private:
76         bit32   m_State[PARAMETER_N];
77 
78     public:
79 
80     //
81     //
82 
83         //----------------------------------------------------------------------
84         //
85         //
86         //
87         //
88         //
89         //----------------------------------------------------------------------
90         void Initialize();
91 
92         //----------------------------------------------------------------------
93         //
94         //
95         //
96         //
97         //
98         //----------------------------------------------------------------------
99         void Initialize(bit32 seed);
100 
101         //----------------------------------------------------------------------
102         //
103         //
104         //
105         //
106         //
107         //
108         //----------------------------------------------------------------------
109         void Initialize(const bit32* pSeed, int numSeed);
110 
111         //----------------------------------------------------------------------
112         //
113         //----------------------------------------------------------------------
Finalize()114         void Finalize(){}
115 
116     //
117 
118     //
119     //
120 
121         //----------------------------------------------------------------------
122         //
123         //
124         //
125         //
126         //
127         //
128         //
129         //
130         //
131         //
132         //
133         //----------------------------------------------------------------------
134         void SaveState(TinyMt::State* pStateBuffer);
135 
136         //----------------------------------------------------------------------
137         //
138         //
139         //
140         //
141         //
142         //
143         //
144         //
145         //----------------------------------------------------------------------
146         void RestoreState(const TinyMt::State* pStateBuffer);
147 
148     //
149 
150     //
151     //
152 
153         //----------------------------------------------------------------------
154         //
155         //
156         //
157         //
158         //
159         //----------------------------------------------------------------------
160         u32 GenerateRandomU32();
161 
162         //----------------------------------------------------------------------
163         //
164         //
165         //
166         //
167         //
168         //----------------------------------------------------------------------
169         u64 GenerateRandomU64();
170 
171         //----------------------------------------------------------------------
172         //
173         //
174         //
175         //----------------------------------------------------------------------
176         f32 GenerateRandomF32();
177 
178         //----------------------------------------------------------------------
179         //
180         //
181         //
182         //----------------------------------------------------------------------
183         f64 GenerateRandomF64();
184 
185         //----------------------------------------------------------------------
186         //
187         //
188         //
189         //
190         //
191         //
192         //
193         //
194         //
195         //
196         //
197         //
198         //
199         //
200         //
201         //
202         //
203         //
204         //
205         //
206         //
207         //
208         //----------------------------------------------------------------------
209         u32 GenerateRandomN(u16 max);
210 
211         //----------------------------------------------------------------------
212         //
213         //
214         //
215         //
216         //
217         //
218         //
219         //----------------------------------------------------------------------
220         void GenerateRandomBytes(void* p, size_t size);
221 
222     //
223 
224     private:
GenerateRandomU24()225         u32 GenerateRandomU24()
226         {
227             return GenerateRandomU32() >> 8;
228         }
229 
230         void FinalizeInitialization();
231 
232         static void GenerateInitialValuePlus(bit32* p, int d, bit32 k);
233         static void GenerateInitialValueXor(bit32* p, int d);
234     };
235 
236 
237 
238     /* ------------------------------------------------------------------------
239             Inline member function definitions
240        ------------------------------------------------------------------------ */
241 
GenerateRandomU64()242     inline u64 TinyMt::GenerateRandomU64()
243     {
244         const u32 lo = GenerateRandomU32();
245         const u32 hi = GenerateRandomU32();
246         return (static_cast<u64>(hi) << 32) | lo;
247     }
248 
GenerateRandomF32()249     inline f32 TinyMt::GenerateRandomF32()
250     {
251         return GenerateRandomU24() * (1.0f / (1ull << 24));
252     }
253 
GenerateRandomF64()254     inline f64 TinyMt::GenerateRandomF64()
255     {
256         static const int RESOLUTION = 53;
257         static const int U32_BITS   = 32;
258         static const int A_SHIFT    = (2 * U32_BITS - RESOLUTION) / 2;
259         static const int B_SHIFT    = (2 * U32_BITS - RESOLUTION) - A_SHIFT;
260         //static const int A_BITS     = U32_BITS - A_SHIFT;
261         static const int B_BITS     = U32_BITS - B_SHIFT;
262 
263         u32 a = (GenerateRandomU32() >> A_SHIFT);
264         u32 b = (GenerateRandomU32() >> B_SHIFT);
265 
266         return (1.0 * a * (1u << B_BITS) + b) * (1.0 / (1ull << RESOLUTION));
267     }
268 
GenerateRandomN(u16 max)269     inline u32 TinyMt::GenerateRandomN(u16 max)
270     {
271         return static_cast<u32>((static_cast<u64>(GenerateRandomU32()) * max) >> 32);
272     }
273 
274 
275 
276 }}
277 
278 
279 /* NN_MATH_MATH_TINY_MT_H_ */
280 #endif
281