예제 #1
0
    def logp(self, value):
        value_x = value[0][0]
        value_y = value[0][1]
        mu_x = self.mu_x
        mu_y = self.mu_y

        log_prob_x = bound(
            logpow(mu_x, value_x) - factln(value_x) - mu_x,
            mu_x >= 0, value_x >= 0)
        log_prob_y = bound(
            logpow(mu_y, value_y) - factln(value_y) - mu_y,
            mu_y >= 0, value_y >= 0)
        out = T.switch(1 * T.eq(mu_x, 0) * T.eq(value_x, 0), 0, log_prob_x)
        out += T.switch(1 * T.eq(mu_x, 0) * T.eq(value_x, 0), 0, log_prob_y)
        return out
예제 #2
0
    def logp(self, weights):
        """
        Calculate log-probability of the given set of weights.

        Parameters
        ----------
        value : 1-D array, having numeric values
            Set of weights for which log-probability is calculated.

        Returns
        -------
        TensorVariable
        """
        k = self.shape
        a = self.a
        
        wts = tt.as_tensor_variable(weights)
        wt = wts[:-1]
        wt_sum = tt.extra_ops.cumsum(wt)
        denom = 1 - wt_sum
        denom_shift = tt.concatenate([[1.], denom])
        betas = wts/denom_shift
        Beta_ = pm.Beta.dist(1, a)
        logp = Beta_.logp(betas).sum()
        return bound(Beta_.logp(betas).sum(),
                     tt.all(betas > 0), tt.all(weights) > 0,
                     wt_sum < 1, wt_sum > 0,
                     tt.all(denom) > 0)
예제 #3
0
    def logp(self, value):
        """
        Calculate log-probability of defined Mixture distribution at specified value.

        Parameters
        ----------
        value: numeric
            Value(s) for which log-probability is calculated. If the log probabilities for multiple
            values are desired the values must be provided in a numpy array or Aesara tensor

        Returns
        -------
        TensorVariable
        """
        w = self.w

        return bound(
            logsumexp(at.log(w) + self._comp_logp(value),
                      axis=-1,
                      keepdims=False),
            w >= 0,
            w <= 1,
            at.allclose(w.sum(axis=-1), 1),
            broadcast_conditions=False,
        )
예제 #4
0
 def gev_logp(value):
     scaled = (value - loc) / scale
     logp = -(tt.log(scale) + (((c - 0.5) + 1) / (c - 0.5) * tt.log1p(
         (c - 0.5) * scaled) + (1 + (c - 0.5) * scaled)**(-1 /
                                                          (c - 0.5))))
     bound1 = loc - scale / (c - 0.5)
     bounds = tt.switch((c - 0.5) > 0, value > bound1, value < bound1)
     return bound(logp, bounds, c != 0)
예제 #5
0
 def logp(self, value):
     mu = self.mu
     tau = self.tau
     offset = self.offset
     v = value + offset
     log_pdf = (-0.5 * tau * (tt.log(v) - mu)**2 +
                0.5 * tt.log(tau / (2. * np.pi)) - tt.log(v))
     return bound(log_pdf, tau > 0, offset > 0)
예제 #6
0
파일: util.py 프로젝트: lfsblack/cs-ranking
    def logp(self, value):
        p = self.p
        k = self.k
        a = self.loss_func(p, value)
        p = ttu.normalize(p)
        sum_to1 = theano.gradient.zero_grad(tt.le(abs(tt.sum(p, axis=-1) - 1), 1e-5))

        value_k = tt.argmax(value, axis=1)
        return bound(a, value_k >= 0, value_k <= (k - 1), sum_to1)
예제 #7
0
 def logp(value, n, p):
     return bound(
         factln(n) - factln(value).sum() + (value * at.log(p)).sum(),
         value >= 0,
         0 <= p,
         p <= 1,
         at.isclose(p.sum(), 1),
         broadcast_conditions=False,
     )
예제 #8
0
 def gev_logp(value, t):
     loc_ = m1_ * t + m2_
     scaled = (value - loc_) / scale_
     logp = -(tt.log(scale_) +
              (((c_ - 0.5) + 1) / (c_ - 0.5) * tt.log1p(
                  (c_ - 0.5) * scaled) +
               (1 + (c_ - 0.5) * scaled)**(-1 / (c_ - 0.5))))
     bound1 = loc_ - scale_ / (c_ - 0.5)
     bounds = tt.switch((c_ - 0.5) > 0, value > bound1, value < bound1)
     return bound(logp, bounds, c_ != 0)
