You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
155 lines
5.2 KiB
Python
155 lines
5.2 KiB
Python
from __future__ import division, print_function, absolute_import
|
|
|
|
import inspect
|
|
import warnings
|
|
|
|
import numpy as np
|
|
import numpy.testing as npt
|
|
|
|
from scipy.lib._version import NumpyVersion
|
|
from wafo import stats
|
|
|
|
|
|
NUMPY_BELOW_1_7 = NumpyVersion(np.__version__) < '1.7.0'
|
|
|
|
|
|
def check_normalization(distfn, args, distname):
|
|
norm_moment = distfn.moment(0, *args)
|
|
npt.assert_allclose(norm_moment, 1.0)
|
|
|
|
# this is a temporary plug: either ncf or expect is problematic;
|
|
# best be marked as a knownfail, but I've no clue how to do it.
|
|
if distname == "ncf":
|
|
atol, rtol = 1e-5, 0
|
|
else:
|
|
atol, rtol = 1e-7, 1e-7
|
|
|
|
normalization_expect = distfn.expect(lambda x: 1, args=args)
|
|
npt.assert_allclose(normalization_expect, 1.0, atol=atol, rtol=rtol,
|
|
err_msg=distname, verbose=True)
|
|
|
|
normalization_cdf = distfn.cdf(distfn.b, *args)
|
|
npt.assert_allclose(normalization_cdf, 1.0)
|
|
|
|
|
|
def check_moment(distfn, arg, m, v, msg):
|
|
m1 = distfn.moment(1, *arg)
|
|
m2 = distfn.moment(2, *arg)
|
|
if not np.isinf(m):
|
|
npt.assert_almost_equal(m1, m, decimal=10, err_msg=msg +
|
|
' - 1st moment')
|
|
else: # or np.isnan(m1),
|
|
npt.assert_(np.isinf(m1),
|
|
msg + ' - 1st moment -infinite, m1=%s' % str(m1))
|
|
|
|
if not np.isinf(v):
|
|
npt.assert_almost_equal(m2 - m1 * m1, v, decimal=10, err_msg=msg +
|
|
' - 2ndt moment')
|
|
else: # or np.isnan(m2),
|
|
npt.assert_(np.isinf(m2),
|
|
msg + ' - 2nd moment -infinite, m2=%s' % str(m2))
|
|
|
|
|
|
def check_mean_expect(distfn, arg, m, msg):
|
|
if np.isfinite(m):
|
|
m1 = distfn.expect(lambda x: x, arg)
|
|
npt.assert_almost_equal(m1, m, decimal=5, err_msg=msg +
|
|
' - 1st moment (expect)')
|
|
|
|
|
|
def check_var_expect(distfn, arg, m, v, msg):
|
|
if np.isfinite(v):
|
|
m2 = distfn.expect(lambda x: x*x, arg)
|
|
npt.assert_almost_equal(m2, v + m*m, decimal=5, err_msg=msg +
|
|
' - 2st moment (expect)')
|
|
|
|
|
|
def check_skew_expect(distfn, arg, m, v, s, msg):
|
|
if np.isfinite(s):
|
|
m3e = distfn.expect(lambda x: np.power(x-m, 3), arg)
|
|
npt.assert_almost_equal(m3e, s * np.power(v, 1.5),
|
|
decimal=5, err_msg=msg + ' - skew')
|
|
else:
|
|
npt.assert_(np.isnan(s))
|
|
|
|
|
|
def check_kurt_expect(distfn, arg, m, v, k, msg):
|
|
if np.isfinite(k):
|
|
m4e = distfn.expect(lambda x: np.power(x-m, 4), arg)
|
|
npt.assert_allclose(m4e, (k + 3.) * np.power(v, 2), atol=1e-5, rtol=1e-5,
|
|
err_msg=msg + ' - kurtosis')
|
|
else:
|
|
npt.assert_(np.isnan(k))
|
|
|
|
|
|
def check_entropy(distfn, arg, msg):
|
|
ent = distfn.entropy(*arg)
|
|
npt.assert_(not np.isnan(ent), msg + 'test Entropy is nan')
|
|
|
|
|
|
def check_private_entropy(distfn, args, superclass):
|
|
# compare a generic _entropy with the distribution-specific implementation
|
|
npt.assert_allclose(distfn._entropy(*args),
|
|
superclass._entropy(distfn, *args))
|
|
|
|
|
|
def check_edge_support(distfn, args):
|
|
# Make sure the x=self.a and self.b are handled correctly.
|
|
x = [distfn.a, distfn.b]
|
|
if isinstance(distfn, stats.rv_continuous):
|
|
npt.assert_equal(distfn.cdf(x, *args), [0.0, 1.0])
|
|
npt.assert_equal(distfn.logcdf(x, *args), [-np.inf, 0.0])
|
|
|
|
npt.assert_equal(distfn.sf(x, *args), [1.0, 0.0])
|
|
npt.assert_equal(distfn.logsf(x, *args), [0.0, -np.inf])
|
|
|
|
if isinstance(distfn, stats.rv_discrete):
|
|
x = [distfn.a-1, distfn.b]
|
|
npt.assert_equal(distfn.ppf([0.0, 1.0], *args), x)
|
|
npt.assert_equal(distfn.isf([0.0, 1.0], *args), x[::-1])
|
|
|
|
# out-of-bounds for isf & ppf
|
|
npt.assert_(np.isnan(distfn.isf([-1, 2], *args)).all())
|
|
npt.assert_(np.isnan(distfn.ppf([-1, 2], *args)).all())
|
|
|
|
|
|
def check_named_args(distfn, x, shape_args, defaults, meths):
|
|
## Check calling w/ named arguments.
|
|
|
|
# check consistency of shapes, numargs and _parse signature
|
|
signature = inspect.getargspec(distfn._parse_args)
|
|
npt.assert_(signature.varargs is None)
|
|
npt.assert_(signature.keywords is None)
|
|
npt.assert_(signature.defaults == defaults)
|
|
|
|
shape_argnames = signature.args[1:-len(defaults)] # self, a, b, loc=0, scale=1
|
|
if distfn.shapes:
|
|
shapes_ = distfn.shapes.replace(',', ' ').split()
|
|
else:
|
|
shapes_ = ''
|
|
npt.assert_(len(shapes_) == distfn.numargs)
|
|
npt.assert_(len(shapes_) == len(shape_argnames))
|
|
|
|
# check calling w/ named arguments
|
|
shape_args = list(shape_args)
|
|
|
|
vals = [meth(x, *shape_args) for meth in meths]
|
|
npt.assert_(np.all(np.isfinite(vals)))
|
|
|
|
names, a, k = shape_argnames[:], shape_args[:], {}
|
|
while names:
|
|
k.update({names.pop(): a.pop()})
|
|
v = [meth(x, *a, **k) for meth in meths]
|
|
npt.assert_array_equal(vals, v)
|
|
if 'n' not in k.keys():
|
|
# `n` is first parameter of moment(), so can't be used as named arg
|
|
with warnings.catch_warnings():
|
|
warnings.simplefilter("ignore", UserWarning)
|
|
npt.assert_equal(distfn.moment(1, *a, **k),
|
|
distfn.moment(1, *shape_args))
|
|
|
|
# unknown arguments should not go through:
|
|
k.update({'kaboom': 42})
|
|
npt.assert_raises(TypeError, distfn.cdf, x, **k)
|
|
|