From b6842f3d6d8939812cb00db24abd6759aab31e09 Mon Sep 17 00:00:00 2001 From: Marco De Nadai Date: Mon, 1 May 2017 11:47:45 +0200 Subject: [PATCH] Logit-normal distribution added --- pymc3/distributions/continuous.py | 48 +++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/pymc3/distributions/continuous.py b/pymc3/distributions/continuous.py index 039054632a..da9b2bb0cc 100644 --- a/pymc3/distributions/continuous.py +++ b/pymc3/distributions/continuous.py @@ -13,6 +13,7 @@ import warnings from pymc3.theanof import floatX +from pymc3.math import logit from . import transforms from .dist_math import bound, logpow, gammaln, betaln, std_cdf, i0, i1, alltrue_elemwise @@ -20,9 +21,9 @@ __all__ = ['Uniform', 'Flat', 'Normal', 'Beta', 'Exponential', 'Laplace', 'StudentT', 'Cauchy', 'HalfCauchy', 'Gamma', 'Weibull', - 'HalfStudentT', 'StudentTpos', 'Lognormal', 'ChiSquared', - 'HalfNormal', 'Wald', 'Pareto', 'InverseGamma', 'ExGaussian', - 'VonMises', 'SkewNormal'] + 'HalfStudentT', 'StudentTpos', 'Lognormal', 'Logitnormal', + 'ChiSquared', 'HalfNormal', 'Wald', 'Pareto', 'InverseGamma', + 'ExGaussian', 'VonMises', 'SkewNormal'] class PositiveContinuous(Continuous): @@ -643,6 +644,47 @@ def logp(self, value): tau > 0) +class Logitnormal(PositiveContinuous): + R""" + Logit-normal log-likelihood. + + .. math:: + + f(x \mid \mu, \tau) = + \frac{1}{x(1-x)} \sqrt{\frac{\tau}{2\pi}} + \exp\left\{ -\frac{\tau}{2} (logit(x)-\mu)^2 \right\} + + ======== ========================================================================= + Support :math:`x \in (0, 1)` + Mean no analytical solution + Variance no analytical solution + ======== ========================================================================= + + Parameters + ---------- + mu : float + Location parameter. + tau : float + Scale parameter (tau > 0). + """ + + def __init__(self, mu=0.5, tau=None, *args, **kwargs): + super(Logitnormal, self).__init__(*args, **kwargs) + + self.mu = mu = tt.as_tensor_variable(mu) + self.tau = tau = tt.as_tensor_variable(tau) + + self.median = logit(mu) + assert_negative_support(tau, 'tau', 'Logitnormal') + + def logp(self, value): + mu = self.mu + tau = self.tau + return bound(-0.5 * tau * (logit(value) - mu) ** 2 + + 0.5 * tt.log(tau / (2. * np.pi)) + - tt.log(value * (1 - value)), value > 0, value < 1, tau > 0) + + class StudentT(Continuous): R""" Non-central Student's T log-likelihood.