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
173 static constexpr IntegerType DefaultSeed = 121212;
174
176 static constexpr IntegerType StateVectorLength = 624;
177
178#ifndef ITK_FUTURE_LEGACY_REMOVE
182 ITK_FUTURE_DEPRECATED("ITK 6 discourages using this member function. Please use `SetSeed` instead!")
183 void
184 Initialize(const IntegerType seed = Self::CreateRandomSeed())
185 {
186 this->SetSeed(seed);
187 }
188#endif
189
191 double
193 {
194 return static_cast<double>(GetIntegerVariate()) * (1.0 / double{ std::numeric_limits<uint32_t>::max() });
195 }
196
198 double
200 {
201 return GetVariateWithClosedRange() * n;
202 }
203
205 double
207 {
208 return static_cast<double>(GetIntegerVariate()) / double{ 1ULL << 32ULL };
209 }
210
212 double
214 {
215 return GetVariateWithOpenUpperRange() * n;
216 }
217
219 double
221 {
222 return (static_cast<double>(GetIntegerVariate()) + 0.5) / double{ 1ULL << 32ULL };
223 }
224
226 double
228 {
229 return GetVariateWithOpenRange() * n;
230 }
231
233 IntegerType
235
239
242 double
244
245 /* Access to a normal random number distribution
246 * TODO: Compare with vnl_sample_normal */
247 double
248 GetNormalVariate(const double mean = 0.0, const double variance = 1.0);
249
250 /* Access to a uniform random number distribution in the range [a, b)
251 * TODO: Compare with vnl_sample_uniform */
252 double
253 GetUniformVariate(const double a, const double b);
254
260 double
261 GetVariate() override
262 {
264 }
265
267 double
269 {
270 return GetVariate();
271 }
272
277 void
279
285 GetSeed() const
286 {
287 return m_Seed;
288 }
289
295 static IntegerType
297
298protected:
301 void
302 PrintSelf(std::ostream & os, Indent indent) const override;
303
305 void
307
308 static IntegerType
309 hash(time_t t, clock_t c);
310
311private:
313 itkGetGlobalDeclarationMacro(MersenneTwisterGlobals, PimplGlobals);
314
316 static Pointer
318
320 static IntegerType
322 {
323 return hash(time(nullptr), clock());
324 }
325
327 void
329
330 // Internal state
332
333 // Next value to get from state
335
336 // Number of values left before reload is needed
337 int m_Left{};
338
339 // Seed value
340 std::atomic<IntegerType> m_Seed{};
341
342 // Local lock to enable concurrent access to singleton
343 std::mutex m_InstanceMutex{};
344
345 // Static/Global Variable need to be thread-safely accessed
346
347 static MersenneTwisterGlobals * m_PimplGlobals;
348
349}; // end of class
350
351// Declare inlined functions.... (must be declared in the header)
352
355inline double
357{
358 const IntegerType a = GetIntegerVariate() >> 5;
359 const IntegerType b = GetIntegerVariate() >> 6;
360
361 return (a * 67108864.0 + b) * (1.0 / 9007199254740992.0); // by Isaku
362 // Wada
363}
364
366// TODO: Compare with vnl_sample_normal
367inline double
368MersenneTwisterRandomVariateGenerator::GetNormalVariate(const double mean, const double variance)
369{
370 // Return a real number from a normal (Gaussian) distribution with given
371 // mean and variance by Box-Muller method
372 const double r = std::sqrt(-2.0 * std::log(1.0 - GetVariateWithOpenRange()) * variance);
373 const double phi = 2.0 * itk::Math::pi * GetVariateWithOpenUpperRange();
374
375 return mean + r * std::cos(phi);
376}
377
379// TODO: Compare with vnl_sample_uniform
380inline double
382{
383 const double u = GetVariateWithOpenUpperRange();
384
385 return ((1.0 - u) * a + u * b);
386}
387
388/* Change log from MTRand.h */
389// Change log:
390//
391// v0.1 - First release on 15 May 2000
392// - Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus
393// - Translated from C to C++
394// - Made completely ANSI compliant
395// - Designed convenient interface for initialization, seeding, and
396// obtaining numbers in default or user-defined ranges
397// - Added automatic seeding from /dev/urandom or time() and clock()
398// - Provided functions for saving and loading generator state
399//
400// v0.2 - Fixed bug which reloaded generator one step too late
401//
402// v0.3 - Switched to clearer, faster reload() code from Matthew Bellew
403//
404// v0.4 - Removed trailing newline in saved generator format to be consistent
405// with output format of built-in types
406//
407// v0.5 - Improved portability by replacing static const int's with enum's and
408// clarifying return values in seed(); suggested by Eric Heimburg
409// - Removed MAXINT constant; use 0xffffffffUL instead
410//
411// v0.6 - Eliminated seed overflow when uint32 is larger than 32 bits
412// - Changed integer [0,n] generator to give better uniformity
413//
414// v0.7 - Fixed operator precedence ambiguity in reload()
415// - Added access for real numbers in (0,1) and (0,n)
416//
417// v0.8 - Included time.h header to properly support time_t and clock_t
418//
419// v1.0 - Revised seeding to match 26 Jan 2002 update of Nishimura and Matsumoto
420// - Allowed for seeding with arrays of any length
421// - Added access for real numbers in [0,1) with 53-bit resolution
422// - Added access for real numbers from normal (Gaussian) distributions
423// - Increased overall speed by optimizing twist()
424// - Doubled speed of integer [0,n] generation
425// - Fixed out-of-range number generation on 64-bit machines
426// - Improved portability by substituting literal constants for long enum's
427// - Changed license from GNU LGPL to BSD
428} // end namespace Statistics
429} // end namespace itk
430
431#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
The "itk" namespace contains all Insight Segmentation and Registration Toolkit (ITK) classes....