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

dkcMTRand64.c

説明を見る。
00001 
00002 
00070 #define DKUTIL_C_MT_RAND64_C
00071 #include "dkcMTRand64.h"
00072 #include <dkutil_c/dkc_misc.h>
00073 
00074 #define NN dkcdMT_RAND64_NN
00075 #define MM 156
00076 #define MATRIX_A dkcmUINT64DEFINE(0xB5026F5AA96619E9)
00077 #define UM dkcmUINT64DEFINE(0xFFFFFFFF80000000) /* Most significant 33 bits */
00078 #define LM dkcmUINT64DEFINE(0x7FFFFFFF) /* Least significant 31 bits */
00079 
00080 DKC_MT_RAND64 *WINAPI dkcAllocMTRand64(uint64 seed)
00081 {
00082     const uint32 alignMask = 15;    /* = 2^n - 1 */
00083     char *tp = dkcAllocateFast_INL(sizeof(DKC_MT_RAND64) + alignMask);
00084     DKC_MT_RAND64 *p;
00085     if(NULL==tp) return NULL;
00086     //mymt.cより16byte align technic for SSE
00087     p = (DKC_MT_RAND64 *)(((int)tp + alignMask) & ~alignMask);
00088     p->mallocPtr = tp;
00089     dkcMTRand64SetNextFunction(p,dkcMTRand64Next_C);
00090     dkcMTRand64Init(p,seed);
00091     return p;
00092 }
00093 
00094 int WINAPI dkcFreeMTRand64(DKC_MT_RAND64 **p)
00095 {
00096     dkcFreeFast_INL((void **)(&((*p)->mallocPtr)));
00097     return edk_SUCCEEDED;
00098 }
00099 
00100 void WINAPI dkcMTRand64Init(DKC_MT_RAND64 *p,uint64 seed){
00101     int mti = p->index;
00102     uint64 *mt = p->state;
00103     p->state[0] = seed;
00104   for (mti=1; mti<NN; mti++)
00105     {
00106         mt[mti] = (dkcmUINT64DEFINE(6364136223846793005) * (mt[mti-1] ^ (mt[mti-1] >> 62)) + mti);
00107     }
00108     p->index = mti;
00109 }
00110 
00111 void WINAPI dkcMTRand64InitByArray(DKC_MT_RAND64 *p,uint64 *init_key,uint64 key_length)
00112 {
00113     uint64 i, j, k;
00114         uint64 *mt = p->state;
00115     dkcMTRand64Init(p,dkcmUINT64DEFINE(19650218));
00116     i=1; j=0;
00117     k = (NN>key_length ? NN : key_length);
00118     for (; k; k--) {
00119         mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 62)) * dkcmUINT64DEFINE(3935559000370003845)))
00120           + init_key[j] + j; /* non linear */
00121         i++; j++;
00122         if (i>=NN) { mt[0] = mt[NN-1]; i=1; }
00123         if (j>=key_length) j=0;
00124     }
00125     for (k=NN-1; k; k--) {
00126         mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 62)) * dkcmUINT64DEFINE(2862933555777941757)))
00127           - i; /* non linear */
00128         i++;
00129         if (i>=NN) { mt[0] = mt[NN-1]; i=1; }
00130     }
00131 
00132     mt[0] = dkcmUINT64DEFINE(1) << 63; /* MSB is 1; assuring non-zero initial array */ 
00133 }
00134 
00135 DKC_INLINE void dkcMTRand64Next_C(DKC_MT_RAND64 *p){
00136     int i;
00137     int mti = p->index;
00138     uint64 *mt = p->state;
00139     uint64 x;
00140     /* if init_genrand64() has not been called, */
00141     /* a default initial seed is used     */
00142     /*if (mti == NN+1) 
00143             dkcMTRand64Init(p,dkcmUINT64DEFINE(5489)); 
00144     */
00145 
00146     static uint64 mag01[2]={dkcmUINT64DEFINE(0), MATRIX_A};
00147     for (i=0;i<NN-MM;i++) {
00148             x = (mt[i]&UM)|(mt[i+1]&LM);
00149             mt[i] = mt[i+MM] ^ (x>>1) ^ mag01[(int)(x&dkcmUINT64DEFINE(1))];
00150     }
00151     for (;i<NN-1;i++) {
00152             x = (mt[i]&UM)|(mt[i+1]&LM);
00153             mt[i] = mt[i+(MM-NN)] ^ (x>>1) ^ mag01[(int)(x&dkcmUINT64DEFINE(1))];
00154     }
00155     x = (mt[NN-1]&UM)|(mt[0]&LM);
00156     mt[NN-1] = mt[MM-1] ^ (x>>1) ^ mag01[(int)(x&dkcmUINT64DEFINE(1))];
00157 
00158     mti = 0;
00159 
00160         //update
00161     {
00162         uint64 *cache = p->output;
00163         for (i = 0; i < NN; i++) {
00164             register uint64 x;
00165             x = mt[i];
00166             /* Tempering */
00167             x ^= (x >> 29) & dkcmUINT64DEFINE(0x5555555555555555);
00168             x ^= (x << 17) & dkcmUINT64DEFINE(0x71D67FFFEDA60000);
00169             x ^= (x << 37) & dkcmUINT64DEFINE(0xFFF7EEE000000000);
00170             x ^= (x >> 43);
00171             cache[i] = x;
00172         }
00173         p->index = mti;
00174     }
00175 }
00176 
00178 uint64 WINAPI dkcMTRand64Get(DKC_MT_RAND64 *p)
00179 {
00180     return dkcMTRand64Get_INL(p);
00181 }
00182 

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