예제 #9
0
 def gev_logp(value, t, t2):
     loc = m1 * t2 + m2 * t + m3
     #            scale=tt.log(tt.exp(scale1))
     scaled = (value - loc) / scale
     logp = -(tt.log(scale) + (((c - 0.5) + 1) / (c - 0.5) * tt.log1p(
         (c - 0.5) * scaled) + (1 + (c - 0.5) * scaled)**(-1 /
                                                          (c - 0.5))))
     bound1 = loc - scale / (c - 0.5)
     bounds = tt.switch((c - 0.5) > 0, value > bound1, value < bound1)
     return bound(logp, bounds, c != 0)
예제 #10
0
 def logp(self, value):
     logp = self._wrapped.logp(value)
     bounds = []
     if self.lower is not None:
         bounds.append(value >= self.lower)
     if self.upper is not None:
         bounds.append(value <= self.upper)
     if len(bounds) > 0:
         return bound(logp, *bounds)
     else:
         return logp
예제 #11
0
파일: bound.py 프로젝트: pymc-devs/pymc3
 def logp(self, value):
     logp = self._wrapped.logp(value)
     bounds = []
     if self.lower is not None:
         bounds.append(value >= self.lower)
     if self.upper is not None:
         bounds.append(value <= self.upper)
     if len(bounds) > 0:
         return bound(logp, *bounds)
     else:
         return logp
예제 #12
0
    def logp(self, value):
        n = self.n
        p = self.p

        return bound(
            factln(n) - factln(value).sum() + (value * at.log(p)).sum(),
            at.all(value >= 0),
            at.all(0 <= p),
            at.all(p <= 1),
            at.isclose(p.sum(), 1),
            broadcast_conditions=False,
        )
    def logp(self, x):
        n = self.n
        p = self.p

        return bound(tt.sum(factln(n)) - tt.sum(factln(x)) +
                     tt.sum(x * tt.log(p)),
                     tt.all(x >= 0),
                     tt.all(tt.eq(tt.sum(x, axis=-1, keepdims=True), n)),
                     tt.all(p <= 1),
                     tt.all(tt.eq(tt.sum(p, axis=-1), 1)),
                     tt.all(tt.ge(n, 0)),
                     broadcast_conditions=False)
예제 #14
0
    def logp(self, value):
        n = self.n
        p = self.p

        return bound(
            factln(n) - factln(value).sum() + (value * aet.log(p)).sum(),
            value >= 0,
            0 <= p,
            p <= 1,
            aet.isclose(p.sum(), 1),
            broadcast_conditions=False,
        )
예제 #15
0
    def logp(self, Z):
        alpha = self.alpha
        beta = self.beta

        Zanchored = Z[self.mask.nonzero()]

        #import pdb; pdb.set_trace()
        logp = bound(
            gammaln(alpha + beta) - gammaln(alpha) - gammaln(beta) +
            logpow(Zanchored, alpha - 1) + logpow(1 - Zanchored, beta - 1),
            0 <= Zanchored, Zanchored <= 1, alpha > 0, beta > 0)

        return logp
예제 #16
0
 def logp(self, value):
     mu = self.mu
     #              mu^k
     #     PDF = ------------
     #            k! (e^mu - 1)
     # log(PDF) = log(mu^k) - (log(k!) + log(e^mu - 1))
     #
     # See https://en.wikipedia.org/wiki/Zero-truncated_Poisson_distribution
     p = logpow(mu,
                value) - (factln(value) + pm.math.log(pm.math.exp(mu) - 1))
     log_prob = bound(p, mu >= 0, value >= 0)
     # Return zero when mu and value are both zero
     return tt.switch(1 * tt.eq(mu, 0) * tt.eq(value, 0), 0, log_prob)
