guile-user
[Top][All Lists]
Advanced

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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]