Traktor/myenv/Lib/site-packages/sympy/stats/rv_interface.py
2024-05-23 01:57:24 +02:00

520 lines
14 KiB
Python

from sympy.sets import FiniteSet
from sympy.core.numbers import Rational
from sympy.core.relational import Eq
from sympy.core.symbol import Dummy
from sympy.functions.combinatorial.factorials import FallingFactorial
from sympy.functions.elementary.exponential import (exp, log)
from sympy.functions.elementary.miscellaneous import sqrt
from sympy.functions.elementary.piecewise import piecewise_fold
from sympy.integrals.integrals import Integral
from sympy.solvers.solveset import solveset
from .rv import (probability, expectation, density, where, given, pspace, cdf, PSpace,
characteristic_function, sample, sample_iter, random_symbols, independent, dependent,
sampling_density, moment_generating_function, quantile, is_random,
sample_stochastic_process)
__all__ = ['P', 'E', 'H', 'density', 'where', 'given', 'sample', 'cdf',
'characteristic_function', 'pspace', 'sample_iter', 'variance', 'std',
'skewness', 'kurtosis', 'covariance', 'dependent', 'entropy', 'median',
'independent', 'random_symbols', 'correlation', 'factorial_moment',
'moment', 'cmoment', 'sampling_density', 'moment_generating_function',
'smoment', 'quantile', 'sample_stochastic_process']
def moment(X, n, c=0, condition=None, *, evaluate=True, **kwargs):
"""
Return the nth moment of a random expression about c.
.. math::
moment(X, c, n) = E((X-c)^{n})
Default value of c is 0.
Examples
========
>>> from sympy.stats import Die, moment, E
>>> X = Die('X', 6)
>>> moment(X, 1, 6)
-5/2
>>> moment(X, 2)
91/6
>>> moment(X, 1) == E(X)
True
"""
from sympy.stats.symbolic_probability import Moment
if evaluate:
return Moment(X, n, c, condition).doit()
return Moment(X, n, c, condition).rewrite(Integral)
def variance(X, condition=None, **kwargs):
"""
Variance of a random expression.
.. math::
variance(X) = E((X-E(X))^{2})
Examples
========
>>> from sympy.stats import Die, Bernoulli, variance
>>> from sympy import simplify, Symbol
>>> X = Die('X', 6)
>>> p = Symbol('p')
>>> B = Bernoulli('B', p, 1, 0)
>>> variance(2*X)
35/3
>>> simplify(variance(B))
p*(1 - p)
"""
if is_random(X) and pspace(X) == PSpace():
from sympy.stats.symbolic_probability import Variance
return Variance(X, condition)
return cmoment(X, 2, condition, **kwargs)
def standard_deviation(X, condition=None, **kwargs):
r"""
Standard Deviation of a random expression
.. math::
std(X) = \sqrt(E((X-E(X))^{2}))
Examples
========
>>> from sympy.stats import Bernoulli, std
>>> from sympy import Symbol, simplify
>>> p = Symbol('p')
>>> B = Bernoulli('B', p, 1, 0)
>>> simplify(std(B))
sqrt(p*(1 - p))
"""
return sqrt(variance(X, condition, **kwargs))
std = standard_deviation
def entropy(expr, condition=None, **kwargs):
"""
Calculuates entropy of a probability distribution.
Parameters
==========
expression : the random expression whose entropy is to be calculated
condition : optional, to specify conditions on random expression
b: base of the logarithm, optional
By default, it is taken as Euler's number
Returns
=======
result : Entropy of the expression, a constant
Examples
========
>>> from sympy.stats import Normal, Die, entropy
>>> X = Normal('X', 0, 1)
>>> entropy(X)
log(2)/2 + 1/2 + log(pi)/2
>>> D = Die('D', 4)
>>> entropy(D)
log(4)
References
==========
.. [1] https://en.wikipedia.org/wiki/Entropy_%28information_theory%29
.. [2] https://www.crmarsh.com/static/pdf/Charles_Marsh_Continuous_Entropy.pdf
.. [3] https://kconrad.math.uconn.edu/blurbs/analysis/entropypost.pdf
"""
pdf = density(expr, condition, **kwargs)
base = kwargs.get('b', exp(1))
if isinstance(pdf, dict):
return sum([-prob*log(prob, base) for prob in pdf.values()])
return expectation(-log(pdf(expr), base))
def covariance(X, Y, condition=None, **kwargs):
"""
Covariance of two random expressions.
Explanation
===========
The expectation that the two variables will rise and fall together
.. math::
covariance(X,Y) = E((X-E(X)) (Y-E(Y)))
Examples
========
>>> from sympy.stats import Exponential, covariance
>>> from sympy import Symbol
>>> rate = Symbol('lambda', positive=True, real=True)
>>> X = Exponential('X', rate)
>>> Y = Exponential('Y', rate)
>>> covariance(X, X)
lambda**(-2)
>>> covariance(X, Y)
0
>>> covariance(X, Y + rate*X)
1/lambda
"""
if (is_random(X) and pspace(X) == PSpace()) or (is_random(Y) and pspace(Y) == PSpace()):
from sympy.stats.symbolic_probability import Covariance
return Covariance(X, Y, condition)
return expectation(
(X - expectation(X, condition, **kwargs)) *
(Y - expectation(Y, condition, **kwargs)),
condition, **kwargs)
def correlation(X, Y, condition=None, **kwargs):
r"""
Correlation of two random expressions, also known as correlation
coefficient or Pearson's correlation.
Explanation
===========
The normalized expectation that the two variables will rise
and fall together
.. math::
correlation(X,Y) = E((X-E(X))(Y-E(Y)) / (\sigma_x \sigma_y))
Examples
========
>>> from sympy.stats import Exponential, correlation
>>> from sympy import Symbol
>>> rate = Symbol('lambda', positive=True, real=True)
>>> X = Exponential('X', rate)
>>> Y = Exponential('Y', rate)
>>> correlation(X, X)
1
>>> correlation(X, Y)
0
>>> correlation(X, Y + rate*X)
1/sqrt(1 + lambda**(-2))
"""
return covariance(X, Y, condition, **kwargs)/(std(X, condition, **kwargs)
* std(Y, condition, **kwargs))
def cmoment(X, n, condition=None, *, evaluate=True, **kwargs):
"""
Return the nth central moment of a random expression about its mean.
.. math::
cmoment(X, n) = E((X - E(X))^{n})
Examples
========
>>> from sympy.stats import Die, cmoment, variance
>>> X = Die('X', 6)
>>> cmoment(X, 3)
0
>>> cmoment(X, 2)
35/12
>>> cmoment(X, 2) == variance(X)
True
"""
from sympy.stats.symbolic_probability import CentralMoment
if evaluate:
return CentralMoment(X, n, condition).doit()
return CentralMoment(X, n, condition).rewrite(Integral)
def smoment(X, n, condition=None, **kwargs):
r"""
Return the nth Standardized moment of a random expression.
.. math::
smoment(X, n) = E(((X - \mu)/\sigma_X)^{n})
Examples
========
>>> from sympy.stats import skewness, Exponential, smoment
>>> from sympy import Symbol
>>> rate = Symbol('lambda', positive=True, real=True)
>>> Y = Exponential('Y', rate)
>>> smoment(Y, 4)
9
>>> smoment(Y, 4) == smoment(3*Y, 4)
True
>>> smoment(Y, 3) == skewness(Y)
True
"""
sigma = std(X, condition, **kwargs)
return (1/sigma)**n*cmoment(X, n, condition, **kwargs)
def skewness(X, condition=None, **kwargs):
r"""
Measure of the asymmetry of the probability distribution.
Explanation
===========
Positive skew indicates that most of the values lie to the right of
the mean.
.. math::
skewness(X) = E(((X - E(X))/\sigma_X)^{3})
Parameters
==========
condition : Expr containing RandomSymbols
A conditional expression. skewness(X, X>0) is skewness of X given X > 0
Examples
========
>>> from sympy.stats import skewness, Exponential, Normal
>>> from sympy import Symbol
>>> X = Normal('X', 0, 1)
>>> skewness(X)
0
>>> skewness(X, X > 0) # find skewness given X > 0
(-sqrt(2)/sqrt(pi) + 4*sqrt(2)/pi**(3/2))/(1 - 2/pi)**(3/2)
>>> rate = Symbol('lambda', positive=True, real=True)
>>> Y = Exponential('Y', rate)
>>> skewness(Y)
2
"""
return smoment(X, 3, condition=condition, **kwargs)
def kurtosis(X, condition=None, **kwargs):
r"""
Characterizes the tails/outliers of a probability distribution.
Explanation
===========
Kurtosis of any univariate normal distribution is 3. Kurtosis less than
3 means that the distribution produces fewer and less extreme outliers
than the normal distribution.
.. math::
kurtosis(X) = E(((X - E(X))/\sigma_X)^{4})
Parameters
==========
condition : Expr containing RandomSymbols
A conditional expression. kurtosis(X, X>0) is kurtosis of X given X > 0
Examples
========
>>> from sympy.stats import kurtosis, Exponential, Normal
>>> from sympy import Symbol
>>> X = Normal('X', 0, 1)
>>> kurtosis(X)
3
>>> kurtosis(X, X > 0) # find kurtosis given X > 0
(-4/pi - 12/pi**2 + 3)/(1 - 2/pi)**2
>>> rate = Symbol('lamda', positive=True, real=True)
>>> Y = Exponential('Y', rate)
>>> kurtosis(Y)
9
References
==========
.. [1] https://en.wikipedia.org/wiki/Kurtosis
.. [2] https://mathworld.wolfram.com/Kurtosis.html
"""
return smoment(X, 4, condition=condition, **kwargs)
def factorial_moment(X, n, condition=None, **kwargs):
"""
The factorial moment is a mathematical quantity defined as the expectation
or average of the falling factorial of a random variable.
.. math::
factorial-moment(X, n) = E(X(X - 1)(X - 2)...(X - n + 1))
Parameters
==========
n: A natural number, n-th factorial moment.
condition : Expr containing RandomSymbols
A conditional expression.
Examples
========
>>> from sympy.stats import factorial_moment, Poisson, Binomial
>>> from sympy import Symbol, S
>>> lamda = Symbol('lamda')
>>> X = Poisson('X', lamda)
>>> factorial_moment(X, 2)
lamda**2
>>> Y = Binomial('Y', 2, S.Half)
>>> factorial_moment(Y, 2)
1/2
>>> factorial_moment(Y, 2, Y > 1) # find factorial moment for Y > 1
2
References
==========
.. [1] https://en.wikipedia.org/wiki/Factorial_moment
.. [2] https://mathworld.wolfram.com/FactorialMoment.html
"""
return expectation(FallingFactorial(X, n), condition=condition, **kwargs)
def median(X, evaluate=True, **kwargs):
r"""
Calculuates the median of the probability distribution.
Explanation
===========
Mathematically, median of Probability distribution is defined as all those
values of `m` for which the following condition is satisfied
.. math::
P(X\leq m) \geq \frac{1}{2} \text{ and} \text{ } P(X\geq m)\geq \frac{1}{2}
Parameters
==========
X: The random expression whose median is to be calculated.
Returns
=======
The FiniteSet or an Interval which contains the median of the
random expression.
Examples
========
>>> from sympy.stats import Normal, Die, median
>>> N = Normal('N', 3, 1)
>>> median(N)
{3}
>>> D = Die('D')
>>> median(D)
{3, 4}
References
==========
.. [1] https://en.wikipedia.org/wiki/Median#Probability_distributions
"""
if not is_random(X):
return X
from sympy.stats.crv import ContinuousPSpace
from sympy.stats.drv import DiscretePSpace
from sympy.stats.frv import FinitePSpace
if isinstance(pspace(X), FinitePSpace):
cdf = pspace(X).compute_cdf(X)
result = []
for key, value in cdf.items():
if value>= Rational(1, 2) and (1 - value) + \
pspace(X).probability(Eq(X, key)) >= Rational(1, 2):
result.append(key)
return FiniteSet(*result)
if isinstance(pspace(X), (ContinuousPSpace, DiscretePSpace)):
cdf = pspace(X).compute_cdf(X)
x = Dummy('x')
result = solveset(piecewise_fold(cdf(x) - Rational(1, 2)), x, pspace(X).set)
return result
raise NotImplementedError("The median of %s is not implemented."%str(pspace(X)))
def coskewness(X, Y, Z, condition=None, **kwargs):
r"""
Calculates the co-skewness of three random variables.
Explanation
===========
Mathematically Coskewness is defined as
.. math::
coskewness(X,Y,Z)=\frac{E[(X-E[X]) * (Y-E[Y]) * (Z-E[Z])]} {\sigma_{X}\sigma_{Y}\sigma_{Z}}
Parameters
==========
X : RandomSymbol
Random Variable used to calculate coskewness
Y : RandomSymbol
Random Variable used to calculate coskewness
Z : RandomSymbol
Random Variable used to calculate coskewness
condition : Expr containing RandomSymbols
A conditional expression
Examples
========
>>> from sympy.stats import coskewness, Exponential, skewness
>>> from sympy import symbols
>>> p = symbols('p', positive=True)
>>> X = Exponential('X', p)
>>> Y = Exponential('Y', 2*p)
>>> coskewness(X, Y, Y)
0
>>> coskewness(X, Y + X, Y + 2*X)
16*sqrt(85)/85
>>> coskewness(X + 2*Y, Y + X, Y + 2*X, X > 3)
9*sqrt(170)/85
>>> coskewness(Y, Y, Y) == skewness(Y)
True
>>> coskewness(X, Y + p*X, Y + 2*p*X)
4/(sqrt(1 + 1/(4*p**2))*sqrt(4 + 1/(4*p**2)))
Returns
=======
coskewness : The coskewness of the three random variables
References
==========
.. [1] https://en.wikipedia.org/wiki/Coskewness
"""
num = expectation((X - expectation(X, condition, **kwargs)) \
* (Y - expectation(Y, condition, **kwargs)) \
* (Z - expectation(Z, condition, **kwargs)), condition, **kwargs)
den = std(X, condition, **kwargs) * std(Y, condition, **kwargs) \
* std(Z, condition, **kwargs)
return num/den
P = probability
E = expectation
H = entropy