예제 #17
0
    def logp(self, value):
        """
		Calculate log-probability of EDSD distribution at specified value.
		Parameters
		----------
		value : numeric
			Value(s) for which log-probability is calculated. If the log probabilities for multiple
			values are desired the values must be provided in a numpy array or theano tensor
		Returns
		-------
		TensorVariable
		"""
        scale = self.scale
        log_d = 2.0 * tt.log(value) - tt.log(2.0 * scale**3) - value / scale
        return bound(log_d, value >= 0, scale > 0)
    def logp(self, Z):
        alpha = self.alpha
        beta = self.beta

        Zanchored = Z[self.mask.nonzero()]

        #import pdb; pdb.set_trace()
        logp = bound(
            gammaln(alpha + beta) - gammaln(alpha) - gammaln(beta) +
            logpow(
                Zanchored, alpha - 1) + logpow(1 - Zanchored, beta - 1),
            0 <= Zanchored, Zanchored <= 1,
            alpha > 0,
            beta > 0)

        return logp
예제 #19
0
    def logp(self, x):

        log_p = 0.
        for i in range(0, self.shape[0]):
            p_it = self.PI[x[i, ][:-1]]
            x_t = x[i, ][1:]
            x_0 = tt.stack([x[i, ][0]])
            mask = self.renewal_mask

            log_p_i = pm.Categorical.dist(self.Q).logp(x_0) + tt.sum(
                pm.Categorical.dist(p_it).logp(x_t))

            # Restrction: if not churned, cannot be in state 0 at a renewal period
            log_p = log_p + bound(log_p_i, tt.dot(mask, x_t) > 0)

        return log_p
예제 #20
0
def negative_binomial_gaussian_approx_logp(mu, alpha, value):
    """Generates symbolic Gaussian approximation to negative binomial logp.

    Args:
        mu: negative binomial mean tensor
        alpha: negative binomial over-dispersion tensor
        value: negative binomial counts

    Note:
        `mu`, `alpha` and `value` must be either shape-compatible or be commensurately broadcastable.

    Returns:
        symbolic approximate negative binomial logp
    """
    tau = alpha / (mu * (alpha + mu))  # precision
    return pm_dist_math.bound(0.5 * (tt.log(tau) - _log_2_pi - tau * tt.square(value - mu)),
                              mu > 0, value >= 0, alpha > 0)
예제 #21
0
 def gev_logp(value):
     scaled = (value - loc) / scale
     logp = -(scale
              + ((c + 1) / c) * tt.log1p(c * scaled)
              + (1 + c * scaled) ** (-1/c))
     alpha = loc - scale / c
     
     # If the value is greater than zero, then check to see if 
     # it is greater than alpha. Otherwise, check to see if it 
     # is less than alpha.
     bounds = tt.switch(value > 0, value > alpha, value < alpha)
     
     # The returned array will have entries of -inf if the bound
     # is not satisfied. This condition says "if c is zero or
     # value is less than alpha, return -inf and blow up 
     # the log-likelihood.
     return bound(logp, bounds, c != 0)
예제 #22
0
파일: commons.py 프로젝트: zhaoxia413/gatk
def negative_binomial_gaussian_approx_logp(mu, alpha, value):
    """Generates symbolic Gaussian approximation to negative binomial logp.

    Args:
        mu: negative binomial mean tensor
        alpha: negative binomial over-dispersion tensor
        value: negative binomial counts

    Note:
        `mu`, `alpha` and `value` must be either shape-compatible or be commensurately broadcastable.

    Returns:
        symbolic approximate negative binomial logp
    """
    tau = alpha / (mu * (alpha + mu))  # precision
    return pm_dist_math.bound(0.5 * (tt.log(tau) - _log_2_pi - tau * tt.square(value - mu)),
                              mu > 0, value >= 0, alpha > 0)
예제 #23
0
    def logp(self, value):
        """
        Calculate log-probability of defined ``MixtureSameFamily`` distribution at specified value.

        Parameters
        ----------
        value : numeric
            Value(s) for which log-probability is calculated. If the log probabilities for multiple
            values are desired the values must be provided in a numpy array or Aesara tensor

        Returns
        -------
        TensorVariable
        """

        comp_dists = self.comp_dists
        w = self.w
        mixture_axis = self.mixture_axis

        event_shape = comp_dists.shape[mixture_axis + 1:]

        # To be able to broadcast the comp_dists.logp with w and value
        # We first have to pad the shape of w to the right with ones
        # so that it can broadcast with the event_shape.

        w = at.shape_padright(w, len(event_shape))

        # Second, we have to add the mixture_axis to the value tensor
        # To insert the mixture axis at the correct location, we use the
        # negative number index. This way, we can also handle situations
        # in which, value is an observed value with more batch dimensions
        # than the ones present in the comp_dists.
        comp_dists_ndim = len(comp_dists.shape)

        value = at.shape_padaxis(value, axis=mixture_axis - comp_dists_ndim)

        comp_logp = comp_dists.logp(value)
        return bound(
            logsumexp(at.log(w) + comp_logp, axis=mixture_axis,
                      keepdims=False),
            w >= 0,
            w <= 1,
            at.allclose(w.sum(axis=mixture_axis - comp_dists_ndim), 1),
            broadcast_conditions=False,
        )
