_probability_distribution.py 68 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969
  1. # Temporary file separated from _distribution_infrastructure.py
  2. # to simplify the diff during PR review.
  3. from abc import ABC, abstractmethod
  4. from types import GenericAlias
  5. class _ProbabilityDistribution(ABC):
  6. # generic type compatibility with scipy-stubs
  7. __class_getitem__ = classmethod(GenericAlias)
  8. @abstractmethod
  9. def support(self):
  10. r"""Support of the random variable
  11. The support of a random variable is set of all possible outcomes;
  12. i.e., the subset of the domain of argument :math:`x` for which
  13. the probability density function :math:`f(x)` is nonzero.
  14. This function returns lower and upper bounds of the support.
  15. Returns
  16. -------
  17. out : tuple of Array
  18. The lower and upper bounds of the support.
  19. See Also
  20. --------
  21. pdf
  22. References
  23. ----------
  24. .. [1] Support (mathematics), *Wikipedia*,
  25. https://en.wikipedia.org/wiki/Support_(mathematics)
  26. Notes
  27. -----
  28. Suppose a continuous probability distribution has support ``(l, r)``.
  29. The following table summarizes the value returned by several
  30. methods when the argument is outside the support.
  31. +----------------+---------------------+---------------------+
  32. | Method | Value for ``x < l`` | Value for ``x > r`` |
  33. +================+=====================+=====================+
  34. | ``pdf(x)`` | 0 | 0 |
  35. +----------------+---------------------+---------------------+
  36. | ``logpdf(x)`` | -inf | -inf |
  37. +----------------+---------------------+---------------------+
  38. | ``cdf(x)`` | 0 | 1 |
  39. +----------------+---------------------+---------------------+
  40. | ``logcdf(x)`` | -inf | 0 |
  41. +----------------+---------------------+---------------------+
  42. | ``ccdf(x)`` | 1 | 0 |
  43. +----------------+---------------------+---------------------+
  44. | ``logccdf(x)`` | 0 | -inf |
  45. +----------------+---------------------+---------------------+
  46. For discrete distributions, the same table is applicable with
  47. ``pmf`` and ``logpmf`` substituted for ``pdf`` and ``logpdf``.
  48. For the ``cdf`` and related methods of continuous distributions, the
  49. inequality need not be strict; i.e. the tabulated value is returned
  50. when the method is evaluated *at* the corresponding boundary.
  51. The following table summarizes the value returned by the inverse
  52. methods for arguments ``0`` and ``1``, whether the distribution
  53. is continuous or discrete.
  54. +-------------+-----------+-----------+
  55. | Method | ``x = 0`` | ``x = 1`` |
  56. +=============+===========+===========+
  57. | ``icdf(x)`` | ``l`` | ``r`` |
  58. +-------------+-----------+-----------+
  59. | ``icdf(x)`` | ``r`` | ``l`` |
  60. +-------------+-----------+-----------+
  61. For the inverse log-functions, the same values are returned
  62. for ``x = log(0)`` and ``x = log(1)``. All inverse functions return
  63. ``nan`` when evaluated at an argument outside the domain ``0`` to ``1``.
  64. Examples
  65. --------
  66. Instantiate a distribution with the desired parameters:
  67. >>> from scipy import stats
  68. >>> X = stats.Uniform(a=-0.5, b=0.5)
  69. Retrieve the support of the distribution:
  70. >>> X.support()
  71. (-0.5, 0.5)
  72. For a distribution with infinite support,
  73. >>> X = stats.Normal()
  74. >>> X.support()
  75. (-inf, inf)
  76. Due to underflow, the numerical value returned by the PDF may be zero
  77. even for arguments within the support, even if the true value is
  78. nonzero. In such cases, the log-PDF may be useful.
  79. >>> X.pdf([-100., 100.])
  80. array([0., 0.])
  81. >>> X.logpdf([-100., 100.])
  82. array([-5000.91893853, -5000.91893853])
  83. Use cases for the log-CDF and related methods are analogous.
  84. """
  85. raise NotImplementedError()
  86. @abstractmethod
  87. def sample(self, shape, *, method, rng):
  88. r"""Random sample from the distribution.
  89. Parameters
  90. ----------
  91. shape : tuple of ints, default: ()
  92. The shape of the sample to draw. If the parameters of the distribution
  93. underlying the random variable are arrays of shape ``param_shape``,
  94. the output array will be of shape ``shape + param_shape``.
  95. method : {None, 'formula', 'inverse_transform'}
  96. The strategy used to produce the sample. By default (``None``),
  97. the infrastructure chooses between the following options,
  98. listed in order of precedence.
  99. - ``'formula'``: an implementation specific to the distribution
  100. - ``'inverse_transform'``: generate a uniformly distributed sample and
  101. return the inverse CDF at these arguments.
  102. Not all `method` options are available for all distributions.
  103. If the selected `method` is not available, a `NotImplementedError``
  104. will be raised.
  105. rng : `numpy.random.Generator` or `scipy.stats.QMCEngine`, optional
  106. Pseudo- or quasi-random number generator state. When `rng` is None,
  107. a new `numpy.random.Generator` is created using entropy from the
  108. operating system. Types other than `numpy.random.Generator` and
  109. `scipy.stats.QMCEngine` are passed to `numpy.random.default_rng`
  110. to instantiate a ``Generator``.
  111. If `rng` is an instance of `scipy.stats.QMCEngine` configured to use
  112. scrambling and `shape` is not empty, then each slice along the zeroth
  113. axis of the result is a "quasi-independent", low-discrepancy sequence;
  114. that is, they are distinct sequences that can be treated as statistically
  115. independent for most practical purposes. Separate calls to `sample`
  116. produce new quasi-independent, low-discrepancy sequences.
  117. References
  118. ----------
  119. .. [1] Sampling (statistics), *Wikipedia*,
  120. https://en.wikipedia.org/wiki/Sampling_(statistics)
  121. Examples
  122. --------
  123. Instantiate a distribution with the desired parameters:
  124. >>> import numpy as np
  125. >>> from scipy import stats
  126. >>> X = stats.Uniform(a=0., b=1.)
  127. Generate a pseudorandom sample:
  128. >>> x = X.sample((1000, 1))
  129. >>> octiles = (np.arange(8) + 1) / 8
  130. >>> np.count_nonzero(x <= octiles, axis=0)
  131. array([ 148, 263, 387, 516, 636, 751, 865, 1000]) # may vary
  132. >>> X = stats.Uniform(a=np.zeros((3, 1)), b=np.ones(2))
  133. >>> X.a.shape,
  134. (3, 2)
  135. >>> x = X.sample(shape=(5, 4))
  136. >>> x.shape
  137. (5, 4, 3, 2)
  138. """
  139. raise NotImplementedError()
  140. @abstractmethod
  141. def moment(self, order, kind, *, method):
  142. r"""Raw, central, or standard moment of positive integer order.
  143. In terms of probability density function :math:`f(x)` and support
  144. :math:`\chi`, the "raw" moment (about the origin) of order :math:`n` of
  145. a continuous random variable :math:`X` is:
  146. .. math::
  147. \mu'_n(X) = \int_{\chi} x^n f(x) dx
  148. The "central" moment is the raw moment taken about the mean,
  149. :math:`\mu = \mu'_1`:
  150. .. math::
  151. \mu_n(X) = \int_{\chi} (x - \mu) ^n f(x) dx
  152. The "standardized" moment is the central moment normalized by the
  153. :math:`n^\text{th}` power of the standard deviation
  154. :math:`\sigma = \sqrt{\mu_2}` to produce a scale invariant quantity:
  155. .. math::
  156. \tilde{\mu}_n(X) = \frac{\mu_n(X)}
  157. {\sigma^n}
  158. The definitions for discrete random variables are analogous, with
  159. sums over the support replacing the integrals.
  160. Parameters
  161. ----------
  162. order : int
  163. The integer order of the moment; i.e. :math:`n` in the formulae above.
  164. kind : {'raw', 'central', 'standardized'}
  165. Whether to return the raw (default), central, or standardized moment
  166. defined above.
  167. method : {None, 'formula', 'general', 'transform', 'normalize', 'quadrature', 'cache'}
  168. The strategy used to evaluate the moment. By default (``None``),
  169. the infrastructure chooses between the following options,
  170. listed in order of precedence.
  171. - ``'cache'``: use the value of the moment most recently calculated
  172. via another method
  173. - ``'formula'``: use a formula for the moment itself
  174. - ``'general'``: use a general result that is true for all distributions
  175. with finite moments; for instance, the zeroth raw moment is
  176. identically 1
  177. - ``'transform'``: transform a raw moment to a central moment or
  178. vice versa (see Notes)
  179. - ``'normalize'``: normalize a central moment to get a standardized
  180. or vice versa
  181. - ``'quadrature'``: numerically integrate (or, in the discrete case, sum)
  182. according to the definition
  183. Not all `method` options are available for all orders, kinds, and
  184. distributions. If the selected `method` is not available, a
  185. ``NotImplementedError`` will be raised.
  186. Returns
  187. -------
  188. out : array
  189. The moment of the random variable of the specified order and kind.
  190. See Also
  191. --------
  192. pdf
  193. mean
  194. variance
  195. standard_deviation
  196. skewness
  197. kurtosis
  198. Notes
  199. -----
  200. Not all distributions have finite moments of all orders; moments of some
  201. orders may be undefined or infinite. If a formula for the moment is not
  202. specifically implemented for the chosen distribution, SciPy will attempt
  203. to compute the moment via a generic method, which may yield a finite
  204. result where none exists. This is not a critical bug, but an opportunity
  205. for an enhancement.
  206. The definition of a raw moment in the summary is specific to the raw moment
  207. about the origin. The raw moment about any point :math:`a` is:
  208. .. math::
  209. E[(X-a)^n] = \int_{\chi} (x-a)^n f(x) dx
  210. In this notation, a raw moment about the origin is :math:`\mu'_n = E[x^n]`,
  211. and a central moment is :math:`\mu_n = E[(x-\mu)^n]`, where :math:`\mu`
  212. is the first raw moment; i.e. the mean.
  213. The ``'transform'`` method takes advantage of the following relationships
  214. between moments taken about different points :math:`a` and :math:`b`.
  215. .. math::
  216. E[(X-b)^n] = \sum_{i=0}^n E[(X-a)^i] {n \choose i} (a - b)^{n-i}
  217. For instance, to transform the raw moment to the central moment, we let
  218. :math:`b = \mu` and :math:`a = 0`.
  219. The distribution infrastructure provides flexibility for distribution
  220. authors to implement separate formulas for raw moments, central moments,
  221. and standardized moments of any order. By default, the moment of the
  222. desired order and kind is evaluated from the formula if such a formula
  223. is available; if not, the infrastructure uses any formulas that are
  224. available rather than resorting directly to numerical integration.
  225. For instance, if formulas for the first three raw moments are
  226. available and the third standardized moments is desired, the
  227. infrastructure will evaluate the raw moments and perform the transforms
  228. and standardization required. The decision tree is somewhat complex,
  229. but the strategy for obtaining a moment of a given order and kind
  230. (possibly as an intermediate step due to the recursive nature of the
  231. transform formula above) roughly follows this order of priority:
  232. #. Use cache (if order of same moment and kind has been calculated)
  233. #. Use formula (if available)
  234. #. Transform between raw and central moment and/or normalize to convert
  235. between central and standardized moments (if efficient)
  236. #. Use a generic result true for most distributions (if available)
  237. #. Use quadrature
  238. References
  239. ----------
  240. .. [1] Moment, *Wikipedia*,
  241. https://en.wikipedia.org/wiki/Moment_(mathematics)
  242. Examples
  243. --------
  244. Instantiate a distribution with the desired parameters:
  245. >>> from scipy import stats
  246. >>> X = stats.Normal(mu=1., sigma=2.)
  247. Evaluate the first raw moment:
  248. >>> X.moment(order=1, kind='raw')
  249. 1.0
  250. >>> X.moment(order=1, kind='raw') == X.mean() == X.mu
  251. True
  252. Evaluate the second central moment:
  253. >>> X.moment(order=2, kind='central')
  254. 4.0
  255. >>> X.moment(order=2, kind='central') == X.variance() == X.sigma**2
  256. True
  257. Evaluate the fourth standardized moment:
  258. >>> X.moment(order=4, kind='standardized')
  259. 3.0
  260. >>> X.moment(order=4, kind='standardized') == X.kurtosis(convention='non-excess')
  261. True
  262. """ # noqa:E501
  263. raise NotImplementedError()
  264. @abstractmethod
  265. def mean(self, *, method):
  266. r"""Mean (raw first moment about the origin)
  267. Parameters
  268. ----------
  269. method : {None, 'formula', 'transform', 'quadrature', 'cache'}
  270. Method used to calculate the raw first moment. Not
  271. all methods are available for all distributions. See
  272. `moment` for details.
  273. See Also
  274. --------
  275. moment
  276. median
  277. mode
  278. References
  279. ----------
  280. .. [1] Mean, *Wikipedia*,
  281. https://en.wikipedia.org/wiki/Mean#Mean_of_a_probability_distribution
  282. Examples
  283. --------
  284. Instantiate a distribution with the desired parameters:
  285. >>> from scipy import stats
  286. >>> X = stats.Normal(mu=1., sigma=2.)
  287. Evaluate the variance:
  288. >>> X.mean()
  289. 1.0
  290. >>> X.mean() == X.moment(order=1, kind='raw') == X.mu
  291. True
  292. """
  293. raise NotImplementedError()
  294. @abstractmethod
  295. def median(self, *, method):
  296. r"""Median (50th percentile)
  297. If a continuous random variable :math:`X` has probability :math:`0.5` of
  298. taking on a value less than :math:`m`, then :math:`m` is the median.
  299. More generally, a median is a value :math:`m` for which:
  300. .. math::
  301. P(X ≤ m) ≤ 0.5 ≥ P(X ≥ m)
  302. For discrete random variables, the median may not be unique, in which
  303. case the smallest value satisfying the definition is reported.
  304. Parameters
  305. ----------
  306. method : {None, 'formula', 'icdf'}
  307. The strategy used to evaluate the median.
  308. By default (``None``), the infrastructure chooses between the
  309. following options, listed in order of precedence.
  310. - ``'formula'``: use a formula for the median
  311. - ``'icdf'``: evaluate the inverse CDF of 0.5
  312. Not all `method` options are available for all distributions.
  313. If the selected `method` is not available, a ``NotImplementedError``
  314. will be raised.
  315. Returns
  316. -------
  317. out : array
  318. The median
  319. See Also
  320. --------
  321. mean
  322. mode
  323. icdf
  324. References
  325. ----------
  326. .. [1] Median, *Wikipedia*,
  327. https://en.wikipedia.org/wiki/Median#Probability_distributions
  328. Examples
  329. --------
  330. Instantiate a distribution with the desired parameters:
  331. >>> from scipy import stats
  332. >>> X = stats.Uniform(a=0., b=10.)
  333. Compute the median:
  334. >>> X.median()
  335. np.float64(5.0)
  336. >>> X.median() == X.icdf(0.5) == X.iccdf(0.5)
  337. True
  338. """
  339. raise NotImplementedError()
  340. @abstractmethod
  341. def mode(self, *, method):
  342. r"""Mode (most likely value)
  343. Informally, the mode is a value that a random variable has the highest
  344. probability (density) of assuming. That is, the mode is the element of
  345. the support :math:`\chi` that maximizes the probability density (or mass,
  346. for discrete random variables) function :math:`f(x)`:
  347. .. math::
  348. \text{mode} = \arg\max_{x \in \chi} f(x)
  349. Parameters
  350. ----------
  351. method : {None, 'formula', 'optimization'}
  352. The strategy used to evaluate the mode.
  353. By default (``None``), the infrastructure chooses between the
  354. following options, listed in order of precedence.
  355. - ``'formula'``: use a formula for the median
  356. - ``'optimization'``: numerically maximize the PDF/PMF
  357. Not all `method` options are available for all distributions.
  358. If the selected `method` is not available, a ``NotImplementedError``
  359. will be raised.
  360. Returns
  361. -------
  362. out : array
  363. The mode
  364. See Also
  365. --------
  366. mean
  367. median
  368. pdf
  369. Notes
  370. -----
  371. For some distributions
  372. #. the mode is not unique (e.g. the uniform distribution);
  373. #. the PDF has one or more singularities, and it is debatable whether
  374. a singularity is considered to be in the domain and called the mode
  375. (e.g. the gamma distribution with shape parameter less than 1); and/or
  376. #. the probability density function may have one or more local maxima
  377. that are not a global maximum (e.g. mixture distributions).
  378. In such cases, `mode` will
  379. #. return a single value,
  380. #. consider the mode to occur at a singularity, and/or
  381. #. return a local maximum which may or may not be a global maximum.
  382. If a formula for the mode is not specifically implemented for the
  383. chosen distribution, SciPy will attempt to compute the mode
  384. numerically, which may not meet the user's preferred definition of a
  385. mode. In such cases, the user is encouraged to subclass the
  386. distribution and override ``mode``.
  387. References
  388. ----------
  389. .. [1] Mode (statistics), *Wikipedia*,
  390. https://en.wikipedia.org/wiki/Mode_(statistics)
  391. Examples
  392. --------
  393. Instantiate a distribution with the desired parameters:
  394. >>> from scipy import stats
  395. >>> X = stats.Normal(mu=1., sigma=2.)
  396. Evaluate the mode:
  397. >>> X.mode()
  398. 1.0
  399. If the mode is not uniquely defined, ``mode`` nonetheless returns a
  400. single value.
  401. >>> X = stats.Uniform(a=0., b=1.)
  402. >>> X.mode()
  403. 0.5
  404. If this choice does not satisfy your requirements, subclass the
  405. distribution and override ``mode``:
  406. >>> class BetterUniform(stats.Uniform):
  407. ... def mode(self):
  408. ... return self.b
  409. >>> X = BetterUniform(a=0., b=1.)
  410. >>> X.mode()
  411. 1.0
  412. """
  413. raise NotImplementedError()
  414. @abstractmethod
  415. def variance(self, *, method):
  416. r"""Variance (central second moment)
  417. Parameters
  418. ----------
  419. method : {None, 'formula', 'transform', 'normalize', 'quadrature', 'cache'}
  420. Method used to calculate the central second moment. Not
  421. all methods are available for all distributions. See
  422. `moment` for details.
  423. See Also
  424. --------
  425. moment
  426. standard_deviation
  427. mean
  428. References
  429. ----------
  430. .. [1] Variance, *Wikipedia*,
  431. https://en.wikipedia.org/wiki/Variance#Absolutely_continuous_random_variable
  432. Examples
  433. --------
  434. Instantiate a distribution with the desired parameters:
  435. >>> from scipy import stats
  436. >>> X = stats.Normal(mu=1., sigma=2.)
  437. Evaluate the variance:
  438. >>> X.variance()
  439. 4.0
  440. >>> X.variance() == X.moment(order=2, kind='central') == X.sigma**2
  441. True
  442. """
  443. raise NotImplementedError()
  444. @abstractmethod
  445. def standard_deviation(self, *, method):
  446. r"""Standard deviation (square root of the second central moment)
  447. Parameters
  448. ----------
  449. method : {None, 'formula', 'transform', 'normalize', 'quadrature', 'cache'}
  450. Method used to calculate the central second moment. Not
  451. all methods are available for all distributions. See
  452. `moment` for details.
  453. See Also
  454. --------
  455. variance
  456. mean
  457. moment
  458. References
  459. ----------
  460. .. [1] Standard deviation, *Wikipedia*,
  461. https://en.wikipedia.org/wiki/Standard_deviation#Definition_of_population_values
  462. Examples
  463. --------
  464. Instantiate a distribution with the desired parameters:
  465. >>> from scipy import stats
  466. >>> X = stats.Normal(mu=1., sigma=2.)
  467. Evaluate the standard deviation:
  468. >>> X.standard_deviation()
  469. 2.0
  470. >>> X.standard_deviation() == X.moment(order=2, kind='central')**0.5 == X.sigma
  471. True
  472. """
  473. raise NotImplementedError()
  474. @abstractmethod
  475. def skewness(self, *, method):
  476. r"""Skewness (standardized third moment)
  477. Parameters
  478. ----------
  479. method : {None, 'formula', 'general', 'transform', 'normalize', 'cache'}
  480. Method used to calculate the standardized third moment. Not
  481. all methods are available for all distributions. See
  482. `moment` for details.
  483. See Also
  484. --------
  485. moment
  486. mean
  487. variance
  488. References
  489. ----------
  490. .. [1] Skewness, *Wikipedia*,
  491. https://en.wikipedia.org/wiki/Skewness
  492. Examples
  493. --------
  494. Instantiate a distribution with the desired parameters:
  495. >>> from scipy import stats
  496. >>> X = stats.Normal(mu=1., sigma=2.)
  497. Evaluate the skewness:
  498. >>> X.skewness()
  499. 0.0
  500. >>> X.skewness() == X.moment(order=3, kind='standardized')
  501. True
  502. """
  503. raise NotImplementedError()
  504. @abstractmethod
  505. def kurtosis(self, *, method):
  506. r"""Kurtosis (standardized fourth moment)
  507. By default, this is the standardized fourth moment, also known as the
  508. "non-excess" or "Pearson" kurtosis (e.g. the kurtosis of the normal
  509. distribution is 3). The "excess" or "Fisher" kurtosis (the standardized
  510. fourth moment minus 3) is available via the `convention` parameter.
  511. Parameters
  512. ----------
  513. method : {None, 'formula', 'general', 'transform', 'normalize', 'cache'}
  514. Method used to calculate the standardized fourth moment. Not
  515. all methods are available for all distributions. See
  516. `moment` for details.
  517. convention : {'non-excess', 'excess'}
  518. Two distinct conventions are available:
  519. - ``'non-excess'``: the standardized fourth moment (Pearson's kurtosis)
  520. - ``'excess'``: the standardized fourth moment minus 3 (Fisher's kurtosis)
  521. The default is ``'non-excess'``.
  522. See Also
  523. --------
  524. moment
  525. mean
  526. variance
  527. References
  528. ----------
  529. .. [1] Kurtosis, *Wikipedia*,
  530. https://en.wikipedia.org/wiki/Kurtosis
  531. Examples
  532. --------
  533. Instantiate a distribution with the desired parameters:
  534. >>> from scipy import stats
  535. >>> X = stats.Normal(mu=1., sigma=2.)
  536. Evaluate the kurtosis:
  537. >>> X.kurtosis()
  538. 3.0
  539. >>> (X.kurtosis()
  540. ... == X.kurtosis(convention='excess') + 3.
  541. ... == X.moment(order=4, kind='standardized'))
  542. True
  543. """
  544. raise NotImplementedError()
  545. @abstractmethod
  546. def pdf(self, x, /, *, method):
  547. r"""Probability density function
  548. The probability density function ("PDF"), denoted :math:`f(x)`, is the
  549. probability *per unit length* that the random variable will assume the
  550. value :math:`x`. Mathematically, it can be defined as the derivative
  551. of the cumulative distribution function :math:`F(x)`:
  552. .. math::
  553. f(x) = \frac{d}{dx} F(x)
  554. `pdf` accepts `x` for :math:`x`.
  555. Parameters
  556. ----------
  557. x : array_like
  558. The argument of the PDF.
  559. method : {None, 'formula', 'logexp'}
  560. The strategy used to evaluate the PDF. By default (``None``), the
  561. infrastructure chooses between the following options, listed in
  562. order of precedence.
  563. - ``'formula'``: use a formula for the PDF itself
  564. - ``'logexp'``: evaluate the log-PDF and exponentiate
  565. Not all `method` options are available for all distributions.
  566. If the selected `method` is not available, a ``NotImplementedError``
  567. will be raised.
  568. Returns
  569. -------
  570. out : array
  571. The PDF evaluated at the argument `x`.
  572. See Also
  573. --------
  574. cdf
  575. logpdf
  576. Notes
  577. -----
  578. Suppose a continuous probability distribution has support :math:`[l, r]`.
  579. By definition of the support, the PDF evaluates to its minimum value
  580. of :math:`0` outside the support; i.e. for :math:`x < l` or
  581. :math:`x > r`. The maximum of the PDF may be less than or greater than
  582. :math:`1`; since the value is a probability *density*, only its integral
  583. over the support must equal :math:`1`.
  584. For discrete distributions, `pdf` returns ``inf`` at supported points
  585. and ``0`` elsewhere.
  586. References
  587. ----------
  588. .. [1] Probability density function, *Wikipedia*,
  589. https://en.wikipedia.org/wiki/Probability_density_function
  590. Examples
  591. --------
  592. Instantiate a distribution with the desired parameters:
  593. >>> from scipy import stats
  594. >>> X = stats.Uniform(a=-1., b=1.)
  595. Evaluate the PDF at the desired argument:
  596. >>> X.pdf(0.25)
  597. 0.5
  598. """
  599. raise NotImplementedError()
  600. @abstractmethod
  601. def logpdf(self, x, /, *, method):
  602. r"""Log of the probability density function
  603. The probability density function ("PDF"), denoted :math:`f(x)`, is the
  604. probability *per unit length* that the random variable will assume the
  605. value :math:`x`. Mathematically, it can be defined as the derivative
  606. of the cumulative distribution function :math:`F(x)`:
  607. .. math::
  608. f(x) = \frac{d}{dx} F(x)
  609. `logpdf` computes the logarithm of the probability density function
  610. ("log-PDF"), :math:`\log(f(x))`, but it may be numerically favorable
  611. compared to the naive implementation (computing :math:`f(x)` and
  612. taking the logarithm).
  613. `logpdf` accepts `x` for :math:`x`.
  614. Parameters
  615. ----------
  616. x : array_like
  617. The argument of the log-PDF.
  618. method : {None, 'formula', 'logexp'}
  619. The strategy used to evaluate the log-PDF. By default (``None``), the
  620. infrastructure chooses between the following options, listed in order
  621. of precedence.
  622. - ``'formula'``: use a formula for the log-PDF itself
  623. - ``'logexp'``: evaluate the PDF and takes its logarithm
  624. Not all `method` options are available for all distributions.
  625. If the selected `method` is not available, a ``NotImplementedError``
  626. will be raised.
  627. Returns
  628. -------
  629. out : array
  630. The log-PDF evaluated at the argument `x`.
  631. See Also
  632. --------
  633. pdf
  634. logcdf
  635. Notes
  636. -----
  637. Suppose a continuous probability distribution has support :math:`[l, r]`.
  638. By definition of the support, the log-PDF evaluates to its minimum value
  639. of :math:`-\infty` (i.e. :math:`\log(0)`) outside the support; i.e. for
  640. :math:`x < l` or :math:`x > r`. The maximum of the log-PDF may be less
  641. than or greater than :math:`\log(1) = 0` because the maximum of the PDF
  642. can be any positive real.
  643. For distributions with infinite support, it is common for `pdf` to return
  644. a value of ``0`` when the argument is theoretically within the support;
  645. this can occur because the true value of the PDF is too small to be
  646. represented by the chosen dtype. The log-PDF, however, will often be finite
  647. (not ``-inf``) over a much larger domain. Consequently, it may be preferred
  648. to work with the logarithms of probabilities and probability densities to
  649. avoid underflow.
  650. For discrete distributions, `logpdf` returns ``inf`` at supported points and
  651. ``-inf`` (``log(0)``) elsewhere.
  652. References
  653. ----------
  654. .. [1] Probability density function, *Wikipedia*,
  655. https://en.wikipedia.org/wiki/Probability_density_function
  656. Examples
  657. --------
  658. Instantiate a distribution with the desired parameters:
  659. >>> import numpy as np
  660. >>> from scipy import stats
  661. >>> X = stats.Uniform(a=-1.0, b=1.0)
  662. Evaluate the log-PDF at the desired argument:
  663. >>> X.logpdf(0.5)
  664. -0.6931471805599453
  665. >>> np.allclose(X.logpdf(0.5), np.log(X.pdf(0.5)))
  666. True
  667. """
  668. raise NotImplementedError()
  669. def pmf(self, x, /, *, method=None):
  670. r"""Probability mass function
  671. The probability mass function ("PMF"), denoted :math:`f(x)`, is the
  672. probability that the random variable :math:`X` will assume the value :math:`x`.
  673. .. math::
  674. f(x) = P(X = x)
  675. `pmf` accepts `x` for :math:`x`.
  676. Parameters
  677. ----------
  678. x : array_like
  679. The argument of the PMF.
  680. method : {None, 'formula', 'logexp'}
  681. The strategy used to evaluate the PMF. By default (``None``), the
  682. infrastructure chooses between the following options, listed in
  683. order of precedence.
  684. - ``'formula'``: use a formula for the PMF itself
  685. - ``'logexp'``: evaluate the log-PMF and exponentiate
  686. Not all `method` options are available for all distributions.
  687. If the selected `method` is not available, a ``NotImplementedError``
  688. will be raised.
  689. Returns
  690. -------
  691. out : array
  692. The PMF evaluated at the argument `x`.
  693. See Also
  694. --------
  695. cdf
  696. logpmf
  697. Notes
  698. -----
  699. Suppose a discrete probability distribution has support over the integers
  700. :math:`{l, l+1, ..., r-1, r}`.
  701. By definition of the support, the PMF evaluates to its minimum value
  702. of :math:`0` for non-integral :math:`x` and for :math:`x` outside the support;
  703. i.e. for :math:`x < l` or :math:`x > r`.
  704. For continuous distributions, `pmf` returns ``0`` at all real arguments.
  705. References
  706. ----------
  707. .. [1] Probability mass function, *Wikipedia*,
  708. https://en.wikipedia.org/wiki/Probability_mass_function
  709. Examples
  710. --------
  711. Instantiate a distribution with the desired parameters:
  712. >>> from scipy import stats
  713. >>> X = stats.Binomial(n=10, p=0.5)
  714. Evaluate the PMF at the desired argument:
  715. >>> X.pmf(5)
  716. np.float64(0.24609375)
  717. """
  718. raise NotImplementedError()
  719. def logpmf(self, x, /, *, method=None):
  720. r"""Log of the probability mass function
  721. The probability mass function ("PMF"), denoted :math:`f(x)`, is the
  722. probability that the random variable :math:`X` will assume the value :math:`x`.
  723. .. math::
  724. f(x) = \frac{d}{dx} F(x)
  725. `logpmf` computes the logarithm of the probability mass function
  726. ("log-PMF"), :math:`\log(f(x))`, but it may be numerically favorable
  727. compared to the naive implementation (computing :math:`f(x)` and
  728. taking the logarithm).
  729. `logpmf` accepts `x` for :math:`x`.
  730. Parameters
  731. ----------
  732. x : array_like
  733. The argument of the log-PMF.
  734. method : {None, 'formula', 'logexp'}
  735. The strategy used to evaluate the log-PMF. By default (``None``), the
  736. infrastructure chooses between the following options, listed in order
  737. of precedence.
  738. - ``'formula'``: use a formula for the log-PMF itself
  739. - ``'logexp'``: evaluate the PMF and takes its logarithm
  740. Not all `method` options are available for all distributions.
  741. If the selected `method` is not available, a ``NotImplementedError``
  742. will be raised.
  743. Returns
  744. -------
  745. out : array
  746. The log-PMF evaluated at the argument `x`.
  747. See Also
  748. --------
  749. pmf
  750. logcdf
  751. Notes
  752. -----
  753. Suppose a discrete probability distribution has support over the integers
  754. :math:`{l, l+1, ..., r-1, r}`.
  755. By definition of the support, the log-PMF evaluates to its minimum value
  756. of :math:`-\infty` (i.e. :math:`\log(0)`) for non-integral :math:`x` and
  757. for :math:`x` outside the support; i.e. for :math:`x < l` or :math:`x > r`.
  758. For distributions with infinite support, it is common for `pmf` to return
  759. a value of ``0`` when the argument is theoretically within the support;
  760. this can occur because the true value of the PMF is too small to be
  761. represented by the chosen dtype. The log-PMF, however, will often be finite
  762. (not ``-inf``) over a much larger domain. Consequently, it may be preferred
  763. to work with the logarithms of probabilities and probability densities to
  764. avoid underflow.
  765. References
  766. ----------
  767. .. [1] Probability density function, *Wikipedia*,
  768. https://en.wikipedia.org/wiki/Probability_density_function
  769. Examples
  770. --------
  771. Instantiate a distribution with the desired parameters:
  772. >>> import numpy as np
  773. >>> from scipy import stats
  774. >>> X = stats.Binomial(n=10, p=0.5)
  775. Evaluate the log-PMF at the desired argument:
  776. >>> X.logpmf(5)
  777. np.float64(-1.4020427180880297)
  778. >>> np.allclose(X.logpmf(5), np.log(X.pmf(5)))
  779. True
  780. """
  781. raise NotImplementedError()
  782. @abstractmethod
  783. def cdf(self, x, y, /, *, method):
  784. r"""Cumulative distribution function
  785. The cumulative distribution function ("CDF"), denoted :math:`F(x)`, is
  786. the probability the random variable :math:`X` will assume a value
  787. less than or equal to :math:`x`:
  788. .. math::
  789. F(x) = P(X ≤ x)
  790. A two-argument variant of this function is also defined as the
  791. probability the random variable :math:`X` will assume a value between
  792. :math:`x` and :math:`y`.
  793. .. math::
  794. F(x, y) = P(x ≤ X ≤ y)
  795. `cdf` accepts `x` for :math:`x` and `y` for :math:`y`.
  796. Parameters
  797. ----------
  798. x, y : array_like
  799. The arguments of the CDF. `x` is required; `y` is optional.
  800. method : {None, 'formula', 'logexp', 'complement', 'quadrature', 'subtraction'}
  801. The strategy used to evaluate the CDF.
  802. By default (``None``), the one-argument form of the function
  803. chooses between the following options, listed in order of precedence.
  804. - ``'formula'``: use a formula for the CDF itself
  805. - ``'logexp'``: evaluate the log-CDF and exponentiate
  806. - ``'complement'``: evaluate the CCDF and take the complement
  807. - ``'quadrature'``: numerically integrate the PDF (or, in the discrete
  808. case, sum the PMF)
  809. In place of ``'complement'``, the two-argument form accepts:
  810. - ``'subtraction'``: compute the CDF at each argument and take
  811. the difference.
  812. Not all `method` options are available for all distributions.
  813. If the selected `method` is not available, a ``NotImplementedError``
  814. will be raised.
  815. Returns
  816. -------
  817. out : array
  818. The CDF evaluated at the provided argument(s).
  819. See Also
  820. --------
  821. logcdf
  822. ccdf
  823. Notes
  824. -----
  825. Suppose a continuous probability distribution has support :math:`[l, r]`.
  826. The CDF :math:`F(x)` is related to the probability density function
  827. :math:`f(x)` by:
  828. .. math::
  829. F(x) = \int_l^x f(u) du
  830. The two argument version is:
  831. .. math::
  832. F(x, y) = \int_x^y f(u) du = F(y) - F(x)
  833. The CDF evaluates to its minimum value of :math:`0` for :math:`x ≤ l`
  834. and its maximum value of :math:`1` for :math:`x ≥ r`.
  835. Suppose a discrete probability distribution has support :math:`[l, r]`.
  836. The CDF :math:`F(x)` is related to the probability mass function
  837. :math:`f(x)` by:
  838. .. math::
  839. F(x) = \sum_{u=l}^{\lfloor x \rfloor} f(u)
  840. The CDF evaluates to its minimum value of :math:`0` for :math:`x < l`
  841. and its maximum value of :math:`1` for :math:`x ≥ r`.
  842. The CDF is also known simply as the "distribution function".
  843. References
  844. ----------
  845. .. [1] Cumulative distribution function, *Wikipedia*,
  846. https://en.wikipedia.org/wiki/Cumulative_distribution_function
  847. Examples
  848. --------
  849. Instantiate a distribution with the desired parameters:
  850. >>> from scipy import stats
  851. >>> X = stats.Uniform(a=-0.5, b=0.5)
  852. Evaluate the CDF at the desired argument:
  853. >>> X.cdf(0.25)
  854. 0.75
  855. Evaluate the cumulative probability between two arguments:
  856. >>> X.cdf(-0.25, 0.25) == X.cdf(0.25) - X.cdf(-0.25)
  857. True
  858. """ # noqa: E501
  859. raise NotImplementedError()
  860. @abstractmethod
  861. def icdf(self, p, /, *, method):
  862. r"""Inverse of the cumulative distribution function.
  863. For monotonic continuous distributions, the inverse of the cumulative
  864. distribution function ("inverse CDF"), denoted :math:`F^{-1}(p)`, is the
  865. argument :math:`x` for which the cumulative distribution function
  866. :math:`F(x)` evaluates to :math:`p`.
  867. .. math::
  868. F^{-1}(p) = x \quad \text{s.t.} \quad F(x) = p
  869. When a strict "inverse" of the cumulative distribution function does not
  870. exist (e.g. discrete random variables), the "inverse CDF" is defined by
  871. convention as the smallest value within the support :math:`\chi` for which
  872. :math:`F(x)` is at least :math:`p`.
  873. .. math::
  874. F^{-1}(p) = \min_\chi \quad \text{s.t.} \quad F(x) ≥ p
  875. `icdf` accepts `p` for :math:`p \in [0, 1]`.
  876. Parameters
  877. ----------
  878. p : array_like
  879. The argument of the inverse CDF.
  880. method : {None, 'formula', 'complement', 'inversion'}
  881. The strategy used to evaluate the inverse CDF.
  882. By default (``None``), the infrastructure chooses between the
  883. following options, listed in order of precedence.
  884. - ``'formula'``: use a formula for the inverse CDF itself
  885. - ``'complement'``: evaluate the inverse CCDF at the
  886. complement of `p`
  887. - ``'inversion'``: solve numerically for the argument at which the
  888. CDF is equal to `p`
  889. Not all `method` options are available for all distributions.
  890. If the selected `method` is not available, a ``NotImplementedError``
  891. will be raised.
  892. Returns
  893. -------
  894. out : array
  895. The inverse CDF evaluated at the provided argument.
  896. See Also
  897. --------
  898. cdf
  899. ilogcdf
  900. Notes
  901. -----
  902. Suppose a probability distribution has support :math:`[l, r]`. The
  903. inverse CDF returns its minimum value of :math:`l` at :math:`p = 0`
  904. and its maximum value of :math:`r` at :math:`p = 1`. Because the CDF
  905. has range :math:`[0, 1]`, the inverse CDF is only defined on the
  906. domain :math:`[0, 1]`; for :math:`p < 0` and :math:`p > 1`, `icdf`
  907. returns ``nan``.
  908. The inverse CDF is also known as the quantile function, percentile function,
  909. and percent-point function.
  910. References
  911. ----------
  912. .. [1] Quantile function, *Wikipedia*,
  913. https://en.wikipedia.org/wiki/Quantile_function
  914. Examples
  915. --------
  916. Instantiate a distribution with the desired parameters:
  917. >>> import numpy as np
  918. >>> from scipy import stats
  919. >>> X = stats.Uniform(a=-0.5, b=0.5)
  920. Evaluate the inverse CDF at the desired argument:
  921. >>> X.icdf(0.25)
  922. -0.25
  923. >>> np.allclose(X.cdf(X.icdf(0.25)), 0.25)
  924. True
  925. This function returns NaN when the argument is outside the domain.
  926. >>> X.icdf([-0.1, 0, 1, 1.1])
  927. array([ nan, -0.5, 0.5, nan])
  928. """
  929. raise NotImplementedError()
  930. @abstractmethod
  931. def ccdf(self, x, y, /, *, method):
  932. r"""Complementary cumulative distribution function
  933. The complementary cumulative distribution function ("CCDF"), denoted
  934. :math:`G(x)`, is the complement of the cumulative distribution function
  935. :math:`F(x)`; i.e., probability the random variable :math:`X` will
  936. assume a value greater than :math:`x`:
  937. .. math::
  938. G(x) = 1 - F(x) = P(X > x)
  939. A two-argument variant of this function is:
  940. .. math::
  941. G(x, y) = 1 - F(x, y) = P(X < x \text{ or } X > y)
  942. `ccdf` accepts `x` for :math:`x` and `y` for :math:`y`.
  943. Parameters
  944. ----------
  945. x, y : array_like
  946. The arguments of the CCDF. `x` is required; `y` is optional.
  947. method : {None, 'formula', 'logexp', 'complement', 'quadrature', 'addition'}
  948. The strategy used to evaluate the CCDF.
  949. By default (``None``), the infrastructure chooses between the
  950. following options, listed in order of precedence.
  951. - ``'formula'``: use a formula for the CCDF itself
  952. - ``'logexp'``: evaluate the log-CCDF and exponentiate
  953. - ``'complement'``: evaluate the CDF and take the complement
  954. - ``'quadrature'``: numerically integrate the PDF (or, in the discrete
  955. case, sum the PMF)
  956. The two-argument form chooses between:
  957. - ``'formula'``: use a formula for the CCDF itself
  958. - ``'addition'``: compute the CDF at `x` and the CCDF at `y`, then add
  959. Not all `method` options are available for all distributions.
  960. If the selected `method` is not available, a ``NotImplementedError``
  961. will be raised.
  962. Returns
  963. -------
  964. out : array
  965. The CCDF evaluated at the provided argument(s).
  966. See Also
  967. --------
  968. cdf
  969. logccdf
  970. Notes
  971. -----
  972. Suppose a continuous probability distribution has support :math:`[l, r]`.
  973. The CCDF :math:`G(x)` is related to the probability density function
  974. :math:`f(x)` by:
  975. .. math::
  976. G(x) = \int_x^r f(u) du
  977. The two argument version is:
  978. .. math::
  979. G(x, y) = \int_l^x f(u) du + \int_y^r f(u) du
  980. The CCDF returns its minimum value of :math:`0` for :math:`x ≥ r`
  981. and its maximum value of :math:`1` for :math:`x ≤ l`.
  982. Suppose a discrete probability distribution has support :math:`[l, r]`.
  983. The CCDF :math:`G(x)` is related to the probability mass function
  984. :math:`f(x)` by:
  985. .. math::
  986. G(x) = \sum_{u=\lfloor x + 1 \rfloor}^{r} f(u)
  987. The CCDF evaluates to its minimum value of :math:`0` for :math:`x ≥ r`
  988. and its maximum value of :math:`1` for :math:`x < l`.
  989. The CCDF is also known as the "survival function".
  990. References
  991. ----------
  992. .. [1] Cumulative distribution function, *Wikipedia*,
  993. https://en.wikipedia.org/wiki/Cumulative_distribution_function#Derived_functions
  994. Examples
  995. --------
  996. Instantiate a distribution with the desired parameters:
  997. >>> import numpy as np
  998. >>> from scipy import stats
  999. >>> X = stats.Uniform(a=-0.5, b=0.5)
  1000. Evaluate the CCDF at the desired argument:
  1001. >>> X.ccdf(0.25)
  1002. 0.25
  1003. >>> np.allclose(X.ccdf(0.25), 1-X.cdf(0.25))
  1004. True
  1005. Evaluate the complement of the cumulative probability between two arguments:
  1006. >>> X.ccdf(-0.25, 0.25) == X.cdf(-0.25) + X.ccdf(0.25)
  1007. True
  1008. """ # noqa: E501
  1009. raise NotImplementedError()
  1010. @abstractmethod
  1011. def iccdf(self, p, /, *, method):
  1012. r"""Inverse complementary cumulative distribution function.
  1013. The inverse complementary cumulative distribution function ("inverse CCDF"),
  1014. denoted :math:`G^{-1}(p)`, is the argument :math:`x` for which the
  1015. complementary cumulative distribution function :math:`G(x)` evaluates to
  1016. :math:`p`.
  1017. .. math::
  1018. G^{-1}(p) = x \quad \text{s.t.} \quad G(x) = p
  1019. When a strict "inverse" of the complementary cumulative distribution function
  1020. does not exist (e.g. discrete random variables), the "inverse CCDF" is defined
  1021. by convention as the smallest value within the support :math:`\chi` for which
  1022. :math:`G(x)` is no greater than :math:`p`.
  1023. .. math::
  1024. G^{-1}(p) = \min_\chi \quad \text{s.t.} \quad G(x) ≤ p
  1025. `iccdf` accepts `p` for :math:`p \in [0, 1]`.
  1026. Parameters
  1027. ----------
  1028. p : array_like
  1029. The argument of the inverse CCDF.
  1030. method : {None, 'formula', 'complement', 'inversion'}
  1031. The strategy used to evaluate the inverse CCDF.
  1032. By default (``None``), the infrastructure chooses between the
  1033. following options, listed in order of precedence.
  1034. - ``'formula'``: use a formula for the inverse CCDF itself
  1035. - ``'complement'``: evaluate the inverse CDF at the
  1036. complement of `p`
  1037. - ``'inversion'``: solve numerically for the argument at which the
  1038. CCDF is equal to `p`
  1039. Not all `method` options are available for all distributions.
  1040. If the selected `method` is not available, a ``NotImplementedError``
  1041. will be raised.
  1042. Returns
  1043. -------
  1044. out : array
  1045. The inverse CCDF evaluated at the provided argument.
  1046. Notes
  1047. -----
  1048. Suppose a probability distribution has support :math:`[l, r]`. The
  1049. inverse CCDF returns its minimum value of :math:`l` at :math:`p = 1`
  1050. and its maximum value of :math:`r` at :math:`p = 0`. Because the CCDF
  1051. has range :math:`[0, 1]`, the inverse CCDF is only defined on the
  1052. domain :math:`[0, 1]`; for :math:`p < 0` and :math:`p > 1`, ``iccdf``
  1053. returns ``nan``.
  1054. See Also
  1055. --------
  1056. icdf
  1057. ilogccdf
  1058. Examples
  1059. --------
  1060. Instantiate a distribution with the desired parameters:
  1061. >>> import numpy as np
  1062. >>> from scipy import stats
  1063. >>> X = stats.Uniform(a=-0.5, b=0.5)
  1064. Evaluate the inverse CCDF at the desired argument:
  1065. >>> X.iccdf(0.25)
  1066. 0.25
  1067. >>> np.allclose(X.iccdf(0.25), X.icdf(1-0.25))
  1068. True
  1069. This function returns NaN when the argument is outside the domain.
  1070. >>> X.iccdf([-0.1, 0, 1, 1.1])
  1071. array([ nan, 0.5, -0.5, nan])
  1072. """
  1073. raise NotImplementedError()
  1074. @abstractmethod
  1075. def logcdf(self, x, y, /, *, method):
  1076. r"""Log of the cumulative distribution function
  1077. The cumulative distribution function ("CDF"), denoted :math:`F(x)`, is
  1078. the probability the random variable :math:`X` will assume a value
  1079. less than or equal to :math:`x`:
  1080. .. math::
  1081. F(x) = P(X ≤ x)
  1082. A two-argument variant of this function is also defined as the
  1083. probability the random variable :math:`X` will assume a value between
  1084. :math:`x` and :math:`y`.
  1085. .. math::
  1086. F(x, y) = P(x ≤ X ≤ y)
  1087. `logcdf` computes the logarithm of the cumulative distribution function
  1088. ("log-CDF"), :math:`\log(F(x))`/:math:`\log(F(x, y))`, but it may be
  1089. numerically favorable compared to the naive implementation (computing
  1090. the CDF and taking the logarithm).
  1091. `logcdf` accepts `x` for :math:`x` and `y` for :math:`y`.
  1092. Parameters
  1093. ----------
  1094. x, y : array_like
  1095. The arguments of the log-CDF. `x` is required; `y` is optional.
  1096. method : {None, 'formula', 'logexp', 'complement', 'quadrature', 'subtraction'}
  1097. The strategy used to evaluate the log-CDF.
  1098. By default (``None``), the one-argument form of the function
  1099. chooses between the following options, listed in order of precedence.
  1100. - ``'formula'``: use a formula for the log-CDF itself
  1101. - ``'logexp'``: evaluate the CDF and take the logarithm
  1102. - ``'complement'``: evaluate the log-CCDF and take the
  1103. logarithmic complement (see Notes)
  1104. - ``'quadrature'``: numerically log-integrate the log-PDF (or, in the
  1105. discrete case, log-sum the log-PMF)
  1106. In place of ``'complement'``, the two-argument form accepts:
  1107. - ``'subtraction'``: compute the log-CDF at each argument and take
  1108. the logarithmic difference (see Notes)
  1109. Not all `method` options are available for all distributions.
  1110. If the selected `method` is not available, a ``NotImplementedError``
  1111. will be raised.
  1112. Returns
  1113. -------
  1114. out : array
  1115. The log-CDF evaluated at the provided argument(s).
  1116. See Also
  1117. --------
  1118. cdf
  1119. logccdf
  1120. Notes
  1121. -----
  1122. Suppose a continuous probability distribution has support :math:`[l, r]`.
  1123. The log-CDF evaluates to its minimum value of :math:`\log(0) = -\infty`
  1124. for :math:`x ≤ l` and its maximum value of :math:`\log(1) = 0` for
  1125. :math:`x ≥ r`. An analogous statement can be made for discrete distributions,
  1126. but the inequality governing the minimum value is strict.
  1127. For distributions with infinite support, it is common for
  1128. `cdf` to return a value of ``0`` when the argument
  1129. is theoretically within the support; this can occur because the true value
  1130. of the CDF is too small to be represented by the chosen dtype. `logcdf`,
  1131. however, will often return a finite (not ``-inf``) result over a much larger
  1132. domain. Similarly, `logcdf` may provided a strictly negative result with
  1133. arguments for which `cdf` would return ``1.0``. Consequently, it may be
  1134. preferred to work with the logarithms of probabilities to avoid underflow
  1135. and related limitations of floating point numbers.
  1136. The "logarithmic complement" of a number :math:`z` is mathematically
  1137. equivalent to :math:`\log(1-\exp(z))`, but it is computed to avoid loss
  1138. of precision when :math:`\exp(z)` is nearly :math:`0` or :math:`1`.
  1139. Similarly, the term "logarithmic difference" of :math:`w` and :math:`z`
  1140. is used here to mean :math:`\log(\exp(w)-\exp(z))`.
  1141. If ``y < x``, the CDF is negative, and therefore the log-CCDF
  1142. is complex with imaginary part :math:`\pi`. For
  1143. consistency, the result of this function always has complex dtype
  1144. when `y` is provided, regardless of the value of the imaginary part.
  1145. References
  1146. ----------
  1147. .. [1] Cumulative distribution function, *Wikipedia*,
  1148. https://en.wikipedia.org/wiki/Cumulative_distribution_function
  1149. Examples
  1150. --------
  1151. Instantiate a distribution with the desired parameters:
  1152. >>> import numpy as np
  1153. >>> from scipy import stats
  1154. >>> X = stats.Uniform(a=-0.5, b=0.5)
  1155. Evaluate the log-CDF at the desired argument:
  1156. >>> X.logcdf(0.25)
  1157. -0.287682072451781
  1158. >>> np.allclose(X.logcdf(0.), np.log(X.cdf(0.)))
  1159. True
  1160. """ # noqa: E501
  1161. raise NotImplementedError()
  1162. @abstractmethod
  1163. def ilogcdf(self, logp, /, *, method):
  1164. r"""Inverse of the logarithm of the cumulative distribution function.
  1165. The inverse of the logarithm of the cumulative distribution function
  1166. ("inverse log-CDF") is the argument :math:`x` for which the logarithm
  1167. of the cumulative distribution function :math:`\log(F(x))` evaluates
  1168. to :math:`\log(p)`.
  1169. Mathematically, it is equivalent to :math:`F^{-1}(\exp(y))`, where
  1170. :math:`y = \log(p)`, but it may be numerically favorable compared to
  1171. the naive implementation (computing :math:`p = \exp(y)`, then
  1172. :math:`F^{-1}(p)`).
  1173. `ilogcdf` accepts `logp` for :math:`\log(p) ≤ 0`.
  1174. Parameters
  1175. ----------
  1176. logp : array_like
  1177. The argument of the inverse log-CDF.
  1178. method : {None, 'formula', 'complement', 'inversion'}
  1179. The strategy used to evaluate the inverse log-CDF.
  1180. By default (``None``), the infrastructure chooses between the
  1181. following options, listed in order of precedence.
  1182. - ``'formula'``: use a formula for the inverse log-CDF itself
  1183. - ``'complement'``: evaluate the inverse log-CCDF at the
  1184. logarithmic complement of `logp` (see Notes)
  1185. - ``'inversion'``: solve numerically for the argument at which the
  1186. log-CDF is equal to `logp`
  1187. Not all `method` options are available for all distributions.
  1188. If the selected `method` is not available, a ``NotImplementedError``
  1189. will be raised.
  1190. Returns
  1191. -------
  1192. out : array
  1193. The inverse log-CDF evaluated at the provided argument.
  1194. See Also
  1195. --------
  1196. icdf
  1197. logcdf
  1198. Notes
  1199. -----
  1200. Suppose a probability distribution has support :math:`[l, r]`.
  1201. The inverse log-CDF returns its minimum value of :math:`l` at
  1202. :math:`\log(p) = \log(0) = -\infty` and its maximum value of :math:`r` at
  1203. :math:`\log(p) = \log(1) = 0`. Because the log-CDF has range
  1204. :math:`[-\infty, 0]`, the inverse log-CDF is only defined on the
  1205. negative reals; for :math:`\log(p) > 0`, `ilogcdf` returns ``nan``.
  1206. Occasionally, it is needed to find the argument of the CDF for which
  1207. the resulting probability is very close to ``0`` or ``1`` - too close to
  1208. represent accurately with floating point arithmetic. In many cases,
  1209. however, the *logarithm* of this resulting probability may be
  1210. represented in floating point arithmetic, in which case this function
  1211. may be used to find the argument of the CDF for which the *logarithm*
  1212. of the resulting probability is :math:`y = \log(p)`.
  1213. The "logarithmic complement" of a number :math:`z` is mathematically
  1214. equivalent to :math:`\log(1-\exp(z))`, but it is computed to avoid loss
  1215. of precision when :math:`\exp(z)` is nearly :math:`0` or :math:`1`.
  1216. Examples
  1217. --------
  1218. Instantiate a distribution with the desired parameters:
  1219. >>> import numpy as np
  1220. >>> from scipy import stats
  1221. >>> X = stats.Uniform(a=-0.5, b=0.5)
  1222. Evaluate the inverse log-CDF at the desired argument:
  1223. >>> X.ilogcdf(-0.25)
  1224. 0.2788007830714034
  1225. >>> np.allclose(X.ilogcdf(-0.25), X.icdf(np.exp(-0.25)))
  1226. True
  1227. """
  1228. raise NotImplementedError()
  1229. @abstractmethod
  1230. def logccdf(self, x, y, /, *, method):
  1231. r"""Log of the complementary cumulative distribution function
  1232. The complementary cumulative distribution function ("CCDF"), denoted
  1233. :math:`G(x)` is the complement of the cumulative distribution function
  1234. :math:`F(x)`; i.e., probability the random variable :math:`X` will
  1235. assume a value greater than :math:`x`:
  1236. .. math::
  1237. G(x) = 1 - F(x) = P(X > x)
  1238. A two-argument variant of this function is:
  1239. .. math::
  1240. G(x, y) = 1 - F(x, y) = P(X < x \quad \text{or} \quad X > y)
  1241. `logccdf` computes the logarithm of the complementary cumulative
  1242. distribution function ("log-CCDF"), :math:`\log(G(x))`/:math:`\log(G(x, y))`,
  1243. but it may be numerically favorable compared to the naive implementation
  1244. (computing the CDF and taking the logarithm).
  1245. `logccdf` accepts `x` for :math:`x` and `y` for :math:`y`.
  1246. Parameters
  1247. ----------
  1248. x, y : array_like
  1249. The arguments of the log-CCDF. `x` is required; `y` is optional.
  1250. method : {None, 'formula', 'logexp', 'complement', 'quadrature', 'addition'}
  1251. The strategy used to evaluate the log-CCDF.
  1252. By default (``None``), the one-argument form of the function
  1253. chooses between the following options, listed in order of precedence.
  1254. - ``'formula'``: use a formula for the log CCDF itself
  1255. - ``'logexp'``: evaluate the CCDF and take the logarithm
  1256. - ``'complement'``: evaluate the log-CDF and take the
  1257. logarithmic complement (see Notes)
  1258. - ``'quadrature'``: numerically log-integrate the log-PDF (or, in the
  1259. discrete case, log-sum the log-PMF)
  1260. The two-argument form chooses between:
  1261. - ``'formula'``: use a formula for the log CCDF itself
  1262. - ``'addition'``: compute the log-CDF at `x` and the log-CCDF at `y`,
  1263. then take the logarithmic sum (see Notes)
  1264. Not all `method` options are available for all distributions.
  1265. If the selected `method` is not available, a ``NotImplementedError``
  1266. will be raised.
  1267. Returns
  1268. -------
  1269. out : array
  1270. The log-CCDF evaluated at the provided argument(s).
  1271. See Also
  1272. --------
  1273. ccdf
  1274. logcdf
  1275. Notes
  1276. -----
  1277. Suppose a continuous probability distribution has support :math:`[l, r]`.
  1278. The log-CCDF returns its minimum value of :math:`\log(0)=-\infty` for
  1279. :math:`x ≥ r` and its maximum value of :math:`\log(1) = 0` for
  1280. :math:`x ≤ l`. An analogous statement can be made for discrete distributions,
  1281. but the inequality governing the maximum value is strict.
  1282. For distributions with infinite support, it is common for
  1283. `ccdf` to return a value of ``0`` when the argument
  1284. is theoretically within the support; this can occur because the true value
  1285. of the CCDF is too small to be represented by the chosen dtype. The log
  1286. of the CCDF, however, will often be finite (not ``-inf``) over a much larger
  1287. domain. Similarly, `logccdf` may provided a strictly negative result with
  1288. arguments for which `ccdf` would return ``1.0``. Consequently, it may be
  1289. preferred to work with the logarithms of probabilities to avoid underflow
  1290. and related limitations of floating point numbers.
  1291. The "logarithmic complement" of a number :math:`z` is mathematically
  1292. equivalent to :math:`\log(1-\exp(z))`, but it is computed to avoid loss
  1293. of precision when :math:`\exp(z)` is nearly :math:`0` or :math:`1`.
  1294. Similarly, the term "logarithmic sum" of :math:`w` and :math:`z`
  1295. is used here to mean the :math:`\log(\exp(w)+\exp(z))`, AKA
  1296. :math:`\text{LogSumExp}(w, z)`.
  1297. References
  1298. ----------
  1299. .. [1] Cumulative distribution function, *Wikipedia*,
  1300. https://en.wikipedia.org/wiki/Cumulative_distribution_function#Derived_functions
  1301. Examples
  1302. --------
  1303. Instantiate a distribution with the desired parameters:
  1304. >>> import numpy as np
  1305. >>> from scipy import stats
  1306. >>> X = stats.Uniform(a=-0.5, b=0.5)
  1307. Evaluate the log-CCDF at the desired argument:
  1308. >>> X.logccdf(0.25)
  1309. -1.3862943611198906
  1310. >>> np.allclose(X.logccdf(0.), np.log(X.ccdf(0.)))
  1311. True
  1312. """ # noqa: E501
  1313. raise NotImplementedError()
  1314. @abstractmethod
  1315. def ilogccdf(self, logp, /, *, method):
  1316. r"""Inverse of the log of the complementary cumulative distribution function.
  1317. The inverse of the logarithm of the complementary cumulative distribution
  1318. function ("inverse log-CCDF") is the argument :math:`x` for which the logarithm
  1319. of the complementary cumulative distribution function :math:`\log(G(x))`
  1320. evaluates to :math:`\log(p)`.
  1321. Mathematically, it is equivalent to :math:`G^{-1}(\exp(y))`, where
  1322. :math:`y = \log(p)`, but it may be numerically favorable compared to the naive
  1323. implementation (computing :math:`p = \exp(y)`, then :math:`G^{-1}(p)`).
  1324. `ilogccdf` accepts `logp` for :math:`\log(p) ≤ 0`.
  1325. Parameters
  1326. ----------
  1327. x : array_like
  1328. The argument of the inverse log-CCDF.
  1329. method : {None, 'formula', 'complement', 'inversion'}
  1330. The strategy used to evaluate the inverse log-CCDF.
  1331. By default (``None``), the infrastructure chooses between the
  1332. following options, listed in order of precedence.
  1333. - ``'formula'``: use a formula for the inverse log-CCDF itself
  1334. - ``'complement'``: evaluate the inverse log-CDF at the
  1335. logarithmic complement of `x` (see Notes)
  1336. - ``'inversion'``: solve numerically for the argument at which the
  1337. log-CCDF is equal to `x`
  1338. Not all `method` options are available for all distributions.
  1339. If the selected `method` is not available, a ``NotImplementedError``
  1340. will be raised.
  1341. Returns
  1342. -------
  1343. out : array
  1344. The inverse log-CCDF evaluated at the provided argument.
  1345. Notes
  1346. -----
  1347. Suppose a probability distribution has support :math:`[l, r]`. The
  1348. inverse log-CCDF returns its minimum value of :math:`l` at
  1349. :math:`\log(p) = \log(1) = 0` and its maximum value of :math:`r` at
  1350. :math:`\log(p) = \log(0) = -\infty`. Because the log-CCDF has range
  1351. :math:`[-\infty, 0]`, the inverse log-CDF is only defined on the
  1352. negative reals; for :math:`\log(p) > 0`, `ilogccdf` returns ``nan``.
  1353. Occasionally, it is needed to find the argument of the CCDF for which
  1354. the resulting probability is very close to ``0`` or ``1`` - too close to
  1355. represent accurately with floating point arithmetic. In many cases,
  1356. however, the *logarithm* of this resulting probability may be
  1357. represented in floating point arithmetic, in which case this function
  1358. may be used to find the argument of the CCDF for which the *logarithm*
  1359. of the resulting probability is :math:`y = \log(p)`.
  1360. The "logarithmic complement" of a number :math:`z` is mathematically
  1361. equivalent to :math:`\log(1-\exp(z))`, but it is computed to avoid loss
  1362. of precision when :math:`\exp(z)` is nearly :math:`0` or :math:`1`.
  1363. See Also
  1364. --------
  1365. iccdf
  1366. ilogccdf
  1367. Examples
  1368. --------
  1369. Instantiate a distribution with the desired parameters:
  1370. >>> import numpy as np
  1371. >>> from scipy import stats
  1372. >>> X = stats.Uniform(a=-0.5, b=0.5)
  1373. Evaluate the inverse log-CCDF at the desired argument:
  1374. >>> X.ilogccdf(-0.25)
  1375. -0.2788007830714034
  1376. >>> np.allclose(X.ilogccdf(-0.25), X.iccdf(np.exp(-0.25)))
  1377. True
  1378. """
  1379. raise NotImplementedError()
  1380. @abstractmethod
  1381. def logentropy(self, *, method):
  1382. r"""Logarithm of the differential entropy
  1383. In terms of probability density function :math:`f(x)` and support
  1384. :math:`\chi`, the differential entropy (or simply "entropy") of a
  1385. continuous random variable :math:`X` is:
  1386. .. math::
  1387. h(X) = - \int_{\chi} f(x) \log f(x) dx
  1388. The definition for a discrete random variable is analogous, with the PMF
  1389. replacing the PDF and a sum over the support replacing the integral.
  1390. `logentropy` computes the logarithm of the differential entropy
  1391. ("log-entropy"), :math:`\log(h(X))`, but it may be numerically favorable
  1392. compared to the naive implementation (computing :math:`h(X)` then
  1393. taking the logarithm).
  1394. Parameters
  1395. ----------
  1396. method : {None, 'formula', 'logexp', 'quadrature}
  1397. The strategy used to evaluate the log-entropy. By default
  1398. (``None``), the infrastructure chooses between the following options,
  1399. listed in order of precedence.
  1400. - ``'formula'``: use a formula for the log-entropy itself
  1401. - ``'logexp'``: evaluate the entropy and take the logarithm
  1402. - ``'quadrature'``: numerically log-integrate (or, in the discrete
  1403. case, log-sum) the logarithm of the entropy integrand (summand)
  1404. Not all `method` options are available for all distributions.
  1405. If the selected `method` is not available, a ``NotImplementedError``
  1406. will be raised.
  1407. Returns
  1408. -------
  1409. out : array
  1410. The log-entropy.
  1411. See Also
  1412. --------
  1413. entropy
  1414. logpdf
  1415. Notes
  1416. -----
  1417. The differential entropy of a continuous distribution can be negative.
  1418. In this case, the log-entropy is complex with imaginary part :math:`\pi`.
  1419. For consistency, the result of this function always has complex dtype,
  1420. regardless of the value of the imaginary part.
  1421. References
  1422. ----------
  1423. .. [1] Differential entropy, *Wikipedia*,
  1424. https://en.wikipedia.org/wiki/Differential_entropy
  1425. Examples
  1426. --------
  1427. Instantiate a distribution with the desired parameters:
  1428. >>> import numpy as np
  1429. >>> from scipy import stats
  1430. >>> X = stats.Uniform(a=-1., b=1.)
  1431. Evaluate the log-entropy:
  1432. >>> X.logentropy()
  1433. (-0.3665129205816642+0j)
  1434. >>> np.allclose(np.exp(X.logentropy()), X.entropy())
  1435. True
  1436. For a random variable with negative entropy, the log-entropy has an
  1437. imaginary part equal to `np.pi`.
  1438. >>> X = stats.Uniform(a=-.1, b=.1)
  1439. >>> X.entropy(), X.logentropy()
  1440. (-1.6094379124341007, (0.4758849953271105+3.141592653589793j))
  1441. """
  1442. raise NotImplementedError()
  1443. @abstractmethod
  1444. def entropy(self, *, method):
  1445. r"""Differential entropy
  1446. In terms of probability density function :math:`f(x)` and support
  1447. :math:`\chi`, the differential entropy (or simply "entropy") of a
  1448. continuous random variable :math:`X` is:
  1449. .. math::
  1450. h(X) = - \int_{\chi} f(x) \log f(x) dx
  1451. The definition for a discrete random variable is analogous, with the
  1452. PMF replacing the PDF and a sum over the support replacing the integral.
  1453. Parameters
  1454. ----------
  1455. method : {None, 'formula', 'logexp', 'quadrature'}
  1456. The strategy used to evaluate the entropy. By default (``None``),
  1457. the infrastructure chooses between the following options, listed
  1458. in order of precedence.
  1459. - ``'formula'``: use a formula for the entropy itself
  1460. - ``'logexp'``: evaluate the log-entropy and exponentiate
  1461. - ``'quadrature'``: numerically integrate (or, in the discrete
  1462. case, sum) the entropy integrand (summand)
  1463. Not all `method` options are available for all distributions.
  1464. If the selected `method` is not available, a ``NotImplementedError``
  1465. will be raised.
  1466. Returns
  1467. -------
  1468. out : array
  1469. The entropy of the random variable.
  1470. See Also
  1471. --------
  1472. logentropy
  1473. pdf
  1474. Notes
  1475. -----
  1476. This function calculates the entropy using the natural logarithm; i.e.
  1477. the logarithm with base :math:`e`. Consequently, the value is expressed
  1478. in (dimensionless) "units" of nats. To convert the entropy to different
  1479. units (i.e. corresponding with a different base), divide the result by
  1480. the natural logarithm of the desired base.
  1481. References
  1482. ----------
  1483. .. [1] Differential entropy, *Wikipedia*,
  1484. https://en.wikipedia.org/wiki/Differential_entropy
  1485. Examples
  1486. --------
  1487. Instantiate a distribution with the desired parameters:
  1488. >>> from scipy import stats
  1489. >>> X = stats.Uniform(a=-1., b=1.)
  1490. Evaluate the entropy:
  1491. >>> X.entropy()
  1492. 0.6931471805599454
  1493. """
  1494. raise NotImplementedError()