#lang racket
(require (planet williams/science/random-source)
(planet williams/science/random-distributions-with-graphics))
(define random-distribution-hash (make-hasheq))
(define (find-random-distribution sym)
(hash-ref random-distribution-hash sym
(lambda ()
(error
(format "~a is not the name of a random distribution" sym)))))
(struct random-distribution
(spec
form
sample
pdf
cdf
plot))
(define-syntax-rule (define-random-distribution (name . args)
form random pdf cdf plot)
(hash-set! random-distribution-hash
'name
(random-distribution
'(name . args)
form
random
pdf
cdf
plot)))
(define-random-distribution (beta a b)
"beta distribution with parameters ~a and ~a"
random-beta
beta-pdf
beta-cdf
beta-plot)
(define-random-distribution (chi-squared nu)
"chi squared distribution with ~a degrees of freedom"
random-chi-squared
chi-squared-pdf
chi-squared-cdf
chi-squared-plot)
(define-random-distribution (exponential mu)
"exponential distribution with mean ~a"
random-exponential
exponential-pdf
exponential-cdf
exponential-plot)
(define-random-distribution (f-distribution nu1 nu2)
"F-distribution with ~a and ~a degrees of freedom"
random-f-distribution
f-distribution-pdf
f-distribution-cdf
f-distribution-plot)
(define-random-distribution (flat a b)
"flat (uniform) distribution from ~a to ~a"
random-flat
flat-pdf
flat-cdf
flat-plot)
(define-random-distribution (gamma a b)
"gamma distribution with parameters ~a and ~a"
random-gamma
gamma-pdf
gamma-cdf
gamma-plot)
(define-random-distribution (gaussian mu sigma)
"Gaussian (normal) distribution with mean ~a and standard deviation ~a"
random-gaussian
gaussian-pdf
gaussian-cdf
gaussian-plot)
(define-random-distribution (gaussian-tail a mu sigma)
"upper tail of the Gaussian (normal) distribution with lower limit ~a, mean ~a and standard deviation ~a"
random-gaussian-tail
gaussian-tail-pdf
#f
gaussian-tail-plot)
(define-random-distribution (lognormal mu sigma)
"log normal distribution with mean ~a and standard deviation ~a"
random-lognormal
lognormal-pdf
lognormal-cdf
lognormal-plot)
(define-random-distribution (normal mu sigma)
"Gaussian (normal) distribution with mean ~a and standard deviation ~a"
random-gaussian
gaussian-pdf
gaussian-cdf
gaussian-plot)
(define-random-distribution (pareto a b)
"Pareto distribution with parameters ~a and ~a"
random-pareto
pareto-pdf
pareto-cdf
pareto-plot)
(define-random-distribution (standard-normal)
"Gaussian (normal) distribution with mean 0.0 and standard deviation 1.0"
random-unit-gaussian
unit-gaussian-pdf
unit-gaussian-cdf
unit-gaussian-plot)
(define-random-distribution (standard-normal-tail a)
"upper tail of the Gaussian (normal) distribution with lower limit ~a, mean 0.0 and standard deviation 1.0"
random-unit-gaussian-tail
unit-gaussian-tail-pdf
#f
unit-gaussian-tail-plot)
(define-random-distribution (t-distribution nu)
"t-distribution with ~a degrees of freedom"
random-t-distribution
t-distribution-pdf
t-distribution-cdf
t-distribution-plot)
(define-random-distribution (triangular a b c)
"triangular distribution with minimum value ~a, maximum value ~a, and most likely value ~a"
random-triangular
triangular-pdf
triangular-cdf
triangular-plot)
(define-random-distribution (unit-gaussian)
"Gaussian (normal) distribution with mean 0.0 and standard deviation 1.0"
random-unit-gaussian
unit-gaussian-pdf
unit-gaussian-cdf
unit-gaussian-plot)
(define-random-distribution (unit-gaussian-tail a)
"upper tail of the Gaussian (normal) distribution with lower limit ~a, mean 0.0 and standard deviation 1.0"
random-unit-gaussian-tail
unit-gaussian-tail-pdf
#f
unit-gaussian-tail-plot)
(define-random-distribution (bernoulli p)
"Bernoulli distribution with probability ~a"
random-bernoulli
bernoulli-pdf
bernoulli-cdf
bernoulli-plot)
(define-random-distribution (biomial p n)
"binomial distribution with parameters ~a and ~a"
random-binomial
binomial-pdf
#f
binomial-plot)
(define-random-distribution (geometric p)
"geometric distribution with probability ~a"
random-geometric
geometric-pdf
#f
geometric-plot)
(define-random-distribution (logarithmic p)
"logarithmic distribution with probability ~a"
random-logarithmic
logarithmic-pdf
#f
logarithmic-plot)
(define-random-distribution (poisson mu)
"Poisson distribution with mean ~a"
random-poisson
poisson-pdf
#f
poisson-plot)
(define-random-distribution (discrete weights)
"discrete distribution whose probability density is given by ~s"
(lambda (s weights)
(let ((d (make-discrete weights)))
(random-discrete s d)))
(lambda (x weights)
(let ((d (make-discrete weights)))
(discrete-pdf d x)))
(lambda (x weights)
(let ((d (make-discrete weights)))
(discrete-cdf d x)))
(lambda (weights)
(let ((d (make-discrete weights)))
(discrete-plot d))))
(define (random-distribution-description name)
(let ((dist (find-random-distribution name)))
(apply format (random-distribution-form dist)
(cdr (random-distribution-spec dist)))))
(define (random-description spec)
(let ((dist (find-random-distribution (car spec))))
(apply format (random-distribution-form dist) (cdr spec))))
(define (random-sample spec (s (current-random-source)))
(let ((dist (find-random-distribution (car spec))))
(apply (random-distribution-sample dist) s (cdr spec))))
(define (random-pdf-exists? spec)
(let ((dist (find-random-distribution (car spec))))
(if (random-distribution-pdf dist) #t #f)))
(define (random-pdf x spec)
(let ((dist (find-random-distribution (car spec))))
(apply (random-distribution-pdf dist) x (cdr spec))))
(define (random-cdf-exists? spec)
(let ((dist (find-random-distribution (car spec))))
(if (random-distribution-cdf dist) #t #f)))
(define (random-cdf x spec)
(let ((dist (find-random-distribution (car spec))))
(apply (random-distribution-cdf dist) x (cdr spec))))
(define (random-plot-exists? spec)
(let ((dist (find-random-distribution (car spec))))
(if (random-distribution-pdf dist) #t #f)))
(define (random-plot spec)
(let ((dist (find-random-distribution (car spec))))
(apply (random-distribution-plot dist) (cdr spec))))
(define (random-sample-function spec)
(let ((dist (find-random-distribution (car spec))))
(lambda ((s (current-random-source)))
(apply (random-distribution-sample dist) s (cdr spec)))))
(provide define-random-distribution)
(define random-spec/c
(flat-named-contract
'random-spec/c
(lambda (x)
(and (cons? x)
(symbol? (car x))
(list? (cdr x))
(andmap real? (cdr x))))))
(provide/contract
(random-distribution-description
(-> symbol? string?))
(random-description
(-> random-spec/c string?))
(random-sample
(->* (random-spec/c) (random-source?) real?))
(random-pdf-exists?
(-> random-spec/c boolean?))
(random-pdf
(-> real? random-spec/c real?))
(random-cdf-exists?
(-> random-spec/c boolean?))
(random-cdf
(-> real? random-spec/c real?))
(random-plot-exists?
(-> random-spec/c boolean?))
(random-plot
(-> random-spec/c any))
(random-sample-function
(-> random-spec/c (->* () (random-source?) real?))))