|
| 1 | +(ns gen.distribution.kixi |
| 2 | + (:require [gen.distribution :as d] |
| 3 | + [gen.distribution.math.log-likelihood :as ll] |
| 4 | + [kixi.stats.distribution :as k]) |
| 5 | + (:import (kixi.stats.distribution Bernoulli Cauchy |
| 6 | + Exponential Beta |
| 7 | + Gamma Normal Uniform))) |
| 8 | + |
| 9 | +;; ## Kixi.stats protocol implementations |
| 10 | +;; |
| 11 | +;; NOTE: If we want to seed the PRNG here, the right way to do it is to create |
| 12 | +;; wrapper types that hold a kixi distribution instance and an RNG. Then, |
| 13 | +;; instead of `draw`, we can call `sample-1` with the distribution and RNG. |
| 14 | + |
| 15 | + |
| 16 | +(extend-type Bernoulli |
| 17 | + d/Sample |
| 18 | + (sample [this] (k/draw this)) |
| 19 | + |
| 20 | + d/LogPDF |
| 21 | + (logpdf [this v] |
| 22 | + (ll/bernoulli (.-p this) v))) |
| 23 | + |
| 24 | +(extend-type Beta |
| 25 | + d/Sample |
| 26 | + (sample [this] (k/draw this)) |
| 27 | + |
| 28 | + d/LogPDF |
| 29 | + (logpdf [this v] |
| 30 | + (ll/beta (.-alpha this) |
| 31 | + (.-beta this) |
| 32 | + v))) |
| 33 | + |
| 34 | +(extend-type Cauchy |
| 35 | + d/Sample |
| 36 | + (sample [this] (k/draw this)) |
| 37 | + |
| 38 | + d/LogPDF |
| 39 | + (logpdf [this v] |
| 40 | + (ll/cauchy (.-location this) |
| 41 | + (.-scale this) |
| 42 | + v))) |
| 43 | + |
| 44 | +(extend-type Exponential |
| 45 | + d/Sample |
| 46 | + (sample [this] (k/draw this)) |
| 47 | + |
| 48 | + d/LogPDF |
| 49 | + (logpdf [this v] |
| 50 | + (ll/exponential (.-rate this) v))) |
| 51 | + |
| 52 | +(extend-type Uniform |
| 53 | + d/Sample |
| 54 | + (sample [this] (k/draw this)) |
| 55 | + |
| 56 | + d/LogPDF |
| 57 | + (logpdf [this v] |
| 58 | + (let [min (.-a this) |
| 59 | + max (.-b this)] |
| 60 | + (ll/uniform min max v)))) |
| 61 | + |
| 62 | +(extend-type Gamma |
| 63 | + d/Sample |
| 64 | + (sample [this] (k/draw this)) |
| 65 | + |
| 66 | + d/LogPDF |
| 67 | + (logpdf [this v] |
| 68 | + (ll/gamma (.-shape this) |
| 69 | + (.-scale this) |
| 70 | + v))) |
| 71 | + |
| 72 | +(extend-type Normal |
| 73 | + d/Sample |
| 74 | + (sample [this] (k/draw this)) |
| 75 | + |
| 76 | + d/LogPDF |
| 77 | + (logpdf [this v] |
| 78 | + (ll/gaussian (.-mu this) |
| 79 | + (.-sd this) |
| 80 | + v))) |
| 81 | + |
| 82 | +;; ## Primitive probability distributions |
| 83 | + |
| 84 | +(defn bernoulli-distribution |
| 85 | + ([] (bernoulli-distribution 0.5)) |
| 86 | + ([p] (k/bernoulli {:p p}))) |
| 87 | + |
| 88 | +(defn beta-distribution |
| 89 | + ([] (beta-distribution 1.0 1.0)) |
| 90 | + ([alpha beta] |
| 91 | + (k/beta {:alpha alpha :beta beta}))) |
| 92 | + |
| 93 | +(defn cauchy-distribution [location scale] |
| 94 | + (k/cauchy {:location location :scale scale})) |
| 95 | + |
| 96 | +(defn exponential-distribution [rate] |
| 97 | + (k/exponential {:rate rate})) |
| 98 | + |
| 99 | +(defn uniform-distribution |
| 100 | + ([] (uniform-distribution 0.0 1.0)) |
| 101 | + ([lo hi] |
| 102 | + (k/uniform {:a lo :b hi}))) |
| 103 | + |
| 104 | +(defn normal-distribution |
| 105 | + ([] (normal-distribution 0.0 1.0)) |
| 106 | + ([mu sigma] |
| 107 | + (k/normal {:mu mu :sd sigma}))) |
| 108 | + |
| 109 | +(defn gamma-distribution [shape scale] |
| 110 | + (k/gamma {:shape shape :scale scale})) |
| 111 | + |
| 112 | +;; ## Primitive generative functions |
| 113 | + |
| 114 | +(def bernoulli |
| 115 | + (d/->GenerativeFn bernoulli-distribution)) |
| 116 | + |
| 117 | +(def beta |
| 118 | + (d/->GenerativeFn beta-distribution)) |
| 119 | + |
| 120 | +(def cauchy |
| 121 | + (d/->GenerativeFn cauchy-distribution)) |
| 122 | + |
| 123 | +(def exponential |
| 124 | + (d/->GenerativeFn exponential-distribution)) |
| 125 | + |
| 126 | +(def uniform |
| 127 | + (d/->GenerativeFn uniform-distribution)) |
| 128 | + |
| 129 | +(def normal |
| 130 | + (d/->GenerativeFn normal-distribution)) |
| 131 | + |
| 132 | +(def gamma |
| 133 | + (d/->GenerativeFn gamma-distribution)) |
0 commit comments