예제 #24
0
def centered_heavy_tail_logp(mu, value):
    """This distribution is obtained by taking X ~ Exp and performing a Bose transformation
    Y = (exp(X) - 1)^{-1}. The result is:

        p(y) = (1 + 2 \mu) y^{2\mu} (1 + y)^{-2(1 + \mu)}

    It is a heavy-tail distribution with non-existent first moment.

    Args:
        mu: exponential parameter of X
        value: values of Y

    Returns:
        symbolic logp
    """
    return pm_dist_math.bound(tt.log(1.0 + 2.0 * mu) + 2.0 * mu * tt.log(value)
                              - 2.0 * (1.0 + mu) * tt.log(1.0 + value),
                              mu >= 0, value > 0)
예제 #25
0
파일: commons.py 프로젝트: zhaoxia413/gatk
def centered_heavy_tail_logp(mu, value):
    """This distribution is obtained by taking X ~ Exp and performing a Bose transformation
    Y = (exp(X) - 1)^{-1}. The result is:

        p(y) = (1 + 2 \mu) y^{2\mu} (1 + y)^{-2(1 + \mu)}

    It is a heavy-tail distribution with non-existent first moment.

    Args:
        mu: exponential parameter of X
        value: values of Y

    Returns:
        symbolic logp
    """
    return pm_dist_math.bound(tt.log(1.0 + 2.0 * mu) + 2.0 * mu * tt.log(value)
                              - 2.0 * (1.0 + mu) * tt.log(1.0 + value),
                              mu >= 0, value > 0)
예제 #26
0
파일: commons.py 프로젝트: zhaoxia413/gatk
def negative_binomial_logp(mu, alpha, value):
    """Generates symbolic negative binomial logp.

    Args:
        mu: negative binomial mean tensor
        alpha: negative binomial over-dispersion tensor
        value: negative binomial counts

    Note:
        `mu`, `alpha` and `value` must be either shape-compatible or be commensurately broadcastable.

    Returns:
        symbolic negative binomial logp
    """
    return pm_dist_math.bound(pm_dist_math.binomln(value + alpha - 1, value)
                              + pm_dist_math.logpow(mu / (mu + alpha), value)
                              + pm_dist_math.logpow(alpha / (mu + alpha), alpha),
                              mu > 0, value >= 0, alpha > 0)
예제 #27
0
def negative_binomial_logp(mu, alpha, value):
    """Generates symbolic negative binomial logp.

    Args:
        mu: negative binomial mean tensor
        alpha: negative binomial over-dispersion tensor
        value: negative binomial counts

    Note:
        `mu`, `alpha` and `value` must be either shape-compatible or be commensurately broadcastable.

    Returns:
        symbolic negative binomial logp
    """
    return pm_dist_math.bound(pm_dist_math.binomln(value + alpha - 1, value)
                              + pm_dist_math.logpow(mu / (mu + alpha), value)
                              + pm_dist_math.logpow(alpha / (mu + alpha), alpha),
                              mu > 0, value >= 0, alpha > 0)
예제 #28
0
 def logp(self, value):
     """
     Calculate log-probability of Weibull distribution at specified value.
     Parameters
     ----------
     value: numeric
         Value(s) for which log-probability is calculated. If the log probabilities for multiple
         values are desired the values must be provided in a numpy array or theano tensor
     Returns
     -------
     TensorVariable
     """
     alpha = self.alpha
     beta = self.beta
     value_ = pm.math.maximum(value - self.offset, 1e-313)
     return bound(
         tt.log(alpha) - tt.log(beta) +
         (alpha - 1) * tt.log(value_ / beta) - (value_ / beta)**alpha,
         value_ >= 0,
         alpha > 0,
         beta > 0,
     )
