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
35{
119
120struct MersenneTwisterGlobals;
121
123{
124public:
130
131 using IntegerType = uint32_t;
132
134 itkOverrideGetNameOfClassMacro(MersenneTwisterRandomVariateGenerator);
135
144 static Pointer
146
155 static Pointer
157
160 static void
162
170 static constexpr IntegerType DefaultSeed = 121212;
171
173 static constexpr IntegerType StateVectorLength = 624;
174
175#if !defined(ITK_FUTURE_LEGACY_REMOVE) && !defined(ITK_WRAPPING_PARSER)
179 ITK_FUTURE_DEPRECATED("ITK 6 discourages using this member function. Please use `SetSeed` instead!")
180 void
181 Initialize(const IntegerType seed = Self::CreateRandomSeed())
182 {
183 this->SetSeed(seed);
184 }
185#endif
186
188 double
190 {
191 return static_cast<double>(GetIntegerVariate()) * (1.0 / double{ std::numeric_limits<uint32_t>::max() });
192 }
193
195 double
197 {
198 return GetVariateWithClosedRange() * n;
199 }
200
202 double
204 {
205 return static_cast<double>(GetIntegerVariate()) / double{ 1ULL << 32ULL };
206 }
207
209 double
211 {
212 return GetVariateWithOpenUpperRange() * n;
213 }
214
216 double
218 {
219 return (static_cast<double>(GetIntegerVariate()) + 0.5) / double{ 1ULL << 32ULL };
220 }
221
223 double
225 {
226 return GetVariateWithOpenRange() * n;
227 }
228
230 IntegerType
232
236
239 double
241
242 /* Access to a normal random number distribution
243 * TODO: Compare with vnl_sample_normal */
244 double
245 GetNormalVariate(const double mean = 0.0, const double variance = 1.0);
246
247 /* Access to a uniform random number distribution in the range [a, b)
248 * TODO: Compare with vnl_sample_uniform */
249 double
250 GetUniformVariate(const double a, const double b);
251
257 double
258 GetVariate() override
259 {
261 }
262
264 double
266 {
267 return GetVariate();
268 }
269
274 void
276
282 GetSeed() const
283 {
284 return m_Seed;
285 }
286
292 static IntegerType
294
295protected:
298 void
299 PrintSelf(std::ostream & os, Indent indent) const override;
300
302 void
304
305 static IntegerType
306 hash(time_t t, clock_t c);
307
308private:
310 itkGetGlobalDeclarationMacro(MersenneTwisterGlobals, PimplGlobals);
311
313 static Pointer
315
317 static IntegerType
319 {
320 return hash(time(nullptr), clock());
321 }
322
324 void
326
327 // Internal state
329
330 // Next value to get from state
332
333 // Number of values left before reload is needed
334 int m_Left{};
335
336 // Seed value
337 std::atomic<IntegerType> m_Seed{};
338
339 // Local lock to enable concurrent access to singleton
340 std::mutex m_InstanceMutex{};
341
342 // Static/Global Variable need to be thread-safely accessed
343
344 static MersenneTwisterGlobals * m_PimplGlobals;
345
346}; // end of class
347
348// Declare inlined functions.... (must be declared in the header)
349
352inline double
354{
355 const IntegerType a = GetIntegerVariate() >> 5;
356 const IntegerType b = GetIntegerVariate() >> 6;
357
358 return (a * 67108864.0 + b) * (1.0 / 9007199254740992.0); // by Isaku
359 // Wada
360}
361
363// TODO: Compare with vnl_sample_normal
364inline double
365MersenneTwisterRandomVariateGenerator::GetNormalVariate(const double mean, const double variance)
366{
367 // Return a real number from a normal (Gaussian) distribution with given
368 // mean and variance by Box-Muller method
369 const double r = std::sqrt(-2.0 * std::log(1.0 - GetVariateWithOpenRange()) * variance);
370 const double phi = 2.0 * itk::Math::pi * GetVariateWithOpenUpperRange();
371
372 return mean + r * std::cos(phi);
373}
374
376// TODO: Compare with vnl_sample_uniform
377inline double
379{
380 const double u = GetVariateWithOpenUpperRange();
381
382 return (1.0 - u) * a + u * b;
383}
384
385/* Change log from MTRand.h */
386// Change log:
387//
388// v0.1 - First release on 15 May 2000
389// - Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus
390// - Translated from C to C++
391// - Made completely ANSI compliant
392// - Designed convenient interface for initialization, seeding, and
393// obtaining numbers in default or user-defined ranges
394// - Added automatic seeding from /dev/urandom or time() and clock()
395// - Provided functions for saving and loading generator state
396//
397// v0.2 - Fixed bug which reloaded generator one step too late
398//
399// v0.3 - Switched to clearer, faster reload() code from Matthew Bellew
400//
401// v0.4 - Removed trailing newline in saved generator format to be consistent
402// with output format of built-in types
403//
404// v0.5 - Improved portability by replacing static const int's with enum's and
405// clarifying return values in seed(); suggested by Eric Heimburg
406// spell-check-disable
407// - Removed MAXINT constant; use 0xffffffffUL instead
408// spell-check-enable
409//
410// v0.6 - Eliminated seed overflow when uint32 is larger than 32 bits
411// - Changed integer [0,n] generator to give better uniformity
412//
413// v0.7 - Fixed operator precedence ambiguity in reload()
414// - Added access for real numbers in (0,1) and (0,n)
415//
416// v0.8 - Included time.h header to properly support time_t and clock_t
417//
418// v1.0 - Revised seeding to match 26 Jan 2002 update of Nishimura and Matsumoto
419// - Allowed for seeding with arrays of any length
420// - Added access for real numbers in [0,1) with 53-bit resolution
421// - Added access for real numbers from normal (Gaussian) distributions
422// - Increased overall speed by optimizing twist()
423// - Doubled speed of integer [0,n] generation
424// - Fixed out-of-range number generation on 64-bit machines
425// - Improved portability by substituting literal constants for long enum's
426// - Changed license from GNU LGPL to BSD
427} // namespace itk::Statistics
428
429#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 SetSeed(const IntegerType seed=Self::CreateRandomSeed())
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