|
80 | 80 | "Interpolated",
|
81 | 81 | "Rice",
|
82 | 82 | "Moyal",
|
| 83 | + "AsymmetricLaplace", |
83 | 84 | ]
|
84 | 85 |
|
85 | 86 |
|
@@ -1661,6 +1662,106 @@ def logcdf(self, value):
|
1661 | 1662 | )
|
1662 | 1663 |
|
1663 | 1664 |
|
| 1665 | +class AsymmetricLaplace(Continuous): |
| 1666 | + r""" |
| 1667 | + Asymmetric-Laplace log-likelihood. |
| 1668 | +
|
| 1669 | + The pdf of this distribution is |
| 1670 | +
|
| 1671 | + .. math:: |
| 1672 | + {f(x|\\b,\kappa,\mu) = |
| 1673 | + \left({\frac{\\b}{\kappa + 1/\kappa}}\right)\,e^{-(x-\mu)\\b\,s\kappa ^{s}}} |
| 1674 | +
|
| 1675 | + where |
| 1676 | +
|
| 1677 | + .. math:: |
| 1678 | +
|
| 1679 | + s = sgn(x-\mu) |
| 1680 | +
|
| 1681 | + ======== ======================== |
| 1682 | + Support :math:`x \in \mathbb{R}` |
| 1683 | + Mean :math:`\mu-\frac{\\\kappa-1/\kappa}b` |
| 1684 | + Variance :math:`\frac{1+\kappa^{4}}{b^2\kappa^2 }` |
| 1685 | + ======== ======================== |
| 1686 | +
|
| 1687 | + Parameters |
| 1688 | + ---------- |
| 1689 | + b: float |
| 1690 | + Scale parameter (b > 0) |
| 1691 | + kappa: float |
| 1692 | + Symmetry parameter (kappa > 0) |
| 1693 | + mu: float |
| 1694 | + Location parameter |
| 1695 | +
|
| 1696 | + See Also: |
| 1697 | + -------- |
| 1698 | + `Reference <https://en.wikipedia.org/wiki/Asymmetric_Laplace_distribution>`_ |
| 1699 | + """ |
| 1700 | + |
| 1701 | + def __init__(self, b, kappa, mu=0, *args, **kwargs): |
| 1702 | + self.b = tt.as_tensor_variable(floatX(b)) |
| 1703 | + self.kappa = tt.as_tensor_variable(floatX(kappa)) |
| 1704 | + self.mu = mu = tt.as_tensor_variable(floatX(mu)) |
| 1705 | + |
| 1706 | + self.mean = self.mu - (self.kappa - 1 / self.kappa) / b |
| 1707 | + self.variance = (1 + self.kappa ** 4) / (self.kappa ** 2 * self.b ** 2) |
| 1708 | + |
| 1709 | + assert_negative_support(kappa, "kappa", "AsymmetricLaplace") |
| 1710 | + assert_negative_support(b, "b", "AsymmetricLaplace") |
| 1711 | + |
| 1712 | + super().__init__(*args, **kwargs) |
| 1713 | + |
| 1714 | + def _random(self, b, kappa, mu, size=None): |
| 1715 | + u = np.random.uniform(size=size) |
| 1716 | + switch = kappa ** 2 / (1 + kappa ** 2) |
| 1717 | + non_positive_x = mu + kappa * np.log(u * (1 / switch)) / b |
| 1718 | + positive_x = mu - np.log((1 - u) * (1 + kappa ** 2)) / (kappa * b) |
| 1719 | + draws = non_positive_x * (u <= switch) + positive_x * (u > switch) |
| 1720 | + return draws |
| 1721 | + |
| 1722 | + def random(self, point=None, size=None): |
| 1723 | + """ |
| 1724 | + Draw random samples from this distribution, using the inverse CDF method. |
| 1725 | +
|
| 1726 | + Parameters |
| 1727 | + ---------- |
| 1728 | + point: dict, optional |
| 1729 | + Dict of variable values on which random values are to be |
| 1730 | + conditioned (uses default point if not specified). |
| 1731 | + size:int, optional |
| 1732 | + Desired size of random sample (returns one sample if not |
| 1733 | + specified). |
| 1734 | +
|
| 1735 | + Returns |
| 1736 | + ------- |
| 1737 | + array |
| 1738 | + """ |
| 1739 | + b, kappa, mu = draw_values([self.b, self.kappa, self.mu], point=point, size=size) |
| 1740 | + return generate_samples(self._random, b, kappa, mu, dist_shape=self.shape, size=size) |
| 1741 | + |
| 1742 | + def logp(self, value): |
| 1743 | + """ |
| 1744 | + Calculate log-probability of Asymmetric-Laplace distribution at specified value. |
| 1745 | +
|
| 1746 | + Parameters |
| 1747 | + ---------- |
| 1748 | + value: numeric |
| 1749 | + Value(s) for which log-probability is calculated. If the log probabilities for multiple |
| 1750 | + values are desired the values must be provided in a numpy array or theano tensor |
| 1751 | +
|
| 1752 | + Returns |
| 1753 | + ------- |
| 1754 | + TensorVariable |
| 1755 | + """ |
| 1756 | + value = value - self.mu |
| 1757 | + return bound( |
| 1758 | + tt.log(self.b / (self.kappa + (self.kappa ** -1))) |
| 1759 | + + (-value * self.b * tt.sgn(value) * (self.kappa ** tt.sgn(value))), |
| 1760 | + 0 < self.b, |
| 1761 | + 0 < self.kappa, |
| 1762 | + ) |
| 1763 | + |
| 1764 | + |
1664 | 1765 | class Lognormal(PositiveContinuous):
|
1665 | 1766 | r"""
|
1666 | 1767 | Log-normal log-likelihood.
|
|
0 commit comments