Skip to content

Commit

Permalink
Merge e2f4fc3 into 8c87f73
Browse files Browse the repository at this point in the history
  • Loading branch information
jimenofonseca committed Jan 16, 2017
2 parents 8c87f73 + e2f4fc3 commit bc23fe9
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 3 deletions.
1 change: 1 addition & 0 deletions pymc3/distributions/__init__.py
Expand Up @@ -24,6 +24,7 @@
from .continuous import ExGaussian
from .continuous import VonMises
from .continuous import SkewNormal
from .continuous import Triangular

from .discrete import Binomial
from .discrete import BetaBinomial
Expand Down
45 changes: 44 additions & 1 deletion pymc3/distributions/continuous.py
Expand Up @@ -13,7 +13,7 @@
import warnings

from . import transforms
from .dist_math import bound, logpow, gammaln, betaln, std_cdf, i0, i1
from .dist_math import bound, logpow, gammaln, betaln, std_cdf, i0, i1, alltrue_elemwise
from .distribution import Continuous, draw_values, generate_samples

__all__ = ['Uniform', 'Flat', 'Normal', 'Beta', 'Exponential', 'Laplace',
Expand Down Expand Up @@ -1410,3 +1410,46 @@ def logp(self, value):
+ (-tau * (value - mu)**2
+ tt.log(tau / np.pi / 2.)) / 2.,
tau > 0, sd > 0)


class Triangular(Continuous):
"""
Continuous Triangular log-likelihood
Implemented by J. A. Fonseca 22/12/16
Parameters
----------
lower : float
Lower limit.
c: float
mode
upper : float
Upper limit.
"""

def __init__(self, lower=0, upper=1, c=0.5,
*args, **kwargs):
super(Triangular, self).__init__(*args, **kwargs)

self.c = c
self.lower = lower
self.upper = upper
self.mean = c
self.median = self.mean

def random(self, point=None, size=None):
c, lower, upper = draw_values([self.c, self.lower, self.upper],
point=point)
return generate_samples(stats.triang.rvs, c=c-lower, loc=lower, scale=upper-lower,
size=size, random_state=None)

def logp(self, value):
c = self.c
lower = self.lower
upper = self.upper
return tt.switch(alltrue_elemwise([lower <= value, value < c]),
tt.log(2 * (value - lower) / ((upper - lower) * (c - lower))),
tt.switch(tt.eq(value, c), tt.log(2 / (upper - lower)),
tt.switch(alltrue_elemwise([c < value, value <= upper]),
tt.log(2 * (upper - value) / ((upper - lower) * (upper - c))),np.inf)))

11 changes: 9 additions & 2 deletions pymc3/tests/test_distributions.py
Expand Up @@ -11,7 +11,7 @@
BetaBinomial, HalfStudentT, StudentT, Weibull, Pareto, InverseGamma,
Gamma, Cauchy, HalfCauchy, Lognormal, Laplace, NegativeBinomial,
Geometric, Exponential, ExGaussian, Normal, Flat, LKJCorr, Wald,
ChiSquared, HalfNormal, DiscreteUniform, Bound, Uniform,
ChiSquared, HalfNormal, DiscreteUniform, Bound, Uniform, Triangular,
Binomial, Wishart, SkewNormal)
from ..distributions import continuous, multivariate
from numpy import array, inf, log, exp
Expand Down Expand Up @@ -333,6 +333,14 @@ def test_uniform(self):
Uniform, Runif, {'lower': -Rplusunif, 'upper': Rplusunif},
lambda value, lower, upper: sp.uniform.logpdf(value, lower, upper - lower))

Runif = Domain([-1, -.4, 0, .4, 1])
Rdunif = Domain([-10, 0, 10.])
Rplusunif = Domain([0, .5, inf])
def test_triangular(self):
self.pymc3_matches_scipy(
Triangular, Runif, {'lower': -Rplusunif, 'c': Runif, 'upper': Rplusunif},
lambda value, c, lower, upper: sp.triang.logpdf(value, c-lower, lower, upper-lower))

def test_bound_normal(self):
PositiveNormal = Bound(Normal, lower=0.)
self.pymc3_matches_scipy(PositiveNormal, Rplus, {'mu': Rplus, 'sd': Rplus},
Expand Down Expand Up @@ -462,7 +470,6 @@ def test_student_tpos(self):
def test_skew_normal(self):
self.pymc3_matches_scipy(SkewNormal, R, {'mu': R, 'sd': Rplusbig, 'alpha': R},
lambda value, alpha, mu, sd: sp.skewnorm.logpdf(value, alpha, mu, sd))

def test_binomial(self):
self.pymc3_matches_scipy(Binomial, Nat, {'n': NatSmall, 'p': Unit},
lambda value, n, p: sp.binom.logpmf(value, n, p))
Expand Down
4 changes: 4 additions & 0 deletions pymc3/tests/test_distributions_random.py
Expand Up @@ -180,6 +180,10 @@ class TestUniform(BaseTestCases.BaseTestCase):
distribution = pm.Uniform
params = {'lower': 0., 'upper': 1.}

class TestTriangular(BaseTestCases.BaseTestCase):
distribution = pm.Triangular
params = {'c': 0.5,'lower': 0., 'upper': 1.}


class TestWald(BaseTestCases.BaseTestCase):
distribution = pm.Wald
Expand Down

0 comments on commit bc23fe9

Please sign in to comment.