1classdef MT19937 < handle
2 % MT19937 Bit-exact reimplementation of numpy
's legacy MT19937 core,
3 % matching the generator underlying numpy.random.RandomState.
5 % Reproduces numpy's exact 32-bit output stream so that NumpyRandomState
6 % and
the differential-evolution optimizer generate identical draws to
the
7 % native-Python line-opt
for a given seed. Seeding follows numpy
's
8 % _legacy_seeding: a scalar seed that fits in 32 bits uses init_genrand;
9 % otherwise the seed words are fed to init_by_array.
12 mt % 1x624 uint32 state
13 mti % scalar position (numpy get_state pos)
17 function obj = MT19937(seed)
18 obj.mt = zeros(1, 624, 'uint32
');
24 if s <= uint64(4294967295)
25 obj.initGenrand(uint32(s));
29 key(end+1) = uint32(bitand(s, uint64(4294967295))); %#ok<AGROW>
36 function initGenrand(obj, s)
37 obj.mt(1) = uint32(s);
39 prev = uint64(obj.mt(ii));
40 x = bitxor(prev, bitshift(prev, -30));
41 val = uint64(1812433253) * x + uint64(ii);
42 obj.mt(ii+1) = uint32(bitand(val, uint64(4294967295)));
47 function initByArray(obj, initKey)
48 obj.initGenrand(uint32(19650218));
50 % numpy-style 0-based ii,jj; MATLAB mt[ii] == mt(ii+1), mt[ii-1] == mt(ii).
54 prev = uint64(obj.mt(ii)); % mt[i-1] in numpy == mt(ii) here (ii is 1-based == numpy i)
55 mixed = bitxor(prev, bitshift(prev, -30));
56 term = uint64(bitand(uint64(mixed) * uint64(1664525), uint64(4294967295)));
57 val = bitxor(uint64(obj.mt(ii+1)), term);
58 val = mod(uint64(val) + uint64(initKey(jj+1)) + uint64(jj), uint64(4294967296));
59 obj.mt(ii+1) = uint32(val);
60 ii = ii + 1; jj = jj + 1;
62 obj.mt(1) = obj.mt(624);
71 prev = uint64(obj.mt(ii));
72 mixed = bitxor(prev, bitshift(prev, -30));
73 term = uint64(bitand(uint64(mixed) * uint64(1566083941), uint64(4294967295)));
74 val = bitxor(uint64(obj.mt(ii+1)), term);
75 val = mod(uint64(val) - uint64(ii) + uint64(4294967296), uint64(4294967296));
76 obj.mt(ii+1) = uint32(val);
79 obj.mt(1) = obj.mt(624);
83 obj.mt(1) = uint32(2147483648); % 0x80000000
87 function y = nextUint32(obj)
89 MATRIX_A = uint32(2567483615); % 0x9908b0df
90 UPPER = uint32(2147483648); % 0x80000000
91 LOWER = uint32(2147483647); % 0x7fffffff
94 yv = bitor(bitand(obj.mt(kk), UPPER), bitand(obj.mt(kk+1), LOWER));
96 if bitand(yv, uint32(1)) ~= 0
99 obj.mt(kk) = bitxor(bitxor(obj.mt(kk+M), bitshift(yv, -1)), mag);
101 for kk = (N-M+1):(N-1)
102 yv = bitor(bitand(obj.mt(kk), UPPER), bitand(obj.mt(kk+1), LOWER));
104 if bitand(yv, uint32(1)) ~= 0
107 obj.mt(kk) = bitxor(bitxor(obj.mt(kk+(M-N)), bitshift(yv, -1)), mag);
109 yv = bitor(bitand(obj.mt(N), UPPER), bitand(obj.mt(1), LOWER));
111 if bitand(yv, uint32(1)) ~= 0
114 obj.mt(N) = bitxor(bitxor(obj.mt(M), bitshift(yv, -1)), mag);
118 y = obj.mt(obj.mti + 1);
119 obj.mti = obj.mti + 1;
120 y = bitxor(y, bitshift(y, -11));
121 y = bitxor(y, bitand(bitshift(y, 7), uint32(2636928640))); % 0x9d2c5680
122 y = bitxor(y, bitand(bitshift(y, 15), uint32(4022730752))); % 0xefc60000
123 y = bitxor(y, bitshift(y, -18));
126 function key = getStateKey(obj)