Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MixMax RNG with variate_generator returns constant values when initialised with seed = 0 #104

Open
andrjohns opened this issue May 17, 2024 · 2 comments

Comments

@andrjohns
Copy link

When the mixmax RNG is initialised with a seed of 0 and used with variate_generator, repeated calls always produce the same value:

Reproducible example (here on godbolt):

#include <boost/random.hpp>
#include <iostream>

int main() {
  using boost::normal_distribution;
  using boost::random::uniform_real_distribution;
  using boost::variate_generator;
  using boost::random::mixmax;

  mixmax rng(0);
  variate_generator<mixmax&, normal_distribution<> > norm_rng(rng, normal_distribution<>(5, 10));
  variate_generator<mixmax&, uniform_real_distribution<> > unif_rng(rng, uniform_real_distribution<>(5.0, 10.0));

  for (size_t i = 0; i < 5; ++i) {
    std::cout   << "Normal(5,10): " << norm_rng() << "\n"
                << "Uniform(5,10): " << unif_rng() << "\n";
  }
    std::cout << std::endl;
    return 0;
}

Returns:

Normal(5,10): 5
Uniform(5,10): 5
Normal(5,10): 5
Uniform(5,10): 5
Normal(5,10): 5
Uniform(5,10): 5
Normal(5,10): 5
Uniform(5,10): 5
Normal(5,10): 5
Uniform(5,10): 5
@mborland
Copy link
Member

@kotika Does a check need to be added to ensure the user gives a non-zero seed? We could throw std::range_error saying the value has to be [1, UINT32/64_MAX]

@WardBrian
Copy link

This seems to be the case only when the 4-argument version is called with all zeros. If the line

///< constructor, one uint64_t seed, random numbers are statistically independent from any two distinct seeds, e.g. consecutive seeds are ok
seed_uniquestream( &S, 0, 0, (uint32_t)(seedval>>32), (uint32_t)seedval );

was updated to e.g. seed_uniquestream( &S, 0, 1, (uint32_t)(seedval>>32), (uint32_t)seedval );

Then the issue appears to go away

https://arxiv.org/pdf/1403.5355 includes the line

For the purposes of generating pseudo-random numbers with this method, one chooses the initial vector u(0), called the “seed”, with at least one non-zero component

(emphasis mine), which seems to imply any restriction should just be on the full four-argument form. The uint64_t overload could be made to never have an invalid value if at least one of the two other arguments were nonzero, I believe.

My question is if the statement "random numbers are statistically independent from any two distinct seeds, e.g. consecutive seeds are ok" remains true in this case.

Several other implementations do seem to trap the seed being 0:
https://github.com/ramos/mxmx/blob/master/src/mixmax.f90#L180-L181
https://root.cern/doc/master/mixmax_8icc_source.html#l00212

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants