Essays/RNG
The numbers generated by ? depend completely on the RNG state, queried by 9!:44 and set by 9!:45 . The state can be used to implement RNGs that provide independently reproducible sets of numbers. Thus:
init=: 4 : 0 sn=. 'state',x y2=. 2{.y,9!:42 '' NB. seed and optional RNG # ('parm',x)=: y2 9!:43 {:y2 NB. select RNG 9!:1 {.y2 NB. set seed (sn)=: 9!:44 '' NB. record state i.0 0 ) gen=: 4 : 0 sn=. 'state',x assert. 2=#y 9!:45 ".sn NB. set state z=. ?@$&>/y (sn)=: 9!:44 '' NB. record state z )
x init seed,i initializes independent reproducible RNG x . i is optional and specifies the RNG# (RNG algorithm); if elided, then the current RNG# is used.
x gen m,n or x gen m;n generates m?@$n using independently reproducible RNG x . Thus:
'a' init 16807 'b' init 314159 'a' gen 10 1000 590 147 158 729 522 732 355 5 955 673 'b' gen 10 1000 867 439 794 893 437 543 272 665 586 595 'a' gen 10 1000 858 350 740 105 669 546 334 840 546 184 'b' gen 10 1000 103 809 553 195 69 605 785 339 937 456
Two independently reproducible sets of random numbers are produced interleaved with one another.
'a' init 16807 'a' gen 10 1000 590 147 158 729 522 732 355 5 955 673 'a' gen 10 1000 858 350 740 105 669 546 334 840 546 184 'b' init 314159 'b' gen 10 1000 867 439 794 893 437 543 272 665 586 595 'b' gen 10 1000 103 809 553 195 69 605 785 339 937 456
This second example demonstrates that the numbers really are independently reproducible.
Object Implementation
Object implementation by Bill Lam.
coclass 'rng' create=: 3 : 0 y2=. 2{.y,9!:42 '' NB. seed and optional RNG # parm=: y2 9!:43 {:y2 NB. select RNG 9!:1 {.y2 NB. set seed state=: 9!:44 '' NB. record state i.0 0 ) gen=: 4 : 0 9!:45 state NB. set state z=. x ?@$ y state=: 9!:44 '' NB. record state z ) roll=: 3 : 0 9!:45 state NB. set state z=. ? y state=: 9!:44 '' NB. record state z : 9!:45 state NB. set state z=. x ? y state=: 9!:44 '' NB. record state z ) destroy=: codestroy
Examples of using these verbs:
a=: 16807 conew 'rng' b=: 314159 conew 'rng' 10 gen__a 1000 10 gen__b 1000 10 gen__a 1000 10 gen__b 1000 destroy__a '' destroy__b '' a=: 16807 conew 'rng' b=: 314159 conew 'rng' 10 gen__a 1000 10 gen__a 1000 10 gen__b 1000 10 gen__b 1000 destroy__a '' destroy__b ''
See also
Contributed by Roger Hui with additional contributions by Bill Lam.