Skip to content

Commit

Permalink
Merge 2ec7126 into fc523cc
Browse files Browse the repository at this point in the history
  • Loading branch information
twiecki committed Dec 19, 2018
2 parents fc523cc + 2ec7126 commit bad2580
Show file tree
Hide file tree
Showing 8 changed files with 403 additions and 363 deletions.
477 changes: 254 additions & 223 deletions pymc3/distributions/continuous.py

Large diffs are not rendered by default.

32 changes: 17 additions & 15 deletions pymc3/distributions/dist_math.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,19 +108,21 @@ def normal_lccdf(mu, sigma, x):
)


def sd2rho(sd):
def sigma2rho(sigma):
"""
`sd -> rho` theano converter
:math:`mu + sd*e = mu + log(1+exp(rho))*e`"""
return tt.log(tt.exp(tt.abs_(sd)) - 1.)
`sigma -> rho` theano converter
:math:`mu + sigma*e = mu + log(1+exp(rho))*e`"""
return tt.log(tt.exp(tt.abs_(sigma)) - 1.)


def rho2sd(rho):
def rho2sigma(rho):
"""
`rho -> sd` theano converter
:math:`mu + sd*e = mu + log(1+exp(rho))*e`"""
`rho -> sigma` theano converter
:math:`mu + sigma*e = mu + log(1+exp(rho))*e`"""
return tt.nnet.softplus(rho)

rho2sd = rho2sigma
sd2rho = sigma2rho

def log_normal(x, mean, **kwargs):
"""
Expand All @@ -133,7 +135,7 @@ def log_normal(x, mean, **kwargs):
point of evaluation
mean : Tensor
mean of normal distribution
kwargs : one of parameters `{sd, tau, w, rho}`
kwargs : one of parameters `{sigma, tau, w, rho}`
Notes
-----
Expand All @@ -145,22 +147,22 @@ def log_normal(x, mean, **kwargs):
4) `tau` that follows this equation :math:`tau = std^{-1}`
----
"""
sd = kwargs.get('sd')
sigma = kwargs.get('sigma')
w = kwargs.get('w')
rho = kwargs.get('rho')
tau = kwargs.get('tau')
eps = kwargs.get('eps', 0.)
check = sum(map(lambda a: a is not None, [sd, w, rho, tau]))
check = sum(map(lambda a: a is not None, [sigma, w, rho, tau]))
if check > 1:
raise ValueError('more than one required kwarg is passed')
if check == 0:
raise ValueError('none of required kwarg is passed')
if sd is not None:
std = sd
if sigma is not None:
std = sigma
elif w is not None:
std = tt.exp(w)
elif rho is not None:
std = rho2sd(rho)
std = rho2sigma(rho)
else:
std = tau**(-1)
std += f(eps)
Expand Down Expand Up @@ -330,11 +332,11 @@ def random_choice(*args, **kwargs):
return samples


def zvalue(value, sd, mu):
def zvalue(value, sigma, mu):
"""
Calculate the z-value for a normal distribution.
"""
return (value - mu) / sd
return (value - mu) / sigma


def incomplete_beta_cfe(a, b, x, small):
Expand Down
21 changes: 12 additions & 9 deletions pymc3/distributions/mixture.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from .dist_math import bound, random_choice
from .distribution import (Discrete, Distribution, draw_values,
generate_samples, _DrawValuesContext)
from .continuous import get_tau_sd, Normal
from .continuous import get_tau_sigma, Normal


def all_discrete(comp_dists):
Expand Down Expand Up @@ -208,7 +208,7 @@ class NormalMixture(Mixture):
the mixture weights
mu : array of floats
the component means
sd : array of floats
sigma : array of floats
the component standard deviations
tau : array of floats
the component precisions
Expand All @@ -217,27 +217,30 @@ class NormalMixture(Mixture):
of the mixture distribution, with one axis being
the number of components.
Note: You only have to pass in sd or tau, but not both.
Note: You only have to pass in sigma or tau, but not both.
"""

def __init__(self, w, mu, comp_shape=(), *args, **kwargs):
_, sd = get_tau_sd(tau=kwargs.pop('tau', None),
sd=kwargs.pop('sd', None))
if 'sd' in kwargs.keys():
kwargs['sigma'] = kwargs.pop('sd')

_, sigma = get_tau_sigma(tau=kwargs.pop('tau', None),
sigma=kwargs.pop('sigma', None))

self.mu = mu = tt.as_tensor_variable(mu)
self.sd = sd = tt.as_tensor_variable(sd)
self.sigma = self.sd = sigma = tt.as_tensor_variable(sigma)

super(NormalMixture, self).__init__(w, Normal.dist(mu, sd=sd, shape=comp_shape),
super(NormalMixture, self).__init__(w, Normal.dist(mu, sigma=sigma, shape=comp_shape),
*args, **kwargs)

def _repr_latex_(self, name=None, dist=None):
if dist is None:
dist = self
mu = dist.mu
w = dist.w
sd = dist.sd
sigma = dist.sigma
name = r'\text{%s}' % name
return r'${} \sim \text{{NormalMixture}}(\mathit{{w}}={},~\mathit{{mu}}={},~\mathit{{sigma}}={})$'.format(name,
get_variable_name(w),
get_variable_name(mu),
get_variable_name(sd))
get_variable_name(sigma))
48 changes: 26 additions & 22 deletions pymc3/distributions/timeseries.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from theano import scan

from pymc3.util import get_variable_name
from .continuous import get_tau_sd, Normal, Flat
from .continuous import get_tau_sigma, Normal, Flat
from . import multivariate
from . import distribution

Expand Down Expand Up @@ -79,23 +79,25 @@ class AR(distribution.Continuous):
----------
rho : tensor
Tensor of autoregressive coefficients. The first dimension is the p lag.
sd : float
Standard deviation of innovation (sd > 0). (only required if tau is not specified)
sigma : float
Standard deviation of innovation (sigma > 0). (only required if tau is not specified)
tau : float
Precision of innovation (tau > 0). (only required if sd is not specified)
Precision of innovation (tau > 0). (only required if sigma is not specified)
constant: bool (optional, default = False)
Whether to include a constant.
init : distribution
distribution for initial values (Defaults to Flat())
"""

