Upated wafo.stats

master
Per A Brodtkorb 9 years ago
parent 939f2c7252
commit aeed49139b

@ -13,7 +13,8 @@ from scipy import optimize
from scipy import integrate from scipy import integrate
from scipy.special import (gammaln as gamln, gamma as gam, boxcox, boxcox1p, from scipy.special import (gammaln as gamln, gamma as gam, boxcox, boxcox1p,
inv_boxcox, inv_boxcox1p, erfc, chndtr, chndtrix, inv_boxcox, inv_boxcox1p, erfc, chndtr, chndtrix,
log1p, expm1) log1p, expm1,
i0, i1, ndtr as _norm_cdf, log_ndtr as _norm_logcdf)
from numpy import (where, arange, putmask, ravel, shape, from numpy import (where, arange, putmask, ravel, shape,
log, sqrt, exp, arctanh, tan, sin, arcsin, arctan, log, sqrt, exp, arctanh, tan, sin, arcsin, arctan,
@ -32,9 +33,8 @@ from scipy.stats._tukeylambda_stats import (tukeylambda_variance as _tlvar,
tukeylambda_kurtosis as _tlkurt) tukeylambda_kurtosis as _tlkurt)
from ._distn_infrastructure import ( from ._distn_infrastructure import (
rv_continuous, valarray, _skew, _kurtosis, # @UnresolvedImport rv_continuous, valarray, _skew, _kurtosis, _lazywhere,
_lazywhere, _ncx2_log_pdf, _ncx2_pdf, _ncx2_cdf, # @UnresolvedImport _ncx2_log_pdf, _ncx2_pdf, _ncx2_cdf, get_distribution_names,
get_distribution_names, # @UnresolvedImport
) )
from ._constants import _XMIN, _EULER, _ZETA3, _XMAX, _LOGXMAX, _EPS from ._constants import _XMIN, _EULER, _ZETA3, _XMAX, _LOGXMAX, _EPS
@ -89,24 +89,16 @@ def _norm_logpdf(x):
return -x**2 / 2.0 - _norm_pdf_logC return -x**2 / 2.0 - _norm_pdf_logC
def _norm_cdf(x):
return special.ndtr(x)
def _norm_logcdf(x):
return special.log_ndtr(x)
def _norm_ppf(q): def _norm_ppf(q):
return special.ndtri(q) return special.ndtri(q)
def _norm_sf(x): def _norm_sf(x):
return special.ndtr(-x) return _norm_cdf(-x)
def _norm_logsf(x): def _norm_logsf(x):
return special.log_ndtr(-x) return _norm_logcdf(-x)
def _norm_isf(q): def _norm_isf(q):
@ -127,6 +119,10 @@ class norm_gen(rv_continuous):
norm.pdf(x) = exp(-x**2/2)/sqrt(2*pi) norm.pdf(x) = exp(-x**2/2)/sqrt(2*pi)
The survival function, ``norm.sf``, is also referred to as the
Q-function in some contexts (see, e.g.,
`Wikipedia's <https://en.wikipedia.org/wiki/Q-function>`_ definition).
%(after_notes)s %(after_notes)s
%(example)s %(example)s
@ -220,13 +216,13 @@ class alpha_gen(rv_continuous):
""" """
def _pdf(self, x, a): def _pdf(self, x, a):
return 1.0/(x**2)/special.ndtr(a)*_norm_pdf(a-1.0/x) return 1.0/(x**2)/_norm_cdf(a)*_norm_pdf(a-1.0/x)
def _logpdf(self, x, a): def _logpdf(self, x, a):
return -2*log(x) + _norm_logpdf(a-1.0/x) - log(special.ndtr(a)) return -2*log(x) + _norm_logpdf(a-1.0/x) - log(_norm_cdf(a))
def _cdf(self, x, a): def _cdf(self, x, a):
return special.ndtr(a-1.0/x) / special.ndtr(a) return _norm_cdf(a-1.0/x) / _norm_cdf(a)
def _ppf(self, q, a): def _ppf(self, q, a):
return 1.0/asarray(a-special.ndtri(q*special.ndtr(a))) return 1.0/asarray(a-special.ndtri(q*special.ndtr(a)))
@ -1221,12 +1217,12 @@ class exponnorm_gen(rv_continuous):
def _cdf(self, x, K): def _cdf(self, x, K):
invK = 1.0 / K invK = 1.0 / K
expval = invK * (0.5 * invK - x) expval = invK * (0.5 * invK - x)
return special.ndtr(x) - exp(expval) * special.ndtr(x - invK) return _norm_cdf(x) - exp(expval) * _norm_cdf(x - invK)
def _sf(self, x, K): def _sf(self, x, K):
invK = 1.0 / K invK = 1.0 / K
expval = invK * (0.5 * invK - x) expval = invK * (0.5 * invK - x)
return special.ndtr(-x) + exp(expval) * special.ndtr(x - invK) return _norm_cdf(-x) + exp(expval) * _norm_cdf(x - invK)
def _stats(self, K): def _stats(self, K):
K2 = K * K K2 = K * K
@ -1366,7 +1362,7 @@ class fatiguelife_gen(rv_continuous):
0.5*(log(2*pi) + 3*log(x))) 0.5*(log(2*pi) + 3*log(x)))
def _cdf(self, x, c): def _cdf(self, x, c):
return special.ndtr(1.0 / c * (sqrt(x) - 1.0/sqrt(x))) return _norm_cdf(1.0 / c * (sqrt(x) - 1.0/sqrt(x)))
def _ppf(self, q, c): def _ppf(self, q, c):
tmp = c*special.ndtri(q) tmp = c*special.ndtri(q)
@ -1545,7 +1541,7 @@ class foldnorm_gen(rv_continuous):
return _norm_pdf(x + c) + _norm_pdf(x-c) return _norm_pdf(x + c) + _norm_pdf(x-c)
def _cdf(self, x, c): def _cdf(self, x, c):
return special.ndtr(x-c) + special.ndtr(x+c) - 1.0 return _norm_cdf(x-c) + _norm_cdf(x+c) - 1.0
def _stats(self, c): def _stats(self, c):
# Regina C. Elandt, Technometrics 3, 551 (1961) # Regina C. Elandt, Technometrics 3, 551 (1961)
@ -2061,6 +2057,13 @@ class genextreme_gen(rv_continuous):
return _lazywhere((x == x) & (c != 0), (x, c), return _lazywhere((x == x) & (c != 0), (x, c),
lambda x, c: -expm1(-c * x) / c, x) lambda x, c: -expm1(-c * x) / c, x)
def _isf(self, q, c):
x = -log(-special.log1p(-q))
result = _lazywhere((c == 0)*(x == x), (x, c),
f=lambda x, c: x,
f2=lambda x, c: -special.expm1(-c*x)/c)
return result
def _stats(self, c): def _stats(self, c):
g = lambda n: gam(n*c+1) g = lambda n: gam(n*c+1)
g1 = g(1) g1 = g(1)
@ -2087,16 +2090,6 @@ class genextreme_gen(rv_continuous):
ku = where(abs(c) <= (eps)**0.23, 12.0/5.0, ku1-3.0) ku = where(abs(c) <= (eps)**0.23, 12.0/5.0, ku1-3.0)
return m, v, sk, ku return m, v, sk, ku
def _munp(self, n, c):
k = arange(0, n+1)
vals = 1.0/c**n * np.sum(
comb(n, k) * (-1)**k * special.gamma(c*k + 1),
axis=0)
return where(c*n > -1, vals, inf)
def _entropy(self, c):
return _EULER*(1 - c) + 1
def _fitstart(self, data): def _fitstart(self, data):
d = asarray(data) d = asarray(data)
# Probability weighted moments # Probability weighted moments
@ -2114,6 +2107,17 @@ class genextreme_gen(rv_continuous):
(exp(gamln(1 + shape)) * (1 - 2 ** (-shape))) (exp(gamln(1 + shape)) * (1 - 2 ** (-shape)))
loc = b0 + scale * (expm1(gamln(1 + shape))) / shape loc = b0 + scale * (expm1(gamln(1 + shape))) / shape
return shape, loc, scale return shape, loc, scale
def _munp(self, n, c):
k = arange(0, n+1)
vals = 1.0/c**n * np.sum(
comb(n, k) * (-1)**k * special.gamma(c*k + 1),
axis=0)
return where(c*n > -1, vals, inf)
def _entropy(self, c):
return _EULER*(1 - c) + 1
genextreme = genextreme_gen(name='genextreme') genextreme = genextreme_gen(name='genextreme')
@ -2695,7 +2699,7 @@ class halfnorm_gen(rv_continuous):
return 0.5 * np.log(2.0/pi) - x*x/2.0 return 0.5 * np.log(2.0/pi) - x*x/2.0
def _cdf(self, x): def _cdf(self, x):
return special.ndtr(x)*2-1.0 return _norm_cdf(x)*2-1.0
def _ppf(self, q): def _ppf(self, q):
return special.ndtri((1+q)/2.0) return special.ndtri((1+q)/2.0)
@ -2852,7 +2856,7 @@ class invgauss_gen(rv_continuous):
%(after_notes)s %(after_notes)s
When `mu` is too small, evaluating the cumulative density function will be When `mu` is too small, evaluating the cumulative distribution function will be
inaccurate due to ``cdf(mu -> 0) = inf * 0``. inaccurate due to ``cdf(mu -> 0) = inf * 0``.
NaNs are returned for ``mu <= 0.0028``. NaNs are returned for ``mu <= 0.0028``.
@ -3348,9 +3352,18 @@ class lognorm_gen(rv_continuous):
def _cdf(self, x, s): def _cdf(self, x, s):
return _norm_cdf(log(x) / s) return _norm_cdf(log(x) / s)
def _logcdf(self, x, s):
return _norm_logcdf(log(x) / s)
def _ppf(self, q, s): def _ppf(self, q, s):
return exp(s * _norm_ppf(q)) return exp(s * _norm_ppf(q))
def _sf(self, x, s):
return _norm_sf(log(x) / s)
def _logsf(self, x, s):
return _norm_logsf(log(x) / s)
def _stats(self, s): def _stats(self, s):
p = exp(s*s) p = exp(s*s)
mu = sqrt(p) mu = sqrt(p)
@ -4546,13 +4559,13 @@ class skew_norm_gen(rv_continuous):
Notes Notes
----- -----
The pdf is The pdf is::
skewnorm.pdf(x, a) = 2*norm.pdf(x)*norm.cdf(ax) skewnorm.pdf(x, a) = 2*norm.pdf(x)*norm.cdf(ax)
`skewnorm` takes ``a`` as a skewness parameter `skewnorm` takes ``a`` as a skewness parameter
When a=0 the distribution is identical to a normal distribution. When a=0 the distribution is identical to a normal distribution.
rvs implements the method of [1]. rvs implements the method of [1]_.
%(after_notes)s %(after_notes)s
@ -4562,7 +4575,7 @@ class skew_norm_gen(rv_continuous):
References References
---------- ----------
[1] A. Azzalini and A. Capitanio (1999). Statistical applications of the .. [1] A. Azzalini and A. Capitanio (1999). Statistical applications of the
multivariate skew-normal distribution. J. Roy. Statist. Soc., B 61, 579-602. multivariate skew-normal distribution. J. Roy. Statist. Soc., B 61, 579-602.
http://azzalini.stat.unipd.it/SN/faq-r.html http://azzalini.stat.unipd.it/SN/faq-r.html
""" """
@ -4597,6 +4610,56 @@ class skew_norm_gen(rv_continuous):
skewnorm = skew_norm_gen(name='skewnorm') skewnorm = skew_norm_gen(name='skewnorm')
class trapz_gen(rv_continuous):
"""A trapezoidal continuous random variable.
%(before_notes)s
Notes
-----
The trapezoidal distribution can be represented with an up-sloping line
from ``loc`` to ``(loc + c*scale)``, then constant to ``(loc + d*scale)``
and then downsloping from ``(loc + d*scale)`` to ``(loc+scale)``.
`trapz` takes ``c`` and ``d`` as shape parameters.
%(after_notes)s
The standard form is in the range [0, 1] with c the mode.
The location parameter shifts the start to `loc`.
The scale parameter changes the width from 1 to `scale`.
%(example)s
"""
def _argcheck(self, c, d):
return (c >= 0) & (c <= 1) & (d >= 0) & (d <= 1) & (d >= c)
def _pdf(self, x, c, d):
u = 2 / (d - c + 1)
condlist = [x < c, x <= d, x > d]
choicelist = [u * x / c, u, u * (1 - x) / (1 - d)]
return np.select(condlist, choicelist)
def _cdf(self, x, c, d):
condlist = [x < c, x <= d, x > d]
choicelist = [x**2 / c / (d - c + 1),
(c + 2 * (x - c)) / (d - c + 1),
1 - ((1 - x)**2 / (d - c + 1) / (1 - d))]
return np.select(condlist, choicelist)
def _ppf(self, q, c, d):
qc, qd = self._cdf(c, c, d), self._cdf(d, c, d)
condlist = [q < qc, q <= qd, q > qd]
choicelist = [np.sqrt(q * c * (1 + d - c)),
0.5 * q * (1 + d - c) + 0.5 * c,
1 - sqrt((1 - q) * (d - c + 1) * (1 - d))]
return np.select(condlist, choicelist)
trapz = trapz_gen(a=0.0, b=1.0, name="trapz")
class triang_gen(rv_continuous): class triang_gen(rv_continuous):
"""A triangular continuous random variable. """A triangular continuous random variable.
@ -4868,13 +4931,17 @@ class vonmises_gen(rv_continuous):
return self._random_state.vonmises(0.0, kappa, size=self._size) return self._random_state.vonmises(0.0, kappa, size=self._size)
def _pdf(self, x, kappa): def _pdf(self, x, kappa):
return exp(kappa * cos(x)) / (2*pi*special.i0(kappa)) return exp(kappa * cos(x)) / (2*pi*i0(kappa))
def _cdf(self, x, kappa): def _cdf(self, x, kappa):
return vonmises_cython.von_mises_cdf(kappa, x) return vonmises_cython.von_mises_cdf(kappa, x)
def _stats_skip(self, kappa): def _stats_skip(self, kappa):
return 0, None, 0, None return 0, None, 0, None
def _entropy(self, kappa):
return (-kappa * i1(kappa) / i0(kappa)
+ np.log(2 * np.pi * i0(kappa)))
vonmises = vonmises_gen(name='vonmises') vonmises = vonmises_gen(name='vonmises')
vonmises_line = vonmises_gen(a=-np.pi, b=np.pi, name='vonmises_line') vonmises_line = vonmises_gen(a=-np.pi, b=np.pi, name='vonmises_line')

Loading…
Cancel
Save