|
| 1 | +import aesara.tensor as at |
| 2 | +from etuples import etuple, etuplize |
| 3 | +from kanren import eq, lall, var |
| 4 | + |
| 5 | + |
| 6 | +def halfcauchy_inverse_gamma(in_expr, out_expr): |
| 7 | + r"""Produce a goal that represents the fact that a half-Cauchy distribution can be |
| 8 | + expressed as a scale mixture of inverse-Gamma distributions. |
| 9 | +
|
| 10 | + .. math:: |
| 11 | +
|
| 12 | + \begin{equation*} |
| 13 | + \frac{ |
| 14 | + X^2 | a \sim \operatorname{Gamma^{-1}}\left(1/2, a), \quad |
| 15 | + a \sim \operatorname{Gamma^{-1}}\left(1/2, 1/A^2\right), \quad |
| 16 | + }{ |
| 17 | + X \sim \operatorname{C^{+}}\left(0, A) |
| 18 | + } |
| 19 | + \end{equation*} |
| 20 | +
|
| 21 | + TODO: This relation is a particular case of a similar relation for the |
| 22 | + Half-t distribution [1]_ which does not have an implementation yet in Aesara. |
| 23 | + When it becomes available we should replace this relation with the more |
| 24 | + general one, and implement the relation between the Half-t and Half-Cauchy |
| 25 | + distributions. |
| 26 | +
|
| 27 | + Parameters |
| 28 | + ---------- |
| 29 | + in_expr |
| 30 | + An expression that represents a half-Cauchy distribution. |
| 31 | + out_expr |
| 32 | + An expression that represents the square root of the inverse-Gamma scale |
| 33 | + mixture. |
| 34 | +
|
| 35 | + References |
| 36 | + ---------- |
| 37 | + .. [1]: Wand, M. P., Ormerod, J. T., Padoan, S. A., & Frühwirth, R. (2011). |
| 38 | + Mean field variational Bayes for elaborate distributions. Bayesian |
| 39 | + Analysis, 6(4), 847-900. |
| 40 | +
|
| 41 | + """ |
| 42 | + |
| 43 | + # Half-Cauchy distribution |
| 44 | + rng_lv, size_lv, type_idx_lv = var(), var(), var() |
| 45 | + loc_at = at.as_tensor(0) |
| 46 | + scale_lv = var() |
| 47 | + X_halfcauchy_et = etuple( |
| 48 | + etuplize(at.random.halfcauchy), rng_lv, size_lv, type_idx_lv, loc_at, scale_lv |
| 49 | + ) |
| 50 | + |
| 51 | + # Inverse-Gamma scale mixture |
| 52 | + rng_inner_lv, size_inner_lv, type_idx_inner_lv = var(), var(), var() |
| 53 | + rng_outer_lv, size_outer_lv, type_idx_outer_lv = var(), var(), var() |
| 54 | + X_square_scale_mixture_et = etuple( |
| 55 | + etuplize(at.random.invgamma), |
| 56 | + at.as_tensor(0.5), |
| 57 | + etuple( |
| 58 | + etuplize(at.true_div), |
| 59 | + at.as_tensor(1), |
| 60 | + etuple( |
| 61 | + etuplize(at.random.invgamma), |
| 62 | + at.as_tensor(0.5), |
| 63 | + etuple( |
| 64 | + etuplize(at.true_div), |
| 65 | + at.as_tensor(1), |
| 66 | + etuple(etuplize(at.pow), scale_lv, at.as_tensor(2)), |
| 67 | + ), |
| 68 | + rng=rng_inner_lv, |
| 69 | + size=size_inner_lv, |
| 70 | + dtype=type_idx_inner_lv, |
| 71 | + ), |
| 72 | + ), |
| 73 | + rng=rng_outer_lv, |
| 74 | + size=size_outer_lv, |
| 75 | + dtype=type_idx_outer_lv, |
| 76 | + ) |
| 77 | + X_scale_mixture_et = etuple(etuplize(at.sqrt), X_square_scale_mixture_et) |
| 78 | + |
| 79 | + return lall( |
| 80 | + eq(in_expr, X_halfcauchy_et), |
| 81 | + eq(out_expr, X_scale_mixture_et), |
| 82 | + ) |
0 commit comments