Annotation of OpenXM_contrib2/asir2000/engine/mt19937.c, Revision 1.1
1.1 ! noro 1: /* $OpenXM: OpenXM/src/asir99/engine/mt19937.c,v 1.1.1.1 1999/11/10 08:12:26 noro Exp $ */
! 2: #include <stdio.h>
! 3:
! 4: /* A C-program for MT19937: Real number version */
! 5: /* genrand() generates one pseudorandom real number (double) */
! 6: /* which is uniformly distributed on [0,1]-interval, for each */
! 7: /* call. sgenrand(seed) set initial values to the working area */
! 8: /* of 624 words. Before genrand(), sgenrand(seed) must be */
! 9: /* called once. (seed is any 32-bit integer except for 0). */
! 10: /* Integer generator is obtained by modifying two lines. */
! 11: /* Coded by Takuji Nishimura, considering the suggestions by */
! 12: /* Topher Cooper and Marc Rieffel in July-Aug. 1997. */
! 13:
! 14: /* This library is free software; you can redistribute it and/or */
! 15: /* modify it under the terms of the GNU Library General Public */
! 16: /* License as published by the Free Software Foundation; either */
! 17: /* version 2 of the License, or (at your option) any later */
! 18: /* version. */
! 19: /* This library is distributed in the hope that it will be useful, */
! 20: /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
! 21: /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */
! 22: /* See the GNU Library General Public License for more details. */
! 23: /* You should have received a copy of the GNU Library General */
! 24: /* Public License along with this library; if not, write to the */
! 25: /* Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA */
! 26: /* 02111-1307 USA */
! 27:
! 28: /* Copyright (C) 1997 Makoto Matsumoto and Takuji Nishimura. */
! 29: /* When you use this, send an email to: matumoto@math.keio.ac.jp */
! 30: /* with an appropriate reference to your work. */
! 31:
! 32: #define genrand mt_genrand
! 33: #define sgenrand mt_sgenrand
! 34:
! 35: #include<stdio.h>
! 36:
! 37: /* Period parameters */
! 38: #define N 624
! 39: #define M 397
! 40: #define MATRIX_A 0x9908b0df /* constant vector a */
! 41: #define UPPER_MASK 0x80000000 /* most significant w-r bits */
! 42: #define LOWER_MASK 0x7fffffff /* least significant r bits */
! 43:
! 44: /* Tempering parameters */
! 45: #define TEMPERING_MASK_B 0x9d2c5680
! 46: #define TEMPERING_MASK_C 0xefc60000
! 47: #define TEMPERING_SHIFT_U(y) (y >> 11)
! 48: #define TEMPERING_SHIFT_S(y) (y << 7)
! 49: #define TEMPERING_SHIFT_T(y) (y << 15)
! 50: #define TEMPERING_SHIFT_L(y) (y >> 18)
! 51:
! 52: static unsigned long mt[N]; /* the array for the state vector */
! 53: static int mti=N+1; /* mti==N+1 means mt[N] is not initialized */
! 54:
! 55: int mt_save(name)
! 56: char *name;
! 57: {
! 58: FILE *fp;
! 59:
! 60: if ( !(fp = fopen(name,"wb")) )
! 61: return 0;
! 62: fwrite(mt,N,sizeof(unsigned long),fp);
! 63: fwrite(&mti,1,sizeof(int),fp);
! 64: fclose(fp);
! 65: return 1;
! 66: }
! 67:
! 68: int mt_load(name)
! 69: char *name;
! 70: {
! 71: FILE *fp;
! 72:
! 73: if ( !(fp = fopen(name,"rb")) )
! 74: return 0;
! 75: fread(mt,N,sizeof(unsigned long),fp);
! 76: fread(&mti,1,sizeof(int),fp);
! 77: fclose(fp);
! 78: return 1;
! 79: }
! 80:
! 81: /* initializing the array with a NONZERO seed */
! 82: void
! 83: sgenrand(seed)
! 84: unsigned long seed;
! 85: {
! 86: /* setting initial seeds to mt[N] using */
! 87: /* the generator Line 25 of Table 1 in */
! 88: /* [KNUTH 1981, The Art of Computer Programming */
! 89: /* Vol. 2 (2nd Ed.), pp102] */
! 90: mt[0]= seed & 0xffffffff;
! 91: for (mti=1; mti<N; mti++)
! 92: mt[mti] = (69069 * mt[mti-1]) & 0xffffffff;
! 93: }
! 94:
! 95: #if 0
! 96: double /* generating reals */
! 97: #endif
! 98: unsigned long /* for integer generation */
! 99: genrand()
! 100: {
! 101: unsigned long y;
! 102: static unsigned long mag01[2]={0x0, MATRIX_A};
! 103: /* mag01[x] = x * MATRIX_A for x=0,1 */
! 104:
! 105: if (mti >= N) { /* generate N words at one time */
! 106: int kk;
! 107:
! 108: if (mti == N+1) /* if sgenrand() has not been called, */
! 109: sgenrand(4357); /* a default initial seed is used */
! 110:
! 111: for (kk=0;kk<N-M;kk++) {
! 112: y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
! 113: mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1];
! 114: }
! 115: for (;kk<N-1;kk++) {
! 116: y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
! 117: mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1];
! 118: }
! 119: y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
! 120: mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1];
! 121:
! 122: mti = 0;
! 123: }
! 124:
! 125: y = mt[mti++];
! 126: y ^= TEMPERING_SHIFT_U(y);
! 127: y ^= TEMPERING_SHIFT_S(y) & TEMPERING_MASK_B;
! 128: y ^= TEMPERING_SHIFT_T(y) & TEMPERING_MASK_C;
! 129: y ^= TEMPERING_SHIFT_L(y);
! 130:
! 131: #if 0
! 132: return ( (double)y / (unsigned long)0xffffffff ); /* reals */
! 133: #endif
! 134: return y; /* for integer generation */
! 135: }
! 136:
! 137: #if 0
! 138: /* this main() outputs first 1000 generated numbers */
! 139: main()
! 140: {
! 141: int j;
! 142:
! 143: sgenrand(4357); /* any nonzero integer can be used as a seed */
! 144: for (j=0; j<1000; j++) {
! 145: printf("%5f ", genrand());
! 146: if (j%8==7) printf("\n");
! 147: }
! 148: printf("\n");
! 149: }
! 150: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>