Opened 10 years ago

Closed 10 years ago

#7779 closed Bugs (fixed)

uniform_on_sphere returns nan in certain (rare) cases

Reported by: Robert Gantner <rngantner@…> Owned by: No-Maintainer
Milestone: To Be Determined Component: random
Version: Boost 1.46.1 Severity: Problem
Keywords: uniform_on_sphere, random Cc:

Description

When simulating random vectors using the boost::uniform_on_sphere distribution with single-precision floating-point numbers, certain realizations are a vector of -nan. For the seed used in the included program, this happens at realization 3802480. The realizations before and after the wrong one are correct (i.e. lie on the unit circle).

I have only found this to happen in two dimensions, although it happens for many different seed values. I have not encountered the problem when using doubles.

Attachments (1)

bug_uniform_on_sphere.cpp (1.5 KB ) - added by Robert Gantner <rngantner@…> 10 years ago.
Program recreating uniform_on_sphere bug.

Download all attachments as: .zip

Change History (6)

by Robert Gantner <rngantner@…>, 10 years ago

Attachment: bug_uniform_on_sphere.cpp added

Program recreating uniform_on_sphere bug.

comment:1 by Robert Gantner <rngantner@…>, 10 years ago

When using double precision, the same program leads to a realization composed of NaN's after 1573458057 realizations.

Btw, there's an error in the program: it uses the default seed of 5489u since the generator is copied (forgot an & after GeneratorType on line 13).

comment:2 by Robert Gantner <rngantner@…>, 10 years ago

The bug seems to be at line 70 of uniform_on_sphere.hpp. The function std::divides attempts to divide by zero if sqsum is zero (or close to it). This results in 0/0=NaN for each component, since sqsum is only zero if all components are zero.

In the case mentioned above for floats, sqsum is zero to 20 decimal places at the 3802480th realization. In higher dimensions the probability of obtaining such a case of course decreases, but that does not solve the problem. A simple solution would be to test if sqsum is too small, but this would be an unnecessary overhead.

A better solution may be to implement the suggestion in ticket 1059, which would allow different algorithms to be used in lower-dimensional cases (where the probability of sampling all zeros is higher) and still retain the current, general implementation in higher dimensions where the probability of this error happening might be negligibly small.

comment:3 by Robert Gantner <rngantner@…>, 10 years ago

Keywords: uniform_on_sphere random added
Summary: uniform_on_sphere returns -nan after many correct realizations when using single-precision floatsuniform_on_sphere returns nan in certain (rare) cases
Version: Boost 1.51.0Boost 1.46.1

comment:4 by Steven Watanabe, 10 years ago

Actually it doesn't matter if sqsum is close to zero. As long as it isn't zero, there is no problem. (I suppose if sqsum were denormalized, it could be a problem, but normal_distribution doesn't produce denormalized numbers. I'm just going to add a test for zero. This shouldn't affect the performance in any noticeable way, since generating normal variates and dividing is much more expensive than a branch that is almost never taken.

comment:5 by Steven Watanabe, 10 years ago

Resolution: fixed
Status: newclosed

(In [82936]) Avoid generating NaNs. Fixes #7779.

Note: See TracTickets for help on using tickets.