Navigation Menu

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updating sympy.stats.crv_types for extreme value distributions #16528

Merged
merged 17 commits into from Jun 16, 2019
Merged
10 changes: 7 additions & 3 deletions sympy/core/tests/test_args.py
Expand Up @@ -1341,9 +1341,13 @@ def test_sympy__stats__crv_types__GammaDistribution():
from sympy.stats.crv_types import GammaDistribution
assert _test_args(GammaDistribution(1, 1))

def test_sympy__stats__crv_types__GumbelDistribution():
from sympy.stats.crv_types import GumbelDistribution
assert _test_args(GumbelDistribution(1, 1))
def test_sympy__stats__crv_types__GumbelDistributionMinimum():
from sympy.stats.crv_types import GumbelDistributionMinimum
assert _test_args(GumbelDistributionMinimum(1, 1))

def test_sympy__stats__crv_types__GumbelDistributionMaximum():
from sympy.stats.crv_types import GumbelDistributionMaximum
assert _test_args(GumbelDistributionMaximum(1, 1))

def test_sympy__stats__crv_types__GompertzDistribution():
from sympy.stats.crv_types import GompertzDistribution
Expand Down
54 changes: 47 additions & 7 deletions sympy/stats/crv_types.py
Expand Up @@ -1441,46 +1441,78 @@ def GammaInverse(name, a, b):
return rv(name, GammaInverseDistribution, (a, b))

#-------------------------------------------------------------------------------
# Gumbel distribution --------------------------------------------------------
# Gumbel distribution (Maximum and Minimum)--------------------------------------------------------


class GumbelDistribution(SingleContinuousDistribution):
class GumbelDistributionMaximum(SingleContinuousDistribution):
_argnames = ('beta', 'mu')
czgdp1807 marked this conversation as resolved.
Show resolved Hide resolved

set = Interval(-oo, oo)

@staticmethod
def check(beta, mu):
_value_check(beta > 0, "beta must be positive")

def pdf(self, x):
beta, mu = self.beta, self.mu
z = (x - mu)/beta
return (1/beta)*exp(-(z + exp(-z)))

def _cdf(self, x):
beta, mu = self.beta, self.mu
return exp(-exp((mu - x)/beta))
z = (x - mu)/beta
return exp(-exp(-z))

def _characteristic_function(self, t):
return gamma(1 - I*self.beta*t) * exp(I*self.mu*t)

def _moment_generating_function(self, t):
return gamma(1 - self.beta*t) * exp(I*self.mu*t)

def Gumbel(name, beta, mu):
class GumbelDistributionMinimum(SingleContinuousDistribution):
_argnames = ('beta', 'mu')

set = Interval(-oo, oo)

@staticmethod
def check(beta, mu):
_value_check(beta > 0, "beta must be positive")

def pdf(self, x):
beta, mu = self.beta, self.mu
z = (x - mu)/beta
return (1/beta)*exp(z - exp(z))

def _cdf(self, x):
beta, mu = self.beta, self.mu
z = (x - mu)/beta
return 1 - exp(-exp(z))

def Gumbel(name, beta, mu, **kwargs):
r"""
Create a Continuous Random Variable with Gumbel distribution.

The density of the Gumbel distribution is given by
The density of the Gumbel distribution is given by,

For Maximum
.. math::
f(x) := \dfrac{1}{\beta} \exp \left( -\dfrac{x-\mu}{\beta}
- \exp \left( -\dfrac{x - \mu}{\beta} \right) \right)

with :math:`x \in [ - \infty, \infty ]`.

For Minimum
.. math::
f(x) := \frac{e^{- e^{\frac{- \mu + x}{\beta}}
+ \frac{- \mu + x}{\beta}}}{\beta}

Parameters
==========

mu: Real number, 'mu' is a location
beta: Real number, 'beta > 0' is a scale
for_min: Boolean, optional, False, by default
For enabling the minimum distribution

Returns
==========
Expand All @@ -1492,22 +1524,30 @@ def Gumbel(name, beta, mu):
>>> from sympy.stats import Gumbel, density, E, variance, cdf
>>> from sympy import Symbol, simplify, pprint
>>> x = Symbol("x")
>>> y = Symbol("y")
>>> mu = Symbol("mu")
>>> beta = Symbol("beta", positive=True)
>>> X = Gumbel("x", beta, mu)
>>> Y = Gumbel("y", beta, mu, for_min=True)
>>> density(X)(x)
exp(-exp(-(-mu + x)/beta) - (-mu + x)/beta)/beta
>>> cdf(X)(x)
exp(-exp((mu - x)/beta))
exp(-exp(-(-mu + x)/beta))
>>> density(Y)(y)
exp(-exp((-mu + y)/beta) + (-mu + y)/beta)/beta

References
==========

.. [1] http://mathworld.wolfram.com/GumbelDistribution.html
.. [2] https://en.wikipedia.org/wiki/Gumbel_distribution
.. [3] http://www.mathwave.com/help/easyfit/html/analyses/distributions/gumbel_max.html
.. [4] http://www.mathwave.com/help/easyfit/html/analyses/distributions/gumbel_min.html

"""
return rv(name, GumbelDistribution, (beta, mu))
if kwargs.get('for_min', False):
return rv(name, GumbelDistributionMinimum, (beta, mu))
return rv(name, GumbelDistributionMaximum, (beta, mu))

#-------------------------------------------------------------------------------
# Gompertz distribution --------------------------------------------------------
Expand Down
5 changes: 4 additions & 1 deletion sympy/stats/tests/test_continuous_rv.py
Expand Up @@ -446,9 +446,12 @@ def test_gumbel():
beta = Symbol("beta", positive=True)
mu = Symbol("mu")
x = Symbol("x")
y = Symbol("y")
X = Gumbel("x", beta, mu)
Y = Gumbel("y", beta, mu, for_min=True)
assert str(density(X)(x)) == 'exp(-exp(-(-mu + x)/beta) - (-mu + x)/beta)/beta'
assert cdf(X)(x) == exp(-exp((mu - x)/beta))
assert str(density(Y)(y)) == 'exp(-exp((-mu + y)/beta) + (-mu + y)/beta)/beta'
assert str(cdf(X)(x)) == 'exp(-exp(-(-mu + x)/beta))'
czgdp1807 marked this conversation as resolved.
Show resolved Hide resolved


def test_kumaraswamy():
Expand Down