ITK 6.0.0
Insight Toolkit
 
Loading...
Searching...
No Matches
itkMersenneTwisterRandomVariateGenerator.h
Go to the documentation of this file.
1/*=========================================================================
2 *
3 * Copyright NumFOCUS
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * https://www.apache.org/licenses/LICENSE-2.0.txt
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *=========================================================================*/
18#ifndef itkMersenneTwisterRandomVariateGenerator_h
19#define itkMersenneTwisterRandomVariateGenerator_h
20
21#include "itkMacro.h"
22#include "itkObjectFactory.h"
24#include "itkIntTypes.h"
25#include "itkMath.h"
26#include "itkSingletonMacro.h"
27
28#include <atomic>
29#include <mutex>
30#include <climits>
31#include <ctime>
32#include <limits>
33
34namespace itk
35{
36namespace Statistics
37{
122
123struct MersenneTwisterGlobals;
124
126{
127public:
133
134 using IntegerType = uint32_t;
135
137 itkOverrideGetNameOfClassMacro(MersenneTwisterRandomVariateGenerator);
138
147 static Pointer
149
158 static Pointer
160
163 static void
165
167 static constexpr IntegerType StateVectorLength = 624;
168
170 void
172
173 /* Initialize with clock time */
174 void
176 {
177 SetSeed();
178 }
179
181 double
183 {
184 return static_cast<double>(GetIntegerVariate()) * (1.0 / double{ std::numeric_limits<uint32_t>::max() });
185 }
186
188 double
190 {
191 return GetVariateWithClosedRange() * n;
192 }
193
195 double
197 {
198 return static_cast<double>(GetIntegerVariate()) / double{ 1ULL << 32ULL };
199 }
200
202 double
204 {
205 return GetVariateWithOpenUpperRange() * n;
206 }
207
209 double
211 {
212 return (static_cast<double>(GetIntegerVariate()) + 0.5) / double{ 1ULL << 32ULL };
213 }
214
216 double
218 {
219 return GetVariateWithOpenRange() * n;
220 }
221
223 IntegerType
225
229
232 double
234
235 /* Access to a normal random number distribution
236 * TODO: Compare with vnl_sample_normal */
237 double
238 GetNormalVariate(const double mean = 0.0, const double variance = 1.0);
239
240 /* Access to a uniform random number distribution in the range [a, b)
241 * TODO: Compare with vnl_sample_uniform */
242 double
243 GetUniformVariate(const double a, const double b);
244
250 double
251 GetVariate() override
252 {
254 }
255
257 double
259 {
260 return GetVariate();
261 }
262
268 void
269 SetSeed(const IntegerType oneSeed)
270 {
271 // Seed the generator with a simple IntegerType
272 Initialize(oneSeed);
273 }
274
275 void
280
285 IntegerType
286 GetSeed() const
287 {
288 return m_Seed;
289 }
290
296 static IntegerType
298
299 /*
300 // Saving and loading generator state
301 void save( IntegerType* saveArray ) const; // to array of size SAVE
302 void load( IntegerType *const loadArray ); // from such array
303 */
304
305protected:
308 void
309 PrintSelf(std::ostream & os, Indent indent) const override;
310
312 void
314
315 static IntegerType
316 hash(time_t t, clock_t c);
317
318private:
320 itkGetGlobalDeclarationMacro(MersenneTwisterGlobals, PimplGlobals);
321
323 static Pointer
325
327 static IntegerType
329 {
330 return hash(time(nullptr), clock());
331 }
332
334 void
336
337 // Internal state
339
340 // Next value to get from state
342
343 // Number of values left before reload is needed
344 int m_Left{};
345
346 // Seed value
347 std::atomic<IntegerType> m_Seed{};
348
349 // Local lock to enable concurrent access to singleton
350 std::mutex m_InstanceMutex{};
351
352 // Static/Global Variable need to be thread-safely accessed
353
354 static MersenneTwisterGlobals * m_PimplGlobals;
355
356}; // end of class
357
358// Declare inlined functions.... (must be declared in the header)
359
362inline double
364{
365 const IntegerType a = GetIntegerVariate() >> 5;
366 const IntegerType b = GetIntegerVariate() >> 6;
367
368 return (a * 67108864.0 + b) * (1.0 / 9007199254740992.0); // by Isaku
369 // Wada
370}
371
373// TODO: Compare with vnl_sample_normal
374inline double
375MersenneTwisterRandomVariateGenerator::GetNormalVariate(const double mean, const double variance)
376{
377 // Return a real number from a normal (Gaussian) distribution with given
378 // mean and variance by Box-Muller method
379 const double r = std::sqrt(-2.0 * std::log(1.0 - GetVariateWithOpenRange()) * variance);
380 const double phi = 2.0 * itk::Math::pi * GetVariateWithOpenUpperRange();
381
382 return mean + r * std::cos(phi);
383}
384
386// TODO: Compare with vnl_sample_uniform
387inline double
389{
390 const double u = GetVariateWithOpenUpperRange();
391
392 return ((1.0 - u) * a + u * b);
393}
394
395/* Change log from MTRand.h */
396// Change log:
397//
398// v0.1 - First release on 15 May 2000
399// - Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus
400// - Translated from C to C++
401// - Made completely ANSI compliant
402// - Designed convenient interface for initialization, seeding, and
403// obtaining numbers in default or user-defined ranges
404// - Added automatic seeding from /dev/urandom or time() and clock()
405// - Provided functions for saving and loading generator state
406//
407// v0.2 - Fixed bug which reloaded generator one step too late
408//
409// v0.3 - Switched to clearer, faster reload() code from Matthew Bellew
410//
411// v0.4 - Removed trailing newline in saved generator format to be consistent
412// with output format of built-in types
413//
414// v0.5 - Improved portability by replacing static const int's with enum's and
415// clarifying return values in seed(); suggested by Eric Heimburg
416// - Removed MAXINT constant; use 0xffffffffUL instead
417//
418// v0.6 - Eliminated seed overflow when uint32 is larger than 32 bits
419// - Changed integer [0,n] generator to give better uniformity
420//
421// v0.7 - Fixed operator precedence ambiguity in reload()
422// - Added access for real numbers in (0,1) and (0,n)
423//
424// v0.8 - Included time.h header to properly support time_t and clock_t
425//
426// v1.0 - Revised seeding to match 26 Jan 2002 update of Nishimura and Matsumoto
427// - Allowed for seeding with arrays of any length
428// - Added access for real numbers in [0,1) with 53-bit resolution
429// - Added access for real numbers from normal (Gaussian) distributions
430// - Increased overall speed by optimizing twist()
431// - Doubled speed of integer [0,n] generation
432// - Fixed out-of-range number generation on 64-bit machines
433// - Improved portability by substituting literal constants for long enum's
434// - Changed license from GNU LGPL to BSD
435} // end namespace Statistics
436} // end namespace itk
437
438#endif
Control indentation during Print() invocation.
Definition itkIndent.h:50
Implements transparent reference counting.
IntegerType GetIntegerVariate(const IntegerType n)
static Pointer New()
Method for creation through the object factory.
void PrintSelf(std::ostream &os, Indent indent) const override
static IntegerType hash(time_t t, clock_t c)
itkGetGlobalDeclarationMacro(MersenneTwisterGlobals, PimplGlobals)
void InitializeWithoutMutexLocking(const IntegerType seed)
double GetNormalVariate(const double mean=0.0, const double variance=1.0)
static constexpr double pi
Definition itkMath.h:66
The "itk" namespace contains all Insight Segmentation and Registration Toolkit (ITK) classes....