double unitrand (double randfn(void)) { /* --- compute N(0,1) distrib. number */ static double b; /* buffer for random number */ double x, y, r; /* coordinates and radius */ if (b != 0.0) { /* if the buffer is full, */ x = b; b = 0; return x; } /* return the buffered number */ do { /* pick a random point */ x = 2.0*randfn()-1.0; /* in the unit square [-1,1]^2 */ y = 2.0*randfn()-1.0; /* and check whether it lies */ r = x*x +y*y; /* inside the unit circle */ } while ((r > 1) || (r == 0)); r = sqrt(-2*log(r)/r); /* factor for Box-Muller transform */ b = x *r; /* save one of the random numbers */ return y *r; /* and return the other */ } /* unitrand() */
void v_shuffle (void *vec, int n, double randfn (void)) { /* --- shuffle vector entries */ int i; /* vector index */ void **v = vec, *t; /* vector and exchange buffer */ while (--n > 0) { /* shuffle loop (n random selections) */ i = (int)((n+1) *randfn()); /* compute a random index */ if (i > n) i = n; /* in the remaining section and */ if (i < 0) i = 0; /* exchange the vector elements */ t = v[i]; v[i] = v[n]; v[n] = t; } } /* v_shuffle() */