diff options
author | Charles Harris <charlesr.harris@gmail.com> | 2020-05-13 07:38:14 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-05-13 07:38:14 -0600 |
commit | 77410e26dd94bdd07df096be06ee9aa7d5738ce6 (patch) | |
tree | b5ee3e5b1d4a85a8a47a0671d98eca148b861aa8 /numpy | |
parent | 56f444a0c50d949bf9eba653bb91346fdb8f1069 (diff) | |
parent | ac72f8d63e8d5522b680758a3d6537ab722cabd4 (diff) | |
download | numpy-77410e26dd94bdd07df096be06ee9aa7d5738ce6.tar.gz |
Merge pull request #16153 from bashtage/fix-mt19937-jump
BUG: Correct loop order in MT19937 jump
Diffstat (limited to 'numpy')
-rw-r--r-- | numpy/random/_mt19937.pyx | 17 | ||||
-rw-r--r-- | numpy/random/src/mt19937/mt19937-jump.c | 118 | ||||
-rw-r--r-- | numpy/random/src/mt19937/mt19937-jump.h | 140 | ||||
-rw-r--r-- | numpy/random/src/mt19937/mt19937-poly.h | 207 | ||||
-rw-r--r-- | numpy/random/src/mt19937/mt19937.c | 3 | ||||
-rw-r--r-- | numpy/random/tests/test_generator_mt19937.py | 54 |
6 files changed, 210 insertions, 329 deletions
diff --git a/numpy/random/_mt19937.pyx b/numpy/random/_mt19937.pyx index 919a96a4c..16a377cc6 100644 --- a/numpy/random/_mt19937.pyx +++ b/numpy/random/_mt19937.pyx @@ -226,6 +226,23 @@ cdef class MT19937(BitGenerator): ------- bit_generator : MT19937 New instance of generator jumped iter times + + Notes + ----- + The jump step is computed using a modified version of Matsumoto's + implementation of Horner's method. The step polynomial is precomputed + to perform 2**128 steps. The jumped state has been verified to match + the state produced using Matsumoto's original code. + + References + ---------- + .. [1] Matsumoto, M, Generating multiple disjoint streams of + pseudorandom number sequences. Accessed on: May 6, 2020. + http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/JUMP/ + .. [2] Hiroshi Haramoto, Makoto Matsumoto, Takuji Nishimura, François + Panneton, Pierre L\'Ecuyer, "Efficient Jump Ahead for F2-Linear + Random Number Generators", INFORMS JOURNAL ON COMPUTING, Vol. 20, + No. 3, Summer 2008, pp. 385-390. """ cdef MT19937 bit_generator diff --git a/numpy/random/src/mt19937/mt19937-jump.c b/numpy/random/src/mt19937/mt19937-jump.c index 46b28cf96..1a83a4c2e 100644 --- a/numpy/random/src/mt19937/mt19937-jump.c +++ b/numpy/random/src/mt19937/mt19937-jump.c @@ -10,28 +10,6 @@ unsigned long get_coef(unsigned long *pf, unsigned int deg) { return (0); } -/* 32-bit function */ -/* set the coefficient of the polynomial pf with v */ -void set_coef(unsigned long *pf, unsigned int deg, unsigned long v) { - if (v != 0) - pf[deg >> 5] ^= (LSB << (deg & 0x1ful)); - else - ; -} - -void gray_code(unsigned long *h) { - unsigned int i, j = 1, l = 1, term = LL; - - h[0] = 0; - - for (i = 1; i <= QQ; i++) { - l = (l << 1); - term = (term >> 1); - for (; j < l; j++) - h[j] = h[l - j - 1] ^ term; - } -} - void copy_state(mt19937_state *target_state, mt19937_state *state) { int i; @@ -83,69 +61,6 @@ void add_state(mt19937_state *state1, mt19937_state *state2) { } } -/* -void gen_vec_h(mt19937_state *state, mt19937_state *vec_h, - unsigned long *h) { - int i; - unsigned long k, g; - mt19937_state v; - - gray_code(h); - - copy_state(&vec_h[0], state); - - for (i = 0; i < QQ; i++) - gen_next(&vec_h[0]); - - for (i = 1; i < LL; i++) { - copy_state(&v, state); - g = h[i] ^ h[i - 1]; - for (k = 1; k < g; k = (k << 1)) - gen_next(&v); - copy_state(&vec_h[h[i]], &vec_h[h[i - 1]]); - add_state(&vec_h[h[i]], &v); - } -} -*/ - -/* compute pf(ss) using Sliding window algorithm */ -/* -void calc_state(unsigned long *pf, mt19937_state *state, - mt19937_state *vec_h) { - mt19937_state *temp1; - int i = MEXP - 1, j, digit, skip = 0; - - temp1 = (mt19937_state *)calloc(1, sizeof(mt19937_state)); - - while (get_coef(pf, i) == 0) - i--; - - for (; i >= QQ; i--) { - if (get_coef(pf, i) != 0) { - for (j = 0; j < QQ + 1; j++) - gen_next(temp1); - digit = 0; - for (j = 0; j < QQ; j++) - digit = (digit << 1) ^ get_coef(pf, i - j - 1); - add_state(temp1, &vec_h[digit]); - i -= QQ; - } else - gen_next(temp1); - } - - for (; i > -1; i--) { - gen_next(temp1); - if (get_coef(pf, i) == 1) - add_state(temp1, state); - else - ; - } - - copy_state(state, temp1); - free(temp1); -} -*/ - /* compute pf(ss) using standard Horner method */ void horner1(unsigned long *pf, mt19937_state *state) { int i = MEXP - 1; @@ -180,18 +95,15 @@ void horner1(unsigned long *pf, mt19937_state *state) { free(temp); } -void mt19937_jump_state(mt19937_state *state, const char *jump_str) { +void mt19937_jump_state(mt19937_state *state) { unsigned long *pf; int i; pf = (unsigned long *)calloc(P_SIZE, sizeof(unsigned long)); - - for (i = MEXP - 1; i > -1; i--) { - if (jump_str[i] == '1') - set_coef(pf, i, 1); + for (i = 0; i<P_SIZE; i++) { + pf[i] = poly_coef[i]; } - /* TODO: Should generate the next set and start from 0, but doesn't matter ?? - */ + if (state->pos >= N) { state->pos = 0; } @@ -200,25 +112,3 @@ void mt19937_jump_state(mt19937_state *state, const char *jump_str) { free(pf); } -/* -void mt19937_jump(mt19937_state *state, const char *jump_str) -{ - unsigned long h[LL]; - mt19937_state vec_h[LL]; - unsigned long *pf; - int i; - - pf = (unsigned long *)calloc(P_SIZE, sizeof(unsigned long)); - - for (i = MEXP - 1; i > -1; i--) - { - if (jump_str[i] == '1') - set_coef(pf, i, 1); - } - - gen_vec_h(state, &vec_h, &h); - calc_state(pf, state, &vec_h); - - free(pf); -} -*/
\ No newline at end of file diff --git a/numpy/random/src/mt19937/mt19937-jump.h b/numpy/random/src/mt19937/mt19937-jump.h index 394c150a0..8371cbd5f 100644 --- a/numpy/random/src/mt19937/mt19937-jump.h +++ b/numpy/random/src/mt19937/mt19937-jump.h @@ -10,6 +10,142 @@ #define QQ 7 #define LL 128 /* LL = 2^(QQ) */ -void mt19937_jump_state(mt19937_state *state, const char *jump_str); +void mt19937_jump_state(mt19937_state *state); -void set_coef(unsigned long *pf, unsigned int deg, unsigned long v);
\ No newline at end of file +void set_coef(unsigned long *pf, unsigned int deg, unsigned long v); + +/* + * 2**128 step polynomial produced using the file mt19937-generate-jump-poly.c + * (randomgen) which is a modified version of minipoly_mt19937.c as distributed + * in + * http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/JUMP/jump_ahead_1.02.tar.gz + * + * These files are not part of NumPy. + */ + +static const unsigned long poly_coef[624] = { + 1927166307UL, 3044056772UL, 2284297142UL, 2820929765UL, 651705945UL, + 69149273UL, 3892165397UL, 2337412983UL, 1219880790UL, 3207074517UL, + 3836784057UL, 189286826UL, 1049791363UL, 3916249550UL, 2942382547UL, + 166392552UL, 861176918UL, 3246476411UL, 2302311555UL, 4273801148UL, + 29196903UL, 1363664063UL, 3802562022UL, 2600400244UL, 3090369801UL, + 4040416970UL, 1432485208UL, 3632558139UL, 4015816763UL, 3013316418UL, + 551532385UL, 3592224467UL, 3479125595UL, 1195467127UL, 2391032553UL, + 2393493419UL, 1482493632UL, 1625159565UL, 748389672UL, 4042774030UL, + 2998615036UL, 3393119101UL, 2177492569UL, 2265897321UL, 2507383006UL, + 3461498961UL, 2003319700UL, 1942857197UL, 1455226044UL, 4097545580UL, + 529653268UL, 3204756480UL, 2486748289UL, 495294513UL, 3396001954UL, + 2643963605UL, 2655404568UL, 3881604377UL, 624710790UL, 3443737948UL, + 1941294296UL, 2139259604UL, 3368734020UL, 422436761UL, 3602810182UL, + 1384691081UL, 3035786407UL, 2551797119UL, 537227499UL, 65486120UL, + 642436100UL, 2023822537UL, 2515598203UL, 1122953367UL, 2882306242UL, + 1743213032UL, 321965189UL, 336496623UL, 2436602518UL, 3556266590UL, + 1055117829UL, 463541647UL, 743234441UL, 527083645UL, 2606668346UL, + 2274046499UL, 2761475053UL, 2760669048UL, 2538258534UL, 487125077UL, + 3365962306UL, 3604906217UL, 2714700608UL, 680709708UL, 2217161159UL, + 1614899374UL, 3710119533UL, 3201300658UL, 3752620679UL, 2755041105UL, + 3129723037UL, 1247297753UL, 2812642690UL, 4114340845UL, 3485092247UL, + 2752814364UL, 3586551747UL, 4073138437UL, 3462966585UL, 2924318358UL, + 4061374901UL, 3314086806UL, 2640385723UL, 744590670UL, 3007586513UL, + 3959120371UL, 997207767UL, 3420235506UL, 2092400998UL, 3190305685UL, + 60965738UL, 549507222UL, 3784354415UL, 3209279509UL, 1238863299UL, + 2605037827UL, 178570440UL, 1743491299UL, 4079686640UL, 2136795825UL, + 3435430548UL, 1679732443UL, 1835708342UL, 2159367000UL, 1924487218UL, + 4059723674UL, 996192116UL, 2308091645UL, 1336281586UL, 674600050UL, + 1642572529UL, 1383973289UL, 2202960007UL, 3165481279UL, 3385474038UL, + 2501318550UL, 2671842890UL, 3084085109UL, 3475033915UL, 1551329147UL, + 4101397249UL, 1205851807UL, 3641536021UL, 3607635071UL, 1609126163UL, + 2910426664UL, 3324508658UL, 4244311266UL, 254034382UL, 1258304384UL, + 1914048768UL, 1358592011UL, 527610138UL, 3072108727UL, 4289413885UL, + 1417001678UL, 2445445945UL, 896462712UL, 339855811UL, 3699378285UL, + 2529457297UL, 3049459401UL, 2723472429UL, 2838633181UL, 2520397330UL, + 3272339035UL, 1667003847UL, 3742634787UL, 942706520UL, 2301027215UL, + 1907791250UL, 2306299096UL, 1021173342UL, 1539334516UL, 2907834628UL, + 3199959207UL, 1556251860UL, 3642580275UL, 2355865416UL, 285806145UL, + 867932457UL, 1177354172UL, 3291107470UL, 4022765061UL, 1613380116UL, + 588147929UL, 650574324UL, 1236855601UL, 1371354511UL, 2085218212UL, + 1203081931UL, 420526905UL, 1022192219UL, 2903287064UL, 2470845899UL, + 3649873273UL, 2502333582UL, 3972385637UL, 4246356763UL, 199084157UL, + 1567178788UL, 2107121836UL, 4293612856UL, 1902910177UL, 332397359UL, + 83422598UL, 3614961721UL, 456321943UL, 2277615967UL, 2302518510UL, + 3258315116UL, 2521897172UL, 3900282042UL, 4186973154UL, 3146532165UL, + 2299685029UL, 3889120948UL, 1293301857UL, 187455105UL, 3395849230UL, + 913321567UL, 3093513909UL, 1440944571UL, 1923481911UL, 338680924UL, + 1204882963UL, 2739724491UL, 2886241328UL, 2408907774UL, 1299817192UL, + 2474012871UL, 45400213UL, 553186784UL, 134558656UL, 2180943666UL, + 2870807589UL, 76511085UL, 3053566760UL, 2516601415UL, 4172865902UL, + 1751297915UL, 1251975234UL, 2964780642UL, 1412975316UL, 2739978478UL, + 2171013719UL, 637935041UL, 975972384UL, 3044407449UL, 3111425639UL, + 1938684970UL, 2860857400UL, 13419586UL, 2772079268UL, 3484375614UL, + 3184054178UL, 159924837UL, 1386213021UL, 2765617231UL, 2523689118UL, + 1283505218UL, 3510789588UL, 4125878259UL, 2990287597UL, 2152014833UL, + 3084155970UL, 2815101609UL, 1932985704UL, 114887365UL, 1712687646UL, + 2550515629UL, 3299051916UL, 2022747614UL, 2143630992UL, 2244188960UL, + 3309469192UL, 3234358520UL, 800720365UL, 3278176634UL, 554357439UL, + 2415629802UL, 1620877315UL, 2389462898UL, 2229691332UL, 1007748450UL, + 1966873768UL, 2264971043UL, 1214524156UL, 346854700UL, 3471905342UL, + 3984889660UL, 4034246840UL, 216712649UL, 4027196762UL, 3754772604UL, + 2121785562UL, 2347070732UL, 7457687UL, 1443375102UL, 683948143UL, + 2940226032UL, 3211475670UL, 2836507357UL, 774899409UL, 1588968308UL, + 780438009UL, 3278878781UL, 2217181540UL, 2184194887UL, 1642129086UL, + 69346830UL, 297114710UL, 3841068188UL, 2631265450UL, 4167492314UL, + 2613519651UL, 1388582503UL, 2171556668UL, 1201873758UL, 2698772382UL, + 207791958UL, 3936134563UL, 3725025702UL, 3306317801UL, 1055730422UL, + 4069230694UL, 1767821343UL, 4252407395UL, 2422583118UL, 3158834399UL, + 3754582617UL, 1112422556UL, 376187931UL, 3137549150UL, 712221089UL, + 3300799453UL, 3868250200UL, 1165257666UL, 2494837767UL, 131304831UL, + 1619349427UL, 1958236644UL, 3678218946UL, 3651007751UL, 2261987899UL, + 1567368524UL, 2193599522UL, 3034394674UL, 2994602555UL, 3072727647UL, + 889094521UL, 1089692095UL, 1822324824UL, 3876999182UL, 1703361286UL, + 902229515UL, 4213728487UL, 3838170364UL, 672727494UL, 2240733828UL, + 3858539469UL, 1149254245UL, 4166055926UL, 4193525313UL, 1709921593UL, + 2278290377UL, 3190784116UL, 2919588882UL, 1012709717UL, 3640562031UL, + 2931984863UL, 3515665246UL, 250577343UL, 1147230194UL, 1183856202UL, + 3734511989UL, 3243867808UL, 3499383067UL, 2985115159UL, 2036821626UL, + 3298159553UL, 2726542838UL, 1686910320UL, 1778823772UL, 965412224UL, + 233509772UL, 3843098861UL, 1312622954UL, 500855830UL, 2950562091UL, + 1915683607UL, 3405781138UL, 596073719UL, 2195150546UL, 3381728478UL, + 546426436UL, 3527890868UL, 2324975353UL, 2241074266UL, 3992514859UL, + 2576108287UL, 4077653225UL, 2632319392UL, 3127212632UL, 917000669UL, + 2498161805UL, 3980835128UL, 2259526768UL, 1083920509UL, 1187452089UL, + 97018536UL, 3056075838UL, 2059706760UL, 2373335692UL, 182196406UL, + 2136713111UL, 1762080153UL, 1572125803UL, 1145919955UL, 1023966754UL, + 3921694345UL, 1632005969UL, 1418372326UL, 354407429UL, 2438288265UL, + 1620072033UL, 1586320921UL, 1044153697UL, 969324572UL, 613487980UL, + 4230993062UL, 397726764UL, 2194259193UL, 735511759UL, 2066049260UL, + 88093248UL, 1562536153UL, 2114157419UL, 3630951546UL, 589238503UL, + 3120654384UL, 2521793793UL, 2746692127UL, 2557723425UL, 889897693UL, + 2778878177UL, 643269509UL, 3342389831UL, 19218890UL, 3442706236UL, + 3314581273UL, 3503147052UL, 1546343434UL, 1448529060UL, 529038801UL, + 2748942264UL, 2213019208UL, 111314040UL, 2488697563UL, 1180642808UL, + 2605272289UL, 4207476668UL, 1502558669UL, 2972370981UL, 4204339995UL, + 1046225278UL, 992840610UL, 3847290298UL, 2387673094UL, 2221565747UL, + 1045901716UL, 3997739302UL, 1556952765UL, 1103336648UL, 279418400UL, + 2711316466UL, 2336215718UL, 2317900806UL, 974624729UL, 909575434UL, + 1675610631UL, 1922393214UL, 2054896570UL, 3197007361UL, 3932554569UL, + 1008619802UL, 3349254938UL, 113511461UL, 932630384UL, 2098759268UL, + 3436837432UL, 3119972401UL, 1612590197UL, 2281609013UL, 4174211248UL, + 4016332246UL, 2097525539UL, 1398632760UL, 1543697535UL, 2419227174UL, + 1676465074UL, 2882923045UL, 23216933UL, 808195649UL, 3690720147UL, + 484419260UL, 2254772642UL, 2975434733UL, 288528113UL, 204598404UL, + 589968818UL, 3021152400UL, 2463155141UL, 1397846755UL, 157285579UL, + 4230258857UL, 2469135246UL, 625357422UL, 3435224647UL, 465239124UL, + 1022535736UL, 2823317040UL, 274194469UL, 2214966446UL, 3661001613UL, + 518802547UL, 2293436304UL, 1335881988UL, 2247010176UL, 1856732584UL, + 1088028094UL, 1877563709UL, 1015352636UL, 1700817932UL, 2960695857UL, + 1882229300UL, 1666906557UL, 1838841022UL, 3983797810UL, 1667630361UL, + 385998221UL, 241341791UL, 403550441UL, 2629200403UL, 3552759102UL, + 2029750442UL, 2247999048UL, 2726665298UL, 2507798776UL, 2419064129UL, + 1266444923UL, 526255242UL, 2384866697UL, 1886200981UL, 3954956408UL, + 2171436866UL, 2295200753UL, 1047315850UL, 1967809707UL, 2860382973UL, + 3918334466UL, 3057439479UL, 952682588UL, 1925559679UL, 3112119050UL, + 3833190964UL, 1430139895UL, 2089165610UL, 3009202424UL, 3989186157UL, + 3395807230UL, 347600520UL, 120428923UL, 3017004655UL, 1384933954UL, + 303039929UL, 234010146UL, 2278760249UL, 315514836UL, 3987659575UL, + 1239335668UL, 2387869477UL, 3885908826UL, 1983922602UL, 698609264UL, + 3009002846UL, 1520611399UL, 809159940UL, 3089771783UL, 374838722UL, + 2789914419UL, 2500831937UL, 3751970335UL, 4279852547UL, 2362894437UL, + 1588814060UL, 1671213155UL, 434218829UL, 2126587176UL, 2002526422UL, + 2756464095UL, 141700479UL, 2965974322UL, 2211530172UL, 992085992UL, + 1943691492UL, 2705131817UL, 2519208889UL, 1938768395UL, 3949294294UL, + 354046666UL, 2158272751UL, 602858583UL, 0UL}; diff --git a/numpy/random/src/mt19937/mt19937-poly.h b/numpy/random/src/mt19937/mt19937-poly.h deleted file mode 100644 index b03747881..000000000 --- a/numpy/random/src/mt19937/mt19937-poly.h +++ /dev/null @@ -1,207 +0,0 @@ -static const char * poly = -"0001000111110111011100100010101111000000010100100101000001110111100010101000110100101001011001010" -"1110101101100101011100101101011001110011100011110100001000001011100101100010100000010011101110011" -"0100001001111010000100100101001011100111101101001100000111001000011101100100010000001111110100010" -"0000111101000101000101101111001011000011001001001011010011001000001000011100100010110101111111101" -"0010001001100010011011101111101110111010111000010000011010110011111101100000100100101001010000001" -"1001111000011010011101001101011000111001110010110000011000110101111010110011011000001110110010001" -"1001101011011101000011001011111111100011001010111100000001111011111101000101000011000011111100101" -"0100001111101010101100000110100110010010101011011100110011000101100101011110010101110000101011100" -"0001010100010110100000111001100000011101011001101000001000101101010100010101100000100011110110011" -"0101100110111101010111100010100110100011111011100111000001110110010000000100000110101010111001111" -"0011110010000110101101010001110010100111111111100100101010010011101111011000010111101001110110110" -"1011101101101100110111000100101100111001011111110101001000011111010011000111110011100100001101111" -"1001010110110001000100001001000010000000001011011100101010010100011000110101001000010101100111101" -"0011110101100110111100000111001011011001100101111011000101001011011111110110100010001100101001100" -"1111110011111111110111011011100011000100110011011011011001101011100110010001111100001111100100001" -"1000100011001010100101010100111110001100111111011111100100011110011101101000110100101110010111111" -"1001010110000101001110010110001011011010101111111001110001100100011001000010111001011011000111100" -"1101001011110111111010011000110100001010000000101010101001111101111110101111110101110101010010100" -"1100100101010110011111001101100110001011000101010001000110011011111101111110001100000010110110101" -"1111110100001011101011101110111101100001111000011100000110110100100100100101011000111000100110001" -"0110110001001000111110101111000000100100010100100101101111100011010100111101110010000001011111111" -"1101010000011001010101111001111110001111100010100010100001011001110001010010100001011111110110111" -"1100100100001111000111110111000100010101010110100111100001011001101001111101001110010110110011010" -"1000010011000110000000110110110000111010010000111001100010100101010101111100010111000000011101110" -"1100011010110001101100110000001010001100111101101011100111110111000110010011011011001101001111100" -"1011111001100011010110101111100110111101011100000011000010001010001101001011000001111000101000100" -"0110001011001010110000001101100000011000011110010000101000011010011110001101111111010010101100100" -"1111010100000011011001111111011011111001101110101010110111110110101000100001011110111010100111100" -"0000001001111100111111111000100000100100010001011001100001111100100000001111011101100010011000111" -"0011110110100011011001110011100011011000010000000101101101001010111000010000010101111110000000100" -"1011010100001001000011001100011000000111100111100101010100000111000000110111011101011111100010101" -"0011001100110000010101111001000111001001010100011000110010011011101001001100101100000000111000111" -"0111111000010010010100000101010010000100101011111111111001100101101010011010100010111001011100011" -"1001001011010000110000111100010110110100000100110010000010010000001000110010101000110101101100100" -"0001100001100011110110010000100000100010011001010010110111100011011000101011001100001111110110110" -"0001100110010100011001101000100001110011011111101001101011110011011011111110111110101110010011001" -"1000000101100000101100100000100000001011000100100001100100101101010111101010111101010001001010110" -"0011111011001101001110110010100100000011001001111010001001100101110000000010111101000111111101010" -"0110101110101110001001110000111110100000101101100110010001111101111011001000101110111010110111110" -"0011001101011010001011000010000111111111101001011100110101011000000001111000101100011101011011100" -"1111101110000000000110001110011001101100111111010001110000111110100011000100001100110010000110111" -"1001011011001111011100000000011011000100000011000010010111000111101000011001001100011010001111000" -"0011110010100010001101011101010011001100000010101001001101111101000111001110110000000010111101001" -"1110110011101110111010011100101001010101100100011111100110001111011111110010100000011100110110001" -"1011100000101000010100011101000010111100101111101100110001010001010000101110000000110100010110011" -"1111110100101010011010100001100110110110011111110010000100001010011110010110001000000100000111000" -"0111001010011001000010111001100110100110110101111011110111001001000101010010010011000111110010101" -"1100110001100101001000010001101010011001110011001110001110010100010000000000000110111001010101000" -"0111111011011101000111011001011011000101110100010001111100101110000100001011111101111101010011001" -"0010001100011011101100010010101011001000001001010101100110001111001110011100110111111010110010001" -"1111111101111001001101101001001010011001110000101000110010111110010110111111000100101000101011010" -"0000101101101100000110101000101000010001111000100000111110011111111110010010001010001111011001100" -"0011110111000000111111000100001111101110100010101011001010110110011001010010001011100001010110101" -"0100000010101101000011001101110010000010110011000101100100000111111100011001110011010011001110000" -"1110011110000000001001001010100000111001010110001110011100011010010010001110010011001010111100000" -"1110000101101001011010001001010000111000010011010100001010110000101101110110011000011100111100001" -"1001000011010001110110111001100100001111110010110010011111000010100000001101110100000000101101000" -"0011000000100011000111110001000011100111110110000110101111101100011110100111111000000011011110110" -"1101011010111010010001001101000110110010000010101000000001100100100000001111011001001010110100011" -"1011000010101111010111000001001100111110000010110010011011110011111001000101111011010011010100001" -"0110011111100001011111101010010100110001001001001000100010101011011000011100111000110101110000001" -"1100001111100011110010000101011000010101111010001101010101100001100101100000100100000101011001100" -"0011001000101010101010100111000100100010101000111111101010000000101010101001000101010100100111001" -"1001100001010001100110111101010001111010011100000001001110100010010011110100001000011111100010001" -"0010001000100110101011001110100110101110110110100101111000110101101101001000001110011010110011001" -"0111111101011011101001111001011100001010110111000001100010110110100011010111011000111010100011000" -"1111010110001001010000110001000101101100010100000000100001111100000010111001000011000101010100001" -"0001101100011100010100101110010100000010011011010100000111110110000110101011011010010001110000111" -"0110101000110101110010011100010010100111001101110110010001101001101101010100001010001110111011011" -"1010011001010111101001011000100111001110011000000001101000001111001100001100000011001110100110011" -"0011000110001001010111111111110110111111000111100010010101110000101100101000001010001011010100010" -"1010010100010011101111100111010010010001110101011110110100001000001001000111001110010001001100100" -"1100100010001010011011110100000101101011101010110110100100010001110000111010111001111011111001011" -"0000000000011000100100100111001000101111000000110001011110101111110111100000000100101011000111011" -"1011010011101000001011001001110001111010000100101101010111001010001000100001000111011010000110111" -"1010110001001110001100001110011000101100000101100000000110101000000110101100100101110001100100100" -"0110000110101011100001010001010000011101111011111011011000100100101011110101111000001011110010110" -"0111011011100111101010110001111011010011111000010111110100001001010001011001000110111100000101011" -"0010111111010100000110111101001100000100001011101010100011010010000001101100100101001000100011000" -"0101010111111100100000111011101111100000011011111111010001100011001100101101011110101011101100001" -"0100010011101111111011000111111101001000101101111001111000101110010111001010101011010111000000101" -"0110010000010010101111100010111110000000011101001000011111001011111100111100100101100101111010110" -"1010101001110011111100111110100000111100100000111111000010100001111011111110110010001001000000000" -"1110100110010111100101111111001010001111001101100001011000111011100010100001000010100000011001000" -"0000111000110111001001100010111010100111111001111101100101000011001001110011100110101110001101110" -"1110000010110110010110000111001110110000011011100111000101100101000000001110011011001001111001111" -"0000101100001000000111100110110000110111111001101001111111010000001011110011011011100100110000110" -"1001011111101100100111111000000010001110111011010011011101001100000011001010000010101111111010110" -"0001000100101110101101100001001010100110010000110110100110011001000111011110110011001110111110101" -"0000011111011011001111010010101011000010011101001011100001010001111001000110000010000101010011111" -"0110011000001111101001110001101011111111001010010110100001101000000011101000101011101000110101111" -"0000101110011010010000110100000101100011000100101111100011001111011101001010100111001110100001101" -"0000110111011000000110011001101011110000101100110110000101100000110110100001001001110001110001001" -"1100110111111100101001100010010110011011110001000111111111001101111110010000011001011010111101001" -"1101111110101110110100101100110001101101001010111101101000000011111111100101000101110001000011001" -"1000111110111011010010101011110110110001010001001001100111111010011101111000000111011000011010011" -"0111010101001110010100101101000110000110001100010101001110101011010100000110110111111111110011110" -"0100011110100011001000110101111010000001011011110101001100111100010100101100010000010110011001111" -"0011011110001110010010100100011111110000110011011100010110110101001110011010101111011001010101011" -"1001001111001000001100100111000001000110110101100111000101011000000100001000100010011000001110011" -"0000111100000111001101011111010000010001100000010101101000111100001000010011110000001011001001100" -"0011011011111011100000111101001011101000010010001001111110010101111010110101101110110111010000101" -"1100011000000000110110100011010100100010001101010101101110110111111011010110011101011010110101011" -"1101000000010010011111000000101000110001000011100001101111010101100000100000100111111111100000000" -"0011100011100101110010111100010111110010101110101000011000111111001110111111000001101101011011111" -"1100110101001000011111001111000000001010001001010101101000001100111010101100010111001001111100000" -"1110101101110001011100011101101100001001001011100111100110011101111000100010010001111100001010010" -"1011001001010100101100010010000110010000101010111111001000011100000000101101110010001101110101001" -"1110000011100101010000011110000010001000001010110001010000100111001100110001111000100100011100110" -"1100010011110111001001100000100111001010000000000011100011111111101110010101111010100010000100001" -"0101101001010111111110000110110010100000001011110100010111110111010000001011110110111000000110010" -"0001100100111110001100010101000010011111100000100010000101110000111001101100100000011111111100010" -"1001101101001000001111000100100001010110111011110110001001010001110001001100011001001100000000101" -"1100011110101101011001100001010110001010000111100000011011011001000010101100010101110011001101110" -"0000101011010001010011111001011000010101010100110110111110101000111110001000010100000000100010100" -"1000111111000110110010001111000010101011101101111101011110101111100111111100111101000101000010011" -"0010111010100010011001000000010111100010000101001011001101100011100001001111010100100110101111111" -"1000010011110101001010011111111011101001110100001001100010000100001001100101101111011100100011001" -"1111010001011001111101011110101101000111110101001010011101010010010101001000000000011001100110001" -"0001000010101010101000010100111000001110000111001110001101111111000010101010111001011101001001011" -"0011001111011010101110101111110001001100100111010001011000010100000100000001001100000011000011101" -"1100000110000001011001110000101001010111101000110101000011000000111011100101010000111000010010101" -"1010100101100001011011011110110011000100100101010011111101000000100001001101000011000101010111101" -"1110111111100010111000111000010110111010010110000000000100101001000111101101100000000110111011001" -"0100000000100100011110111011101101101101010110001110100001100001001011000000111111110100011110011" -"0010000010000000010100110011110000000010000011111000111101011110000000000010101101001100000010010" -"1011001001101110110011100001100011101001101011110011010001011101000100011111001010100000011111111" -"1010101100000010001000110000110000101000110100110011100000110010110100011111010001000011100001001" -"1000101000010111111011100010111000111001010100110000000010011011101010101111000110001000110111011" -"1011100001100011010001101011010100110110011100000010111001011111110010100110100010001100000011100" -"0001011001011000101011010000001010011010001011000111000011000011110011111001111010001101011010010" -"0010010001001001101000101001011011101110001100010001010100010111111001100100000010001111100010111" -"0100001111001100101001011101010010110010100010001100011010100110000100011010111110001011011001000" -"1001001111011010010011101110100001111100000110101001010111110001101100110010111010111001011111010" -"1110111011111110000001110010000010011111000111011011000011000010011110011111111101100101111011100" -"0101101100000110101110000111111111111010110101010100111000011111011001100000100000101011000101110" -"1011010010100000000100100000010111101110111001000011111011111110100011010010000110001101111101100" -"1100010111001011011001011001010100100110100101001000111011011001100011001010010101111001100100110" -"1000110000111011100101110101101000011001010010100011000001111001110110101101010010110110001100100" -"0100001011101100111001010001111011010110010010110010110111110001001001111001111010010001010001101" -"1110100110101100011110100100110111000111010110011000100100110110001101111100111110100001000110000" -"1110011011001101100101100000001010100011101000010100111011111100011010000110000001011100010000101" -"0100101000010001110010001100010110011111111101111000011001110111011100110010010100100010001000010" -"0100001110010000011000110001101011101001110100100011011001000111010101110100110011010111001100001" -"0100001001101010010111110101110111000000010100111101011010101001000001001000001000101101111000000" -"0110000101110100001111001101110111011110010111101000100101110111010101001101100001110001101101101" -"0010101100100101000100100100110111000111000111100111000001100001000111101011000110111110001010000" -"0100110010001101100011010111000111010111000111110000110000101111101110010110111001011000111010001" -"1011000010010101010010011001000011010110111011010001001010100111001000010110110110101110000110000" -"1110110010011001011011000100011101001001000111011100100000000000100001101101000101000100000111001" -"0011100001100110101011011101110111101111000100100011100001010001011001110010101010001110101101110" -"1011001110111111111010101101000010111111011011011100011100101010001011011100011111011100101011000" -"1000110100101000011111010011110000000101101110010000101100001000100000000010010110000000000110011" -"1000000000001111001001000100000111001110111111001111101100001100111000101100011000100111111110011" -"1110010101011010111100110010110001010000101111111101001010100010001001111010111000010000010010001" -"1111111101100100001101011011100001010101000111110111111101011010011111111101000111011001011011000" -"0000101011100011101110110011101111011110011110010000011001111001110111011011111010011011001110111" -"0101100111110100000100010110010010101001010100010111000101111001011011001001110010100011101111110" -"1101011110010101101011010010011111110000011010011101000000010000111010100100111110111000001101010" -"0101100001111001111010101011110001001010000011010110010100011100100100111110100110000010011111001" -"0100010011001001010101110111111010011101101100000101011110111010011110001111110100111011110011010" -"0111001010110101010110000011001010000000101101010101001101011000011011010110101010101111101101100" -"1100100000111101010111011011011110011001100010010000010100101000111111101011100111010101011000111" -"1100110010101100010011111100000110011111101011100100001110001100001010101001001100010011001000100" -"1101101000101101110010000001101001001110101111000110111000011101111110100100110111000000101011110" -"0001100100001010101001101111001000001100000011010000100101100000001110100010010000110110101010111" -"1100010100000110011100101010111110010110111100000010110011011001011110111001010011011110010001110" -"1101110000001011101101011111101011111110110110000111110011101100110100010000100000110100010010110" -"0011000011000110101001110100111010110000100010110101110111100010110001000111100111001011011110010" -"0001001110101001101101011010111001001101100011101001011011001110011010001010110100111001111100101" -"1000111001010010000010111010101110001100110111111000011101001000001010010011101000111001100111110" -"1110100100100110010111111101010011101111011011111011011010011110100101100001011000001001001010010" -"1100001000000110110011011101010001011110010001001110110100100001101101001011101010001110111111010" -"1100011100101000011110111110110011111111100010110010110111010010001111101110011011010110000001000" -"0010110100010101110100001000010011100110001110001110010100010010010110011100100110010100001110011" -"1100001011010000001101011011011110100000001110100111001000101000001000001001000010000111010000100" -"0111100000101010110010111010010101100000001100110101001001000110001110111011110001010010010011000" -"1100001111101101100001111000101100110010001000111001101101011110100110100011101000011111011010101" -"0101000011111010010110001001100110110111000100100011011101000010001010110001111001111101110001111" -"0100100000010111010011111110000101001001011110100100010011101110011010100101100001010000001110100" -"0011111101111000100110011000011001100100001010110011111100111010100011110100010101011110011001000" -"0000110000100100001011101110111010001001011110010101111100001111101101111011011110001010000100010" -"1001100100100100110010010101100110000000100000000111110011100111101001010000010000000000101011100" -"0011101011100110000001100101010101011111111011010011110010011011001010011101010010100010001011010" -"1100010011101011010111110100001010100011000011001001011011101111110011001110010001100101011001101" -"0100010001111111100000101000001011010100011100111011010111001100110110001100110101000011010001010" -"1011100001001010011110001010100100001101110011101011100100101010001100110011110010001100100001000" -"0110001001110110010111101011101101010111001010011010101110000010100010000111011000010110011000001" -"1000110010100001110001100010010000001101111110000010010110100000000000001111110010001110111100001" -"0100111101000011101110010101011011000101011010111100111111001011110001110011110011011010010111101" -"1010111011101101000001110111001010011001110010100100100100001010001100101010111001110100000110111" -"1010000111000011101101100101101001100000011100100111100110010110011100101000111110111000110111110" -"1101100101011101100111011111111001111000011110111110101100000111000101100100110111000010100101000" -"0110000011011101111101111000110101011000010111010000111011000000100011101010100111001111101010111" -"0001110100001000100001011101001010001110100000101100001011101111100111101011111001111100101101111" -"0101100001110011111110110100110010000011011111101101110110000110110011100110111000111101000010111" -"0111101011100100000000011101111011000100001000111000000111011010101010110000111111101010110001111" -"0000110100111101111011001010101110000011001101001101000010011001101011111110111101010111010011100" -"0101010011001111101111001100101000101000111110111001011111100000001101111011000001001100111111111" -"1010111101000001111011110010001001001110100111110010000011110000011000000101001100011110110011001" -"1010101001000010001010110000010011110101011110010111010001010111101100001001100011101001111101001" -"0110110100111001110011100011111010010010100010111000001100001011010010000100100110101010111001001" -"0110000101011011011100110111111001010000001001011010101010010001011010111100111010101101000101101" -"0100100001011101110111111001111111110110111011000101010000010000011111001000100101100100100110110" -"1100000111110010110011010100000100011111110001110010110001000001001111001101110110110101101010111" -"0000100111101100010001110010110111100011100101100011"; diff --git a/numpy/random/src/mt19937/mt19937.c b/numpy/random/src/mt19937/mt19937.c index e5ca9e0cf..bec518af8 100644 --- a/numpy/random/src/mt19937/mt19937.c +++ b/numpy/random/src/mt19937/mt19937.c @@ -1,6 +1,5 @@ #include "mt19937.h" #include "mt19937-jump.h" -#include "mt19937-poly.h" void mt19937_seed(mt19937_state *state, uint32_t seed) { int pos; @@ -104,4 +103,4 @@ extern inline uint32_t mt19937_next32(mt19937_state *state); extern inline double mt19937_next_double(mt19937_state *state); -void mt19937_jump(mt19937_state *state) { mt19937_jump_state(state, poly); } +void mt19937_jump(mt19937_state *state) { mt19937_jump_state(state); } diff --git a/numpy/random/tests/test_generator_mt19937.py b/numpy/random/tests/test_generator_mt19937.py index a28b7ca11..f72b748ba 100644 --- a/numpy/random/tests/test_generator_mt19937.py +++ b/numpy/random/tests/test_generator_mt19937.py @@ -1,4 +1,5 @@ import sys +import hashlib import pytest @@ -13,6 +14,26 @@ from numpy.random import Generator, MT19937, SeedSequence random = Generator(MT19937()) +JUMP_TEST_DATA = [ + { + "seed": 0, + "steps": 10, + "initial": {"key_md5": "64eaf265d2203179fb5ffb73380cd589", "pos": 9}, + "jumped": {"key_md5": "8cb7b061136efceef5217a9ce2cc9a5a", "pos": 598}, + }, + { + "seed":384908324, + "steps":312, + "initial": {"key_md5": "e99708a47b82ff51a2c7b0625b81afb5", "pos": 311}, + "jumped": {"key_md5": "2ecdbfc47a895b253e6e19ccb2e74b90", "pos": 276}, + }, + { + "seed": [839438204, 980239840, 859048019, 821], + "steps": 511, + "initial": {"key_md5": "9fcd6280df9199785e17e93162ce283c", "pos": 510}, + "jumped": {"key_md5": "433b85229f2ed853cde06cd872818305", "pos": 475}, + }, +] @pytest.fixture(scope='module', params=[True, False]) def endpoint(request): @@ -462,7 +483,6 @@ class TestIntegers: assert_array_equal(scalar, array) def test_repeatability(self, endpoint): - import hashlib # We use a md5 hash of generated sequences of 1000 samples # in the range [0, 6) for all but bool, where the range # is [0, 2). Hashes are for little endian numbers. @@ -487,7 +507,7 @@ class TestIntegers: val = random.integers(0, 6 - endpoint, size=1000, endpoint=endpoint, dtype=dt).byteswap() - res = hashlib.md5(val.view(np.int8)).hexdigest() + res = hashlib.md5(val).hexdigest() assert_(tgt[np.dtype(dt).name] == res) # bools do not depend on endianness @@ -885,8 +905,6 @@ class TestRandomDist: assert actual.dtype == np.int64 def test_choice_large_sample(self): - import hashlib - choice_hash = 'd44962a0b1e92f4a3373c23222244e21' random = Generator(MT19937(self.seed)) actual = random.choice(10000, 5000, replace=False) @@ -2351,3 +2369,31 @@ class TestSingleEltArrayInput: out = func(self.argOne, self.argTwo[0], self.argThree) assert_equal(out.shape, self.tgtShape) + + +@pytest.mark.parametrize("config", JUMP_TEST_DATA) +def test_jumped(config): + # Each config contains the initial seed, a number of raw steps + # the md5 hashes of the initial and the final states' keys and + # the position of of the initial and the final state. + # These were produced using the original C implementation. + seed = config["seed"] + steps = config["steps"] + + mt19937 = MT19937(seed) + # Burn step + mt19937.random_raw(steps) + key = mt19937.state["state"]["key"] + if sys.byteorder == 'big': + key = key.byteswap() + md5 = hashlib.md5(key) + assert mt19937.state["state"]["pos"] == config["initial"]["pos"] + assert md5.hexdigest() == config["initial"]["key_md5"] + + jumped = mt19937.jumped() + key = jumped.state["state"]["key"] + if sys.byteorder == 'big': + key = key.byteswap() + md5 = hashlib.md5(key) + assert jumped.state["state"]["pos"] == config["jumped"]["pos"] + assert md5.hexdigest() == config["jumped"]["key_md5"] |