#! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh 'READMEC' <<'END_OF_FILE' XREADMEC for zufall random number package (C version) X------- --- ------ ------ ------ ------- XThis package contains a portable random number generator set Xfor: uniform (u in [0,1)), normal ( = 0, = 1), and XPoisson distributions. The basic module, the uniform generator, Xuses a lagged Fibonacci series generator: X X t = u(n-273) + u(n-607) X u(n) = t - float(int(t)) X Xwhere each number generated, u(k), is floating point. Since Xthe numbers are floating point, the left end boundary of the Xrange contains zero. This package is portable except that Xthe test package contains some machine dependent timing data. XThese are cycle times (in seconds) for NEC SX-3, Fujitsu VP2200, XCray Y-MP, and Sun-4. Select your favorite and comment out the Xothers. There are also vectorization directives for Cray Y-MP Xmachines in the form of "pragma _CRI", which should be ignored Xalthough perhaps complained about by other compilers. Otherwise Xthe package is portable and returns the same set of floating Xpoint numbers up to word precision on any machine. X XExternal documentation, "Lagged Fibonacci Random Number Generators Xfor the NEC SX-3," is to be published in the International XJournal of High Speed Computing (1994). Otherwise, ask the Xauthor: X X W. P. Petersen X IPS, RZ F-5 X ETHZ X CH 8092, Zurich X Switzerland X Xe-mail: wpp@ips.ethz.ch. X XThe package contains the following routines: X X------------------------------------------------------ XUNIFORM generator routines: X X int zufalli_(seed) X int seed; X/* initializes struct containing seeds. if seed=0, X the default value is 1802. */ X X int zufall_(n,u) X int n; X double u[n]; X/* returns set of n uniforms u[0], ..., u[n-1]. */ X X int zufallsv_(zusave) X double zusave[608]; X/* saves buffer and pointer in zusave, for later restarts */ X X int zufallrs_(zusave) X double zusave[608]; X/* restores seed buffer and pointer from zusave */ X------------------------------------------------------ X XNORMAL generator routines: X X int normalen_(n,g) X int n; X double g[n]; X/* returns set of n normals g[0], ..., g[n-1] such that X mean = 0, and variance = 1. */ X X int normalsv_(normsv) X double normsv[1634]; X/* saves zufall seed buffer and pointer in normsv X buffer/pointer for normalen restart also in normsv */ X X int normalrs_(normsv) X double normsv[1634]; X/* restores zufall seed buffer/pointer and X buffer/pointer for normalen restart from normsv */ X------------------------------------------------------ X XPOISSON generator routine: X X int fische_(n,mu,q) X integer n,q[n]; X double mu; X/* returns set of n integers q, with poisson X distribution, density p(q,mu) = exp(-mu) mu**q/q! X X USE zufallsv and zufallrs for stop/restart sequence */ X X----------------- END READMEC ------------------------ X------------------------------------------------------ END_OF_FILE if test 2984 -ne `wc -c <'READMEC'`; then echo shar: \"'READMEC'\" unpacked with wrong size! fi # end of 'READMEC' fi if test -f 'zufall.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'zufall.c'\" else echo shar: Extracting \"'zufall.c'\" \(17299 characters\) sed "s/^X//" >'zufall.c' <<'END_OF_FILE' X/* Common Block Declarations */ X Xstruct klotz0_1_ { X double buff[607]; X int ptr; X}; X X#define klotz0_1 (*(struct klotz0_1_ *) &klotz0_) X#define min(a,b) (a buff case */ X vl = 273; X k273 = 334; X k607 = 0; X for (k = 0; k < 3; ++k) { X#pragma _CRI ivdep X for (i = 0; i < vl; ++i) { X t = klotz0_1.buff[k273+i]+klotz0_1.buff[k607+i]; X klotz0_1.buff[k607+i] = t - (double) ((int) t); X } X k607 += vl; X k273 += vl; X vl = 167; X if (k == 0) { X k273 = 0; X } X } X goto L1; X } X } else { X X/* more than 1 full segment */ X X kptr = klotz0_1.ptr; X#pragma _CRI ivdep X for (i = 0; i < left; ++i) { X a[i + aptr] = klotz0_1.buff[kptr + i]; X } X nn -= left; X klotz0_1.ptr = 0; X aptr += left; X X/* buff -> a(aptr0) */ X X vl = 273; X k273 = 334; X k607 = 0; X for (k = 0; k < 3; ++k) { X if (k == 0) { X#pragma _CRI ivdep X for (i = 0; i < vl; ++i) { X t = klotz0_1.buff[k273+i]+klotz0_1.buff[k607+i]; X a[aptr + i] = t - (double) ((int) t); X } X k273 = aptr; X k607 += vl; X aptr += vl; X vl = 167; X } else { X#pragma _CRI ivdep X for (i = 0; i < vl; ++i) { X t = a[k273 + i] + klotz0_1.buff[k607 + i]; X a[aptr + i] = t - (double) ((int) t); X } X k607 += vl; X k273 += vl; X aptr += vl; X } X } X nn += -607; X X/* a(aptr-607) -> a(aptr) for last of the q-1 segments */ X X aptr0 = aptr - 607; X vl = 607; X X for (qq = 0; qq < q-2; ++qq) { X k273 = aptr0 + 334; X#pragma _CRI ivdep X for (i = 0; i < vl; ++i) { X t = a[k273 + i] + a[aptr0 + i]; X a[aptr + i] = t - (double) ((int) t); X } X nn += -607; X aptr += vl; X aptr0 += vl; X } X X/* a(aptr0) -> buff, last segment before residual */ X X vl = 273; X k273 = aptr0 + 334; X k607 = aptr0; X bptr = 0; X for (k = 0; k < 3; ++k) { X if (k == 0) { X#pragma _CRI ivdep X for (i = 0; i < vl; ++i) { X t = a[k273 + i] + a[k607 + i]; X klotz0_1.buff[bptr + i] = t - (double) ((int) t); X } X k273 = 0; X k607 += vl; X bptr += vl; X vl = 167; X } else { X#pragma _CRI ivdep X for (i = 0; i < vl; ++i) { X t = klotz0_1.buff[k273 + i] + a[k607 + i]; X klotz0_1.buff[bptr + i] = t - (double) ((int) t); X } X k607 += vl; X k273 += vl; X bptr += vl; X } X } X goto L1; X } X} /* zufall_ */ X X Xint zufalli_(seed) Xint seed; X{ X /* Initialized data */ X X int kl = 9373; X int ij = 1802; X X /* Local variables */ X int i, j, k, l, m; X double s, t; X int ii, jj; X X X/* generates initial seed buffer by linear congruential */ X/* method. Taken from Marsaglia, FSU report FSU-SCRI-87-50 */ X/* variable seed should be 0 < seed <31328 */ X X X if (seed != 0) { X ij = seed; X } X X i = ij / 177 % 177 + 2; X j = ij % 177 + 2; X k = kl / 169 % 178 + 1; X l = kl % 169; X for (ii = 0; ii < 607; ++ii) { X s = 0.; X t = .5; X for (jj = 1; jj <= 24; ++jj) { X m = i * j % 179 * k % 179; X i = j; X j = k; X k = m; X l = (l * 53 + 1) % 169; X if (l * m % 64 >= 32) { X s += t; X } X t *= (double).5; X } X klotz0_1.buff[ii] = s; X } X return 0; X} /* zufalli_ */ X X Xint zufallsv_(svblk) Xdouble *svblk; X{ X int i; X X X/* saves common blocks klotz0, containing seeds and */ X/* pointer to position in seed block. IMPORTANT: svblk must be */ X/* dimensioned at least 608 in driver. The entire contents */ X/* of klotz0 (pointer in buff, and buff) must be saved. */ X X X /* Function Body */ X svblk[0] = (double) klotz0_1.ptr; X#pragma _CRI ivdep X for (i = 0; i < 607; ++i) { X svblk[i + 1] = klotz0_1.buff[i]; X } X X return 0; X} /* zufallsv_ */ X Xint zufallrs_(svblk) Xdouble *svblk; X{ X int i; X X X/* restores common block klotz0, containing seeds and pointer */ X/* to position in seed block. IMPORTANT: svblk must be */ X/* dimensioned at least 608 in driver. The entire contents */ X/* of klotz0 must be restored. */ X X X klotz0_1.ptr = (int) svblk[0]; X#pragma _CRI ivdep X for (i = 0; i < 607; ++i) { X klotz0_1.buff[i] = svblk[i + 1]; X } X X return 0; X} /* zufallrs_ */ X Xint normalen_(n, x) Xint n; Xdouble *x; X{ X int buffsz = 1024; X X /* Local variables */ X int left, i, nn, ptr, kptr; X extern int normal00_(); X/* Box-Muller method for Gaussian random numbers */ X X nn = n; X if (nn <= 0) { X return 0; X } X if (klotz1_1.first == 0) { X normal00_(); X klotz1_1.first = 1; X } X ptr = 0; X XL1: X left = buffsz - klotz1_1.xptr; X if (nn < left) { X kptr = klotz1_1.xptr; X#pragma _CRI ivdep X for (i = 0; i < nn; ++i) { X x[i + ptr] = klotz1_1.xbuff[kptr + i]; X } X klotz1_1.xptr += nn; X return 0; X } else { X kptr = klotz1_1.xptr; X#pragma _CRI ivdep X for (i = 0; i < left; ++i) { X x[i + ptr] = klotz1_1.xbuff[kptr + i]; X } X klotz1_1.xptr = 0; X ptr += left; X nn -= left; X normal00_(); X goto L1; X } X} /* normalen_ */ X Xint normal00_() X{ X /* Builtin functions */ X double cos(), sin(), log(), sqrt(); X X /* Local variables */ X int i; X double twopi, r1, r2, t1, t2; X extern int zufall_(); X X twopi = 6.2831853071795862; X zufall_(1024, klotz1_1.xbuff); X#pragma _CRI ivdep X for (i = 0; i < 1023; i += 2) { X r1 = twopi * klotz1_1.xbuff[i]; X t1 = cos(r1); X t2 = sin(r1); X r2 = sqrt(-2.*(log(1. - klotz1_1.xbuff[i+1]))); X klotz1_1.xbuff[i] = t1 * r2; X klotz1_1.xbuff[i+1] = t2 * r2; X } X X return 0; X} /* normal00_ */ X Xint normalsv_(svbox) Xdouble *svbox; X{ X extern int zufallsv_(); X int i, k; X X X/* IMPORTANT: svbox must be dimensioned at */ X/* least 1634 in driver. The entire contents of blocks */ X/* klotz0 (via zufallsv) and klotz1 must be saved. */ X X if (klotz1_1.first == 0) { X printf("ERROR in normalsv, save of uninitialized block\n"); X } X X/* save zufall block klotz0 */ X X zufallsv_(svbox); X X svbox[608] = (double) klotz1_1.first; X svbox[609] = (double) klotz1_1.xptr; X k = 610; X#pragma _CRI ivdep X for (i = 0; i < 1024; ++i) { X svbox[i + k] = klotz1_1.xbuff[i]; X } X X return 0; X} /* normalsv_ */ X Xint normalrs_(svbox) Xdouble *svbox; X{ X /* Local variables */ X extern int zufallrs_(); X int i, k; X X/* IMPORTANT: svbox must be dimensioned at */ X/* least 1634 in driver. The entire contents */ X/* of klotz0 and klotz1 must be restored. */ X X/* restore zufall blocks klotz0 and klotz1 */ X X zufallrs_(svbox); X klotz1_1.first = (int) svbox[608]; X if (klotz1_1.first == 0) { X printf("ERROR in normalrs, restoration of uninitialized block\n"); X } X klotz1_1.xptr = (int) svbox[609]; X k = 610; X#pragma _CRI ivdep X for (i = 0; i < 1024; ++i) { X klotz1_1.xbuff[i] = svbox[i + k]; X } X X return 0; X} /* normalrs_ */ X Xint fische_(n, mu, p) Xint n; Xdouble mu; Xint *p; X{ X X /* Builtin functions */ X double exp(); X X /* Local variables */ X int left, indx[1024], i, k; X double q[1024], u[1024]; X int nsegs, p0; X double q0; X int ii, jj; X extern /* Subroutine */ int zufall_(); X int nl0; X double pmu; X X/* Poisson generator for distribution function of p's: */ X X/* q(mu,p) = exp(-mu) mu**p/p! */ X X/* initialize arrays, pointers */ X X X /* Function Body */ X if (n <= 0) { X return 0; X } X X pmu = exp(-mu); X p0 = 0; X X nsegs = (n - 1) / 1024; X left = n - (nsegs << 10); X ++nsegs; X nl0 = left; X X for (k = 0; k < nsegs; ++k) { X X for (i = 0; i < left; ++i) { X indx[i] = i; X p[p0 + i] = 0; X q[i] = 1.; X } X X/* Begin iterative loop on segment of p's */ X XL1: X X/* Get the needed uniforms */ X X zufall_(left, u); X X jj = 0; X X for (i = 0; i < left; ++i) { X ii = indx[i]; X q0 = q[ii] * u[i]; X q[ii] = q0; X if (q0 > pmu) { X indx[jj++] = ii; X ++p[p0 + ii]; X } X } X X/* any left in this segment? */ X X left = jj; X if (left > 0) { X goto L1; X } X X p0 += nl0; X nl0 = 1024; X left = 1024; X X } X X return 0; X} /* fische_ */ END_OF_FILE if test 17299 -ne `wc -c <'zufall.c'`; then echo shar: \"'zufall.c'\" unpacked with wrong size! fi # end of 'zufall.c' fi echo shar: End of shell archive. exit 0 .