メインページ | アルファベット順一覧 | 構成 | ファイル一覧 | 構成メンバ | ファイルメンバ | 関連ページ

dkcMTRand32.c

説明を見る。
00001 
00005 #define DKUTIL_C_MT_RAND32_C
00006 #include "dkcMTRand32.h"
00007 #include "cpu_x86.h"
00008 #include <dkutil_c/dkc_misc.h>
00009 
00011 //in mymt.c
00012 
00013 /* Period parameters */  
00014 //#define dkcdMT_RAND32_N 624 in header
00015 #define M 397
00016 #define MATRIX_A 0x9908B0DF   /* constant vector a */
00017 #define UMASK 0x80000000 /* most significant w-r bits */
00018 #define LMASK 0x7FFFFFFF /* least significant r bits */
00019 #define MIXBITS(u,v) ( ((u) & UMASK) | ((v) & LMASK) )
00020 #define TWIST(u,v) ((MIXBITS(u,v) >> 1) ^ ((v)&1 ? MATRIX_A : 0))
00021 
00022 
00024 
00025 /* defined in mymt_x86.nas */
00026 /*
00027 DKC_EXTERN void myMT_Next_SSE2(DKC_MT_RAND32 *mt);
00028 DKC_EXTERN void myMT_Next_MMX(DKC_MT_RAND32 *mt);
00029 */
00030 //void myMT_Next_other(myMT_t *mt);
00031 
00032 void dkcMTRand32Next_C(DKC_MT_RAND32 *mt)
00033 {
00034     int i;
00035     uint32 *p, *q;
00036 
00037     p = mt->state;
00038     for (i = 0; i < dkcdMT_RAND32_N - M; i++, p++) {
00039         *p = p[M] ^ TWIST(p[0], p[1]);
00040     }
00041 
00042     for (i = 0; i < M - 1; i++, p++) {
00043         *p = p[M-dkcdMT_RAND32_N] ^ TWIST(p[0], p[1]);
00044     }
00045 
00046     *p = p[M-dkcdMT_RAND32_N] ^ TWIST(p[0], mt->state[0]);
00047     mt->index = 0;
00048 
00049     p = mt->state;
00050     q = mt->output;
00051     for (i = 0; i < dkcdMT_RAND32_N; i++) {
00052         uint32 y;
00053         y = *p++;
00054         /* Tempering */
00055         y ^= (y >> 11);
00056         y ^= (y << 7) & 0x9D2C5680;
00057         y ^= (y << 15) & 0xEFC60000;
00058         y ^= (y >> 18);
00059         *q++ = y;
00060     }
00061 }
00062 
00063 static DKC_INLINE next(DKC_MT_RAND32 *mt)
00064 {
00065     DKC_MT_RAND32_GENERATE_F_TYPE pf;
00066     pf = mt->function_ptr;
00067     pf(mt);
00068 }
00069         
00070 //myMT_SetSeed()
00071 void WINAPI dkcMTRand32Init(DKC_MT_RAND32 *mt, uint32 seed)
00072 {
00073     uint32 *p;
00074     int i;
00075 
00076     p = mt->state;
00077     p[0] = seed;
00078 
00079     for (i = 1; i < dkcdMT_RAND32_N; i++) {
00080         p[i] = (1812433253 * (p[i-1] ^ (p[i-1] >> 30)) + i); 
00081         /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
00082         /* In the previous versions, MSBs of the seed affect   */
00083         /* only MSBs of the array state[]. */
00084         /* 2002/01/09 modified by Makoto Matsumoto */
00085         p[i] &= 0xffffffffUL;
00086     /* for >32 bit machines */
00087     }
00088     //update
00089     mt->index = i;
00090     //myMT_Next(mt);
00091 }
00092 
00093 void WINAPI dkcMTRand32InitByArray(DKC_MT_RAND32 *p,uint32 *init_key,int32 key_length)
00094 {
00095   int i, j, k;
00096     uint32 *mt = p->state;
00097     //uint32 mti = p->index;
00098   dkcMTRand32Init(p,19650218UL);
00099   i=1; j=0;
00100   k = (dkcdMT_RAND32_N>key_length ? dkcdMT_RAND32_N : key_length);
00101   for (; k; k--) {
00102       mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525UL))
00103         + init_key[j] + j; /* non linear */
00104       mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
00105       i++; j++;
00106       if (i>=dkcdMT_RAND32_N) { mt[0] = mt[dkcdMT_RAND32_N-1]; i=1; }
00107       if (j>=key_length) j=0;
00108   }
00109   for (k=dkcdMT_RAND32_N-1; k; k--) {
00110       mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941UL))
00111         - i; /* non linear */
00112       mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
00113       i++;
00114       if (i>=dkcdMT_RAND32_N) { mt[0] = mt[dkcdMT_RAND32_N-1]; i=1; }
00115   }
00116 
00117   mt[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */ 
00118     //update
00119     //next(p);
00120     //p->index = mti;
00121 }
00122 
00123 
00124 #if 0
00125 void myMT_SetSeeds(myMT_t *mt, uint32 *seed, int seedNum)
00126 {
00127     uint32 *p = mt->state;
00128     int i;
00129     int num = (seedNum < dkcdMT_RAND32_N) ? seedNum : dkcdMT_RAND32_N;
00130 
00131     if (num <= 0) {
00132         myMT_SetSeed(mt, 1234);
00133         return;
00134     }
00135 
00136     memcpy(p, seed, num * sizeof(uint32));
00137 
00138     for (i = num; i < dkcdMT_RAND32_N; i++) {
00139         p[i] = (1812433253 * (p[i-1] ^ (p[i-1] >> 30)) + i); 
00140         /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
00141         /* In the previous versions, MSBs of the seed affect   */
00142         /* only MSBs of the array state[]. */
00143         /* 2002/01/09 modified by Makoto Matsumoto */
00144     }
00145     myMT_Next(mt);
00146 }
00147 #endif
00148 
00149 
00150 
00151 DKC_MT_RAND32 *WINAPI dkcAllocMTRand32(uint32 seed)
00152 {
00153     const uint32 alignMask = 15;    /* = 2^dkcdMT_RAND32_N - 1 */
00154     uint8 *tp = dkcAllocateFast_INL(sizeof(DKC_MT_RAND32) + alignMask);
00155     DKC_MT_RAND32 *p;
00156     int unit;
00157     if(NULL==tp) return NULL;
00158     //mymt.cより16byte align technic for SSE
00159     p = (DKC_MT_RAND32 *)(((int)tp + alignMask) & ~alignMask);
00160     p->mallocPtr = (char *)tp;
00161 #if 1
00162     unit = haveX86_UNIT();
00163     if (unit & MU_tSSE2) {
00164         p->function_ptr = (void *)dkcMTRand32Next_SSE2;
00165     } else if (unit & MU_tMMX) {
00166         p->function_ptr  = (void *)dkcMTRand32Next_MMX;
00167     } else {
00168         p->function_ptr  = (void *)dkcMTRand32Next_C;
00169     }
00170 #else
00171     p->function_ptr  = (void *)dkcMTRand32Next_C;
00172 #endif
00173     dkcMTRand32Init(p,seed);
00174     return p;
00175 }
00176 
00177 int WINAPI dkcFreeMTRand32(DKC_MT_RAND32 **p)
00178 {
00179     dkcFreeFast_INL((void **)(&((*p)->mallocPtr)));
00180     return edk_SUCCEEDED;
00181 }
00182 
00183 
00184 
00185 uint32 WINAPI dkcMTRand32Get(DKC_MT_RAND32 *p){
00186 
00187     return dkcMTRand32Get_INL(p);
00188 }

dKingyoMersenneTwisterLibraryに対してThu Jan 19 05:10:23 2006に生成されました。  doxygen 1.4.4