From: Brad King <brad.king@ki...> - 2005-01-17 23:20:02
Recent problems in ITK have exposed a few weaknesses in vnl_sample.cxx.
This source has two implementations. One uses drand48 if it is
available, and the other is a hand-coded implementation. There are a
couple problems here:
1.) The hand-coded implementation is not thread-safe. This is probably
okay because drand48 is not necessarily thread safe on all systems
anyway. However, this could be stated in the documentation if we don't
want to try to fix it.
2.) vnl_sample_uniform uses drand48 without making sure that srand48 has
been called. According to the documentation on at least some platforms,
one is always supposed to use srand48 to seed the generator before using
drand48. On Cygwin the default initialization seems to always generate
zeros from calling drand48.
Somehow I need to fix #2. We could just state in the documentation that
one must always call vnl_sample_reseed before calling
vnl_sample_uniform, but that is not very C++-ish. It is possible to
simply create a static instance of a class in the file whose constructor
initializes the seed to zero. This will work for generating random
numbers in the main thread only. Cygwin's reentrant implementation of
drand48 uses a separate seed for each thread. Creating a new thread
leaves the generator uninitialized, so it looks like calling srand48
before drand48 must be done in each thread!
From: Ian Scott <ian.scott@st...> - 2005-01-18 10:33:47
Brad King wrote:
> Recent problems in ITK have exposed a few weaknesses in vnl_sample.cxx.
> This source has two implementations. One uses drand48 if it is
> available, and the other is a hand-coded implementation. There are a
> couple problems here:
Solution: Don't use vnl_sample, use vnl_random.
IMO we should deprecate vnl_sample in favour of vnl_random.
1) vnl_sample uses shared (program) global state, vnl_random's state is
local to the vnl_random object.
2) vnl_sample produces a different pseudo-random number sequence on
different platforms. vnl_random produces the same sequence (given the
same seed.) This makes it very useful for cross-platform testing
3) In some circumstances (i.e. when using some libc provided rand*()
functions, the cycle length is small enough for a program to get
repeats. vnl_random's cycle length is 10^354.
4) vnl_random has undergone massive in-use testing by the statistical
image modeling group in ISBE, Manchester, for the past ten years or so.
The code also easily passed at least one rigorous investigation of its
> The SF.Net email is sponsored by: Beat the post-holiday blues
> Get a FREE limited edition SourceForge.net t-shirt from ThinkGeek.
> It's fun and FREE -- well, almost....http://www.thinkgeek.com/sfshirt
> Vxl-maintainers mailing list
From: Brad King <brad.king@ki...> - 2005-01-18 12:46:49
Ian Scott wrote:
> IMO we should deprecate vnl_sample in favour of vnl_random.
I agree. Object-based generators are always better than global-state
generators for the reasons you mentioned and for thread safety. I'm
willing to implement the deprecation changes, but someone will need to
let me know how the deprecation mechanism works.