guile-user
[Top][All Lists]

## Re: Normal distribution random numbers

 From: Zelphir Kaltstahl Subject: Re: Normal distribution random numbers Date: Sun, 31 May 2020 21:54:27 +0200 User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Icedove/60.9.0

```Hi!

Interesting technique, that when thinking about it, intuitively makes
sense to me. Thanks for sharing!

Regards,
Zelphir

On 31.05.20 17:12, tantalum wrote:
> 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*))
> ~~~
>
>

```

reply via email to