Search code examples
cmathrandomembeddeddistribution

Using a single set of random number generators in a loop


Given the code below, is it possible to modify it so that there's a single set of M "random" numbers for x and y that will "restart" at the beginning of the set for every iteration of i?

What I know I can do is pre-generate an array for x and y of length M but I cannot use arrays because of limited memory. I was thinking of using random numbers with seeds somehow but haven't been able to figure it out.

double sampleNormal()
{
   double u = ((double) rand() / (RAND_MAX)) * 2 - 1;
   double v = ((double) rand() / (RAND_MAX)) * 2 - 1;
   double r = u * u + v * v;
   if (r == 0 || r > 1) return sampleNormal();
   double c = sqrt(-2 * log(r) / r);
   return u * c;
}

...

double x = 0;
double y = 0;
double a = 0;
double f = 100e6;
double t = 0;
double fsamp = 2e9;

for(int i = 0; i < N; i++)
{
    for(int j = 0; j < M; j++)
    {
        x = sampleNormal();
        y = sampleNormal();
        t = j/fsamp;

        a = x*cos(2*pi*f*t)+y*sin(2*pi*f*t);
    }
}

Solution

  • that will "restart" at the beginning of the set for every iteration of i

    was thinking of using random numbers with seeds somehow but haven't been able to figure it out.

    Code could abuse srand()

    // Get some state info from rand() for later.
    unsigned start = rand();
    start = start*(RAND_MAX + 1u) + rand();
    
    for(int i = 0; i < N; i++) {
      // Initialize the random number generator to produce the same sequence.
      srand(42);  // Use your favorite constant.
      for(int j = 0; j < M; j++) {
        x = sampleNormal();
        y = sampleNormal();
        t = j/fsamp;
    
        a = x*cos(2*pi*f*t)+y*sin(2*pi*f*t);
      }
    }
    
    // Re-seed so other calls to `rand()` are not so predictable.
    srand(start);