Boost logo

Boost Users :

Subject: [Boost-users] [Random] uniform_real, min/max at end of value range
From: Ruediger Berlich (ruediger.berlich_at_[hidden])
Date: 2010-09-08 10:37:48


Hi there,

from what I can see, uniform_real(min,max) essentially does this:

fp_type result = uniform_fp_between_0_and_1 * (max - min) + min; // (1)

(1) will fail e.g. if the distance between min and max is >
std::numeric_limits<fp_type>::max()

While writing unit tests for my code I have come across exactly this
situation. My application would not suffer much from reducing the allowed
value range for my variables to < +/-0.5*std::numeric_limits<fp_type>::max()
. However I feel that this would be a bit artificial.

Hence I was wondering whether code like the following made more sense
(although it is certainly not as efficient):

/**********************************************************/

fp_type uniform_real(const fp_type& min, const fp_type& max) {
   // Check that min and max have appropriate values
  assert(min<=max);
  
  if(min >= fp_type(0.) || max <= fp_type(0.)) { // (max-min) is valid
     return uniform_01() * (max - min) + min;
  } else { // Some values will fail (max-min)
     // We know: min<0., max>0.
     assert(min<0);
     assert(max>0);

     // Calculate a random number in the range [0,1[
     fp_type fraction = uniform_01();

     // Calculate the fraction of the distance of min from 0.
     volatile fp_type minFraction = -fraction*min;
     // Calculate the fraction of the distance of max from 0.
     volatile fp_type maxFraction = fraction*max; //

     // The start of the scale
     volatile fp_type result = min + minFraction;

     // Add maxFraction to the result.
     result += maxFraction;

     return result;
  }
}

/**********************************************************/

Essentially, in cases where (max-min) could be larger than the allowed value
range, the distance to 0 of each max and min is individually multiplied with
a fp random number in the range [0,1[ . The resulting values are then added
seperately to min. There should be no situation where an attempt is made to
create a value larger than the allowed value range ... unless the compiler
optimizes this to "result=min+minFraction+maxFraction;" or worse. volatile
might or might not prevent this, I am not sure (seems to work with g++
4.4.3, though).

What is your view on this ? Are there different/better approaches in Boost
that I could use ?

Best Regards,
Ruediger


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net