[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[IMP-dev] Remove uniform_01 from Monte Carlo code



The attached patch removes the code from the Monte Carlo NormalMover::generate_move method that uses boost::uniform_01, and replaces it with code that uses boost::variate_generator instead. This is because uniform_01 takes the random number generator by value rather than reference; thus, it creates a temporary copy of it and doesn't update the generator state (so that every time you call the method, you get the same result, unless you call some other method somewhere which _does_ update the RNG). At least, this is what was happening in the MD code, which also used uniform_01, until I fixed it in r454.

variate_generator in the attached patch takes a reference to the underlying RNG, so *does* update the state. variate_generator seems to be the "official" Boost way to tie a distribution with a random number generator these days anyway.

Comments?

	Ben
--
                      http://salilab.org/~ben/
"It is a capital mistake to theorize before one has data."
	- Sir Arthur Conan Doyle
Index: kernel/src/optimizers/movers/NormalMover.cpp
===================================================================
--- kernel/src/optimizers/movers/NormalMover.cpp	(revision 452)
+++ kernel/src/optimizers/movers/NormalMover.cpp	(working copy)
@@ -26,13 +26,15 @@
 
 void NormalMover::generate_move(float scale)
 {
-  std::vector<Float> center(number_of_float_keys());
-  boost::uniform_01<RandomNumberGenerator> u01(random_number_generator);
   boost::normal_distribution<double> mrng(0, stddev_);
+  boost::variate_generator<RandomNumberGenerator&,
+                           boost::normal_distribution<double> >
+                          sampler(random_number_generator, mrng);
+
   for (unsigned int i = 0; i < number_of_particles(); ++i) {
     for (unsigned int j = 0; j < number_of_float_keys(); ++j) {
       float c = get_float(i, j);
-      float r = mrng(u01);
+      float r = sampler();
       // Check for NaN (x!=x when x==NaN) (can only use std::isnan with C99)
       IMP_assert(r == r, "Bad random");
       IMP_assert(c == c, "Bad stored");