retrieving random number generator state and other RNG questions

Discussion in 'C++' started by ilias, Jul 26, 2006.

  1. ilias

    ilias Guest

    Hi,

    I am running a C++ code in multiple environments/clusters. Until now I
    was using the standart rand() function as RNG. The problem is that I
    want to be able to stop my code and start it again every now and then
    (i.e. to have checkpoints), and to do that I need the state of the RNG
    to reseed it. Reading the rand() code (in "Numerical Recipes in C") I
    understand this is not possible. Am I right ?

    So I am trying to make a RNG that is fast, compatible in windows, linux
    and darwin, and at least of equal statistical value as rand() - I know,
    hard to beat :) -. The following code works in windows, but not quite
    in linux. More specifically, (a)it produces a -1 as the first random
    number, then the same 9 numbers as in windows and (b) any attempt to
    reseed it fails.

    Any help would be greatly appreciated. Thanks!
    ilias

    CODE:
    ************************************************
    #include <iostream>
    #include <stdlib.h>
    #include <stdio.h>
    using namespace::std;

    static unsigned long jflone = 0x3f800000;
    static unsigned long jflmsk = 0x007fffff;
    unsigned long idum,itemp;

    double my_rand(){
    idum = 1664525L*idum + 1013904223L;
    itemp = (jflone | (jflmsk & idum)); //(*)
    return( *(float *)&itemp)-1.0;
    };
    void my_srand(unsigned int seed){idum = seed;};

    void main()
    {
    int i;
    my_srand(0);
    for (i=0;i<10;i++)
    {
    my_rand();
    cout << my_rand() <<"\n";
    }

    unsigned int temp;
    temp =idum;
    cout << "\nidum is " << idum << " and temp is " << temp ;
    cout << "\nnext number would be " <<my_rand() <<" and next idum
    " << idum;
    my_srand(temp);
    cout << "\nafter init.srand idum is " << idum << " random
    number is " << my_rand() << " and new idum " << idum;

    *************************************************************************

    LINUX OUTPUT:
    -1
    0.626257
    0.947852
    0.365433
    0.698232
    0.880344
    0.633586
    0.179411
    0.552378
    0.577698
    idum is 2768872580 and temp is 2768872580
    next number would be 0.0753331 and next idum 2254235155
    after init.srand idum is 2254235155 random number is 0.725771 and new
    idum 2254235155846930886
     
    ilias, Jul 26, 2006
    #1
    1. Advertising

  2. ilias wrote:
    > I am running a C++ code in multiple environments/clusters. Until now I
    > was using the standart rand() function as RNG. The problem is that I
    > want to be able to stop my code and start it again every now and then
    > (i.e. to have checkpoints), and to do that I need the state of the RNG
    > to reseed it. Reading the rand() code (in "Numerical Recipes in C") I
    > understand this is not possible. Am I right ?
    >
    > So I am trying to make a RNG that is fast, compatible in windows,
    > linux and darwin, and at least of equal statistical value as rand() -
    > I know, hard to beat :) -. The following code works in windows, but
    > not quite in linux. More specifically, (a)it produces a -1 as the
    > first random number, then the same 9 numbers as in windows and (b)
    > any attempt to reseed it fails.
    >
    > Any help would be greatly appreciated. Thanks!
    > ilias
    >
    > CODE:
    > ************************************************
    > #include <iostream>
    > #include <stdlib.h>
    > #include <stdio.h>
    > using namespace::std;
    >
    > static unsigned long jflone = 0x3f800000;
    > static unsigned long jflmsk = 0x007fffff;
    > unsigned long idum,itemp;
    >
    > double my_rand(){
    > idum = 1664525L*idum + 1013904223L;
    > itemp = (jflone | (jflmsk & idum)); //(*)
    > return( *(float *)&itemp)-1.0;


    This cast to float is bogus. Try casting to 'double'. On your
    Linux, it's possible that 'unsigned long' is larger in size than
    'float' (on Windows it's the same).

    Generally speaking, you should avoid casts like that (and especially
    when posting here). The behaviour of code that uses such casts is
    undefined in Standard C++, so you're on your own when you try using
    them.

    > };
    > void my_srand(unsigned int seed){idum = seed;};
    >
    > void main()


    int main()

    > {
    > int i;
    > my_srand(0);
    > for (i=0;i<10;i++)
    > {
    > my_rand();
    > cout << my_rand() <<"\n";
    > }
    >
    > unsigned int temp;
    > temp =idum;
    > cout << "\nidum is " << idum << " and temp is " << temp ;
    > cout << "\nnext number would be " <<my_rand() <<" and next idum
    > " << idum;
    > my_srand(temp);
    > cout << "\nafter init.srand idum is " << idum << " random
    > number is " << my_rand() << " and new idum " << idum;
    >
    > *************************************************************************
    >
    > LINUX OUTPUT:
    > -1
    > 0.626257
    > 0.947852
    > 0.365433
    > 0.698232
    > 0.880344
    > 0.633586
    > 0.179411
    > 0.552378
    > 0.577698
    > idum is 2768872580 and temp is 2768872580
    > next number would be 0.0753331 and next idum 2254235155
    > after init.srand idum is 2254235155 random number is 0.725771 and new
    > idum 2254235155846930886


    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Jul 26, 2006
    #2
    1. Advertising

  3. ilias

    osmium Guest

    "ilias" writes:

    > I am running a C++ code in multiple environments/clusters. Until now I
    > was using the standart rand() function as RNG. The problem is that I
    > want to be able to stop my code and start it again every now and then
    > (i.e. to have checkpoints), and to do that I need the state of the RNG
    > to reseed it. Reading the rand() code (in "Numerical Recipes in C") I
    > understand this is not possible. Am I right ?


    That's right. Any generator that doesn't have internal state would be
    unable to produce and return any number more than once.

    <snip code>

    (I don't like global variables unless they are serve a purpose, yours don't,
    so why bother fixing something when starting over is probably a better
    idea?)

    I would find code for a generator I like, I see such code on the net and it
    is not hard to find. I would put it in a class that was able to return the
    internal state via a member function on demand.
     
    osmium, Jul 26, 2006
    #3
  4. ilias

    Jerry Coffin Guest

    In article <>,
    says...
    > I am running a C++ code in multiple environments/clusters. Until now I
    > was using the standart rand() function as RNG. The problem is that I
    > want to be able to stop my code and start it again every now and then
    > (i.e. to have checkpoints), and to do that I need the state of the RNG
    > to reseed it. Reading the rand() code (in "Numerical Recipes in C") I
    > understand this is not possible. Am I right ?


    With the version of rand() in the standard library, yes, that's
    correct. I'd consider something along these lines:

    #include <iostream>

    class PRNG {
    mutable unsigned long seed;
    static const unsigned long max = 0xffffffff;

    unsigned long rand_() const {
    seed = (seed * 314159269 + 1) & max;
    return seed;
    }

    public:
    PRNG(unsigned long s=0) : seed(s) {}

    double rand() const {
    return rand_() / static_cast<double>(max);
    }

    friend operator<<(std::eek:stream &os, PRNG const &p) {
    os << p.seed;
    }

    friend operator>>(std::istream &is, PRNG &p) {
    is >> p.seed;
    }
    };

    #ifdef TEST
    #include <time.h>

    int main() {

    PRNG p(time(NULL));

    for (int i=0; i<10; i++)
    std::cout << p.rand() << std::endl;
    return 0;
    }

    #endif

    --
    Later,
    Jerry.

    The universe is a figment of its own imagination.
     
    Jerry Coffin, Jul 26, 2006
    #4
  5. ilias

    ilias Guest

    Thanks for your suggestions. Just a follow up with the problem.
    You were right to bring the casting issue up, although this was not the
    problem and I was initially casting to double. Jerry's code is nice but
    slower than what I wanted.

    So the problem I was having was not in the code itself but on the -O3
    compiler attribute. without it (g++ -o foo foo.cpp -lm) it works fine.
    Does anyone know what is messed up when optimization is on?
     
    ilias, Jul 27, 2006
    #5
  6. ilias

    Pete Becker Guest

    ilias wrote:
    >
    > I am running a C++ code in multiple environments/clusters. Until now I
    > was using the standart rand() function as RNG. The problem is that I
    > want to be able to stop my code and start it again every now and then
    > (i.e. to have checkpoints), and to do that I need the state of the RNG
    > to reseed it. Reading the rand() code (in "Numerical Recipes in C") I
    > understand this is not possible. Am I right ?
    >


    The rand code in Numerical Recipes may or may not be like the code used
    to implement rand in your standard library. For checkpoints you really
    need the random number generators in TR1, which will also be part of the
    next version of the C++ standard. You can find documentation for the
    various random number generators in TR1 at
    http://www.dinkumware.com/manuals/?manual=compleat&page=random.html. For
    a more detailed discussion, see my book, "The C++ Standard Library
    Extensions", coming soon to a bookstore near you. It's a tutorial and
    reference for all of TR1.
     
    Pete Becker, Jul 27, 2006
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Kingsley Oteng

    Random Number Generator??

    Kingsley Oteng, Apr 27, 2004, in forum: VHDL
    Replies:
    11
    Views:
    52,692
    rahul.iyer
    Aug 9, 2010
  2. Joe
    Replies:
    2
    Views:
    492
    Howard
    Nov 19, 2004
  3. globalrev
    Replies:
    4
    Views:
    796
    Gabriel Genellina
    Apr 20, 2008
  4. Francois Grieu
    Replies:
    7
    Views:
    454
    Ben Bacarisse
    Apr 8, 2009
  5. VK
    Replies:
    15
    Views:
    1,279
    Dr J R Stockton
    May 2, 2010
Loading...

Share This Page