1 ! Copyright (C) 2009 Doug Coleman.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors alien.c-types kernel locals math math.ranges
4 math.bitwise math.vectors math.vectors.simd random
5 sequences specialized-arrays sequences.private classes.struct ;
7 SPECIALIZED-ARRAY: uint
8 SPECIALIZED-ARRAY: uint-4
13 CONSTANT: state-multiplier 1812433253
26 { uint-array uint-array }
27 { uint-4-array uint-4-array } ;
30 dup 1 hlshift vbitxor ; inline
33 [ 11 vrshift ] dip vbitand ; inline
41 : formula ( a b mask c d -- r )
44 [ wA ] dip vbitxor ; inline
46 GENERIC: generate ( sfmt -- )
48 M:: sfmt generate ( sfmt -- )
50 sfmt uint-4-array>> :> array
51 state n>> 2 - array nth state (>>r1)
52 state n>> 1 - array nth state (>>r2)
57 n m - >fixnum iota [| i |
59 i m + array nth-unsafe
60 mask state r1>> state r2>> formula :> r
62 r i array set-nth-unsafe
63 state r2>> state (>>r1)
69 n m - 1 + + >fixnum :> i
71 m n - i + array nth-unsafe
72 mask state r1>> state r2>> formula :> r
74 r i array set-nth-unsafe
75 state r2>> state (>>r1)
81 : <sfmt-array> ( sfmt -- uint-array uint-4-array )
83 [ n>> 4 * iota >uint-array ] [ seed>> ] bi
87 [ -30 shift ] [ ] bi bitxor
88 state-multiplier * 32 bits
91 ] uint-array{ } accumulate-as nip
92 dup underlying>> byte-array>uint-4-array ;
94 : <sfmt-state> ( seed n m mask -- sfmt )
102 : init-sfmt ( sfmt -- sfmt' )
103 dup <sfmt-array> [ >>uint-array ] [ >>uint-4-array ] bi*
104 [ generate ] keep ; inline
106 : <sfmt> ( seed n m mask -- sfmt )
112 : refill-sfmt? ( sfmt -- ? )
113 state>> [ ix>> ] [ n>> 4 * ] bi >= ;
115 : next-ix ( sfmt -- ix )
116 state>> [ dup 1 + ] change-ix drop ; inline
119 [ next-ix ] [ uint-array>> ] bi nth-unsafe ; inline
123 M: sfmt random-32* ( sfmt -- n )
124 dup refill-sfmt? [ dup generate ] when next ; inline
126 M: sfmt seed-random ( sfmt seed -- sfmt )
127 [ [ state>> ] dip >>seed drop ]
128 [ drop init-sfmt ] 2bi ;
130 : <sfmt-19937> ( seed -- sfmt )
131 348 330 uint-4{ HEX: BFFFFFF6 HEX: BFFAFFFF HEX: DDFECB7F HEX: DFFFFFEF }