diff --git a/Modules/Core/Common/include/itkMersenneTwisterRandomVariateGenerator.h b/Modules/Core/Common/include/itkMersenneTwisterRandomVariateGenerator.h index 41eeaa13570..1e1d626a3d9 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 12d1380ec32..7edab3c47fd 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 867e6dd3cac..b99b11dc5c8 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); +}