Opened 15 years ago

Closed 15 years ago

Last modified 15 years ago

#904 closed Bugs (Rejected)

random::normal_distribution

Reported by: mcbeth Owned by: jmaurer
Milestone: Component: random
Version: None Severity:
Keywords: Cc:

Description

random::normal_distribution always returns a NaN when presented with a UniformRandomNumberGenerator that provides values outside the range of (0,1).

So, for example, this will print a NaN.

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

int main(int argc, char *argv[])
{
        boost::mt19937 eng(40);
        boost::normal_distribution<> norm(0,1);
        std::cout << norm(eng) << std::endl;
}

Looking at the code, it is clear that for normal_distribution's answers to be defined, the values need to be in the range (0,1)

The attached patch uses uniform_real to restrict the range to [0,1).  Unfortunately, this leaves 0 as a fail point.  I don't see a clear way to fix that at the moment.

Change History (3)

comment:1 by jmaurer, 15 years ago

Status: assignedclosed
Logged In: YES 
user_id=53943
Originator: NO

Use a variate_generator<> to do the right thing here, see http://www.boost.org/libs/random/index.html 

Furthermore, at least since boost 1.33.1, the template parameter for normal_distribution<> has been named "Engine" in the source code (not in the documentation).  I agree that the documentation should mention that you must plug in an engine with a [0,1) range if you want to use the distribution standalone.

I have updated the documentation in the CVS accordingly.

comment:2 by daniel_kruegler, 15 years ago

Logged In: YES 
user_id=1540640
Originator: NO

Since I gave submitter the advice to report this as bug, I
would like to ask the following question:

Obviously the current standard proposal for random number generation, 
N2134, strongly bases on original boost code. But since then the interface 
has drastically changed compared to the boost interface, which has lead to 
my assignment as a bug. 

Are there already ideas how to resolve the forseeable problems which will 
occur once programmers get used to upcoming standard nomenclature (provided 
it remains as currently written) but will apply these to the Boost Random 
Number Library? 

The most severe problems are probably that the names are essentially equal, 
but semantic changes drastically.
What about the idea to provide e.g. two mutually exclusive (via SFINAE) 
operator() overloads for random number distributions (in the sense of N2134):
One overload would be activated, if it's argument fulfills 
UniformRandomNumberGenerator (at least the most simple requirement: 
X::result_type is an unsigned integer type). The other would be interpreted
as boost engine. It would probably make sense to mark the second one as 
deprecated once the standard interface is accepted.


comment:3 by jmaurer, 15 years ago

Logged In: YES 
user_id=53943
Originator: NO

Yes, TR1 random numbers are heavily based on boost.random.

However, TR1 does place the requirement on Engines that they only return values in the range [0,1).
See section 5.1.1p9 of TR1:

"... If std::numeric_limits<X::input_type>::is_integer is false, the value of e.min() shall be 0 and the value of e.max() shall be 1."

And 5.1.1p6 of TR1 says
"In table 17, X denotes a random distribution class returning objects of type T, u is a value of X, x is a (possibly const) value of X, e is an lvalue of an arbitrary type that meets the requirements of a uniform random number generator, returning values of type U, ..."

And table 17 of TR1 associates X::input_type with "U", the type returned by the engine e.

The result is that if a distribution specifies a floating-point input_type, you should plug in an Engine that returns floating-point values in the range [0,1), otherwise you're violating the interface requirements.

Subtly cool, eh?  :-)
Note: See TracTickets for help on using tickets.