def __init__(self, rho, sd=None, tau=None,
def __init__(self, rho, sigma=None, tau=None,
constant=False, init=Flat.dist(),
*args, **kwargs):

sd=None, *args, **kwargs):
super(AR, self).__init__(*args, **kwargs)
tau, sd = get_tau_sd(tau=tau, sd=sd)
self.sd = tt.as_tensor_variable(sd)
if sd is not None:
sigma = sd

tau, sigma = get_tau_sigma(tau=tau, sigma=sigma)
self.sigma = self.sd = tt.as_tensor_variable(sigma)
self.tau = tt.as_tensor_variable(tau)

self.mean = tt.as_tensor_variable(0.)
Expand Down Expand Up @@ -147,45 +149,47 @@ class GaussianRandomWalk(distribution.Continuous):
----------
mu: tensor
innovation drift, defaults to 0.0
sd : tensor
sd > 0, innovation standard deviation (only required if tau is not specified)
sigma : tensor
sigma > 0, innovation standard deviation (only required if tau is not specified)
tau : tensor
tau > 0, innovation precision (only required if sd is not specified)
tau > 0, innovation precision (only required if sigma is not specified)
init : distribution
distribution for initial value (Defaults to Flat())
"""

def __init__(self, tau=None, init=Flat.dist(), sd=None, mu=0.,
*args, **kwargs):
def __init__(self, tau=None, init=Flat.dist(), sigma=None, mu=0.,
sd=None, *args, **kwargs):
super(GaussianRandomWalk, self).__init__(*args, **kwargs)
tau, sd = get_tau_sd(tau=tau, sd=sd)
if sd is not None:
sigma = sd
tau, sigma = get_tau_sigma(tau=tau, sigma=sigma)
self.tau = tau = tt.as_tensor_variable(tau)
self.sd = sd = tt.as_tensor_variable(sd)
self.sigma = self.sd = sigma = tt.as_tensor_variable(sigma)
self.mu = mu = tt.as_tensor_variable(mu)
self.init = init
self.mean = tt.as_tensor_variable(0.)

def logp(self, x):
tau = self.tau
sd = self.sd
sigma = self.sigma
mu = self.mu
init = self.init

x_im1 = x[:-1]
x_i = x[1:]

innov_like = Normal.dist(mu=x_im1 + mu, sd=sd).logp(x_i)
innov_like = Normal.dist(mu=x_im1 + mu, sigma=sigma).logp(x_i)
return init.logp(x[0]) + tt.sum(innov_like)

def _repr_latex_(self, name=None, dist=None):
if dist is None:
dist = self
mu = dist.mu
sd = dist.sd
sigma = dist.sigma
name = r'\text{%s}' % name
return r'${} \sim \text{{GaussianRandomWalk}}(\mathit{{mu}}={},~\mathit{{sd}}={})$'.format(name,
return r'${} \sim \text{{GaussianRandomWalk}}(\mathit{{mu}}={},~\mathit{{sigma}}={})$'.format(name,
get_variable_name(mu),
get_variable_name(sd))
get_variable_name(sigma))


class GARCH11(distribution.Continuous):
Expand Down Expand Up @@ -237,7 +241,7 @@ def volatility_update(x, vol, w, a, b):

def logp(self, x):
vol = self.get_volatility(x)
return tt.sum(Normal.dist(0., sd=vol).logp(x))
return tt.sum(Normal.dist(0., sigma=vol).logp(x))

def _repr_latex_(self, name=None, dist=None):
if dist is None:
Expand Down

0 comments on commit bad2580

Please sign in to comment.