From a75ac39172c057ab3bcad5bdec32ae38d606c6eb Mon Sep 17 00:00:00 2001 From: Niels Dekker Date: Mon, 2 Oct 2023 17:05:53 +0200 Subject: [PATCH] ENH: Add `MersenneTwisterRandomVariateGenerator::ResetNextSeed()` Allows generating a reproducible sequence of pseudo-random numbers. --- .../itkMersenneTwisterRandomVariateGenerator.h | 5 +++++ .../itkMersenneTwisterRandomVariateGenerator.cxx | 10 ++++++++++ ...MersenneTwisterRandomVariateGeneratorGTest.cxx | 15 +++++++++++++++ 3 files changed, 30 insertions(+) diff --git a/Modules/Core/Common/include/itkMersenneTwisterRandomVariateGenerator.h b/Modules/Core/Common/include/itkMersenneTwisterRandomVariateGenerator.h index 41eeaa135701..1e1d626a3d96 100644 --- a/Modules/Core/Common/include/itkMersenneTwisterRandomVariateGenerator.h +++ b/Modules/Core/Common/include/itkMersenneTwisterRandomVariateGenerator.h @@ -160,6 +160,11 @@ class ITKCommon_EXPORT MersenneTwisterRandomVariateGenerator : public RandomVari static Pointer GetInstance(); + /** Resets the internal data that is used to calculate the next seed. (Does not reset the initial seed.) Allows + * generating a reproducible sequence of pseudo-random numbers. */ + static void + ResetNextSeed(); + /** Length of state vector */ static constexpr IntegerType StateVectorLength = 624; diff --git a/Modules/Core/Common/src/itkMersenneTwisterRandomVariateGenerator.cxx b/Modules/Core/Common/src/itkMersenneTwisterRandomVariateGenerator.cxx index 12d1380ec32c..7edab3c47fdf 100644 --- a/Modules/Core/Common/src/itkMersenneTwisterRandomVariateGenerator.cxx +++ b/Modules/Core/Common/src/itkMersenneTwisterRandomVariateGenerator.cxx @@ -81,6 +81,16 @@ MersenneTwisterRandomVariateGenerator::GetInstance() return m_PimplGlobals->m_StaticInstance; } + +void +MersenneTwisterRandomVariateGenerator::ResetNextSeed() +{ + itkInitGlobalsMacro(PimplGlobals); + const std::lock_guard lockGuard(m_PimplGlobals->m_StaticInstanceLock); + m_PimplGlobals->m_StaticDiffer = 0; +} + + MersenneTwisterRandomVariateGenerator::MersenneTwisterRandomVariateGenerator() { SetSeed(121212); diff --git a/Modules/Core/Common/test/itkMersenneTwisterRandomVariateGeneratorGTest.cxx b/Modules/Core/Common/test/itkMersenneTwisterRandomVariateGeneratorGTest.cxx index 867e6dd3cac4..b99b11dc5c83 100644 --- a/Modules/Core/Common/test/itkMersenneTwisterRandomVariateGeneratorGTest.cxx +++ b/Modules/Core/Common/test/itkMersenneTwisterRandomVariateGeneratorGTest.cxx @@ -59,3 +59,18 @@ TEST(MersenneTwisterRandomVariateGenerator, GetIntegerVariateReturnsSameAsStdMt1 EXPECT_EQ(generator->GetIntegerVariate(), stdMt19937()); } } + + +TEST(MersenneTwisterRandomVariateGenerator, ResetNextSeed) +{ + using GeneratorType = itk::Statistics::MersenneTwisterRandomVariateGenerator; + + const auto globalGenerator = GeneratorType::GetInstance(); + ASSERT_NE(globalGenerator, nullptr); + + GeneratorType::ResetNextSeed(); + const auto nextSeed = globalGenerator->GetNextSeed(); + + GeneratorType::ResetNextSeed(); + EXPECT_EQ(globalGenerator->GetNextSeed(), nextSeed); +}