[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Normal distribution random numbers
From: |
tantalum |
Subject: |
Re: Normal distribution random numbers |
Date: |
Sun, 31 May 2020 15:12:16 +0000 |
User-agent: |
Posteo Webmail |
surely not the ideal way to generate numbers with a normal distribution,
but there is a way to use custom probabilities from a list, which i
think is nice to know.
it works like this:
have a list of probabilities. can be as long as you want. i think that
is called probability density.
->
(1 0 3 1)
create the cumulative sums for this list. that is, sums like this
(a b c ...) -> (a (+ a b) (+ a b c) ...)
i think that is called cumulative distribution.
->
(1 1 4 5)
create a random number up to the largest sum
->
(random 5)
return the first index of the list of cumulative sums that is greater
than the random number.
given the distribution above, you would see index 2 a lot, never index
1, and index 0 and 3 rarely.
~~~
(use-modules ((srfi srfi-1) #:select (last)))
(define (cusum a . b)
"calculate cumulative sums from the given numbers.
(a b c ...) -> (a (+ a b) (+ a b c) ...)"
(cons a (if (null? b) (list) (apply cusum (+ a (car b)) (cdr b)))))
(define* (random-discrete-f probabilities #:optional (state
*random-state*))
"(real ...) [random-state] -> procedure:{-> integer}"
(let* ((cuprob (apply cusum probabilities)) (sum (last cuprob)))
(lambda ()
(let ((deviate (random sum state)))
(let loop ((a 0) (b cuprob))
(if (null? b) a (if (< deviate (car b)) a (loop (+ 1 a) (cdr
b)))))))))
(define random* (random-discrete-f (list 1 0 3 1)
(random-state-from-platform)))
(display (random*))
~~~