From gary Wed Jun 5 10:44:38 1996 From: fischer-michael@CS.YALE.EDU Date: Tue, 4 Jun 96 18:44:20 EDT Subject: Patches to mrandom-3.0 To: Clark Thomborson *** 3.1 1993/05/28 19:25:35 --- bentley.c 1996/06/04 14:51:51 *************** *** 60,66 **** long rngstate[RNGstatesize_2]; { int i, ii; ! long last, next, v[55]; arr[0] = last = seed; next = 1; for (i=1; i < 55; i++) { --- 60,66 ---- long rngstate[RNGstatesize_2]; { int i, ii; ! long last, next; arr[0] = last = seed; next = 1; for (i=1; i < 55; i++) { *** 3.1 1993/05/28 19:25:36 --- mrandom.c 1996/06/04 19:35:53 *************** *** 1,4 **** ! /* mrandom.c 3.1 5/28/93 */ /* * mrandom.c * --- 1,4 ---- ! /* mrandom.c 3.1x 5/31/96, derived from mrandom.c 3.1 5/28/93 */ /* * mrandom.c * *************** *** 27,32 **** --- 27,40 ---- * - Allow choice of algorithms in mrandomrv * - Dynamic allocation of RNGs * + * Version 3.1x: + * Michael Fischer, May 1996 + * - Ported to NeXT; removed unused variables + * - Converted function headers to ISO-C + * - Fixed memory-overwrite bug in scanvector() + * - Fixed state saving/restoring for 4.3bsd random() + * - Cleaned up nextval() and restart_rng(). + * * This material is based upon work supported by the National * Science Foundation under grant number MIP-9023238. The * Government has certain rights in this material. *************** *** 47,57 **** --- 55,71 ---- /*****************/ /* Include files */ /*****************/ + #ifdef NeXT + #include + #else #include /* To allocate space for RNGs*/ + #endif #include /* we need floor() */ #include /* We need FILE */ #include + #ifndef NeXT #include /* We need MAXLONG */ + #endif /*******************************************************/ /* Header files for RNGs currently included in package */ *************** *** 190,197 **** /* fill_buffer */ /* Fill an RNG buffer */ /*************************************/ ! void fill_buffer(rng) ! RNGdata *rng; { long i,j; /* Loop variables */ --- 204,210 ---- /* fill_buffer */ /* Fill an RNG buffer */ /*************************************/ ! void fill_buffer(RNGdata *rng) { long i,j; /* Loop variables */ *************** *** 291,298 **** inc_counts(rng,n) /* Auxiliary routines for 32-bit generators */ ! double longtodouble(l) ! long l; { if (l > 0) return((double)l); --- 304,310 ---- inc_counts(rng,n) /* Auxiliary routines for 32-bit generators */ ! double longtodouble(long l) { if (l > 0) return((double)l); *************** *** 330,341 **** /* drandomrv */ /* Returns doubles */ /*******************/ ! double drandomrv(rng,n,v) ! RNGdata *rng; ! long n; ! double v[]; { - long i; double vdef[1],*vreturn; if (RNGrange > MAXLONG + 1.0) { --- 342,349 ---- /* drandomrv */ /* Returns doubles */ /*******************/ ! double drandomrv(RNGdata *rng, long n, double v[]) { double vdef[1],*vreturn; if (RNGrange > MAXLONG + 1.0) { *************** *** 352,363 **** /* frandomrv */ /* Returns floats */ /******************/ ! float frandomrv(rng,n,v) ! RNGdata *rng; ! long n; ! float v[]; { - long i; float vdef[1],*vreturn; if (RNGrange > MAXLONG + 1.0) { --- 360,367 ---- /* frandomrv */ /* Returns floats */ /******************/ ! float frandomrv(RNGdata *rng, long n, float v[]) { float vdef[1],*vreturn; if (RNGrange > MAXLONG + 1.0) { *************** *** 374,383 **** /* lrandomrv */ /* Returns longs */ /*****************/ ! long lrandomrv(rng,n,v) ! RNGdata *rng; ! long n; ! long v[]; { long vdef[1],*vreturn; --- 378,384 ---- /* lrandomrv */ /* Returns longs */ /*****************/ ! long lrandomrv(RNGdata *rng, long n, long v[]) { long vdef[1],*vreturn; *************** *** 397,406 **** /* i.e. each generate from the underlying*/ /* RNG is used to generate one bit. */ /******************************************/ ! int brandomrv(rng,n,v) ! RNGdata *rng; ! long n; ! int v[]; { long i,j; int vdef[1],*vreturn; --- 398,404 ---- /* i.e. each generate from the underlying*/ /* RNG is used to generate one bit. */ /******************************************/ ! int brandomrv(RNGdata *rng, long n, int v[]) { long i,j; int vdef[1],*vreturn; *************** *** 429,438 **** /* is not 2^32. */ /******************************************/ /* Splitting of this fast bit stream is not currently supported. */ ! int brandomrv_f(rng,n,v) ! RNGdata *rng; ! long n; ! int v[]; { long i,j,r; int vdef[1],*vreturn; --- 427,433 ---- /* is not 2^32. */ /******************************************/ /* Splitting of this fast bit stream is not currently supported. */ ! int brandomrv_f(RNGdata *rng, long n, int v[]) { long i,j,r; int vdef[1],*vreturn; *************** *** 462,475 **** /* dxrandomrv */ /* Returns doubles */ /*******************/ ! double dxrandomrv(rng,n,v) ! RNGdata *rng; ! long n; ! double v[]; { ! long i,j; double vdef[1],*vreturn; - double d; xrandom_setup(); if (RNGreturns == RET_DOUBLE) { --- 457,466 ---- /* dxrandomrv */ /* Returns doubles */ /*******************/ ! double dxrandomrv(RNGdata *rng, long n, double v[]) { ! long j; double vdef[1],*vreturn; xrandom_setup(); if (RNGreturns == RET_DOUBLE) { *************** *** 495,506 **** /* fxrandomrv */ /* Returns floats */ /******************/ ! float fxrandomrv(rng,n,v) ! RNGdata *rng; ! long n; ! float v[]; { ! long i,j; float vdef[1],*vreturn; xrandom_setup(); --- 486,494 ---- /* fxrandomrv */ /* Returns floats */ /******************/ ! float fxrandomrv(RNGdata *rng, long n, float v[]) { ! long j; float vdef[1],*vreturn; xrandom_setup(); *************** *** 527,538 **** /* lxrandomrv */ /* Returns longs */ /*****************/ ! long lxrandomrv(rng,n,v) ! RNGdata *rng; ! long n; ! long v[]; { ! long i,j; long vdef[1],*vreturn; xrandom_setup(); --- 515,523 ---- /* lxrandomrv */ /* Returns longs */ /*****************/ ! long lxrandomrv(RNGdata *rng, long n, long v[]) { ! long j; long vdef[1],*vreturn; xrandom_setup(); *************** *** 559,570 **** /* bxrandomrv */ /* Return "high quality" bits. */ /*******************************/ ! int bxrandomrv(rng,n,v) ! RNGdata *rng; ! long n; ! int v[]; { ! long i,j; int vdef[1],*vreturn; xrandom_setup(); --- 544,552 ---- /* bxrandomrv */ /* Return "high quality" bits. */ /*******************************/ ! int bxrandomrv(RNGdata *rng, long n, int v[]) { ! long j; int vdef[1],*vreturn; xrandom_setup(); *************** *** 597,610 **** * of bits. * Splitting of this fast bit stream is not currently supported. */ ! int bxrandomrv_f(rng,n,v) ! RNGdata *rng; ! long n; ! int v[]; { ! long i,j; int vdef[1],*vreturn; ! long value; long index; inc_counts(rng,n); --- 579,589 ---- * of bits. * Splitting of this fast bit stream is not currently supported. */ ! int bxrandomrv_f(RNGdata *rng, long n, int v[]) { ! long i; int vdef[1],*vreturn; ! long value=0; long index; inc_counts(rng,n); *************** *** 628,636 **** /* seed_rng */ /* Seeds the underlying RNG */ /*************************************/ ! void seed_rng(rng, seed) ! RNGdata *rng; ! long *seed; { long i; --- 607,613 ---- /* seed_rng */ /* Seeds the underlying RNG */ /*************************************/ ! void seed_rng(RNGdata *rng, long *seed) { long i; *************** *** 654,662 **** /* stderr if alg is out of range */ /* Return 1 otherwise */ /*************************************/ ! int setRNGparams(rng,alg) ! RNGdata *rng; ! long alg; { if (alg<0 || alg>NUM_RNGS-1) /* alg is out of range */ return(0); --- 631,637 ---- /* stderr if alg is out of range */ /* Return 1 otherwise */ /*************************************/ ! int setRNGparams(RNGdata *rng, long alg) { if (alg<0 || alg>NUM_RNGS-1) /* alg is out of range */ return(0); *************** *** 677,684 **** /* Check the integrity of the RNG. */ /* Return 1 if ok, 0 if not. */ /*************************************/ ! int check_rng(rng) ! RNGdata *rng; { /* Temporary variables */ long statesize, seedsize; --- 652,658 ---- /* Check the integrity of the RNG. */ /* Return 1 if ok, 0 if not. */ /*************************************/ ! int check_rng(RNGdata *rng) { /* Temporary variables */ long statesize, seedsize; *************** *** 724,732 **** /* Currently only supports RNGs with */ /* at most two seeds. */ /*************************************/ ! char *describe_rng (rng,rngid) ! RNGdata *rng; ! char rngid[RNGIDSTRLEN]; { if (!check_rng(rng)) { BADRNG_ERR; --- 698,704 ---- /* Currently only supports RNGs with */ /* at most two seeds. */ /*************************************/ ! char *describe_rng (RNGdata *rng, char rngid[RNGIDSTRLEN]) { if (!check_rng(rng)) { BADRNG_ERR; *************** *** 750,758 **** /* Exits on error if rng has not */ /* been initialized */ /*************************************/ ! int split_rng(rng,new_value) ! RNGdata *rng; ! long new_value; { if (check_rng(rng)) { if (new_value < 0) --- 722,728 ---- /* Exits on error if rng has not */ /* been initialized */ /*************************************/ ! int split_rng(RNGdata *rng, long new_value) { if (check_rng(rng)) { if (new_value < 0) *************** *** 776,784 **** /* Exits on error if rng has not */ /* been initialized */ /*************************************/ ! int mralg_rng(rng,new_value) ! RNGdata *rng; ! long new_value; { if (check_rng(rng)) { if (new_value == 0 || new_value == 1) { --- 746,752 ---- /* Exits on error if rng has not */ /* been initialized */ /*************************************/ ! int mralg_rng(RNGdata *rng, long new_value) { if (check_rng(rng)) { if (new_value == 0 || new_value == 1) { *************** *** 802,809 **** /* Exits on error if rng has not */ /* been initialized */ /*************************************/ ! double range_rng(rng) ! RNGdata *rng; { if (check_rng(rng)) return(RNGrange); --- 770,776 ---- /* Exits on error if rng has not */ /* been initialized */ /*************************************/ ! double range_rng(RNGdata *rng) { if (check_rng(rng)) return(RNGrange); *************** *** 813,822 **** } /* Auxiliary routine for allocating memory for an RNG */ ! RNGdata *allocate_rng(rng, alg, bufsize) ! RNGdata *rng; ! long alg, bufsize; { if (bufsize <= 0) bufsize=1; if ((rng = (RNGdata *)malloc(sizeof(RNGdata))) == 0) --- 780,788 ---- } /* Auxiliary routine for allocating memory for an RNG */ ! RNGdata *allocate_rng(long alg, long bufsize) { + RNGdata *rng; if (bufsize <= 0) bufsize=1; if ((rng = (RNGdata *)malloc(sizeof(RNGdata))) == 0) *************** *** 931,948 **** * replicating experiments or debugging, it is better to restart an * existing generator (stored in a statefile) than to initialize a new one. */ ! RNGdata *init_rng(alg, mrandom_alg, seed, count1, count2, bufsize) ! long alg; /* The RNG algorithm to use */ ! long mrandom_alg; /* Algorithm to use for mrandom: 0 = Thomborson's slow but unbasied conversion 1 = (int) (m*drandom()) */ ! long *seed; /* Seed */ ! long count1, count2; /* Initial counts */ ! long bufsize; /* Size of buffer */ { RNGdata *rng; double x[64]; /* Temporary vector */ - long i; /* Loop variable */ /* Are count1 and count2 in range? */ if (count1 >= BILLION || count1 < 0 || count2 < 0) { --- 897,914 ---- * replicating experiments or debugging, it is better to restart an * existing generator (stored in a statefile) than to initialize a new one. */ ! RNGdata *init_rng( ! long alg, /* The RNG algorithm to use */ ! long mrandom_alg, /* Algorithm to use for mrandom: 0 = Thomborson's slow but unbasied conversion 1 = (int) (m*drandom()) */ ! long *seed, /* Seed */ ! long count1, /* Initial counts */ ! long count2, ! long bufsize) /* Size of buffer */ { RNGdata *rng; double x[64]; /* Temporary vector */ /* Are count1 and count2 in range? */ if (count1 >= BILLION || count1 < 0 || count2 < 0) { *************** *** 953,959 **** fprintf(stderr, "Warning: this initialization will take a LONG time!\n"); fflush(stderr); } ! if ((rng=allocate_rng(rng,alg,bufsize))==0) return(0); /* Allocate space for the RNG */ seed_rng(rng, seed); /* Seed the RNG */ if (mralg_rng(rng, mrandom_alg) == 0) --- 919,925 ---- fprintf(stderr, "Warning: this initialization will take a LONG time!\n"); fflush(stderr); } ! if ((rng=allocate_rng(alg,bufsize))==0) return(0); /* Allocate space for the RNG */ seed_rng(rng, seed); /* Seed the RNG */ if (mralg_rng(rng, mrandom_alg) == 0) *************** *** 980,989 **** /* Returns 0 if kill failed */ /* Returns 1 otherwise */ /*******************************/ ! int kill_rng(rng) ! RNGdata *rng; { if (check_rng(rng)) { free(RNGstate); free(RNGseed); free(RNGbuffer.lbuf); --- 946,959 ---- /* Returns 0 if kill failed */ /* Returns 1 otherwise */ /*******************************/ ! int kill_rng(RNGdata *rng) { if (check_rng(rng)) { + + /* Special fixup for 4.3bsd random(): deactivate current + state before freeing its memory */ + if (RNGalg == 1) random_deactivate_state(); + free(RNGstate); free(RNGseed); free(RNGbuffer.lbuf); *************** *** 1001,1018 **** /* Return the next lxrandomrv() output */ /* without disturbing the RNG state. */ /***************************************/ ! long nextval(rng) ! RNGdata *rng; { ! static long *state=0; ! long i, r, tcount1, tcount2, retval; ! ! if (state != 0) ! free(state); ! state = (long *)calloc(RNGstatesize,sizeof(long)); ! /* Check that this only allocates the first time */ /* Preserve old RNG state */ tcount1 = RNGcount1; tcount2 = RNGcount2; for (i=0; i