From: Brad K. <bra...@ki...> - 2005-01-17 23:20:02
|
Hello, 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! Comments? -Brad |
From: Ian S. <ian...@st...> - 2005-01-18 10:33:47
|
Brad King wrote: > Hello, > > 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: <snip> > Comments? Solution: Don't use vnl_sample, use vnl_random. IMO we should deprecate vnl_sample in favour of vnl_random. Reasons. 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 probabilistic code. 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 randomness. Ian. > -Brad > > > ------------------------------------------------------- > 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 > Vxl...@li... > https://lists.sourceforge.net/lists/listinfo/vxl-maintainers > |
From: Brad K. <bra...@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. -Brad |