Hello all,
One of the functions I use in my code is a modified form of a module in the GNU Scientific Library, which follows this post.
Note that the "seed" for the random number sequence is contained in the variables x_ran2, y_ran2, n_ran2, shuffle_ran2.
Now, this is a module, so... these should be static, right? And I thought they were... which was why it was a bit of a shock to come back to the code and find they weren't.
However, there is no clear sign from my program results that the random number generators haven't been working. Is there a reason why the values for these variables should have been preserved despite their not being labelled as static?
I use the compile command,
[tt]gcc -O3 -march=pentium-m -mtune=pentium-m -ansi -pedantic -Wall[/tt]
Any ideas?
Many thanks,
-- Joe
One of the functions I use in my code is a modified form of a module in the GNU Scientific Library, which follows this post.
Note that the "seed" for the random number sequence is contained in the variables x_ran2, y_ran2, n_ran2, shuffle_ran2.
Now, this is a module, so... these should be static, right? And I thought they were... which was why it was a bit of a shock to come back to the code and find they weren't.
However, there is no clear sign from my program results that the random number generators haven't been working. Is there a reason why the values for these variables should have been preserved despite their not being labelled as static?
I use the compile command,
[tt]gcc -O3 -march=pentium-m -mtune=pentium-m -ansi -pedantic -Wall[/tt]
Any ideas?
Many thanks,
-- Joe
Code:
/* gsl-_ran2.c
*
* This progam is a modified version of the rng/ran2.c code in the GNU
* Scientific Library (GSL), version 1.7. It will stand alone as a
* module and does not need any code other than is contained herein!
* -- Joseph Rushton Wakeling, 2005
*
* Copyright (C) 1996, 1997, 1998, 1999, 2000 James Theiler, Brian Gough
* Copyright (C) 2005 Joseph Rushton Wakeling
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WAR[URL unfurl="true"]http://www.novell.com/linux/RANTY;[/URL] without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/* This is an implementation of the algorithm used in Numerical
Recipe's ran2 generator. It is a L'Ecuyer combined recursive
generator with a 32-element shuffle-box.
As far as I can tell, in general the effects of adding a shuffle
box cannot be proven theoretically, so the period of this generator
is unknown.
The period of the underlying combined generator is O(2^60). */
static const long int m1_ran2 = 2147483563, a1_ran2 = 40014, q1_ran2 = 53668, r1_ran2 = 12211;
static const long int m2_ran2 = 2147483399, a2_ran2 = 40692, q2_ran2 = 52774, r2_ran2 = 3791;
static const double z_max_ran2 = 1 - 1.2e-7f ; /* Numerical Recipes version of 1-FLT_EPS */
#define N_SHUFFLE 32
#define N_DIV (1 + 2147483562/N_SHUFFLE)
unsigned long int x_ran2;
unsigned long int y_ran2;
unsigned long int n_ran2;
unsigned long int shuffle_ran2[N_SHUFFLE];
static unsigned long int
ran2_get (void) {
long int h1 = x_ran2 / q1_ran2;
long int t1 = a1_ran2 * (x_ran2 - h1 * q1_ran2) - h1 * r1_ran2;
long int h2 = y_ran2 / q2_ran2;
long int t2 = a2_ran2 * (y_ran2 - h2 * q2_ran2) - h2 * r2_ran2;
if (t1 < 0)
t1 += m1_ran2;
if (t2 < 0)
t2 += m2_ran2;
x_ran2 = t1;
y_ran2 = t2;
{
unsigned long int j = n_ran2 / N_DIV;
long int delta = shuffle_ran2[j] - t2;
if (delta < 1)
delta += m1_ran2 - 1;
n_ran2 = delta;
shuffle_ran2[j] = t1;
}
return(n_ran2);
}
double
ran2_get_double (void) {
double z = ran2_get() / 2147483563.0f ;
if (z > z_max_ran2)
return(z_max_ran2);
return(z);
}
void
ran2_set (unsigned long int s)
{
int i;
if (s == 0)
s = 1; /* default seed is 1 */
y_ran2 = s;
for (i = 0; i < 8; i++) {
long int h = s / q1_ran2;
long int t = a1_ran2 * (s - h * q1_ran2) - h * r1_ran2;
if (t < 0)
t += m1_ran2;
s = t;
}
for (i = N_SHUFFLE - 1; i >= 0; i--) {
long int h = s / q1_ran2;
long int t = a1_ran2 * (s - h * q1_ran2) - h * r1_ran2;
if (t < 0)
t += m1_ran2;
s = t;
shuffle_ran2[i] = s;
}
x_ran2 = s;
n_ran2 = s;
return;
}