• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

sst/elements/mcopteron/mersenne.h

00001 /* 
00002    A C-program for MT19937, with initialization improved 2002/2/10.
00003    Coded by Takuji Nishimura and Makoto Matsumoto.
00004    This is a faster version by taking Shawn Cokus's optimization,
00005    Matthe Bellew's simplification, Isaku Wada's real version.
00006 
00007    Before using, initialize the state by using init_genrand(seed) 
00008    or init_by_array(init_key, key_length).
00009 
00010    Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
00011    All rights reserved.                          
00012 
00013    Redistribution and use in source and binary forms, with or without
00014    modification, are permitted provided that the following conditions
00015    are met:
00016 
00017      1. Redistributions of source code must retain the above copyright
00018         notice, this list of conditions and the following disclaimer.
00019 
00020      2. Redistributions in binary form must reproduce the above copyright
00021         notice, this list of conditions and the following disclaimer in the
00022         documentation and/or other materials provided with the distribution.
00023 
00024      3. The names of its contributors may not be used to endorse or promote 
00025         products derived from this software without specific prior written 
00026         permission.
00027 
00028    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00029    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00030    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00031    A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
00032    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00033    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00034    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00035    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00036    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00037    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00038    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00039 
00040 
00041    Any feedback is very welcome.
00042    http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
00043    email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
00044 */
00045 
00046 #include <stdio.h>
00047 
00048 /* Period parameters */  
00049 #define N 624
00050 #define M 397
00051 #define MATRIX_A 0x9908b0dfUL   /* constant vector a */
00052 #define UMASK 0x80000000UL /* most significant w-r bits */
00053 #define LMASK 0x7fffffffUL /* least significant r bits */
00054 #define MIXBITS(u,v) ( ((u) & UMASK) | ((v) & LMASK) )
00055 #define TWIST(u,v) ((MIXBITS(u,v) >> 1) ^ ((v)&1UL ? MATRIX_A : 0UL))
00056 
00057 static unsigned long state[N]; /* the array for the state vector  */
00058 static int left = 1;
00059 static int initf = 0;
00060 static unsigned long *next;
00061 
00062 /* initializes state[N] with a seed */
00063 void init_genrand(unsigned long s)
00064 {
00065     int j;
00066     state[0]= s & 0xffffffffUL;
00067     for (j=1; j<N; j++) {
00068         state[j] = (1812433253UL * (state[j-1] ^ (state[j-1] >> 30)) + j); 
00069         /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
00070         /* In the previous versions, MSBs of the seed affect   */
00071         /* only MSBs of the array state[].                        */
00072         /* 2002/01/09 modified by Makoto Matsumoto             */
00073         state[j] &= 0xffffffffUL;  /* for >32 bit machines */
00074     }
00075     left = 1; initf = 1;
00076 }
00077 
00078 /* initialize by an array with array-length */
00079 /* init_key is the array for initializing keys */
00080 /* key_length is its length */
00081 /* slight change for C++, 2004/2/26 */
00082 void init_by_array(unsigned long init_key[], int key_length)
00083 {
00084     int i, j, k;
00085     init_genrand(19650218UL);
00086     i=1; j=0;
00087     k = (N>key_length ? N : key_length);
00088     for (; k; k--) {
00089         state[i] = (state[i] ^ ((state[i-1] ^ (state[i-1] >> 30)) * 1664525UL))
00090           + init_key[j] + j; /* non linear */
00091         state[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
00092         i++; j++;
00093         if (i>=N) { state[0] = state[N-1]; i=1; }
00094         if (j>=key_length) j=0;
00095     }
00096     for (k=N-1; k; k--) {
00097         state[i] = (state[i] ^ ((state[i-1] ^ (state[i-1] >> 30)) * 1566083941UL))
00098           - i; /* non linear */
00099         state[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
00100         i++;
00101         if (i>=N) { state[0] = state[N-1]; i=1; }
00102     }
00103 
00104     state[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */ 
00105     left = 1; initf = 1;
00106 }
00107 
00108 static void next_state(void)
00109 {
00110     unsigned long *p=state;
00111     int j;
00112 
00113     /* if init_genrand() has not been called, */
00114     /* a default initial seed is used         */
00115     if (initf==0) init_genrand(5489UL);
00116 
00117     left = N;
00118     next = state;
00119     
00120     for (j=N-M+1; --j; p++) 
00121         *p = p[M] ^ TWIST(p[0], p[1]);
00122 
00123     for (j=M; --j; p++) 
00124         *p = p[M-N] ^ TWIST(p[0], p[1]);
00125 
00126     *p = p[M-N] ^ TWIST(p[0], state[0]);
00127 }
00128 
00129 /* generates a random number on [0,0xffffffff]-interval */
00130 unsigned long genrand_int32(void)
00131 {
00132     unsigned long y;
00133 
00134     if (--left == 0) next_state();
00135     y = *next++;
00136 
00137     /* Tempering */
00138     y ^= (y >> 11);
00139     y ^= (y << 7) & 0x9d2c5680UL;
00140     y ^= (y << 15) & 0xefc60000UL;
00141     y ^= (y >> 18);
00142 
00143     return y;
00144 }
00145 
00146 /* generates a random number on [0,0x7fffffff]-interval */
00147 long genrand_int31(void)
00148 {
00149     unsigned long y;
00150 
00151     if (--left == 0) next_state();
00152     y = *next++;
00153 
00154     /* Tempering */
00155     y ^= (y >> 11);
00156     y ^= (y << 7) & 0x9d2c5680UL;
00157     y ^= (y << 15) & 0xefc60000UL;
00158     y ^= (y >> 18);
00159 
00160     return (long)(y>>1);
00161 }
00162 
00163 /* generates a random number on [0,1]-real-interval */
00164 double genrand_real1(void)
00165 {
00166     unsigned long y;
00167 
00168     if (--left == 0) next_state();
00169     y = *next++;
00170 
00171     /* Tempering */
00172     y ^= (y >> 11);
00173     y ^= (y << 7) & 0x9d2c5680UL;
00174     y ^= (y << 15) & 0xefc60000UL;
00175     y ^= (y >> 18);
00176 
00177     return (double)y * (1.0/4294967295.0); 
00178     /* divided by 2^32-1 */ 
00179 }
00180 
00181 /* generates a random number on [0,1)-real-interval */
00182 double genrand_real2(void)
00183 {
00184     unsigned long y;
00185 
00186     if (--left == 0) next_state();
00187     y = *next++;
00188 
00189     /* Tempering */
00190     y ^= (y >> 11);
00191     y ^= (y << 7) & 0x9d2c5680UL;
00192     y ^= (y << 15) & 0xefc60000UL;
00193     y ^= (y >> 18);
00194 
00195     return (double)y * (1.0/4294967296.0); 
00196     /* divided by 2^32 */
00197 }
00198 
00199 /* generates a random number on (0,1)-real-interval */
00200 double genrand_real3(void)
00201 {
00202     unsigned long y;
00203 
00204     if (--left == 0) next_state();
00205     y = *next++;
00206 
00207     /* Tempering */
00208     y ^= (y >> 11);
00209     y ^= (y << 7) & 0x9d2c5680UL;
00210     y ^= (y << 15) & 0xefc60000UL;
00211     y ^= (y >> 18);
00212 
00213     return ((double)y + 0.5) * (1.0/4294967296.0); 
00214     /* divided by 2^32 */
00215 }
00216 
00217 /* generates a random number on [0,1) with 53-bit resolution*/
00218 double genrand_res53(void) 
00219 { 
00220     unsigned long a=genrand_int32()>>5, b=genrand_int32()>>6; 
00221     return(a*67108864.0+b)*(1.0/9007199254740992.0); 
00222 } 
00223 /* These real versions are due to Isaku Wada, 2002/01/09 added */
00224 #ifdef MERSENNE_MAIN
00225 int main(void)
00226 {
00227     int i;
00228     unsigned long init[4]={0x123, 0x234, 0x345, 0x456}, length=4;
00229     init_by_array(init, length);
00230     /* This is an example of initializing by an array.       */
00231     /* You may use init_genrand(seed) with any 32bit integer */
00232     /* as a seed for a simpler initialization                */
00233     printf("1000 outputs of genrand_int32()\n");
00234     for (i=0; i<1000; i++) {
00235       printf("%10lu ", genrand_int32());
00236       if (i%5==4) printf("\n");
00237     }
00238     printf("\n1000 outputs of genrand_real2()\n");
00239     for (i=0; i<1000; i++) {
00240       printf("%10.8f ", genrand_real2());
00241       if (i%5==4) printf("\n");
00242     }
00243 
00244     return 0;
00245 }
00246 
00247 #endif

Generated on Fri Oct 22 2010 11:02:25 for SST by  doxygen 1.7.1