00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 #include <math.h>
00054 #include "machine.h"
00055 #include "grand.h"
00056 #include "sciprint.h"
00057
00058 int set_state_mt_simple(double s);
00059
00060
00061
00062 #define N 624
00063 #define M 397
00064 #define MATRIX_A 0x9908b0df
00065 #define UPPER_MASK 0x80000000
00066 #define LOWER_MASK 0x7fffffff
00067
00068
00069 #define TEMPERING_MASK_B 0x9d2c5680
00070 #define TEMPERING_MASK_C 0xefc60000
00071 #define TEMPERING_SHIFT_U(y) (y >> 11)
00072 #define TEMPERING_SHIFT_S(y) (y << 7)
00073 #define TEMPERING_SHIFT_T(y) (y << 15)
00074 #define TEMPERING_SHIFT_L(y) (y >> 18)
00075
00076 static unsigned long mt[N];
00077 static int mti=N;
00078 static int is_init=0;
00079 static double DEFAULT_SEED=5489.0;
00080
00081 extern void sciprint __PARAMS((char *fmt,...));
00082
00083 unsigned long randmt()
00084 {
00085 unsigned long y;
00086 static unsigned long mag01[2]={0x0, MATRIX_A};
00087
00088
00089 if (mti >= N) {
00090 int kk;
00091
00092 if ( ! is_init )
00093 set_state_mt_simple(DEFAULT_SEED);
00094
00095 for (kk=0;kk<N-M;kk++) {
00096 y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
00097 mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1];
00098 }
00099 for (;kk<N-1;kk++) {
00100 y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
00101 mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1];
00102 }
00103 y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
00104 mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1];
00105
00106 mti = 0;
00107 }
00108
00109 y = mt[mti++];
00110 y ^= TEMPERING_SHIFT_U(y);
00111 y ^= TEMPERING_SHIFT_S(y) & TEMPERING_MASK_B;
00112 y ^= TEMPERING_SHIFT_T(y) & TEMPERING_MASK_C;
00113 y ^= TEMPERING_SHIFT_L(y);
00114
00115 return ( y );
00116 }
00117
00118
00119 int set_state_mt_simple(double s)
00120 {
00121
00122 unsigned long seed;
00123
00124 if ( s == floor(s) && 0.0 <= s && s <= 4294967295.0)
00125 {
00126 seed = (unsigned long) s;
00127 mt[0]= seed & 0xffffffff;
00128 for (mti=1; mti<N; mti++)
00129 {
00130 mt[mti] = (1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti);
00131
00132
00133
00134
00135 mt[mti] &= 0xffffffffUL;
00136 }
00137 is_init = 1;
00138 return ( 1 );
00139 }
00140 else
00141 {
00142 sciprint("\n\r bad seed for mt, must be an integer in [0, 2^32-1] \n\r");
00143 return ( 0 );
00144 }
00145 }
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161 int set_state_mt(double seed_array[])
00162
00163 {
00164 int i, mti_try;
00165
00166 mti_try = (int) seed_array[0];
00167 if (mti_try < 1 || mti_try > 624)
00168 {
00169 sciprint("\n\r the first component of the mt state mt, must be an integer in [1, 624] \n\r");
00170 return ( 0 );
00171 }
00172 is_init = 1;
00173 mti = mti_try;
00174 for (i=0;i<N;i++)
00175 mt[i] = ((unsigned long) seed_array[i+1]) & 0xffffffff;
00176 return ( 1 );
00177 }
00178
00179
00180
00181 void get_state_mt(double state[])
00182 {
00183 int i;
00184
00185 if ( ! is_init )
00186 set_state_mt_simple(DEFAULT_SEED);
00187
00188 state[0] = (double) mti;
00189 for (i=0;i<N;i++)
00190 state[i+1] = (double) mt[i];
00191 }
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201