guile-user
[Top][All Lists]

## 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*))
~~~

```