Add constrained random number generator
This commit is contained in:
parent
df7a44b43b
commit
fef9a58275
83
embddr/random.scm
Normal file
83
embddr/random.scm
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
(define-module (embddr random))
|
||||||
|
|
||||||
|
(import (srfi srfi-1)
|
||||||
|
(srfi srfi-27))
|
||||||
|
|
||||||
|
(export clean-constraints
|
||||||
|
constrained-random-generator)
|
||||||
|
|
||||||
|
;;;
|
||||||
|
;;; Remove redundant (zero range) constraints.
|
||||||
|
;;; Limit weight in range (0..1]
|
||||||
|
;;;
|
||||||
|
(define (clean-constraints constrs)
|
||||||
|
(remove (lambda (c)
|
||||||
|
(let ((from (car c))
|
||||||
|
(to (cadr c))
|
||||||
|
(w (caddr c)))
|
||||||
|
(or (= from to)
|
||||||
|
(zero? w))))
|
||||||
|
(map (lambda (c)
|
||||||
|
(let ((from (inexact->exact (round (car c))))
|
||||||
|
(to (inexact->exact (round (cadr c))))
|
||||||
|
(w (caddr c)))
|
||||||
|
(let ((w (cond
|
||||||
|
((< w 0) 0)
|
||||||
|
((> w 1) 1)
|
||||||
|
(else w))))
|
||||||
|
(if (> from to)
|
||||||
|
(list to from w)
|
||||||
|
(list from to w)))))
|
||||||
|
constrs)))
|
||||||
|
;;;
|
||||||
|
;;; Make constrained random number generator.
|
||||||
|
;;; Constraints is list of '(from to weight)
|
||||||
|
;;;
|
||||||
|
(define (constrained-random-generator constrs)
|
||||||
|
(let ((constrs (clean-constraints constrs)))
|
||||||
|
(let* (;; Max weight / min weight ration
|
||||||
|
(weight-scale
|
||||||
|
(let ((weights (map caddr constrs)))
|
||||||
|
(/ (apply max weights) (apply min weights))))
|
||||||
|
|
||||||
|
;; Place constraints to uniform linear axis
|
||||||
|
(constrs
|
||||||
|
(let loop ((constrs constrs)
|
||||||
|
(position 0)
|
||||||
|
(result '()))
|
||||||
|
(if (null? constrs)
|
||||||
|
(reverse result)
|
||||||
|
(let* ((c (car constrs))
|
||||||
|
(from (car c))
|
||||||
|
(to (cadr c))
|
||||||
|
(w (caddr c))
|
||||||
|
(l-range (* w weight-scale
|
||||||
|
(- to from))))
|
||||||
|
(loop (cdr constrs)
|
||||||
|
(+ position l-range)
|
||||||
|
(cons (list position (+ position l-range)
|
||||||
|
from to w)
|
||||||
|
result))))))
|
||||||
|
|
||||||
|
;; Linear range of required random number
|
||||||
|
(range
|
||||||
|
(apply max (map cadr constrs))))
|
||||||
|
|
||||||
|
;; Make generator
|
||||||
|
(lambda ()
|
||||||
|
(let* (;; Generate random from linear space
|
||||||
|
(rand-lin (random-integer range))
|
||||||
|
|
||||||
|
;; Find corresponding constraint
|
||||||
|
(c
|
||||||
|
(find (lambda (c)
|
||||||
|
(and (>= rand-lin (car c))
|
||||||
|
(< rand-lin (cadr c))))
|
||||||
|
constrs)))
|
||||||
|
|
||||||
|
;; Scale random
|
||||||
|
(inexact->exact
|
||||||
|
(floor
|
||||||
|
(+ (caddr c)
|
||||||
|
(/ (- rand-lin (car c))
|
||||||
|
(* weight-scale (list-ref c 4)))))))))))
|
||||||
Loading…
x
Reference in New Issue
Block a user