예제 #29
0
파일: bound.py 프로젝트: AlexAndorra/pymc3
    def logp(self, value):
        """
        Calculate log-probability of Bounded distribution at specified value.

        Parameters
        ----------
        value: numeric
            Value for which log-probability is calculated.

        Returns
        -------
        TensorVariable
        """
        logp = self._wrapped.logp(value)
        bounds = []
        if self.lower is not None:
            bounds.append(value >= self.lower)
        if self.upper is not None:
            bounds.append(value <= self.upper)
        if len(bounds) > 0:
            return bound(logp, *bounds)
        else:
            return logp
예제 #30
0
def test_bound():
    logp = at.ones((10, 10))
    cond = at.ones((10, 10))
    assert np.all(bound(logp, cond).eval() == logp.eval())

    logp = at.ones((10, 10))
    cond = at.zeros((10, 10))
    assert np.all(bound(logp, cond).eval() == (-np.inf * logp).eval())

    logp = at.ones((10, 10))
    cond = True
    assert np.all(bound(logp, cond).eval() == logp.eval())

    logp = at.ones(3)
    cond = np.array([1, 0, 1])
    assert not np.all(bound(logp, cond).eval() == 1)
    assert np.prod(bound(logp, cond).eval()) == -np.inf

    logp = at.ones((2, 3))
    cond = np.array([[1, 1, 1], [1, 0, 1]])
    assert not np.all(bound(logp, cond).eval() == 1)
    assert np.prod(bound(logp, cond).eval()) == -np.inf
 def logp_Poisson(self, value):
     r"""
     Calculate log-probability of Poisson distribution at specified value. 
     Switches to Gamma distribution when mu gets large (> 1000)
     Parameters
     ----------
     value: numeric
         Value(s) for which log-probability is calculated. If the log probabilities for multiple
         values are desired the values must be provided in a numpy array or theano tensor
     Returns
     -------
     TensorVariable
     """
     # Return zero when mu and value are both zero, return Gamma log-probability when mu is > 1000,
     # otherwise return Poisson log-probability
     return tt.switch(
         tt.gt(self.mu_biol, 1e3),
         pm.Gamma.dist(mu=self.mu_biol,
                       sd=tt.sqrt(self.mu_biol)).logp(value),
         tt.switch(
             tt.eq(self.mu_biol, 0) * tt.eq(value, 0), 0,
             bound(
                 logpow(self.mu_biol, value) - factln(value) - self.mu_biol,
                 self.mu_biol >= 0, value >= 0)))
