1
unit LUX.Random.WELL.P19937;
3
{ http://www.iro.umontreal.ca/~panneton/WELLRNG.html }
5
interface //#################################################################### ■
12
type //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$【型】
14
TRandom32WEL19937a = class;
15
TRandom32WEL19937c = class;
16
TRandom32WEL19937anew = class;
18
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$【レコード】
20
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% TSeed32WEL19937a
22
TSeed32WEL19937a = record
27
MASKU = $ffffffff shr ( W - P );
34
function GetV0 :Int32u;
35
procedure SetV0( const V0_:Int32u );
36
function GetVM1Over :Int32u;
37
procedure SetVM1Over( const VM1Over_:Int32u );
38
function GetVM1 :Int32u;
39
procedure SetVM1( const VM1_:Int32u );
40
function GetVM2Over :Int32u;
41
procedure SetVM2Over( const VM2Over_:Int32u );
42
function GetVM2 :Int32u;
43
procedure SetVM2( const VM2_:Int32u );
44
function GetVM3Over :Int32u;
45
procedure SetVM3Over( const VM3Over_:Int32u );
46
function GetVM3 :Int32u;
47
procedure SetVM3( const VM3_:Int32u );
48
function GetVRm1 :Int32u;
49
procedure SetVRm1( const VRm1_:Int32u );
50
function GetVRm1Under :Int32u;
51
procedure SetVRm1Under( const VRm1Under_:Int32u );
52
function GetVRm2 :Int32u;
53
procedure SetVRm2( const VRm2_:Int32u );
54
function GetVRm2Under :Int32u;
55
procedure SetVRm2Under( const VRm2Under_:Int32u );
56
function GetnewV0 :Int32u;
57
procedure SetnewV0( const newV0_:Int32u );
58
function GetnewV0Under :Int32u;
59
procedure SetnewV0Under( const newV0Under_:Int32u );
60
function GetnewV1 :Int32u;
61
procedure SetnewV1( const newV1_:Int32u );
62
function GetnewVRm1 :Int32u;
63
procedure SetnewVRm1( const newVRm1_:Int32u );
64
function GetnewVRm1Under :Int32u;
65
procedure SetnewVRm1Under( const newVRm1Under_:Int32u );
67
function GetnewVM2Over :Int32u;
68
procedure SetnewVM2Over( const newVM2Over_:Int32u );
69
function GetnewVM2 :Int32u;
70
procedure SetnewVM2( const newVM2_:Int32u );
73
STATE :array [ 0..R-1 ] of Int32u;
76
property V0 :Int32u read GetV0 write SetV0 ;
77
property VM1Over :Int32u read GetVM1Over write SetVM1Over ;
78
property VM1 :Int32u read GetVM1 write SetVM1 ;
79
property VM2Over :Int32u read GetVM2Over write SetVM2Over ;
80
property VM2 :Int32u read GetVM2 write SetVM2 ;
81
property VM3Over :Int32u read GetVM3Over write SetVM3Over ;
82
property VM3 :Int32u read GetVM3 write SetVM3 ;
83
property VRm1 :Int32u read GetVRm1 write SetVRm1 ;
84
property VRm1Under :Int32u read GetVRm1Under write SetVRm1Under ;
85
property VRm2 :Int32u read GetVRm2 write SetVRm2 ;
86
property VRm2Under :Int32u read GetVRm2Under write SetVRm2Under ;
87
property newV0 :Int32u read GetnewV0 write SetnewV0 ;
88
property newV0Under :Int32u read GetnewV0Under write SetnewV0Under ;
89
property newV1 :Int32u read GetnewV1 write SetnewV1 ;
90
property newVRm1 :Int32u read GetnewVRm1 write SetnewVRm1 ;
91
property newVRm1Under :Int32u read GetnewVRm1Under write SetnewVRm1Under;
93
property newVM2Over :Int32u read GetnewVM2Over write SetnewVM2Over ;
94
property newVM2 :Int32u read GetnewVM2 write SetnewVM2 ;
97
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$【クラス】
99
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% TRandom32WEL19937a
101
TRandom32WEL19937a = class( TRandomWEL<TSeed32WEL19937a> )
110
procedure CalcNextSeed; override;
111
function CalcRandInt32u :Int32u; override;
113
constructor CreateFromRand( const Random_:IRandom ); overload; override;
115
function MAT0POS( const t:Int32u; const v:Int32u ) :Int32u; inline;
116
function MAT0NEG( const t:Int32s; const v:Int32u ) :Int32u; inline;
117
function MAT1( const v:Int32u ) :Int32u; inline;
118
function MAT3POS( const t:Int32u; const v:Int32u ) :Int32u; inline;
121
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% TRandom32WEL19937c
123
TRandom32WEL19937c = class( TRandom32WEL19937a )
130
function CalcRandInt32u :Int32u; override;
134
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% TRandom32WEL19937anew
136
TRandom32WEL19937anew = class( TRandom32WEL19937a )
142
function CalcRandInt32u :Int32u; override;
146
//const //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$【定数】
148
//var //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$【変数】
150
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$【ルーチン】
152
implementation //############################################################### ■
154
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$【レコード】
156
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% TSeed32WEL19937a
158
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& private
160
/////////////////////////////////////////////////////////////////////// アクセス
162
function TSeed32WEL19937a.GetV0 :Int32u;
164
Result := STATE[ state_i ];
167
procedure TSeed32WEL19937a.SetV0( const V0_:Int32u );
169
STATE[ state_i ] := V0_;
172
function TSeed32WEL19937a.GetVM1Over :Int32u;
174
Result := STATE[ state_i+M1-R ];
177
procedure TSeed32WEL19937a.SetVM1Over( const VM1Over_:Int32u );
179
STATE[ state_i+M1-R ] := VM1Over_;
182
function TSeed32WEL19937a.GetVM1 :Int32u;
184
Result := STATE[ state_i+M1 ];
187
procedure TSeed32WEL19937a.SetVM1( const VM1_:Int32u );
189
STATE[ state_i+M1 ] := VM1_;
192
function TSeed32WEL19937a.GetVM2Over :Int32u;
194
Result := STATE[ state_i+M2-R ];
197
procedure TSeed32WEL19937a.SetVM2Over( const VM2Over_:Int32u );
199
STATE[ state_i+M2-R ] := VM2Over_;
202
function TSeed32WEL19937a.GetVM2 :Int32u;
204
Result := STATE[ state_i+M2 ];
207
procedure TSeed32WEL19937a.SetVM2( const VM2_:Int32u );
209
STATE[ state_i+M2 ] := VM2_;
212
function TSeed32WEL19937a.GetVM3Over :Int32u;
214
Result := STATE[ state_i+M3-R ];
217
procedure TSeed32WEL19937a.SetVM3Over( const VM3Over_:Int32u );
219
STATE[ state_i+M3-R ] := VM3Over_;
222
function TSeed32WEL19937a.GetVM3 :Int32u;
224
Result := STATE[ state_i+M3 ];
227
procedure TSeed32WEL19937a.SetVM3( const VM3_:Int32u );
229
STATE[ state_i+M3 ] := VM3_;
232
function TSeed32WEL19937a.GetVRm1 :Int32u;
234
Result := STATE[ state_i-1 ];
237
procedure TSeed32WEL19937a.SetVRm1( const VRm1_:Int32u );
239
STATE[ state_i-1 ] := VRm1_;
242
function TSeed32WEL19937a.GetVRm1Under :Int32u;
244
Result := STATE[ state_i+R-1 ];
247
procedure TSeed32WEL19937a.SetVRm1Under( const VRm1Under_:Int32u );
249
STATE[ state_i+R-1 ] := VRm1Under_;
252
function TSeed32WEL19937a.GetVRm2 :Int32u;
254
Result := STATE[ state_i-2 ];
257
procedure TSeed32WEL19937a.SetVRm2( const VRm2_:Int32u );
259
STATE[ state_i-2 ] := VRm2_;
262
function TSeed32WEL19937a.GetVRm2Under :Int32u;
264
Result := STATE[ state_i+R-2 ];
267
procedure TSeed32WEL19937a.SetVRm2Under( const VRm2Under_:Int32u );
269
STATE[ state_i+R-2 ] := VRm2Under_;
272
function TSeed32WEL19937a.GetnewV0 :Int32u;
274
Result := STATE[ state_i-1 ];
277
procedure TSeed32WEL19937a.SetnewV0( const newV0_:Int32u );
279
STATE[ state_i-1 ] := newV0_;
282
function TSeed32WEL19937a.GetnewV0Under :Int32u;
284
Result := STATE[ state_i-1+R ];
287
procedure TSeed32WEL19937a.SetnewV0Under( const newV0Under_:Int32u );
289
STATE[ state_i-1+R ] := newV0Under_;
292
function TSeed32WEL19937a.GetnewV1 :Int32u;
294
Result := STATE[ state_i ];
297
procedure TSeed32WEL19937a.SetnewV1( const newV1_:Int32u );
299
STATE[ state_i ] := newV1_;
302
function TSeed32WEL19937a.GetnewVRm1 :Int32u;
304
Result := STATE[ state_i-2 ];
307
procedure TSeed32WEL19937a.SetnewVRm1( const newVRm1_:Int32u );
309
STATE[ state_i-2 ] := newVRm1_;
312
function TSeed32WEL19937a.GetnewVRm1Under :Int32u;
314
Result := STATE[ state_i-2+R ];
317
procedure TSeed32WEL19937a.SetnewVRm1Under( const newVRm1Under_:Int32u );
319
STATE[ state_i-2+R ] := newVRm1Under_;
324
function TSeed32WEL19937a.GetnewVM2Over :Int32u;
326
Result := STATE[ state_i+M2-R+1 ];
329
procedure TSeed32WEL19937a.SetnewVM2Over( const newVM2Over_:Int32u );
331
STATE[ state_i+M2-R+1 ] := newVM2Over_;
334
function TSeed32WEL19937a.GetnewVM2 :Int32u;
336
Result := STATE[ state_i+M2+1 ];
339
procedure TSeed32WEL19937a.SetnewVM2( const newVM2_:Int32u );
341
STATE[ state_i+M2+1 ] := newVM2_;
344
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& public
346
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$【クラス】
348
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% TRandom32WEL19937a
350
{ http://www.iro.umontreal.ca/~panneton/well/WELL19937a.c }
352
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& private
354
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& protected
356
/////////////////////////////////////////////////////////////////////// メソッド
358
procedure TRandom32WEL19937a.case_1;
364
z0 := ( VRm1Under and MASKL )
365
or ( VRm2Under and MASKU );
366
z1 := MAT0NEG( -25, V0 )
367
xor MAT0POS( +27, VM1 );
368
z2 := MAT3POS( +09, VM2 )
369
xor MAT0POS( +01, VM3 );
372
newV0Under := MAT1( z0 )
373
xor MAT0NEG( -09, z1 )
374
xor MAT0NEG( -21, z2 )
375
xor MAT0POS( +21, newV1 );
383
procedure TRandom32WEL19937a.case_2;
389
z0 := ( VRm1 and MASKL )
390
or ( VRm2Under and MASKU );
391
z1 := MAT0NEG( -25, V0 )
392
xor MAT0POS( +27, VM1 );
393
z2 := MAT3POS( +09, VM2 )
394
xor MAT0POS( +01, VM3 );
398
xor MAT0NEG( -09, z1 )
399
xor MAT0NEG( -21, z2 )
400
xor MAT0POS( +21, newV1 );
408
procedure TRandom32WEL19937a.case_3;
414
z0 := ( VRm1 and MASKL )
415
or ( VRm2 and MASKU );
416
z1 := MAT0NEG( -25, V0 )
417
xor MAT0POS( +27, VM1Over );
418
z2 := MAT3POS( +09, VM2Over )
419
xor MAT0POS( +01, VM3Over );
423
xor MAT0NEG( -09, z1 )
424
xor MAT0NEG( -21, z2 )
425
xor MAT0POS( +21, newV1 );
433
procedure TRandom32WEL19937a.case_4;
439
z0 := ( VRm1 and MASKL )
440
or ( VRm2 and MASKU );
441
z1 := MAT0NEG( -25, V0 )
442
xor MAT0POS( +27, VM1 );
443
z2 := MAT3POS( +09, VM2 )
444
xor MAT0POS( +01, VM3Over );
448
xor MAT0NEG( -09, z1 )
449
xor MAT0NEG( -21, z2 )
450
xor MAT0POS( +21, newV1 );
458
procedure TRandom32WEL19937a.case_5;
464
z0 := ( VRm1 and MASKL )
465
or ( VRm2 and MASKU );
466
z1 := MAT0NEG( -25, V0 )
467
xor MAT0POS( +27, VM1 );
468
z2 := MAT3POS( +09, VM2Over )
469
xor MAT0POS( +01, VM3Over );
473
xor MAT0NEG( -09, z1 )
474
xor MAT0NEG( -21, z2 )
475
xor MAT0POS( +21, newV1 );
481
procedure TRandom32WEL19937a.case_6;
487
z0 := ( VRm1 and MASKL )
488
or ( VRm2 and MASKU );
489
z1 := MAT0NEG( -25, V0 )
490
xor MAT0POS( +27, VM1 );
491
z2 := MAT3POS( +09, VM2 )
492
xor MAT0POS( +01, VM3 );
496
xor MAT0NEG( -09, z1 )
497
xor MAT0NEG( -21, z2 )
498
xor MAT0POS( +21, newV1 );
504
//------------------------------------------------------------------------------
506
procedure TRandom32WEL19937a.CalcNextSeed;
513
3: if state_i + M1 < R then case_i := 5;
514
4: if state_i + M3 < R then case_i := 6;
515
5: if state_i + M2 < R then case_i := 4;
516
6: if state_i = 1 then case_i := 2;
520
1: case_1; // 0 = state_i
521
2: case_2; // 1 = state_i
522
3: case_3; // R-M1 <= state_i
523
4: case_4; // R-M3 <= state_i
524
5: case_5; // R-M2 <= state_i
525
6: case_6; // 2 <= state_i <= R-M3-1
530
function TRandom32WEL19937a.CalcRandInt32u :Int32u;
535
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& public
537
constructor TRandom32WEL19937a.CreateFromRand( const Random_:IRandom );
544
for I := 0 to R-1 do STATE[ I ] := Random_.DrawRandInt32u;
553
/////////////////////////////////////////////////////////////////////// メソッド
555
function TRandom32WEL19937a.MAT0POS( const t:Int32u; const v:Int32u ) :Int32u;
557
Result := v xor ( v shr +t );
560
function TRandom32WEL19937a.MAT0NEG( const t:Int32s; const v:Int32u ) :Int32u;
562
Result := v xor ( v shl -t );
565
function TRandom32WEL19937a.MAT1( const v:Int32u ) :Int32u;
570
function TRandom32WEL19937a.MAT3POS( const t:Int32u; const v:Int32u ) :Int32u;
575
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% TRandom32WEL19937c
577
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& private
579
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& protected
581
/////////////////////////////////////////////////////////////////////// メソッド
583
function TRandom32WEL19937c.CalcRandInt32u :Int32u;
587
Result := STATE[ state_i ] xor ( ( STATE[ state_i ] shl 07 ) and TEMPERB );
588
Result := Result xor ( ( Result shl 15 ) and TEMPERC );
592
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& public
594
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% TRandom32WEL19937anew
596
{ http://www.ritsumei.ac.jp/~harase/WELL19937a_new.c }
598
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& private
600
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& protected
602
/////////////////////////////////////////////////////////////////////// メソッド
604
function TRandom32WEL19937anew.CalcRandInt32u :Int32u;
609
1: Result := STATE[ state_i ] xor ( newVM2Over and BITMASK );
610
2: Result := STATE[ state_i ] xor ( newVM2 and BITMASK );
611
3: Result := STATE[ state_i ] xor ( newVM2Over and BITMASK );
612
4: Result := STATE[ state_i ] xor ( newVM2 and BITMASK );
613
5: Result := STATE[ state_i ] xor ( newVM2Over and BITMASK );
614
6: Result := STATE[ state_i ] xor ( newVM2 and BITMASK );
620
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& public
622
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$【ルーチン】
624
//############################################################################## □
626
initialization //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ 初期化
628
finalization //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ 最終化
630
end. //######################################################################### ■