1
unit LUX.Random.PCG.B32;
3
interface //#################################################################### ■
10
type //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$【型】
13
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$【レコード】
15
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% T_pcg_state_32
17
(* Representations for the oneseq, mcg, and unique variants *)
19
T_pcg_state_32 = record
25
T_pcg32s_random_t = T_pcg_state_64;
26
T_pcg32u_random_t = T_pcg_state_64;
27
T_pcg32f_random_t = T_pcg_state_64;
29
T_pcg32si_random_t = T_pcg_state_32;
31
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% T_pcg_state_setseq_32
33
(* Representations setseq variants *)
35
T_pcg_state_setseq_32 = record
42
T_pcg32_random_t = T_pcg_state_setseq_64;
44
T_pcg32i_random_t = T_pcg_state_setseq_32;
46
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$【クラス】
48
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% TRandom32PCG<_TSeed_>
50
{ http://www.pcg-random.org/using-pcg-c.html }
52
TRandom32PCG<_TSeed_:record> = class( TRandomPCG<_TSeed_> )
56
function CalcRandInt08u :Int08u; override;
57
function CalcRandInt16u :Int16u; override;
58
function CalcRandInt64u :Int64u; override;
61
// Rotate helper functions.
62
class function pcg_rotr_8( value:Int08u; rot:Int32u ) :Int08u;
63
class function pcg_rotr_16( value:Int16u; rot:Int32u ) :Int16u;
64
class function pcg_rotr_32( value:Int32u; rot:Int32u ) :Int32u;
65
class function pcg_rotr_64( value:Int64u; rot:Int32u ) :Int64u;
67
class function pcg_output_xsh_rs_32_16( state:Int32u ) :Int16u;
69
class function pcg_output_xsh_rr_32_16( state:Int32u ) :Int16u;
71
class function pcg_output_rxs_m_xs_32_32( state:Int32u ) :Int32u;
74
// Multi-step advance functions (jump-ahead, jump-back)
75
class function pcg_advance_lcg_32( state,delta,cur_mult,cur_plus:Int32u ) :Int32u;
76
// Functions to advance the underlying LCG
77
class procedure pcg_oneseq_32_step_r( var rng:T_pcg_state_32 );
78
class procedure pcg_oneseq_32_advance_r( var rng:T_pcg_state_32; delta:Int32u );
79
class procedure pcg_mcg_32_step_r( var rng:T_pcg_state_32 );
80
class procedure pcg_mcg_32_advance_r( var rng:T_pcg_state_32; delta:Int32u );
81
class procedure pcg_unique_32_step_r( var rng:T_pcg_state_32 );
82
class procedure pcg_unique_32_advance_r( var rng:T_pcg_state_32; delta:Int32u );
83
class procedure pcg_setseq_32_step_r( var rng:T_pcg_state_setseq_32 );
84
class procedure pcg_setseq_32_advance_r( var rng:T_pcg_state_setseq_32; delta:Int32u );
85
{ Functions to seed the RNG state }
86
class procedure pcg_oneseq_32_srandom_r( var rng:T_pcg_state_32; initstate:Int32u );
87
class procedure pcg_mcg_32_srandom_r( var rng:T_pcg_state_32; initstate:Int32u );
88
class procedure pcg_unique_32_srandom_r( var rng:T_pcg_state_32; initstate:Int32u );
89
class procedure pcg_setseq_32_srandom_r( var rng:T_pcg_state_setseq_32; initstate:Int32u; initseq:Int32u );
90
{ Generation functions for XSH RS }
91
class function pcg_oneseq_32_xsh_rs_16_random_r( var rng:T_pcg_state_32 ) :Int16u;
92
class function pcg_oneseq_32_xsh_rs_16_boundedrand_r( var rng:T_pcg_state_32; bound:Int16u ) :Int16u;
94
class function pcg_unique_32_xsh_rs_16_random_r( var rng:T_pcg_state_32 ) :Int16u;
95
class function pcg_unique_32_xsh_rs_16_boundedrand_r( var rng:T_pcg_state_32; bound:Int16u ) :Int16u;
97
class function pcg_setseq_32_xsh_rs_16_random_r( var rng:T_pcg_state_setseq_32 ) :Int16u;
98
class function pcg_setseq_32_xsh_rs_16_boundedrand_r( var rng:T_pcg_state_setseq_32; bound:Int16u ) :Int16u;
100
class function pcg_mcg_32_xsh_rs_16_random_r( var rng:T_pcg_state_32 ) :Int16u;
101
class function pcg_mcg_32_xsh_rs_16_boundedrand_r( var rng:T_pcg_state_32; bound:Int16u ) :Int16u;
102
{ Generation functions for XSH RR }
103
class function pcg_oneseq_32_xsh_rr_16_random_r( var rng:T_pcg_state_32 ) :Int16u;
104
class function pcg_oneseq_32_xsh_rr_16_boundedrand_r( var rng:T_pcg_state_32; bound:Int16u ) :Int16u;
106
class function pcg_unique_32_xsh_rr_16_random_r( var rng:T_pcg_state_32 ) :Int16u;
107
class function pcg_unique_32_xsh_rr_16_boundedrand_r( var rng:T_pcg_state_32; bound:Int16u ) :Int16u;
109
class function pcg_setseq_32_xsh_rr_16_random_r( var rng:T_pcg_state_setseq_32 ) :Int16u;
110
class function pcg_setseq_32_xsh_rr_16_boundedrand_r( var rng:T_pcg_state_setseq_32; bound:Int16u ) :Int16u;
112
class function pcg_mcg_32_xsh_rr_16_random_r( var rng:T_pcg_state_32 ) :Int16u;
113
class function pcg_mcg_32_xsh_rr_16_boundedrand_r( var rng:T_pcg_state_32; bound:Int16u ) :Int16u;
114
{ Generation functions for RXS M XS }
115
class function pcg_oneseq_32_rxs_m_xs_32_random_r( var rng:T_pcg_state_32 ) :Int32u;
116
class function pcg_oneseq_32_rxs_m_xs_32_boundedrand_r( var rng:T_pcg_state_32; bound:Int32u ) :Int32u;
118
class function pcg_unique_32_rxs_m_xs_32_random_r( var rng:T_pcg_state_32 ) :Int32u;
119
class function pcg_unique_32_rxs_m_xs_32_boundedrand_r( var rng:T_pcg_state_32; bound:Int32u ) :Int32u;
121
class function pcg_setseq_32_rxs_m_xs_32_random_r( var rng:T_pcg_state_setseq_32 ) :Int32u;
122
class function pcg_setseq_32_rxs_m_xs_32_boundedrand_r( var rng:T_pcg_state_setseq_32; bound:Int32u ) :Int32u;
123
{ Generation functions for XSL RR }
124
{ Generation functions for XSL RR RR }
126
class function pcg32_random_r( var rng:T_pcg_state_setseq_64 ) :Int32u; inline;
127
class function pcg32s_random_r( var rng:T_pcg_state_64 ) :Int32u; inline;
128
class function pcg32u_random_r( var rng:T_pcg_state_64 ) :Int32u; inline;
129
class function pcg32f_random_r( var rng:T_pcg_state_64 ) :Int32u; inline;
130
class function pcg32si_random_r( var rng:T_pcg_state_32 ) :Int32u; inline;
131
class function pcg32i_random_r( var rng:T_pcg_state_setseq_32 ) :Int32u; inline;
133
class function pcg32_boundedrand_r( var rng:T_pcg_state_setseq_64; bound:Int32u ) :Int32u; inline;
134
class function pcg32s_boundedrand_r( var rng:T_pcg_state_64; bound:Int32u ) :Int32u; inline;
135
class function pcg32u_boundedrand_r( var rng:T_pcg_state_64; bound:Int32u ) :Int32u; inline;
136
class function pcg32f_boundedrand_r( var rng:T_pcg_state_64; bound:Int32u ) :Int32u; inline;
137
class function pcg32si_boundedrand_r( var rng:T_pcg_state_32; bound:Int32u ) :Int32u; inline;
138
class function pcg32i_boundedrand_r( var rng:T_pcg_state_setseq_32; bound:Int32u ) :Int32u; inline;
140
class procedure pcg32_srandom_r( var rng:T_pcg_state_setseq_64; initstate:Int64u; initseq:Int64u ); inline;
141
class procedure pcg32s_srandom_r( var rng:T_pcg_state_64; initstate:Int64u ); inline;
142
class procedure pcg32u_srandom_r( var rng:T_pcg_state_64; initstate:Int64u ); inline;
143
class procedure pcg32f_srandom_r( var rng:T_pcg_state_64; initstate:Int64u ); inline;
144
class procedure pcg32si_srandom_r( var rng:T_pcg_state_32; initstate:Int32u ); inline;
145
class procedure pcg32i_srandom_r( var rng:T_pcg_state_setseq_32; initstate:Int32u; initseq:Int32u ); inline;
147
class procedure pcg32_advance_r( var rng:T_pcg_state_setseq_64; delta:Int64u ); inline;
148
class procedure pcg32s_advance_r( var rng:T_pcg_state_64; delta:Int64u ); inline;
149
class procedure pcg32u_advance_r( var rng:T_pcg_state_64; delta:Int64u ); inline;
150
class procedure pcg32f_advance_r( var rng:T_pcg_state_64; delta:Int64u ); inline;
151
class procedure pcg32si_advance_r( var rng:T_pcg_state_32; delta:Int32u ); inline;
152
class procedure pcg32i_advance_r( var rng:T_pcg_state_setseq_32; delta:Int32u ); inline;
155
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% TRandom32PCG32
157
TRandom32PCG32 = class( TRandom32PCG<T_pcg_state_32> )
161
procedure CalcNextSeed; override;
162
function CalcRandInt32u :Int32u; override;
164
constructor CreateFromRand( const Random_:IRandom ); overload; override;
167
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% TRandom32PCG32x31
169
TRandom32PCG32x31 = class( TRandom32PCG<T_pcg_state_setseq_32> )
173
procedure CalcNextSeed; override;
174
function CalcRandInt32u :Int32u; override;
176
constructor CreateFromRand( const Random_:IRandom ); overload; override;
179
const //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$【定数】
181
PCG_DEFAULT_MULTIPLIER_32 :Int32u = 747796405;
182
PCG_DEFAULT_INCREMENT_32 :Int32u = 2891336453;
185
* Static initialization constants (if you can't call srandom for some
189
PCG_STATE_ONESEQ_32_INITIALIZER :T_pcg_state_32 = ( state:$46b56677 );
190
PCG_STATE_UNIQUE_32_INITIALIZER :T_pcg_state_32 = ( state:$46b56677 ); //= PCG_STATE_ONESEQ_32_INITIALIZER
191
PCG_STATE_MCG_32_INITIALIZER :T_pcg_state_32 = ( state:$d15ea5e5 );
192
PCG_STATE_SETSEQ_32_INITIALIZER :T_pcg_state_setseq_32 = ( state:$ec02d89b; inc:$94b95bdb );
194
PCG_STATE_ONESEQ_64_INITIALIZER :T_pcg_state_64 = ( state:$4d595df4d0f33173 );
195
PCG_STATE_UNIQUE_64_INITIALIZER :T_pcg_state_64 = ( state:$4d595df4d0f33173 ); //= PCG_STATE_ONESEQ_64_INITIALIZER
196
PCG_STATE_MCG_64_INITIALIZER :T_pcg_state_64 = ( state:$cafef00dd15ea5e5 );
197
PCG_STATE_SETSEQ_64_INITIALIZER :T_pcg_state_setseq_64 = ( state:$853c49e6748fea9b; inc:$da3e39cb94b95bdb );
199
PCG32_INITIALIZER :T_pcg_state_setseq_64 = ( state:$853c49e6748fea9b; inc:$da3e39cb94b95bdb ); //= PCG_STATE_SETSEQ_64_INITIALIZER
200
PCG32U_INITIALIZER :T_pcg_state_64 = ( state:$4d595df4d0f33173 ); //= PCG_STATE_UNIQUE_64_INITIALIZER
201
PCG32S_INITIALIZER :T_pcg_state_64 = ( state:$4d595df4d0f33173 ); //= PCG_STATE_ONESEQ_64_INITIALIZER
202
PCG32F_INITIALIZER :T_pcg_state_64 = ( state:$cafef00dd15ea5e5 ); //= PCG_STATE_MCG_64_INITIALIZER
203
PCG32SI_INITIALIZER :T_pcg_state_32 = ( state:$46b56677 ); //= PCG_STATE_ONESEQ_32_INITIALIZER
204
PCG32I_INITIALIZER :T_pcg_state_setseq_32 = ( state:$ec02d89b; inc:$94b95bdb ); //= PCG_STATE_SETSEQ_32_INITIALIZER
206
//var //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$【変数】
208
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$【ルーチン】
210
implementation //############################################################### ■
214
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$【レコード】
216
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$【クラス】
218
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% TRandom32PCG<_TSeed_>
220
{ https://github.com/imneme/pcg-c }
222
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& private
224
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& protected
226
/////////////////////////////////////////////////////////////////////// メソッド
228
function TRandom32PCG<_TSeed_>.CalcRandInt08u :Int08u;
230
Result := CalcRandInt16u shr 08;
233
function TRandom32PCG<_TSeed_>.CalcRandInt16u :Int16u;
235
Result := CalcRandInt32u shr 16;
238
function TRandom32PCG<_TSeed_>.CalcRandInt64u :Int64u;
240
Result := Int64u( CalcRandInt32u ) shl 32 or CalcRandInt32u;
243
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& public
245
/////////////////////////////////////////////////////////////////////// メソッド
247
{ https://github.com/imneme/pcg-c/blob/master/include/pcg_variants.h }
250
* Rotate helper functions.
253
class function TRandom32PCG<_TSeed_>.pcg_rotr_8( value:Int08u; rot:Int32u ) :Int08u;
255
(* Unfortunately, clang is kinda pathetic when it comes to properly
256
* recognizing idiomatic rotate code, so for clang we actually provide
257
* assembler directives (enabled with PCG_USE_INLINE_ASM). Boo, hiss.
260
Result := ( value shr rot ) or ( value shl ( -rot and 07 ) );
263
class function TRandom32PCG<_TSeed_>.pcg_rotr_16( value:Int16u; rot:Int32u ) :Int16u;
265
Result := ( value shr rot ) or ( value shl ( -rot and 15 ) );
268
class function TRandom32PCG<_TSeed_>.pcg_rotr_32( value:Int32u; rot:Int32u ) :Int32u;
270
Result := ( value shr rot ) or ( value shl ( -rot and 31 ) );
273
class function TRandom32PCG<_TSeed_>.pcg_rotr_64( value:Int64u; rot:Int32u ) :Int64u;
275
Result := ( value shr rot ) or ( value shl ( -rot and 63 ) );
279
* Output functions. These are the core of the PCG generation scheme.
284
class function TRandom32PCG<_TSeed_>.pcg_output_xsh_rs_32_16( state:Int32u ) :Int16u;
286
Result := Int16u( ( ( state shr 11 ) xor state ) shr ( ( state shr 30 ) + 11 ) );
291
class function TRandom32PCG<_TSeed_>.pcg_output_xsh_rr_32_16( state:Int32u ) :Int16u;
293
Result := pcg_rotr_16( ( ( state shr 10 ) xor state ) shr 12, state shr 28 );
298
class function TRandom32PCG<_TSeed_>.pcg_output_rxs_m_xs_32_32( state:Int32u ) :Int32u;
302
word := ( ( state shr ( ( state shr 28 ) + 4 ) ) xor state ) * 277803737;
304
Result := ( word shr 22 ) xor word;
307
// XSL RR (only defined for >= 64 bits)
309
// XSL RR RR (only defined for >= 64 bits)
311
(* Functions to advance the underlying LCG, one version for each size and
312
* each style. These functions are considered semi-private. There is rarely
313
* a good reason to call them directly.
316
class procedure TRandom32PCG<_TSeed_>.pcg_oneseq_32_step_r( var rng:T_pcg_state_32 );
318
rng.state := rng.state * PCG_DEFAULT_MULTIPLIER_32 + PCG_DEFAULT_INCREMENT_32;
321
class procedure TRandom32PCG<_TSeed_>.pcg_oneseq_32_advance_r( var rng:T_pcg_state_32; delta:Int32u );
323
rng.state := pcg_advance_lcg_32( rng.state, delta, PCG_DEFAULT_MULTIPLIER_32, PCG_DEFAULT_INCREMENT_32 );
326
class procedure TRandom32PCG<_TSeed_>.pcg_mcg_32_step_r( var rng:T_pcg_state_32 );
328
rng.state := rng.state * PCG_DEFAULT_MULTIPLIER_32;
331
class procedure TRandom32PCG<_TSeed_>.pcg_mcg_32_advance_r( var rng:T_pcg_state_32; delta:Int32u );
333
rng.state := pcg_advance_lcg_32( rng.state, delta, PCG_DEFAULT_MULTIPLIER_32, 0 );
336
class procedure TRandom32PCG<_TSeed_>.pcg_unique_32_step_r( var rng:T_pcg_state_32 );
338
rng.state := rng.state * PCG_DEFAULT_MULTIPLIER_32 + Int32u( IntPtr( @rng ) or 1 );
341
class procedure TRandom32PCG<_TSeed_>.pcg_unique_32_advance_r( var rng:T_pcg_state_32; delta:Int32u );
343
rng.state := pcg_advance_lcg_32( rng.state, delta, PCG_DEFAULT_MULTIPLIER_32, Int32u( IntPtr( @rng ) or 1 ) );
346
class procedure TRandom32PCG<_TSeed_>.pcg_setseq_32_step_r( var rng:T_pcg_state_setseq_32 );
348
rng.state := rng.state * PCG_DEFAULT_MULTIPLIER_32 + rng.inc;
351
class procedure TRandom32PCG<_TSeed_>.pcg_setseq_32_advance_r( var rng:T_pcg_state_setseq_32; delta:Int32u );
353
rng.state := pcg_advance_lcg_32( rng.state, delta, PCG_DEFAULT_MULTIPLIER_32, rng.inc );
356
(* Multi-step advance functions (jump-ahead, jump-back) *)
358
{ https://github.com/imneme/pcg-c/blob/master/src/pcg-advance-32.c }
360
class function TRandom32PCG<_TSeed_>.pcg_advance_lcg_32( state,delta,cur_mult,cur_plus:Int32u ) :Int32u;
362
acc_mult, acc_plus :Int32u;
369
if delta and 1 <> 0 then
371
acc_mult := acc_mult * cur_mult;
372
acc_plus := acc_plus * cur_mult + cur_plus;
375
cur_plus := ( cur_mult + 1 ) * cur_plus;
376
cur_mult := cur_mult * cur_mult;
378
delta := delta div 2;
381
Result := acc_mult * state + acc_plus;
384
(* Functions to seed the RNG state, one version for each size and each
385
* style. Unlike the step functions, regular users can and should call
389
class procedure TRandom32PCG<_TSeed_>.pcg_oneseq_32_srandom_r( var rng:T_pcg_state_32; initstate:Int32u );
392
pcg_oneseq_32_step_r( rng );
393
rng.state := rng.state + initstate;
394
pcg_oneseq_32_step_r( rng );
397
class procedure TRandom32PCG<_TSeed_>.pcg_mcg_32_srandom_r( var rng:T_pcg_state_32; initstate:Int32u );
399
rng.state := initstate or 1;
402
class procedure TRandom32PCG<_TSeed_>.pcg_unique_32_srandom_r( var rng:T_pcg_state_32; initstate:Int32u );
405
pcg_unique_32_step_r( rng );
406
rng.state := rng.state + initstate;
407
pcg_unique_32_step_r( rng );
410
class procedure TRandom32PCG<_TSeed_>.pcg_setseq_32_srandom_r( var rng:T_pcg_state_setseq_32; initstate:Int32u; initseq:Int32u );
413
rng.inc := ( initseq shl 1 ) or 1;
414
pcg_setseq_32_step_r( rng );
415
rng.state := rng.state + initstate;
416
pcg_setseq_32_step_r( rng );
419
(* Generation functions for XSH RS *)
421
class function TRandom32PCG<_TSeed_>.pcg_oneseq_32_xsh_rs_16_random_r( var rng:T_pcg_state_32 ) :Int16u;
425
oldstate := rng.state;
426
pcg_oneseq_32_step_r( rng );
427
Result := pcg_output_xsh_rs_32_16( oldstate );
430
class function TRandom32PCG<_TSeed_>.pcg_oneseq_32_xsh_rs_16_boundedrand_r( var rng:T_pcg_state_32; bound:Int16u ) :Int16u;
432
threshold, r :Int16u;
434
threshold := Int16u( -bound ) mod bound;
437
r := pcg_oneseq_32_xsh_rs_16_random_r( rng );
439
until r >= threshold;
441
Result := r mod bound;
444
//------------------------------------------------------------------------------
446
class function TRandom32PCG<_TSeed_>.pcg_unique_32_xsh_rs_16_random_r( var rng:T_pcg_state_32 ) :Int16u;
450
oldstate := rng.state;
451
pcg_unique_32_step_r( rng );
452
Result := pcg_output_xsh_rs_32_16( oldstate );
455
class function TRandom32PCG<_TSeed_>.pcg_unique_32_xsh_rs_16_boundedrand_r( var rng:T_pcg_state_32; bound:Int16u ) :Int16u;
457
threshold, r :Int16u;
459
threshold := Int16u( -bound ) mod bound;
462
r := pcg_unique_32_xsh_rs_16_random_r( rng );
464
until r >= threshold;
466
Result := r mod bound;
469
//------------------------------------------------------------------------------
471
class function TRandom32PCG<_TSeed_>.pcg_setseq_32_xsh_rs_16_random_r( var rng:T_pcg_state_setseq_32 ) :Int16u;
475
oldstate := rng.state;
476
pcg_setseq_32_step_r( rng );
477
Result := pcg_output_xsh_rs_32_16( oldstate );
480
class function TRandom32PCG<_TSeed_>.pcg_setseq_32_xsh_rs_16_boundedrand_r( var rng:T_pcg_state_setseq_32; bound:Int16u ) :Int16u;
482
threshold, r :Int16u;
484
threshold := Int16u( -bound ) mod bound;
487
r := pcg_setseq_32_xsh_rs_16_random_r( rng );
489
until r >= threshold;
491
Result := r mod bound;
494
//------------------------------------------------------------------------------
496
class function TRandom32PCG<_TSeed_>.pcg_mcg_32_xsh_rs_16_random_r( var rng:T_pcg_state_32 ) :Int16u;
500
oldstate := rng.state;
501
pcg_mcg_32_step_r( rng );
502
Result := pcg_output_xsh_rs_32_16( oldstate );
505
class function TRandom32PCG<_TSeed_>.pcg_mcg_32_xsh_rs_16_boundedrand_r( var rng:T_pcg_state_32; bound:Int16u ) :Int16u;
507
threshold, r :Int16u;
509
threshold := Int16u( -bound ) mod bound;
512
r := pcg_mcg_32_xsh_rs_16_random_r( rng );
514
until r >= threshold;
516
Result := r mod bound;
519
//---------------------------------------------- Generation functions for XSH RR
521
class function TRandom32PCG<_TSeed_>.pcg_oneseq_32_xsh_rr_16_random_r( var rng:T_pcg_state_32 ) :Int16u;
525
oldstate := rng.state;
526
pcg_oneseq_32_step_r( rng );
527
Result := pcg_output_xsh_rr_32_16( oldstate );
530
class function TRandom32PCG<_TSeed_>.pcg_oneseq_32_xsh_rr_16_boundedrand_r( var rng:T_pcg_state_32; bound:Int16u ) :Int16u;
532
threshold, r :Int16u;
534
threshold := Int16u( -bound ) mod bound;
537
r := pcg_oneseq_32_xsh_rr_16_random_r( rng );
539
until r >= threshold;
541
Result := r mod bound;
544
//------------------------------------------------------------------------------
546
class function TRandom32PCG<_TSeed_>.pcg_unique_32_xsh_rr_16_random_r( var rng:T_pcg_state_32 ) :Int16u;
550
oldstate := rng.state;
551
pcg_unique_32_step_r( rng );
552
Result := pcg_output_xsh_rr_32_16( oldstate );
555
class function TRandom32PCG<_TSeed_>.pcg_unique_32_xsh_rr_16_boundedrand_r( var rng:T_pcg_state_32; bound:Int16u ) :Int16u;
557
threshold, r :Int16u;
559
threshold := Int16u( -bound ) mod bound;
562
r := pcg_unique_32_xsh_rr_16_random_r( rng );
564
until r >= threshold;
566
Result := r mod bound;
569
//------------------------------------------------------------------------------
571
class function TRandom32PCG<_TSeed_>.pcg_setseq_32_xsh_rr_16_random_r( var rng:T_pcg_state_setseq_32 ) :Int16u;
575
oldstate := rng.state;
576
pcg_setseq_32_step_r( rng );
577
Result := pcg_output_xsh_rr_32_16( oldstate );
580
class function TRandom32PCG<_TSeed_>.pcg_setseq_32_xsh_rr_16_boundedrand_r( var rng:T_pcg_state_setseq_32; bound:Int16u ) :Int16u;
582
threshold, r :Int16u;
584
threshold := Int16u( -bound ) mod bound;
587
r := pcg_setseq_32_xsh_rr_16_random_r( rng );
589
until r >= threshold;
591
Result := r mod bound;
594
//------------------------------------------------------------------------------
596
class function TRandom32PCG<_TSeed_>.pcg_mcg_32_xsh_rr_16_random_r( var rng:T_pcg_state_32 ) :Int16u;
600
oldstate := rng.state;
601
pcg_mcg_32_step_r( rng );
602
Result := pcg_output_xsh_rr_32_16( oldstate );
605
class function TRandom32PCG<_TSeed_>.pcg_mcg_32_xsh_rr_16_boundedrand_r( var rng:T_pcg_state_32; bound:Int16u ) :Int16u;
607
threshold, r :Int16u;
609
threshold := Int16u( -bound ) mod bound;
612
r := pcg_mcg_32_xsh_rr_16_random_r( rng );
614
until r >= threshold;
616
Result := r mod bound;
619
//-------------------------------------------- Generation functions for RXS M XS
621
class function TRandom32PCG<_TSeed_>.pcg_oneseq_32_rxs_m_xs_32_random_r( var rng:T_pcg_state_32 ) :Int32u;
625
oldstate := rng.state;
626
pcg_oneseq_32_step_r( rng );
627
Result := pcg_output_rxs_m_xs_32_32( oldstate );
630
class function TRandom32PCG<_TSeed_>.pcg_oneseq_32_rxs_m_xs_32_boundedrand_r( var rng:T_pcg_state_32; bound:Int32u ) :Int32u;
632
threshold, r :Int32u;
634
threshold := -bound mod bound;
637
r := pcg_oneseq_32_rxs_m_xs_32_random_r( rng );
639
until r >= threshold;
641
Result := r mod bound;
644
//------------------------------------------------------------------------------
646
class function TRandom32PCG<_TSeed_>.pcg_unique_32_rxs_m_xs_32_random_r( var rng:T_pcg_state_32 ) :Int32u;
650
oldstate := rng.state;
651
pcg_unique_32_step_r( rng );
652
Result := pcg_output_rxs_m_xs_32_32( oldstate );
655
class function TRandom32PCG<_TSeed_>.pcg_unique_32_rxs_m_xs_32_boundedrand_r( var rng:T_pcg_state_32; bound:Int32u ) :Int32u;
657
threshold, r :Int32u;
659
threshold := -bound mod bound;
662
r := pcg_unique_32_rxs_m_xs_32_random_r( rng );
664
until r >= threshold;
666
Result := r mod bound;
669
//------------------------------------------------------------------------------
671
class function TRandom32PCG<_TSeed_>.pcg_setseq_32_rxs_m_xs_32_random_r( var rng:T_pcg_state_setseq_32 ) :Int32u;
675
oldstate := rng.state;
676
pcg_setseq_32_step_r( rng );
677
Result := pcg_output_rxs_m_xs_32_32( oldstate );
680
class function TRandom32PCG<_TSeed_>.pcg_setseq_32_rxs_m_xs_32_boundedrand_r( var rng:T_pcg_state_setseq_32; bound:Int32u ) :Int32u;
682
threshold, r :Int32u;
684
threshold := -bound mod bound;
687
r := pcg_setseq_32_rxs_m_xs_32_random_r( rng );
689
until r >= threshold;
691
Result := r mod bound;
694
//---------------------------------------------- Generation functions for XSL RR
696
//------------------------------------------- Generation functions for XSL RR RR
698
/////////////////////////////////////////////////////////////////////// random_r
700
class function TRandom32PCG<_TSeed_>.pcg32_random_r( var rng:T_pcg_state_setseq_64 ) :Int32u;
702
Result := TRandom64PCG<_TSeed_>.pcg_setseq_64_xsh_rr_32_random_r( rng );
705
class function TRandom32PCG<_TSeed_>.pcg32s_random_r( var rng:T_pcg_state_64 ) :Int32u;
707
Result := TRandom64PCG<_TSeed_>.pcg_oneseq_64_xsh_rr_32_random_r( rng );
710
class function TRandom32PCG<_TSeed_>.pcg32u_random_r( var rng:T_pcg_state_64 ) :Int32u;
712
Result := TRandom64PCG<_TSeed_>.pcg_unique_64_xsh_rr_32_random_r( rng );
715
class function TRandom32PCG<_TSeed_>.pcg32f_random_r( var rng:T_pcg_state_64 ) :Int32u;
717
Result := TRandom64PCG<_TSeed_>.pcg_mcg_64_xsh_rs_32_random_r( rng );
720
class function TRandom32PCG<_TSeed_>.pcg32si_random_r( var rng:T_pcg_state_32 ) :Int32u;
722
Result := pcg_oneseq_32_rxs_m_xs_32_random_r( rng );
725
class function TRandom32PCG<_TSeed_>.pcg32i_random_r( var rng:T_pcg_state_setseq_32 ) :Int32u;
727
Result := pcg_setseq_32_rxs_m_xs_32_random_r( rng );
730
////////////////////////////////////////////////////////////////// boundedrand_r
732
class function TRandom32PCG<_TSeed_>.pcg32_boundedrand_r( var rng:T_pcg_state_setseq_64; bound:Int32u ) :Int32u;
734
Result := TRandom64PCG<_TSeed_>.pcg_setseq_64_xsh_rr_32_boundedrand_r( rng, bound );
737
class function TRandom32PCG<_TSeed_>.pcg32s_boundedrand_r( var rng:T_pcg_state_64; bound:Int32u ) :Int32u;
739
Result := TRandom64PCG<_TSeed_>.pcg_oneseq_64_xsh_rr_32_boundedrand_r( rng, bound );
742
class function TRandom32PCG<_TSeed_>.pcg32u_boundedrand_r( var rng:T_pcg_state_64; bound:Int32u ) :Int32u;
744
Result := TRandom64PCG<_TSeed_>.pcg_unique_64_xsh_rr_32_boundedrand_r( rng, bound );
747
class function TRandom32PCG<_TSeed_>.pcg32f_boundedrand_r( var rng:T_pcg_state_64; bound:Int32u ) :Int32u;
749
Result := TRandom64PCG<_TSeed_>.pcg_mcg_64_xsh_rs_32_boundedrand_r( rng, bound );
752
class function TRandom32PCG<_TSeed_>.pcg32si_boundedrand_r( var rng:T_pcg_state_32; bound:Int32u ) :Int32u;
754
Result := pcg_oneseq_32_rxs_m_xs_32_boundedrand_r( rng, bound );
757
class function TRandom32PCG<_TSeed_>.pcg32i_boundedrand_r( var rng:T_pcg_state_setseq_32; bound:Int32u ) :Int32u;
759
Result := pcg_setseq_32_rxs_m_xs_32_boundedrand_r( rng, bound );
762
////////////////////////////////////////////////////////////////////// srandom_r
764
class procedure TRandom32PCG<_TSeed_>.pcg32_srandom_r( var rng:T_pcg_state_setseq_64; initstate:Int64u; initseq:Int64u );
766
TRandom64PCG<_TSeed_>.pcg_setseq_64_srandom_r( rng, initstate, initseq );
769
class procedure TRandom32PCG<_TSeed_>.pcg32s_srandom_r( var rng:T_pcg_state_64; initstate:Int64u );
771
TRandom64PCG<_TSeed_>.pcg_oneseq_64_srandom_r( rng, initstate );
774
class procedure TRandom32PCG<_TSeed_>.pcg32u_srandom_r( var rng:T_pcg_state_64; initstate:Int64u );
776
TRandom64PCG<_TSeed_>.pcg_unique_64_srandom_r( rng, initstate );
779
class procedure TRandom32PCG<_TSeed_>.pcg32f_srandom_r( var rng:T_pcg_state_64; initstate:Int64u );
781
TRandom64PCG<_TSeed_>.pcg_mcg_64_srandom_r( rng, initstate );
784
class procedure TRandom32PCG<_TSeed_>.pcg32si_srandom_r( var rng:T_pcg_state_32; initstate:Int32u );
786
pcg_oneseq_32_srandom_r( rng, initstate );
789
class procedure TRandom32PCG<_TSeed_>.pcg32i_srandom_r( var rng:T_pcg_state_setseq_32; initstate:Int32u; initseq:Int32u );
791
pcg_setseq_32_srandom_r( rng, initstate, initseq );
794
////////////////////////////////////////////////////////////////////// advance_r
796
class procedure TRandom32PCG<_TSeed_>.pcg32_advance_r( var rng:T_pcg_state_setseq_64; delta:Int64u );
798
TRandom64PCG<_TSeed_>.pcg_setseq_64_advance_r( rng, delta );
801
class procedure TRandom32PCG<_TSeed_>.pcg32s_advance_r( var rng:T_pcg_state_64; delta:Int64u );
803
TRandom64PCG<_TSeed_>.pcg_oneseq_64_advance_r( rng, delta );
806
class procedure TRandom32PCG<_TSeed_>.pcg32u_advance_r( var rng:T_pcg_state_64; delta:Int64u );
808
TRandom64PCG<_TSeed_>.pcg_unique_64_advance_r( rng, delta );
811
class procedure TRandom32PCG<_TSeed_>.pcg32f_advance_r( var rng:T_pcg_state_64; delta:Int64u );
813
TRandom64PCG<_TSeed_>.pcg_mcg_64_advance_r( rng, delta );
816
class procedure TRandom32PCG<_TSeed_>.pcg32si_advance_r( var rng:T_pcg_state_32; delta:Int32u );
818
pcg_oneseq_32_advance_r( rng, delta );
821
class procedure TRandom32PCG<_TSeed_>.pcg32i_advance_r( var rng:T_pcg_state_setseq_32; delta:Int32u );
823
pcg_setseq_32_advance_r( rng, delta );
826
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% TRandom32PCG32
828
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& private
830
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& protected
832
/////////////////////////////////////////////////////////////////////// メソッド
834
procedure TRandom32PCG32.CalcNextSeed;
836
pcg_oneseq_32_step_r( _Seed );
839
//------------------------------------------------------------------------------
841
function TRandom32PCG32.CalcRandInt32u :Int32u;
843
Result := pcg_output_rxs_m_xs_32_32( _Seed.state );
846
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& public
848
constructor TRandom32PCG32.CreateFromRand( const Random_:IRandom );
852
pcg_oneseq_32_srandom_r( S, Random_.DrawRandInt32u );
857
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% TRandom32PCG32x31
859
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& private
861
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& protected
863
/////////////////////////////////////////////////////////////////////// メソッド
865
procedure TRandom32PCG32x31.CalcNextSeed;
867
pcg_setseq_32_step_r( _Seed );
870
//------------------------------------------------------------------------------
872
function TRandom32PCG32x31.CalcRandInt32u :Int32u;
874
Result := pcg_output_rxs_m_xs_32_32( _Seed.state );
877
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& public
879
constructor TRandom32PCG32x31.CreateFromRand( const Random_:IRandom );
881
S :T_pcg_state_setseq_32;
883
pcg_setseq_32_srandom_r( S, Random_.DrawRandInt32u, Random_.DrawRandInt32u );
888
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$【ルーチン】
890
//############################################################################## □
892
initialization //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ 初期化
894
finalization //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ 最終化
896
end. //######################################################################### ■