예제 #32
0
파일: dists.py 프로젝트: zheh12/bayesalpha
    def logp(self, x):
        # -1/2 (x-mu) @ Sigma^-1 @ (x-mu)^T - 1/2 log(2pi^k|Sigma|)
        # Sigma = diag(std) @ Corr @ diag(std)
        # Sigma^-1 = diag(std^-1) @ Corr^-1 @ diag(std^-1)
        # Corr is a block matrix of special form
        #           +----------+
        # Corr = [[ | 1, b1, b1|,  0,  0,  0,..., 0]
        #         [ |b1,  1, b1|,  0,  0,  0,..., 0]
        #         [ |b1, b1,  1|,  0,  0,  0,..., 0]
        #           +-----------+----------+
        #         [  0,  0,  0, | 1, b2, b2|,..., 0]
        #         [  0,  0,  0, |b2,  1, b2|,..., 0]
        #         [  0,  0,  0, |b2, b2,  1|,..., 0]
        #                       +----------+
        #         [            ...                 ]
        #         [  0,  0,  0,   0,  0,  0 ,..., 1]]
        #
        # Corr = [[B1,  0,  0, ...,  0]
        #         [ 0, B2,  0, ...,  0]
        #         [ 0,  0, B3, ...,  0]
        #         [        ...        ]
        #         [ 0,  0,  0, ..., Bk]]
        #
        # Corr^-1 = [[B1^-1,     0,      0, ...,     0]
        #            [    0, B2^-1,      0, ...,     0]
        #            [    0,     0,  B3^-1, ...,     0]
        #            [              ...               ]
        #            [    0,     0,      0, ..., Bk^-1]]
        #
        # |B| matrix of rank r is easy
        # https://math.stackexchange.com/a/1732839
        # Let D = eye(r) * (1-b)
        # Then B = D + b * ones((r, r))
        # |B| = (1-b) ** r + b * r * (1-b) ** (r-1)
        # |B| = (1.-b) ** (r-1) * (1. + b * (r - 1))
        # log(|B|) = log(1-b)*(r-1) + log1p(b*(r-1))
        #
        # Inverse B^-1 is easy as well
        # https://math.stackexchange.com/a/1766118
        # let
        # c = 1/b + r*1/(1-b)
        # (B^-1)ii = 1/(1-b) - 1/(c*(1-b)**2)
        # (B^-1)ij =         - 1/(c*(1-b)**2)
        #
        # assuming
        # z = (x - mu) / std
        # we have det fix
        # detfix = -sum(log(std))
        #
        # now we need to compute z @ Corr^-1 @ z^T
        # note that B can be unique per timestep
        # so we need z_t @ Corr_t^-1 @ z_t^T in perfect
        # z_t @ Corr_t^-1 @ z_t^T is a sum of block terms
        # quad = z_ct @ B_ct^-1 @ z_ct^T = (B^-1)_iict * sum(z_ct**2) + (B^-1)_ijct*sum_{i!=j}(z_ict * z_jct)
        #
        # finally all terms are computed explicitly
        # logp = detfix - 1/2 * ( quad + log(pi*2) * k + log(|B|) )

        x = tt.as_tensor_variable(x)
        clust_ids, clust_pos, clust_counts = \
            tt.extra_ops.Unique(return_inverse=True,
                                return_counts=True)(self.clust)
        clust_order = tt.argsort(clust_pos)
        mu = self.mu
        corr = self.corr[..., clust_ids]
        std = self.std
        if std.ndim == 0:
            std = tt.repeat(std, x.shape[-1])
        if std.ndim == 1:
            std = std[None, :]
        if corr.ndim == 1:
            corr = corr[None, :]
        z = (x - mu) / std
        z = z[..., clust_order]
        detfix = -tt.log(std).sum(-1)
        # following the notation above
        r = clust_counts
        b = corr
        # detB = (1.-b) ** (r-1) * (1. + b * (r - 1))
        logdetB = tt.log1p(-b) * (r - 1) + tt.log1p(b * (r - 1))
        c = 1 / b + r / (1. - b)
        invBij = -1. / (c * (1. - b)**2)
        invBii = 1. / (1. - b) + invBij
        invBij = tt.repeat(invBij, clust_counts, axis=-1)
        invBii = tt.repeat(invBii, clust_counts, axis=-1)

        # to compute (Corr^-1)_ijt*sum_{i!=j}(z_it * z_jt)
        # we use masked cross products
        mask = tt.arange(x.shape[-1])[None, :]
        mask = tt.repeat(mask, x.shape[-1], axis=0)
        mask = tt.maximum(mask, mask.T)
        block_end_pos = tt.cumsum(r)
        block_end_pos = tt.repeat(block_end_pos, clust_counts)
        mask = tt.lt(mask, block_end_pos)
        mask = tt.and_(mask, mask.T)
        mask = tt.fill_diagonal(mask.astype('float32'), 0.)
        # type: tt.TensorVariable

        invBiizizi_sum = ((z**2) * invBii).sum(-1)
        invBijzizj_sum = (
            (z.dimshuffle(0, 1, 'x') * mask.dimshuffle('x', 0, 1) *
             z.dimshuffle(0, 'x', 1)) * invBij.dimshuffle(0, 1, 'x')).sum(
                 [-1, -2])
        quad = invBiizizi_sum + invBijzizj_sum
        k = pm.floatX(x.shape[-1])
        logp = (detfix - .5 *
                (quad + pm.floatX(np.log(np.pi * 2)) * k + logdetB.sum(-1)))
        if self.nonzero:
            logp = tt.switch(tt.eq(x, 0).any(-1), 0., logp)
        return bound(logp,
                     tt.gt(corr, -1.),
                     tt.lt(corr, 1.),
                     tt.gt(std, 0.),
                     broadcast_conditions=False)
예제 #33
0
def test_check_bounds_false():
    with pm.Model(check_bounds=False):
        logp = at.ones(3)
        cond = np.array([1, 0, 1])
        assert np.all(bound(logp, cond).eval() == logp.eval())
