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 ;
9 SPECIALIZED-ARRAY: uint
10 SPECIALIZED-ARRAY: uint-4
15 CONSTANT: state-multiplier 1812433253
18 sl1 sl2 sr1 sr2 mask parity
19 { seed integer } { n fixnum } { m fixnum }
20 { m-n fixnum } { ix fixnum } { state uint-4-array } ;
22 : init-state ( sfmt -- sfmt' )
23 dup [ n>> 4 * iota >uint-array ] [ seed>> ] bi
27 [ -30 shift ] [ ] bi bitxor
28 state-multiplier * 32 bits
31 ] uint-array{ } accumulate-as nip underlying>> byte-array>uint-4-array
35 dup 1 hlshift vbitxor ; inline
38 [ 11 vrshift ] dip vbitand ; inline
46 : formula ( a b mask c d -- r )
49 [ wA ] dip vbitxor ; inline
51 GENERIC: generate ( sfmt -- sfmt' )
53 M:: sfmt generate ( sfmt -- sfmt' )
54 sfmt n>> 2 - sfmt state>> nth :> r1!
55 sfmt n>> 1 - sfmt state>> nth :> r2!
88 : <sfmt> ( seed n m sl1 sl2 sr1 sr2 mask parity -- sfmt )
99 dup [ m>> ] [ n>> ] bi - >>m-n
104 : <sfmt-19937> ( seed -- sfmt )
106 uint-4{ HEX: BFFFFFF6 HEX: BFFAFFFF HEX: DDFECB7F HEX: DFFFFFEF }
107 uint-4{ HEX: ecc1327a HEX: a3ac4000 HEX: 0 HEX: 1 }
110 : refill-sfmt? ( sfmt -- ? )
111 [ ix>> ] [ n>> 4 * ] bi >= ;
113 : nth-sfmt ( sfmt -- n )
116 [ [ 1 + ] change-ix drop ] tri ; inline
118 M: sfmt random-32* ( sfmt -- n )
119 dup refill-sfmt? [ generate ] when