12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667 |
- (library (lib random)
- (export make-random-integer-generator
- try-for-probability
- choose-random-element)
- (import
- (except (rnrs base) error)
- (only (guile) lambda* λ values error
- ;; random numbers
- random:uniform
- )
- ;; SRFI-27 for random number utilities
- (srfi srfi-27)))
- (define make-random-integer-generator
- (lambda* (#:key seed)
- "Get a procedure for generating uniformly distributed
- random integers from 0 up to a not included bound, which is
- seeded by the keyword argument seed, which must be a
- positive integer."
- (cond
- [seed
- (let ([rand-src (make-random-source)])
- ;; Set the given seed to guarantee same results for
- ;; same invokations.
- (random-source-pseudo-randomize! rand-src 0 seed)
- ;; Obtain a procedure, which gives uniformly
- ;; distributed integers.
- (random-source-make-integers rand-src))]
- [else
- (let ([rand-src (make-random-source)])
- ;; Try to make the random source truly random. How
- ;; this works depends on the specific implementation
- ;; of SRFI-27.
- (random-source-randomize! rand-src)
- (random-source-make-integers rand-src))])))
- (define try-for-probability
- (lambda* (probability #:key (random-state #f))
- "Generate a random inexact uniformly distributed float
- between [0,1) and test, if it is less than the given
- PROBABILITY. Return #t if the number is smaller than the
- given PROBABILITY and #t if the number is equal of bigger
- the given PROBABILITY. If a RANDOM-STATE is given, use the
- RANDOM-STATE to generate the random number and return both
- the number and the updated RANDOM-STATE."
- (cond
- [random-state
- (values (< (random:uniform random-state) probability)
- random-state)]
- [else
- (< (random:uniform) probability)])))
- (define choose-random-element
- (lambda* (seq #:key (rand-int-gen (make-random-integer-generator)))
- (cond
- [(pair? seq)
- (let* ([vec (list->vector seq)]
- [random-index (rand-int-gen (vector-length vec))])
- (vector-ref vec random-index))]
- [(vector? seq)
- (vector-ref seq (rand-int-gen (vector-length seq)))]
- [else
- (error "expected sequence of type list or vector, got:" seq)])))
|