예제 #34
0
    def logp(self, data):
        """
		Retrieve thetas
		"""
        theta4 = self.theta4
        theta5 = self.theta5
        theta6 = self.theta6
        theta7 = self.theta7
        theta8 = self.theta8
        #theta9 = self.theta9
        #self.theta10 = theta10
        k1 = self.k1
        """
		Parse data
		"""

        f_lengths = data[0]
        g_starts = data[1]
        rates = data[2]
        p_lengths = data[3]
        g_ends = data[4]
        """
		Transition kernel
		"""
        eps = 0.01
        Q = eps + (1. - 2. * eps) / (1. + tt.exp(-0.1 * theta4 *
                                                 (g_ends - 20. * theta5)))

        ll_Q = tt.log(Q)
        ll_notQ = tt.log(1 - tt.exp(ll_Q))
        """
		Short pause ll
		"""
        """
		p = 0.5
		ll_bout = p + bound(tt.log(theta6) - theta6 * p_lengths, p_lengths > 0, theta6 > 0)
		ll_drink = (1. - p) + bound(tt.log(theta9) - theta9 * p_lengths, p_lengths > 0, theta9 > 0)

		ll_S = ll_drink + tt.log1p(tt.exp(ll_bout - ll_drink))
		"""
        ll_S = bound(
            tt.log(theta6) - theta6 * p_lengths, p_lengths > 0, theta6 > 0)
        """
		Long pause ll
		"""
        ## Full emptying time
        t_cs = 2. * tt.sqrt(g_ends) / k1

        ## ll if time is less than full emptying
        g_pausing_1 = 0.25 * tt.sqr(
            k1 * p_lengths) - tt.sqrt(g_ends) * k1 * p_lengths + g_ends

        phi_L_1 = 1. / (theta7 + theta8 * g_pausing_1)

        psi_L_1 = 2. * tt.arctan(0.5 * tt.sqrt(theta8 / theta7) *
                                 (k1 * p_lengths - 2. * tt.sqrt(g_ends)))
        psi_L_1 = psi_L_1 - 2. * tt.arctan(0.5 * tt.sqrt(theta8 / theta7) *
                                           (-2. * tt.sqrt(g_ends)))
        psi_L_1 = psi_L_1 / (k1 * tt.sqrt(theta7 * theta8))

        ll_L_1 = tt.log(phi_L_1) - psi_L_1

        ## ll if time exceeds full emptying
        phi_L_2 = 1. / theta7

        psi_L_2 = 2. * tt.arctan(0.5 * tt.sqrt(theta8 / theta7) *
                                 (k1 * t_cs - 2. * tt.sqrt(g_ends)))
        psi_L_2 = psi_L_2 - 2. * tt.arctan(0.5 * tt.sqrt(theta8 / theta7) *
                                           (-2. * tt.sqrt(g_ends)))
        psi_L_2 = psi_L_2 / (k1 * tt.sqrt(theta7 * theta8))

        psi_L_2 = psi_L_2 + (p_lengths - t_cs) / theta7

        ll_L_2 = tt.log(phi_L_2) - psi_L_2

        ## Switch based on t_c
        ll_L = tt.switch(tt.lt(p_lengths, t_cs), ll_L_1, ll_L_2)

        ## Avoid numerical issues in logaddexp

        ll_short = ll_notQ + ll_S
        ll_long = ll_Q + ll_L

        ll_pause = ll_short + tt.log1p(tt.exp(ll_long - ll_short))

        return ll_pause
예제 #35
0
 def logp(self, value):
     logp = self.fn
     syms = self.syms
     return logp(value)
     return bound(logp(value), value >= -np.pi / syms, value < np.pi / syms)
