-
+ 51A08CE52E8DF06FC1CAC9D4DFD9EBFED15EACFBE86011D481326668D17007482E2998F516F29CAA2A4175154D3CE60C8A805F7A6214B609A2CD613E7649B5AEudp/libmt/mt.adb(0 . 0)(1 . 128)
 10  -- Ada implementation of the Mersenne Twister Pseudo-Random number generator
 11  -- S.MG, 2018
 12 
 13 
 14 package body MT is
 15 
 16   procedure Init_Genrand(Seed : in U32) is
 17   begin
 18     State(0) := Seed;
 19     for I in State'First + 1 .. State'Last loop
 20       State(I) := U32(1812433253) *
 21                   ( State(I - 1) xor 
 22                     ( Shift_Right(State(I - 1), 30) ) 
 23                   ) + U32(I) ;
 24     end loop;
 25     Mti_Flag := N;
 26   end Init_Genrand;
 27 
 28   procedure Init_Genrand(Seed : in Init_Array_Type) is
 29     Default_Seed: constant U32 := U32(19650218); -- magic value!
 30     I, J, K : Integer;
 31   begin
 32     Init_Genrand(Default_Seed);
 33     I := 1;
 34     J := 0;
 35     if N > Seed'Length then
 36       K := N;
 37     else
 38       K := Seed'Length;
 39     end if;
 40 
 41     while K > 0 loop
 42       State(I) := (State(I) xor 
 43                   ( (State(I-1) xor 
 44                      Shift_Right(State(I-1), 30)
 45                     ) * U32(1664525)
 46                   )) + Seed(J) + U32(J);
 47       I := I + 1;
 48       J := J + 1;
 49       if I >= N then
 50         State(0) := State(N-1);
 51         I := 1;
 52       end if;
 53       if J >= Seed'Length then
 54         J := 0;
 55       end if;
 56       K := K - 1;               
 57     end loop;
 58 
 59     K := N -1;
 60     while K > 0 loop
 61       State(I) := (State(I) xor 
 62                   ( (State(I-1) xor 
 63                      Shift_Right(State(I-1), 30)
 64                     ) * U32(1566083941)
 65                   )) - U32(I); 
 66       I := I + 1;
 67       if I >= N then
 68         State(0) := State(N-1);
 69         I := 1;
 70       end if;     
 71       K := K - 1;
 72     end loop;
 73     State(0) := 16#8000_0000#; -- MSB is 1 to ensure non-zero initial state
 74   end Init_Genrand;
 75 
 76   function Gen_U32 return U32 is
 77     Y     : U32;
 78     MASK1 : constant U32 := U32(1);
 79     Mag01 : Array ( 0 .. 1 ) of U32;
 80   begin
 81     -- Mag01[x] is x * Matrix_A of the algorithm for x 0 or 1
 82     Mag01(0) := U32(0);
 83     Mag01(1) := MATRIX_MASK;
 84 
 85     -- if no numbers available, generate another set of N words
 86     if Mti_Flag >= N then
 87 
 88       -- check it's not a non-initialised generator
 89       if Mti_Flag = (N + 1) then
 90          -- Generator was NOT initialised!
 91          -- Original C code initialises with default seed 5489
 92          -- This code will simply raise exception and abort
 93          raise No_Init_Exception;
 94       end if;
 95 
 96       for K in 0 .. N - M - 1 loop
 97         Y := ( State(K)   and UPPER_MASK ) or
 98              ( State(K+1) and LOWER_MASK );
 99         State(K) := State(K+M) xor 
100                       Shift_Right(Y, 1) xor 
101                         Mag01(Integer(Y and MASK1));
102       end loop;
103       for K in N-M .. N - 2 loop
104         Y := ( State(K)   and UPPER_MASK  ) or
105              ( State(K+1) and LOWER_MASK);
106         State(K) := State(K + M - N) xor
107                       Shift_Right(Y, 1) xor 
108                         Mag01(Integer(Y and MASK1));
109       end loop;
110       Y := (State(N-1) and UPPER_MASK ) or
111              (State(0) and LOWER_MASK );
112       State(N - 1) := State(M-1) xor 
113                         Shift_Right(Y, 1) xor
114                           Mag01(Integer(Y and MASK1));
115       Mti_Flag := 0;
116     end if;
117 
118     -- retrieve next available number
119     Y        := State(Integer(Mti_Flag));
120     Mti_Flag := Mti_Flag + 1;
121 
122     -- tempering
123     Y := Y xor Shift_Right(Y, 11);
124     Y := Y xor (Shift_Left(Y, 7) and 16#9d2c_5680#);
125     Y := Y xor (Shift_Left(Y, 15) and 16#efc6_0000#);
126     Y := Y xor Shift_Right(Y, 18);
127 
128     -- return tempered number
129     return Y;
130   end Gen_U32;
131 
132   function Get_State return State_Type is
133   begin
134     return State;
135   end Get_State;
136 
137 end MT;