| 
									
										
										
										
											2008-03-19 17:18:03 -04:00
										 |  |  | ! Copyright (C) 2008 Doug Coleman. | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | ! See http://factorcode.org/license.txt for BSD license. | 
					
						
							| 
									
										
										
										
											2010-12-25 19:54:45 -05:00
										 |  |  | USING: accessors alien.c-types alien.data arrays assocs | 
					
						
							|  |  |  | byte-arrays byte-vectors combinators fry io.backend io.binary | 
					
						
							|  |  |  | kernel locals math math.bitwise math.constants math.functions | 
					
						
							|  |  |  | math.order math.ranges namespaces sequences sets summary system | 
					
						
							| 
									
										
										
										
											2010-01-30 02:55:01 -05:00
										 |  |  | vocabs.loader ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | IN: random | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-12 22:35:07 -04:00
										 |  |  | SYMBOL: system-random-generator | 
					
						
							| 
									
										
										
										
											2008-03-27 07:27:36 -04:00
										 |  |  | SYMBOL: secure-random-generator | 
					
						
							|  |  |  | SYMBOL: random-generator | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-30 04:22:11 -04:00
										 |  |  | GENERIC# seed-random 1 ( tuple seed -- tuple' )
 | 
					
						
							| 
									
										
										
										
											2009-09-30 16:56:02 -04:00
										 |  |  | GENERIC: random-32* ( tuple -- r )
 | 
					
						
							| 
									
										
										
										
											2008-03-27 07:30:59 -04:00
										 |  |  | GENERIC: random-bytes* ( n tuple -- byte-array )
 | 
					
						
							| 
									
										
										
										
											2008-03-27 07:27:36 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | M: object random-bytes* ( n tuple -- byte-array )
 | 
					
						
							| 
									
										
										
										
											2009-02-02 14:43:54 -05:00
										 |  |  |     [ [ <byte-vector> ] keep 4 /mod ] dip
 | 
					
						
							| 
									
										
										
										
											2009-09-30 16:56:02 -04:00
										 |  |  |     [ pick '[ _ random-32* 4 >le _ push-all ] times ] | 
					
						
							| 
									
										
										
										
											2008-11-12 23:10:34 -05:00
										 |  |  |     [ | 
					
						
							|  |  |  |         over zero?
 | 
					
						
							| 
									
										
										
										
											2009-10-28 16:29:01 -04:00
										 |  |  |         [ 2drop ] [ random-32* 4 >le swap head append! ] if
 | 
					
						
							| 
									
										
										
										
											2009-02-02 14:43:54 -05:00
										 |  |  |     ] bi-curry bi* ;
 | 
					
						
							| 
									
										
										
										
											2008-03-27 07:27:36 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-01 12:58:52 -04:00
										 |  |  | M: object random-32* ( tuple -- r ) 4 swap random-bytes* le> ;
 | 
					
						
							| 
									
										
										
										
											2008-03-27 07:27:36 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | ERROR: no-random-number-generator ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-29 15:50:52 -04:00
										 |  |  | M: no-random-number-generator summary | 
					
						
							|  |  |  |     drop "Random number generator is not defined." ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-27 07:27:36 -04:00
										 |  |  | M: f random-bytes* ( n obj -- * ) no-random-number-generator ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-30 16:56:02 -04:00
										 |  |  | M: f random-32* ( obj -- * ) no-random-number-generator ;
 | 
					
						
							| 
									
										
										
										
											2008-03-27 07:27:36 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-27 07:30:59 -04:00
										 |  |  | : random-bytes ( n -- byte-array )
 | 
					
						
							| 
									
										
										
										
											2008-11-12 23:10:34 -05:00
										 |  |  |     random-generator get random-bytes* ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-10-04 12:44:12 -04:00
										 |  |  | <PRIVATE
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : random-integer ( n -- n' )
 | 
					
						
							| 
									
										
										
										
											2009-08-13 20:21:44 -04:00
										 |  |  |     dup log2 7 + 8 /i 1 +
 | 
					
						
							| 
									
										
										
										
											2008-11-12 23:10:34 -05:00
										 |  |  |     [ random-bytes >byte-array byte-array>bignum ] | 
					
						
							| 
									
										
										
										
											2008-10-04 12:44:12 -04:00
										 |  |  |     [ 3 shift 2^ ] bi / * >integer ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PRIVATE>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-10 14:39:08 -04:00
										 |  |  | : random-bits ( numbits -- r ) 2^ random-integer ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : random-bits* ( numbits -- n )
 | 
					
						
							|  |  |  |     1 - [ random-bits ] keep set-bit ;
 | 
					
						
							| 
									
										
										
										
											2008-10-05 23:08:13 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-14 12:59:53 -05:00
										 |  |  | GENERIC: random ( obj -- elt )
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-14 13:48:57 -05:00
										 |  |  | M: integer random [ f ] [ random-integer ] if-zero ;
 | 
					
						
							| 
									
										
										
										
											2010-01-14 12:59:53 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | M: sequence random | 
					
						
							| 
									
										
										
										
											2008-09-06 20:13:59 -04:00
										 |  |  |     [ f ] [ | 
					
						
							| 
									
										
										
										
											2008-10-04 12:44:12 -04:00
										 |  |  |         [ length random-integer ] keep nth
 | 
					
						
							| 
									
										
										
										
											2008-09-06 20:13:59 -04:00
										 |  |  |     ] if-empty ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-30 16:56:02 -04:00
										 |  |  | : random-32 ( -- n ) random-generator get random-32* ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-30 01:58:29 -05:00
										 |  |  | : randomize-n-last ( seq n -- seq )  | 
					
						
							|  |  |  |     [ dup length dup ] dip - 1 max '[ dup _ > ]  | 
					
						
							| 
									
										
										
										
											2010-01-14 13:48:57 -05:00
										 |  |  |     [ [ random ] [ 1 - ] bi [ pick exchange ] keep ] | 
					
						
							| 
									
										
										
										
											2009-02-17 20:19:49 -05:00
										 |  |  |     while drop ;
 | 
					
						
							| 
									
										
										
										
											2008-12-18 01:15:07 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-18 18:31:52 -05:00
										 |  |  | : randomize ( seq -- randomized )
 | 
					
						
							| 
									
										
										
										
											2010-01-30 01:58:29 -05:00
										 |  |  |     dup length randomize-n-last ;
 | 
					
						
							| 
									
										
										
										
											2009-09-23 13:04:06 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-30 01:58:29 -05:00
										 |  |  | ERROR: too-many-samples seq n ;
 | 
					
						
							| 
									
										
										
										
											2009-09-23 13:04:06 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : sample ( seq n -- seq' )
 | 
					
						
							|  |  |  |     2dup [ length ] dip < [ too-many-samples ] when
 | 
					
						
							| 
									
										
										
										
											2010-01-30 01:58:29 -05:00
										 |  |  |     [ [ length iota >array ] dip [ randomize-n-last ] keep tail-slice* ] | 
					
						
							|  |  |  |     [ drop ] 2bi nths ;
 | 
					
						
							| 
									
										
										
										
											2009-09-23 13:04:06 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-10-04 12:44:12 -04:00
										 |  |  | : delete-random ( seq -- elt )
 | 
					
						
							| 
									
										
										
										
											2009-10-28 00:41:57 -04:00
										 |  |  |     [ length random-integer ] keep [ nth ] 2keep remove-nth! drop ;
 | 
					
						
							| 
									
										
										
										
											2008-03-19 22:41:39 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-19 17:18:03 -04:00
										 |  |  | : with-random ( tuple quot -- )
 | 
					
						
							| 
									
										
										
										
											2008-03-19 22:41:39 -04:00
										 |  |  |     random-generator swap with-variable ; inline
 | 
					
						
							| 
									
										
										
										
											2008-03-28 23:10:01 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-12 22:35:07 -04:00
										 |  |  | : with-system-random ( quot -- )
 | 
					
						
							|  |  |  |     system-random-generator get swap with-random ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-28 23:10:01 -04:00
										 |  |  | : with-secure-random ( quot -- )
 | 
					
						
							| 
									
										
										
										
											2008-04-12 22:35:07 -04:00
										 |  |  |     secure-random-generator get swap with-random ; inline
 | 
					
						
							| 
									
										
										
										
											2008-11-06 02:30:59 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-06 14:22:53 -04:00
										 |  |  | : uniform-random-float ( min max -- n )
 | 
					
						
							| 
									
										
										
										
											2010-10-20 18:42:53 -04:00
										 |  |  |     4 random-bytes underlying>> uint deref >float
 | 
					
						
							|  |  |  |     4 random-bytes underlying>> uint deref >float
 | 
					
						
							| 
									
										
										
										
											2009-05-06 18:26:21 -04:00
										 |  |  |     2.0 32 ^ * +
 | 
					
						
							|  |  |  |     [ over - 2.0 -64 ^ * ] dip
 | 
					
						
							|  |  |  |     * + ; inline
 | 
					
						
							| 
									
										
										
										
											2009-05-06 14:22:53 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : normal-random-float ( mean sigma -- n )
 | 
					
						
							|  |  |  |     0.0 1.0 uniform-random-float | 
					
						
							|  |  |  |     0.0 1.0 uniform-random-float | 
					
						
							|  |  |  |     [ 2 pi * * cos ] | 
					
						
							|  |  |  |     [ 1.0 swap - log -2.0 * sqrt ] | 
					
						
							|  |  |  |     bi* * * + ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-06 02:30:59 -05:00
										 |  |  | { | 
					
						
							|  |  |  |     { [ os windows? ] [ "random.windows" require ] } | 
					
						
							|  |  |  |     { [ os unix? ] [ "random.unix" require ] } | 
					
						
							|  |  |  | } cond
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | "random.mersenne-twister" require |