예제 #36
0
    def logp(self, data):
        """
		Retrieve thetas
		"""
        theta5 = self.theta5
        theta6 = self.theta6
        theta7 = self.theta7
        theta8 = self.theta8
        theta9 = self.theta9
        k1 = self.k1

        #theta5_print = theano.printing.Print('theta5')(theta5)
        #theta6_print = theano.printing.Print('theta6')(theta6)
        #theta7_print = theano.printing.Print('theta7')(theta7)
        #theta8_print = theano.printing.Print('theta8')(theta8)
        #theta9_print = theano.printing.Print('theta9')(theta9)
        """
		Parse data
		"""

        f_lengths = data[0]
        g_starts = data[1]
        rates = data[2]
        p_lengths = data[3]
        g_ends = data[4]

        p_lengths_print = theano.printing.Print('p_lengths')(p_lengths)
        g_ends_print = theano.printing.Print('g_ends')(g_ends)
        """
		Transition kernel
		"""
        eps = 0.01
        Q = eps + (1. - 2. * eps) / (1. + tt.exp(-0.1 * theta5 *
                                                 (g_ends - 20. * theta6)))

        #Q_print = theano.printing.Print('Q')(Q)

        ll_Q = tt.log(Q)

        ll_notQ = tt.log(1 - tt.exp(ll_Q))
        """
		Short pause ll
		"""
        ll_S = bound(
            tt.log(theta7) - theta7 * p_lengths, p_lengths > 0, theta7 > 0)
        #ll_S = tt.log(theta7) - theta7*p_lengths # just exponential dist
        """
		Long pause ll
		"""
        ## Full emptying time
        t_cs = 2. * tt.sqrt(g_ends) / k1

        #t_cs_print = theano.printing.Print('t_cs')(t_cs)
        #p_lengths_print = theano.printing.Print('p_lengths')(p_lengths)

        ## ll if time is less than full emptying
        g_pausing_1 = 0.25 * tt.sqr(
            k1 * p_lengths) - tt.sqrt(g_ends) * k1 * p_lengths + g_ends

        phi_L_1 = 1. / (theta8 + theta9 * g_pausing_1)

        psi_L_1 = 2. * tt.arctan(0.5 * tt.sqrt(theta9 / theta8) *
                                 (k1 * p_lengths - 2. * tt.sqrt(g_ends)))
        psi_L_1 = psi_L_1 - 2. * tt.arctan(0.5 * tt.sqrt(theta9 / theta8) *
                                           (-2. * tt.sqrt(g_ends)))
        psi_L_1 = psi_L_1 / (k1 * tt.sqrt(theta8 * theta9))

        ll_L_1 = tt.log(phi_L_1) - psi_L_1

        ## ll if time exceeds full emptying
        phi_L_2 = 1. / theta8

        psi_L_2 = 2. * tt.arctan(0.5 * tt.sqrt(theta9 / theta8) *
                                 (k1 * t_cs - 2. * tt.sqrt(g_ends)))
        psi_L_2 = psi_L_2 - 2. * tt.arctan(0.5 * tt.sqrt(theta9 / theta8) *
                                           (-2. * tt.sqrt(g_ends)))
        psi_L_2 = psi_L_2 / (k1 * tt.sqrt(theta8 * theta9))

        psi_L_2 = psi_L_2 + (p_lengths - t_cs) / theta8

        ll_L_2 = tt.log(phi_L_2) - psi_L_2

        ## Switch based on t_c
        ll_L = tt.switch(tt.lt(p_lengths, t_cs), ll_L_1, ll_L_2)
        """
		ll_1_print = theano.printing.Print('ll_1_print')(ll_L_1)
		ll_2_print = theano.printing.Print('ll_2_print')(ll_L_2)
		ll_L_print = theano.printing.Print('ll_L_print')(ll_L)
		"""

        ## Assemble 2 likelihood paths

        ll_Q_print = theano.printing.Print('ll_Q')(ll_Q)
        ll_notQ_print = theano.printing.Print('ll_notQ')(ll_notQ)

        ll_L_print = theano.printing.Print('ll_L')(ll_L)
        ll_S_print = theano.printing.Print('ll_S')(ll_S)

        ## Avoid numerical issues in logaddexp
        #ll_short = ll_notQ_print + ll_S_print
        #ll_long = ll_Q_print + ll_L_print

        ll_short = ll_notQ + ll_S
        ll_long = ll_Q + ll_L
        """
		ll_pause = tt.switch(tt.lt(ll_short, ll_long),
							 ll_short + tt.log1p(tt.exp(ll_long - ll_short)),
							 ll_long + tt.log1p(tt.exp(ll_short - ll_long)))
		"""
        #ll_pause = ll_short + tt.log1p(tt.exp(ll_long - ll_short))
        ll_pause = ll_long + tt.log1p(tt.exp(ll_short - ll_long))
        ll_nans = tt.any(tt.isnan(ll_pause))
        ll_nan_print = theano.printing.Print('ll_nans')(ll_nans)
        ll_pause_print = theano.printing.Print('ll_pause')(ll_pause)

        #ll = ll_pause # tt.log(tt.exp(ll_notQ + ll_S) + tt.exp(ll_Q + ll_L))

        #ll_print = theano.printing.Print('ll')(ll)

        return ll_pause_print + ll_nan_print