rv_interface.py 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519
  1. from sympy.sets import FiniteSet
  2. from sympy.core.numbers import Rational
  3. from sympy.core.relational import Eq
  4. from sympy.core.symbol import Dummy
  5. from sympy.functions.combinatorial.factorials import FallingFactorial
  6. from sympy.functions.elementary.exponential import (exp, log)
  7. from sympy.functions.elementary.miscellaneous import sqrt
  8. from sympy.functions.elementary.piecewise import piecewise_fold
  9. from sympy.integrals.integrals import Integral
  10. from sympy.solvers.solveset import solveset
  11. from .rv import (probability, expectation, density, where, given, pspace, cdf, PSpace,
  12. characteristic_function, sample, sample_iter, random_symbols, independent, dependent,
  13. sampling_density, moment_generating_function, quantile, is_random,
  14. sample_stochastic_process)
  15. __all__ = ['P', 'E', 'H', 'density', 'where', 'given', 'sample', 'cdf',
  16. 'characteristic_function', 'pspace', 'sample_iter', 'variance', 'std',
  17. 'skewness', 'kurtosis', 'covariance', 'dependent', 'entropy', 'median',
  18. 'independent', 'random_symbols', 'correlation', 'factorial_moment',
  19. 'moment', 'cmoment', 'sampling_density', 'moment_generating_function',
  20. 'smoment', 'quantile', 'sample_stochastic_process']
  21. def moment(X, n, c=0, condition=None, *, evaluate=True, **kwargs):
  22. """
  23. Return the nth moment of a random expression about c.
  24. .. math::
  25. moment(X, c, n) = E((X-c)^{n})
  26. Default value of c is 0.
  27. Examples
  28. ========
  29. >>> from sympy.stats import Die, moment, E
  30. >>> X = Die('X', 6)
  31. >>> moment(X, 1, 6)
  32. -5/2
  33. >>> moment(X, 2)
  34. 91/6
  35. >>> moment(X, 1) == E(X)
  36. True
  37. """
  38. from sympy.stats.symbolic_probability import Moment
  39. if evaluate:
  40. return Moment(X, n, c, condition).doit()
  41. return Moment(X, n, c, condition).rewrite(Integral)
  42. def variance(X, condition=None, **kwargs):
  43. """
  44. Variance of a random expression.
  45. .. math::
  46. variance(X) = E((X-E(X))^{2})
  47. Examples
  48. ========
  49. >>> from sympy.stats import Die, Bernoulli, variance
  50. >>> from sympy import simplify, Symbol
  51. >>> X = Die('X', 6)
  52. >>> p = Symbol('p')
  53. >>> B = Bernoulli('B', p, 1, 0)
  54. >>> variance(2*X)
  55. 35/3
  56. >>> simplify(variance(B))
  57. p*(1 - p)
  58. """
  59. if is_random(X) and pspace(X) == PSpace():
  60. from sympy.stats.symbolic_probability import Variance
  61. return Variance(X, condition)
  62. return cmoment(X, 2, condition, **kwargs)
  63. def standard_deviation(X, condition=None, **kwargs):
  64. r"""
  65. Standard Deviation of a random expression
  66. .. math::
  67. std(X) = \sqrt(E((X-E(X))^{2}))
  68. Examples
  69. ========
  70. >>> from sympy.stats import Bernoulli, std
  71. >>> from sympy import Symbol, simplify
  72. >>> p = Symbol('p')
  73. >>> B = Bernoulli('B', p, 1, 0)
  74. >>> simplify(std(B))
  75. sqrt(p*(1 - p))
  76. """
  77. return sqrt(variance(X, condition, **kwargs))
  78. std = standard_deviation
  79. def entropy(expr, condition=None, **kwargs):
  80. """
  81. Calculuates entropy of a probability distribution.
  82. Parameters
  83. ==========
  84. expression : the random expression whose entropy is to be calculated
  85. condition : optional, to specify conditions on random expression
  86. b: base of the logarithm, optional
  87. By default, it is taken as Euler's number
  88. Returns
  89. =======
  90. result : Entropy of the expression, a constant
  91. Examples
  92. ========
  93. >>> from sympy.stats import Normal, Die, entropy
  94. >>> X = Normal('X', 0, 1)
  95. >>> entropy(X)
  96. log(2)/2 + 1/2 + log(pi)/2
  97. >>> D = Die('D', 4)
  98. >>> entropy(D)
  99. log(4)
  100. References
  101. ==========
  102. .. [1] https://en.wikipedia.org/wiki/Entropy_(information_theory)
  103. .. [2] https://www.crmarsh.com/static/pdf/Charles_Marsh_Continuous_Entropy.pdf
  104. .. [3] http://www.math.uconn.edu/~kconrad/blurbs/analysis/entropypost.pdf
  105. """
  106. pdf = density(expr, condition, **kwargs)
  107. base = kwargs.get('b', exp(1))
  108. if isinstance(pdf, dict):
  109. return sum([-prob*log(prob, base) for prob in pdf.values()])
  110. return expectation(-log(pdf(expr), base))
  111. def covariance(X, Y, condition=None, **kwargs):
  112. """
  113. Covariance of two random expressions.
  114. Explanation
  115. ===========
  116. The expectation that the two variables will rise and fall together
  117. .. math::
  118. covariance(X,Y) = E((X-E(X)) (Y-E(Y)))
  119. Examples
  120. ========
  121. >>> from sympy.stats import Exponential, covariance
  122. >>> from sympy import Symbol
  123. >>> rate = Symbol('lambda', positive=True, real=True)
  124. >>> X = Exponential('X', rate)
  125. >>> Y = Exponential('Y', rate)
  126. >>> covariance(X, X)
  127. lambda**(-2)
  128. >>> covariance(X, Y)
  129. 0
  130. >>> covariance(X, Y + rate*X)
  131. 1/lambda
  132. """
  133. if (is_random(X) and pspace(X) == PSpace()) or (is_random(Y) and pspace(Y) == PSpace()):
  134. from sympy.stats.symbolic_probability import Covariance
  135. return Covariance(X, Y, condition)
  136. return expectation(
  137. (X - expectation(X, condition, **kwargs)) *
  138. (Y - expectation(Y, condition, **kwargs)),
  139. condition, **kwargs)
  140. def correlation(X, Y, condition=None, **kwargs):
  141. r"""
  142. Correlation of two random expressions, also known as correlation
  143. coefficient or Pearson's correlation.
  144. Explanation
  145. ===========
  146. The normalized expectation that the two variables will rise
  147. and fall together
  148. .. math::
  149. correlation(X,Y) = E((X-E(X))(Y-E(Y)) / (\sigma_x \sigma_y))
  150. Examples
  151. ========
  152. >>> from sympy.stats import Exponential, correlation
  153. >>> from sympy import Symbol
  154. >>> rate = Symbol('lambda', positive=True, real=True)
  155. >>> X = Exponential('X', rate)
  156. >>> Y = Exponential('Y', rate)
  157. >>> correlation(X, X)
  158. 1
  159. >>> correlation(X, Y)
  160. 0
  161. >>> correlation(X, Y + rate*X)
  162. 1/sqrt(1 + lambda**(-2))
  163. """
  164. return covariance(X, Y, condition, **kwargs)/(std(X, condition, **kwargs)
  165. * std(Y, condition, **kwargs))
  166. def cmoment(X, n, condition=None, *, evaluate=True, **kwargs):
  167. """
  168. Return the nth central moment of a random expression about its mean.
  169. .. math::
  170. cmoment(X, n) = E((X - E(X))^{n})
  171. Examples
  172. ========
  173. >>> from sympy.stats import Die, cmoment, variance
  174. >>> X = Die('X', 6)
  175. >>> cmoment(X, 3)
  176. 0
  177. >>> cmoment(X, 2)
  178. 35/12
  179. >>> cmoment(X, 2) == variance(X)
  180. True
  181. """
  182. from sympy.stats.symbolic_probability import CentralMoment
  183. if evaluate:
  184. return CentralMoment(X, n, condition).doit()
  185. return CentralMoment(X, n, condition).rewrite(Integral)
  186. def smoment(X, n, condition=None, **kwargs):
  187. r"""
  188. Return the nth Standardized moment of a random expression.
  189. .. math::
  190. smoment(X, n) = E(((X - \mu)/\sigma_X)^{n})
  191. Examples
  192. ========
  193. >>> from sympy.stats import skewness, Exponential, smoment
  194. >>> from sympy import Symbol
  195. >>> rate = Symbol('lambda', positive=True, real=True)
  196. >>> Y = Exponential('Y', rate)
  197. >>> smoment(Y, 4)
  198. 9
  199. >>> smoment(Y, 4) == smoment(3*Y, 4)
  200. True
  201. >>> smoment(Y, 3) == skewness(Y)
  202. True
  203. """
  204. sigma = std(X, condition, **kwargs)
  205. return (1/sigma)**n*cmoment(X, n, condition, **kwargs)
  206. def skewness(X, condition=None, **kwargs):
  207. r"""
  208. Measure of the asymmetry of the probability distribution.
  209. Explanation
  210. ===========
  211. Positive skew indicates that most of the values lie to the right of
  212. the mean.
  213. .. math::
  214. skewness(X) = E(((X - E(X))/\sigma_X)^{3})
  215. Parameters
  216. ==========
  217. condition : Expr containing RandomSymbols
  218. A conditional expression. skewness(X, X>0) is skewness of X given X > 0
  219. Examples
  220. ========
  221. >>> from sympy.stats import skewness, Exponential, Normal
  222. >>> from sympy import Symbol
  223. >>> X = Normal('X', 0, 1)
  224. >>> skewness(X)
  225. 0
  226. >>> skewness(X, X > 0) # find skewness given X > 0
  227. (-sqrt(2)/sqrt(pi) + 4*sqrt(2)/pi**(3/2))/(1 - 2/pi)**(3/2)
  228. >>> rate = Symbol('lambda', positive=True, real=True)
  229. >>> Y = Exponential('Y', rate)
  230. >>> skewness(Y)
  231. 2
  232. """
  233. return smoment(X, 3, condition=condition, **kwargs)
  234. def kurtosis(X, condition=None, **kwargs):
  235. r"""
  236. Characterizes the tails/outliers of a probability distribution.
  237. Explanation
  238. ===========
  239. Kurtosis of any univariate normal distribution is 3. Kurtosis less than
  240. 3 means that the distribution produces fewer and less extreme outliers
  241. than the normal distribution.
  242. .. math::
  243. kurtosis(X) = E(((X - E(X))/\sigma_X)^{4})
  244. Parameters
  245. ==========
  246. condition : Expr containing RandomSymbols
  247. A conditional expression. kurtosis(X, X>0) is kurtosis of X given X > 0
  248. Examples
  249. ========
  250. >>> from sympy.stats import kurtosis, Exponential, Normal
  251. >>> from sympy import Symbol
  252. >>> X = Normal('X', 0, 1)
  253. >>> kurtosis(X)
  254. 3
  255. >>> kurtosis(X, X > 0) # find kurtosis given X > 0
  256. (-4/pi - 12/pi**2 + 3)/(1 - 2/pi)**2
  257. >>> rate = Symbol('lamda', positive=True, real=True)
  258. >>> Y = Exponential('Y', rate)
  259. >>> kurtosis(Y)
  260. 9
  261. References
  262. ==========
  263. .. [1] https://en.wikipedia.org/wiki/Kurtosis
  264. .. [2] http://mathworld.wolfram.com/Kurtosis.html
  265. """
  266. return smoment(X, 4, condition=condition, **kwargs)
  267. def factorial_moment(X, n, condition=None, **kwargs):
  268. """
  269. The factorial moment is a mathematical quantity defined as the expectation
  270. or average of the falling factorial of a random variable.
  271. .. math::
  272. factorial-moment(X, n) = E(X(X - 1)(X - 2)...(X - n + 1))
  273. Parameters
  274. ==========
  275. n: A natural number, n-th factorial moment.
  276. condition : Expr containing RandomSymbols
  277. A conditional expression.
  278. Examples
  279. ========
  280. >>> from sympy.stats import factorial_moment, Poisson, Binomial
  281. >>> from sympy import Symbol, S
  282. >>> lamda = Symbol('lamda')
  283. >>> X = Poisson('X', lamda)
  284. >>> factorial_moment(X, 2)
  285. lamda**2
  286. >>> Y = Binomial('Y', 2, S.Half)
  287. >>> factorial_moment(Y, 2)
  288. 1/2
  289. >>> factorial_moment(Y, 2, Y > 1) # find factorial moment for Y > 1
  290. 2
  291. References
  292. ==========
  293. .. [1] https://en.wikipedia.org/wiki/Factorial_moment
  294. .. [2] http://mathworld.wolfram.com/FactorialMoment.html
  295. """
  296. return expectation(FallingFactorial(X, n), condition=condition, **kwargs)
  297. def median(X, evaluate=True, **kwargs):
  298. r"""
  299. Calculuates the median of the probability distribution.
  300. Explanation
  301. ===========
  302. Mathematically, median of Probability distribution is defined as all those
  303. values of `m` for which the following condition is satisfied
  304. .. math::
  305. P(X\leq m) \geq \frac{1}{2} \text{ and} \text{ } P(X\geq m)\geq \frac{1}{2}
  306. Parameters
  307. ==========
  308. X: The random expression whose median is to be calculated.
  309. Returns
  310. =======
  311. The FiniteSet or an Interval which contains the median of the
  312. random expression.
  313. Examples
  314. ========
  315. >>> from sympy.stats import Normal, Die, median
  316. >>> N = Normal('N', 3, 1)
  317. >>> median(N)
  318. {3}
  319. >>> D = Die('D')
  320. >>> median(D)
  321. {3, 4}
  322. References
  323. ==========
  324. .. [1] https://en.wikipedia.org/wiki/Median#Probability_distributions
  325. """
  326. if not is_random(X):
  327. return X
  328. from sympy.stats.crv import ContinuousPSpace
  329. from sympy.stats.drv import DiscretePSpace
  330. from sympy.stats.frv import FinitePSpace
  331. if isinstance(pspace(X), FinitePSpace):
  332. cdf = pspace(X).compute_cdf(X)
  333. result = []
  334. for key, value in cdf.items():
  335. if value>= Rational(1, 2) and (1 - value) + \
  336. pspace(X).probability(Eq(X, key)) >= Rational(1, 2):
  337. result.append(key)
  338. return FiniteSet(*result)
  339. if isinstance(pspace(X), (ContinuousPSpace, DiscretePSpace)):
  340. cdf = pspace(X).compute_cdf(X)
  341. x = Dummy('x')
  342. result = solveset(piecewise_fold(cdf(x) - Rational(1, 2)), x, pspace(X).set)
  343. return result
  344. raise NotImplementedError("The median of %s is not implemeted."%str(pspace(X)))
  345. def coskewness(X, Y, Z, condition=None, **kwargs):
  346. r"""
  347. Calculates the co-skewness of three random variables.
  348. Explanation
  349. ===========
  350. Mathematically Coskewness is defined as
  351. .. math::
  352. coskewness(X,Y,Z)=\frac{E[(X-E[X]) * (Y-E[Y]) * (Z-E[Z])]} {\sigma_{X}\sigma_{Y}\sigma_{Z}}
  353. Parameters
  354. ==========
  355. X : RandomSymbol
  356. Random Variable used to calculate coskewness
  357. Y : RandomSymbol
  358. Random Variable used to calculate coskewness
  359. Z : RandomSymbol
  360. Random Variable used to calculate coskewness
  361. condition : Expr containing RandomSymbols
  362. A conditional expression
  363. Examples
  364. ========
  365. >>> from sympy.stats import coskewness, Exponential, skewness
  366. >>> from sympy import symbols
  367. >>> p = symbols('p', positive=True)
  368. >>> X = Exponential('X', p)
  369. >>> Y = Exponential('Y', 2*p)
  370. >>> coskewness(X, Y, Y)
  371. 0
  372. >>> coskewness(X, Y + X, Y + 2*X)
  373. 16*sqrt(85)/85
  374. >>> coskewness(X + 2*Y, Y + X, Y + 2*X, X > 3)
  375. 9*sqrt(170)/85
  376. >>> coskewness(Y, Y, Y) == skewness(Y)
  377. True
  378. >>> coskewness(X, Y + p*X, Y + 2*p*X)
  379. 4/(sqrt(1 + 1/(4*p**2))*sqrt(4 + 1/(4*p**2)))
  380. Returns
  381. =======
  382. coskewness : The coskewness of the three random variables
  383. References
  384. ==========
  385. .. [1] https://en.wikipedia.org/wiki/Coskewness
  386. """
  387. num = expectation((X - expectation(X, condition, **kwargs)) \
  388. * (Y - expectation(Y, condition, **kwargs)) \
  389. * (Z - expectation(Z, condition, **kwargs)), condition, **kwargs)
  390. den = std(X, condition, **kwargs) * std(Y, condition, **kwargs) \
  391. * std(Z, condition, **kwargs)
  392. return num/den
  393. P = probability
  394. E = expectation
  395. H = entropy