| 1 | ;; Dirichlet distribution |
|---|
| 2 | ;; Liam Healy, Sun Oct 29 2006 |
|---|
| 3 | ;; Time-stamp: <2008-03-09 19:29:16EDT dirichlet.lisp> |
|---|
| 4 | ;; $Id$ |
|---|
| 5 | |
|---|
| 6 | (in-package :gsl) |
|---|
| 7 | |
|---|
| 8 | (defmfun dirichlet (generator alpha theta) |
|---|
| 9 | "gsl_ran_dirichlet" |
|---|
| 10 | (((generator generator) :pointer) |
|---|
| 11 | ((dim0 alpha) size) |
|---|
| 12 | ((gsl-array alpha) :pointer) |
|---|
| 13 | ;; theta had better be at least as long as alpha, or they'll be trouble |
|---|
| 14 | ((gsl-array theta) :pointer)) |
|---|
| 15 | :c-return :void |
|---|
| 16 | :documentation ; FDL |
|---|
| 17 | "An array of K=(length alpha) random variates from a Dirichlet |
|---|
| 18 | distribution of order K-1. The distribution function is |
|---|
| 19 | p(\theta_1,\ldots,\theta_K) \, d\theta_1 \cdots d\theta_K = |
|---|
| 20 | {1 \over Z} \prod_{i=1}^{K} \theta_i^{\alpha_i - 1} |
|---|
| 21 | \; \delta(1 -\sum_{i=1}^K \theta_i) d\theta_1 \cdots d\theta_K |
|---|
| 22 | theta_i >= 0 and alpha_i >= 0. |
|---|
| 23 | The delta function ensures that \sum \theta_i = 1. |
|---|
| 24 | The normalization factor Z is |
|---|
| 25 | Z = {\prod_{i=1}^K \Gamma(\alpha_i) \over \Gamma( \sum_{i=1}^K \alpha_i)} |
|---|
| 26 | The random variates are generated by sampling K values |
|---|
| 27 | from gamma distributions with parameters a=alpha_i, b=1, |
|---|
| 28 | and renormalizing. |
|---|
| 29 | See A.M. Law, W.D. Kelton, \"Simulation Modeling and Analysis\" |
|---|
| 30 | (1991).") |
|---|
| 31 | |
|---|
| 32 | (defmfun dirichlet-pdf (alpha theta) |
|---|
| 33 | "gsl_ran_dirichlet_pdf" |
|---|
| 34 | (((1- (dim0 alpha)) size) |
|---|
| 35 | ((gsl-array alpha) :pointer) |
|---|
| 36 | ;; theta had better be at least as long as alpha, or they'll be trouble |
|---|
| 37 | ((gsl-array theta) :pointer)) |
|---|
| 38 | :c-return :double |
|---|
| 39 | :documentation ; FDL |
|---|
| 40 | "The probability density p(\theta_1, ... , \theta_K) |
|---|
| 41 | at theta[K] for a Dirichlet distribution with parameters |
|---|
| 42 | alpha[K], using the formula given for #'dirichlet.") |
|---|
| 43 | |
|---|
| 44 | (defmfun dirichlet-log-pdf (alpha theta) |
|---|
| 45 | "gsl_ran_dirichlet_lnpdf" |
|---|
| 46 | (((1- (dim0 alpha)) size) |
|---|
| 47 | ((gsl-array alpha) :pointer) |
|---|
| 48 | ;; theta had better be at least as long as alpha, or they'll be trouble |
|---|
| 49 | ((gsl-array theta) :pointer)) |
|---|
| 50 | :c-return :double |
|---|
| 51 | :documentation ; FDL |
|---|
| 52 | "The logarithm of the probability density |
|---|
| 53 | p(\theta_1, ... , \theta_K) |
|---|
| 54 | for a Dirichlet distribution with parameters |
|---|
| 55 | alpha[K].") |
|---|
| 56 | |
|---|
| 57 | ;;; Examples and unit test |
|---|
| 58 | #| |
|---|
| 59 | (make-tests dirichlet |
|---|
| 60 | (letm ((rng (random-number-generator *mt19937* 0)) |
|---|
| 61 | (alpha (vector-double-float #(1.0d0 2.0d0 3.0d0 4.0d0))) |
|---|
| 62 | (theta (vector-double-float 4))) |
|---|
| 63 | (dirichlet rng alpha theta) |
|---|
| 64 | (data theta)) |
|---|
| 65 | (letm ((alpha (vector-double-float #(1.0d0 2.0d0 3.0d0 4.0d0))) |
|---|
| 66 | (theta (vector-double-float #(0.1d0 0.3d0 0.4d0 0.2d0)))) |
|---|
| 67 | (dirichlet-pdf alpha theta)) |
|---|
| 68 | (letm ((alpha (vector-double-float #(1.0d0 2.0d0 3.0d0 4.0d0))) |
|---|
| 69 | (theta (vector-double-float #(0.1d0 0.3d0 0.4d0 0.2d0)))) |
|---|
| 70 | (dirichlet-log-pdf alpha theta))) |
|---|
| 71 | |# |
|---|
| 72 | |
|---|
| 73 | (LISP-UNIT:DEFINE-TEST DIRICHLET |
|---|
| 74 | (LISP-UNIT::ASSERT-NUMERICAL-EQUAL |
|---|
| 75 | (LIST |
|---|
| 76 | #(3.9283332456352124d-5 0.468176310887376d0 |
|---|
| 77 | 0.34075044031099977d0 0.19103396546916782d0)) |
|---|
| 78 | (MULTIPLE-VALUE-LIST |
|---|
| 79 | (LETM |
|---|
| 80 | ((RNG (RANDOM-NUMBER-GENERATOR *MT19937* 0)) |
|---|
| 81 | (ALPHA (VECTOR-DOUBLE-FLOAT #(1.0d0 2.0d0 3.0d0 4.0d0))) |
|---|
| 82 | (THETA (VECTOR-DOUBLE-FLOAT 4))) |
|---|
| 83 | (DIRICHLET RNG ALPHA THETA) (DATA THETA)))) |
|---|
| 84 | (LISP-UNIT::ASSERT-NUMERICAL-EQUAL |
|---|
| 85 | (LIST 2.8800000000000043d0) |
|---|
| 86 | (MULTIPLE-VALUE-LIST |
|---|
| 87 | (LETM |
|---|
| 88 | ((ALPHA (VECTOR-DOUBLE-FLOAT #(1.0d0 2.0d0 3.0d0 4.0d0))) |
|---|
| 89 | (THETA (VECTOR-DOUBLE-FLOAT #(0.1d0 0.3d0 0.4d0 0.2d0)))) |
|---|
| 90 | (DIRICHLET-PDF ALPHA THETA)))) |
|---|
| 91 | (LISP-UNIT::ASSERT-NUMERICAL-EQUAL |
|---|
| 92 | (LIST 1.057790294147856d0) |
|---|
| 93 | (MULTIPLE-VALUE-LIST |
|---|
| 94 | (LETM |
|---|
| 95 | ((ALPHA (VECTOR-DOUBLE-FLOAT #(1.0d0 2.0d0 3.0d0 4.0d0))) |
|---|
| 96 | (THETA (VECTOR-DOUBLE-FLOAT #(0.1d0 0.3d0 0.4d0 0.2d0)))) |
|---|
| 97 | (DIRICHLET-LOG-PDF ALPHA THETA))))) |
|---|
| 98 | |
|---|