Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Make docstring examples in stats.distributions docstrings runnable #3207

Merged
merged 9 commits into from

5 participants

@ev-br
Collaborator

closes gh-2106.

I've tweaked the default example a bit: removed the semilog plot of cdf-ppf roundtrip (cf gh-1946), and replaced it with an example from the test suite. Tried adding an example of using the named arguments, but did not manage to convince the doccer to respect indentation. The resulting example is definitely not perfect, but at least it is valid python.

For the moment I'm leaving a slew of commits as is, would be happy to squash them away if there are strong opinions.

@rgommers
Owner

Thanks for doing this! The approach looks good to me. Will have a closer look later.

@coveralls

Coverage Status

Changes Unknown when pulling 50a3815 on ev-br:stats_distr_examples into ** on scipy:master**.

@coveralls

Coverage Status

Changes Unknown when pulling 50a3815 on ev-br:stats_distr_examples into ** on scipy:master**.

@ev-br
Collaborator

Pushed a small tweak to avoid test failures with python -OO (who would do that anyway).
A couple of random remarks:

  • turning the semilog comparison into an assertion for a range of x values (eg 7127781) seems to smoke out a bunch of numerical problems with some distributions. Will investigate separately.
  • gh-2064 is still relevant, is not addressed in this PR. At least this arg1, arg2, arg3 line (shudder). Technically, it's possible to just .replace this line, the same way it's done for the scale parameter (at least twice in different places).
  • docstring generation seems to be a bit more fragile than I naively hoped for. The docstring is assembled from individual pieces into a single template at the module level, and adding/removing bits in the distribution constructors fails in strange ways sometimes which I failed to figure out properly. (eg ev-br@b9d7bd8#diff-15a69deb9bb3f587270cbce8186b4465L703, removed in b9d7bd8)
  • given the number of templating engines out there, I wonder if it'd make sense to switch to one of them. If there's one mature enough, robust enough and lightweight enough, maybe we can use it for other code generation tasks as well.
@rgommers
Owner

No sane person should use -OO indeed. However it is used sometimes anyway, and we added the tests in TravisCI after learning that there is one web framework (forgot which one) that does this by default.

@rgommers
Owner

Re templating engines - do you mean at runtime, or at install time?

@ev-br
Collaborator

Templating engines: for stats docstrings it's runtime (and you're familiar with this waaay more than I am). And if there's a runtime dependency, we could stick to it for build/install time as well.

Now that I think of this, is there a way of generating docstrings at build time, hmm...

@rgommers
Owner

The most commonly used/recommended templating engine for this type of stuff (and Cython) is http://pythonpaste.org/tempita/. It can do both run-time and build-time. If done at build time the output will be very long, would need to hide that somehow.

@ev-br
Collaborator

@rgommers Thanks for the pointer!
At the moment we have cython as a build time dependency only, is this correct? Are there any other places in scipy where using tempita at runtime is warranted? I mean, requiring an extra dependency just for stats docstrings sounds a bit too much.

@argriffing
Collaborator

According to the internet, cython itself uses tempita and embeds it. So if it would be used at runtime in scipy it would probably be embedded as opposed to something that a user would have to install as a dependency. https://github.com/cython/cython/tree/master/Cython/Tempita

@rgommers
Owner

Indeed no external dependency wanted for this. Either way (run/build-time) we should bundle it I think.

@rgommers
Owner

@ev-br did you want to look into the templating engine for this PR, or later? Guess it makes sense to review and merge this first?

@rgommers
Owner

Some more thoughts on vendoring:

  • Cython is only a build-time dependency for unreleased versions, not for the source releases on SF/PyPi.
  • Bundling a templating engine should not be a problem (much less issues than the next Fortran lib to be included will give).
@ev-br
Collaborator

@rgommers I think this can be reviewed as is. It's still an improvement which I think is worth having in 0.14.

Re templating: tempita indeed looks exactly right; what I'm concerned is import time. import scipy.stats already takes ages, and increasing this does not look good. If all docstrings are generated at build time, they'll need to be stored somewhere; and if it's a separate file, load time can be an issue again... Unless we go down the rabbit hole and actually turn the distributions code into a template to be run at build time (what does the experience with numpy *.c.src files tell?).
Not this PR at any rate :-).

One hopefully simpler thing which I did not figure out is whether it's possible to make sphinx generate the web docs for the methods of instances. I mean, the docstring of norm.pdf does not make it to the website. Again, this is not necessary something for this PR.

@rgommers
Owner

All docstrings are currently already generated at import time, so whatever we do it's unlikely to make import significantly slower.

.c.src files work fine, I can't remember any problems with it over the past few years.

scipy/stats/_discrete_distns.py
((6 lines not shown))
>>> rv = hypergeom(M, n, N)
>>> x = np.arange(0, n+1)
>>> pmf_dogs = rv.pmf(x)
- >>> fig = plt.figure()
- >>> ax = fig.add_subplot(111)
- >>> ax.plot(x, pmf_dogs, 'bo')
- >>> ax.vlines(x, 0, pmf_dogs, lw=2)
- >>> ax.set_xlabel('# of dogs in our group of chosen animals')
- >>> ax.set_ylabel('hypergeom PMF')
+ >>> plt.plot(x, pmf_dogs, 'bo')
+ >>> plt.vlines(x, 0, pmf_dogs, lw=2)
+ >>> plt.set_xlabel('# of dogs in our group of chosen animals')
+ >>> plt.set_ylabel('hypergeom PMF')
@rgommers Owner
rgommers added a note

OK to make it 2 lines shorter I think, even though the old version is more idiomatic use of MPL.

@ev-br Collaborator
ev-br added a note

Agree the original was better, but this version is shorter --- do you you want me to roll this change back?

Sorry for the comments from the peanut gallery. As a mpl developer, I think the original version is much better. If you want to shorten it, use fig, ax = plt.subplots(1, 1) instead of relying on the state-machine magic.

@ev-br Collaborator
ev-br added a note

OK, here I stand corrected. Will undo the change. What's the recommended idiom these days, fig, ax = plt.subplots(1, 1) or just fig, ax = plt.subplots()?

I prefer the (1, 1) version (explicit is better than implicit). The no-arg call is too magical.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
scipy/stats/_distn_infrastructure.py
((7 lines not shown))
-Display frozen pdf
+Calculate a few first moments:
+%(set_vals_stmt)s
+>>> mean, var, skew, kurt = %(name)s.stats(%(shapes)s, moments='mvsk')
+
+Display the probability density function (``pdf``):
+
+>>> x = np.linspace(np.maximum(0, %(name)s.a),
@rgommers Owner
rgommers added a note

Why 0 and not -3? The latter would plot symmetric distributions in a more familiar way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@rgommers
Owner

Overall looks good. I fixed some issues in rgommers@431da70, and a bug hat turned up when running the examples in rgommers@c44d500. Could you cherry-pick those?

With that first commit the figures generated by the examples actually show up in the html docs, which is nice to have. unfortunately the import matplotlib.pyplot as plt (which is required to make it actually runnable) now pops up all figures when running the tests you added. Is there actually value in running those tests now? Any breakage shows up very verbosely in the doc build output.

@ev-br
Collaborator

Cherry-picked your changes, rebased, tweaked the plots a bit further, and pushed the result.

The example might need a further tweak, to make it a bit more terse (will do).

Ultimately though, I don't think that using import matplotlib.pyplot as plt is the right thing to do, because:

Is there a way of controlling the namespace when building the docs? In tests, it's easy to have an environment variable to control the namespace where the docstrings are run: eg if SCIPY_USE_MPL_IN_DOCSTRINGS is set, use actual matplotlib, otherwise stub it. This works in tests, but will it work for Sphinx?

@rgommers
Owner

It doesn't bloat the examples by more than one line. We don't need to show the matplotlib return values, that has no value. Note that we add this import in examples all over the place, it's the way you get plots into the built docs. This trumps the examples being doctest-able - doctests are simply not part of the test suite. Given that doctest is god-awful and you and up with all sorts of #+SKIP-DOCTEST like comments in your docstrings to make it happy on all platforms, I'd like to keep it that way.

@rgommers
Owner

It's probably possible to do something smarter by modifying the Sphinx' plot_directive plugin for example, but I'm not sure it's worth the effort.

EDIT: if the goal is just to take out the line from the examples, why not. We do the same for import numpy as np. So should be easy.

@ev-br
Collaborator

My objective never was to make the examples doctest-able in all the detail (which is always never worth it, I agree) --- the examples with the plt stub did not compare the output; the doctests were there only to check for syntax errors.

Anyway, it turns out that the result of make html-scipyorg does not have matplotlib output. Which makes my objections moot :-).

So --- do you want me to take the test off? An alternative would be to remove import matplotlib.pyplot as plt line before running the doctest. I'm fine either way.

@ev-br
Collaborator

Re plot_directive: it might be worth it to have a uniform convention for np and plt in all generated code code snippets in the docs. Maybe even tweak the rc settings so that plots are neither too ugly, nor overloaded with matplotlib-specific parameters ('bo', ms=8, lw=4, alpha=0.5). But that's separate.

@ev-br
Collaborator

OK, pushed a rebased version with fewer commits. Addressed comments, removed the doctests, restored the hypergeom example, tweaked the generic examples to produce sensible plots for almost all distributions.

@rgommers
Owner

Ah OK now I see what you meant with ugly MPL output. The examples are always rendered as is, only plots are inserted.

@rgommers
Owner

Re np and plt: there is a convention for these, see https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt. But we agreed before that only the numpy import is implicit, and mpl and scipy module imports have to be made explicit.

@rgommers
Owner

Tweaking default plot styling we could do, that's what pandas and statsmodels do and it looks good.

@rgommers
Owner

OK this looks quite good now. Merging. Thanks Evgeni.

@rgommers rgommers merged commit 9c7017e into from
@ev-br ev-br deleted the branch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Feb 3, 2014
  1. @ev-br
  2. @ev-br
  3. @ev-br
  4. @ev-br
  5. @ev-br
  6. @ev-br

    MAINT: keep python -OO happy

    ev-br authored
  7. @rgommers @ev-br

    DOC: fix issues in stats.distributions docstrings.

    rgommers authored ev-br committed
    Now shows plots of dist.pdf() in generated docs.
  8. @rgommers @ev-br

    BUG: stats.distributions: _drv method was broken.

    rgommers authored ev-br committed
    Observed in doc build output, but apparently not covered by a test.
  9. @ev-br
This page is out of date. Refresh to see the latest.
View
4 scipy/stats/_continuous_distns.py
@@ -2367,7 +2367,7 @@ def _cdf(self, x, a, b):
def _ppf(self, q, a, b):
return 1.0 / (1 + exp(-1.0 / b * (_norm_ppf(q) - a)))
-johnsonsb = johnsonsb_gen(a=0.0, b=1.0, name='johnsonb')
+johnsonsb = johnsonsb_gen(a=0.0, b=1.0, name='johnsonsb')
class johnsonsu_gen(rv_continuous):
@@ -3951,7 +3951,7 @@ class wald_gen(invgauss_gen):
-----
The probability density function for `wald` is::
- wald.pdf(x, a) = 1/sqrt(2*pi*x**3) * exp(-(x-1)**2/(2*x))
+ wald.pdf(x) = 1/sqrt(2*pi*x**3) * exp(-(x-1)**2/(2*x))
for ``x > 0``.
View
1  scipy/stats/_discrete_distns.py
@@ -268,6 +268,7 @@ class hypergeom_gen(rv_discrete):
Examples
--------
>>> from scipy.stats import hypergeom
+ >>> import matplotlib.pyplot as plt
Suppose we have a collection of 20 animals, of which 7 are dogs. Then if
we want to know the probability of finding a given number of dogs if we
View
160 scipy/stats/_distn_infrastructure.py
@@ -13,6 +13,7 @@
import types
from scipy.misc import doccer
+from ._distr_params import distcont, distdiscrete
from scipy.special import comb, xlogy, chndtr, gammaln, hyp0f1
@@ -150,7 +151,7 @@ def instancemethod(func, obj, cls):
# Note that the two lines for %(shapes) are searched for and replaced in
# rv_continuous and rv_discrete - update there if the exact string changes
-_doc_default_callparams = """\
+_doc_default_callparams = """
Parameters
----------
x : array_like
@@ -188,25 +189,41 @@ def instancemethod(func, obj, cls):
Examples
--------
>>> from scipy.stats import %(name)s
->>> numargs = %(name)s.numargs
->>> [ %(shapes)s ] = [0.9,] * numargs
->>> rv = %(name)s(%(shapes)s)
+>>> import matplotlib.pyplot as plt
+>>> fig, ax = plt.subplots(1, 1)
+
+Calculate a few first moments:
+
+%(set_vals_stmt)s
+>>> mean, var, skew, kurt = %(name)s.stats(%(shapes)s, moments='mvsk')
+
+Display the probability density function (``pdf``):
-Display frozen pdf
+>>> x = np.linspace(%(name)s.ppf(0.01, %(shapes)s),
+... %(name)s.ppf(0.99, %(shapes)s), 100)
+>>> ax.plot(x, %(name)s.pdf(x, %(shapes)s),
+... 'r-', lw=5, alpha=0.6, label='%(name)s pdf')
->>> x = np.linspace(0, np.minimum(rv.dist.b, 3))
->>> h = plt.plot(x, rv.pdf(x))
+Alternatively, freeze the distribution and display the frozen pdf:
-Here, ``rv.dist.b`` is the right endpoint of the support of ``rv.dist``.
+>>> rv = %(name)s(%(shapes)s)
+>>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')
+
+Check accuracy of ``cdf`` and ``ppf``:
-Check accuracy of cdf and ppf
+>>> vals = %(name)s.ppf([0.001, 0.5, 0.999], %(shapes)s)
+>>> np.allclose([0.001, 0.5, 0.999], %(name)s.cdf(vals, %(shapes)s))
+True
->>> prb = %(name)s.cdf(x, %(shapes)s)
->>> h = plt.semilogy(np.abs(x - %(name)s.ppf(prb, %(shapes)s)) + 1e-20)
+Generate random numbers:
-Random number generation
+>>> r = %(name)s.rvs(%(shapes)s, size=1000)
->>> R = %(name)s.rvs(%(shapes)s, size=100)
+And compare the histogram:
+
+>>> ax.hist(r, normed=True, histtype='stepfilled', alpha=0.2)
+>>> ax.legend(loc='best', frameon=False)
+>>> plt.show()
"""
_doc_default = ''.join([_doc_default_longsummary,
@@ -283,25 +300,38 @@ def instancemethod(func, obj, cls):
Examples
--------
>>> from scipy.stats import %(name)s
->>> [ %(shapes)s ] = [<Replace with reasonable values>]
->>> rv = %(name)s(%(shapes)s)
+>>> import matplotlib.pyplot as plt
+>>> fig, ax = plt.subplots(1, 1)
-Display frozen pmf
+Calculate a few first moments:
->>> x = np.arange(0, np.minimum(rv.dist.b, 3))
->>> h = plt.vlines(x, 0, rv.pmf(x), lw=2)
+%(set_vals_stmt)s
+>>> mean, var, skew, kurt = %(name)s.stats(%(shapes)s, moments='mvsk')
-Here, ``rv.dist.b`` is the right endpoint of the support of ``rv.dist``.
+Display the probability mass function (``pmf``):
-Check accuracy of cdf and ppf
+>>> x = np.arange(%(name)s.ppf(0.01, %(shapes)s),
+... %(name)s.ppf(0.99, %(shapes)s))
+>>> ax.plot(x, %(name)s.pmf(x, %(shapes)s), 'bo', ms=8, label='%(name)s pmf')
+>>> ax.vlines(x, 0, %(name)s.pmf(x, %(shapes)s), colors='b', lw=5, alpha=0.5)
->>> prb = %(name)s.cdf(x, %(shapes)s)
->>> h = plt.semilogy(np.abs(x - %(name)s.ppf(prb, %(shapes)s)) + 1e-20)
+Alternatively, freeze the distribution and display the frozen ``pmf``:
-Random number generation
+>>> rv = %(name)s(%(shapes)s)
+>>> ax.vlines(x, 0, rv.pmf(x), colors='k', linestyles='-', lw=1,
+... label='frozen pmf')
+>>> ax.legend(loc='best', frameon=False)
+>>> plt.show()
+
+Check accuracy of ``cdf`` and ``ppf``:
->>> R = %(name)s.rvs(%(shapes)s, size=100)
+>>> prob = %(name)s.cdf(x, %(shapes)s)
+>>> np.allclose(x, %(name)s.ppf(prob, %(shapes)s))
+True
+Generate random numbers:
+
+>>> r = %(name)s.rvs(%(shapes)s, size=1000)
"""
docdict_discrete['example'] = _doc_default_discrete_example
@@ -397,10 +427,10 @@ def __init__(self, dist, *args, **kwds):
self.kwds = kwds
# create a new instance
- self.dist = dist.__class__(**dist._ctor_param)
+ self.dist = dist.__class__(**dist._ctor_param)
# a, b may be set in _argcheck, depending on *args, **kwds. Ouch.
- shapes, _, _ = self.dist._parse_args(*args, **kwds)
+ shapes, _, _ = self.dist._parse_args(*args, **kwds)
self.dist._argcheck(*shapes)
def pdf(self, x): # raises AttributeError in frozen discrete distribution
@@ -657,6 +687,36 @@ def _construct_argparser(self, meths_to_inspect, locscale_in, locscale_out):
# allows more general subclassing with *args
self.numargs = len(shapes)
+ def _construct_doc(self, docdict, shapes_vals=None):
+ """Construct the instance docstring with string substitutions."""
+ tempdict = docdict.copy()
+ tempdict['name'] = self.name or 'distname'
+ tempdict['shapes'] = self.shapes or ''
+
+ if shapes_vals is None:
+ shapes_vals = ()
+ vals = ', '.join(str(_) for _ in shapes_vals)
+ tempdict['vals'] = vals
+
+ if self.shapes:
+ tempdict['set_vals_stmt'] = '>>> %s = %s' % (self.shapes, vals)
+ else:
+ tempdict['set_vals_stmt'] = ''
+
+ if self.shapes is None:
+ # remove shapes from call parameters if there are none
+ for item in ['callparams', 'default', 'before_notes']:
+ tempdict[item] = tempdict[item].replace(
+ "\n%(shapes)s : array_like\n shape parameters", "")
+ for i in range(2):
+ if self.shapes is None:
+ # necessary because we use %(shapes)s in two forms (w w/o ", ")
+ self.__doc__ = self.__doc__.replace("%(shapes)s, ", "")
+ self.__doc__ = doccer.docformat(self.__doc__, tempdict)
+
+ # correct for empty shapes
+ self.__doc__ = self.__doc__.replace('(, ', '(').replace(', )', ')')
+
def freeze(self, *args, **kwds):
"""Freeze the distribution for the given arguments.
@@ -1391,7 +1451,8 @@ def __init__(self, momtype=1, a=None, b=None, xtol=1e-14,
self._construct_default_doc(longname=longname,
extradoc=extradoc)
else:
- self._construct_doc()
+ dct = dict(distcont)
+ self._construct_doc(docdict, dct.get(self.name))
def _construct_default_doc(self, longname=None, extradoc=None):
"""Construct instance docstring from the default template."""
@@ -1404,24 +1465,7 @@ def _construct_default_doc(self, longname=None, extradoc=None):
self.__doc__ = ''.join(['%s continuous random variable.' % longname,
'\n\n%(before_notes)s\n', docheaders['notes'],
extradoc, '\n%(example)s'])
- self._construct_doc()
-
- def _construct_doc(self):
- """Construct the instance docstring with string substitutions."""
- tempdict = docdict.copy()
- tempdict['name'] = self.name or 'distname'
- tempdict['shapes'] = self.shapes or ''
-
- if self.shapes is None:
- # remove shapes from call parameters if there are none
- for item in ['callparams', 'default', 'before_notes']:
- tempdict[item] = tempdict[item].replace(
- "\n%(shapes)s : array_like\n shape parameters", "")
- for i in range(2):
- if self.shapes is None:
- # necessary because we use %(shapes)s in two forms (w w/o ", ")
- self.__doc__ = self.__doc__.replace("%(shapes)s, ", "")
- self.__doc__ = doccer.docformat(self.__doc__, tempdict)
+ self._construct_doc(docdict)
def _ppf_to_solve(self, x, q, *args):
return self.cdf(*(x, )+args)-q
@@ -2187,12 +2231,12 @@ def _drv_nonzero(self, k, *args):
def _drv_moment(self, n, *args):
n = asarray(n)
- return sum(self.xk**n[newaxis,...] * self.pk, axis=0)
+ return sum(self.xk**n[np.newaxis,...] * self.pk, axis=0)
def _drv_moment_gen(self, t, *args):
t = asarray(t)
- return sum(exp(self.xk * t[newaxis,...]) * self.pk, axis=0)
+ return sum(exp(self.xk * t[np.newaxis,...]) * self.pk, axis=0)
def _drv2_moment(self, n, *args):
@@ -2611,7 +2655,8 @@ def __init__(self, a=0, b=inf, name=None, badvalue=None,
self._construct_default_doc(longname=longname,
extradoc=extradoc)
else:
- self._construct_doc()
+ dct = dict(distdiscrete)
+ self._construct_doc(docdict_discrete, dct.get(self.name))
#discrete RV do not have the scale parameter, remove it
self.__doc__ = self.__doc__.replace(
@@ -2627,24 +2672,7 @@ def _construct_default_doc(self, longname=None, extradoc=None):
self.__doc__ = ''.join(['%s discrete random variable.' % longname,
'\n\n%(before_notes)s\n', docheaders['notes'],
extradoc, '\n%(example)s'])
- self._construct_doc()
-
- def _construct_doc(self):
- """Construct the instance docstring with string substitutions."""
- tempdict = docdict_discrete.copy()
- tempdict['name'] = self.name or 'distname'
- tempdict['shapes'] = self.shapes or ''
-
- if self.shapes is None:
- # remove shapes from call parameters if there are none
- for item in ['callparams', 'default', 'before_notes']:
- tempdict[item] = tempdict[item].replace(
- "\n%(shapes)s : array_like\n shape parameters", "")
- for i in range(2):
- if self.shapes is None:
- # necessary because we use %(shapes)s in two forms (w w/o ", ")
- self.__doc__ = self.__doc__.replace("%(shapes)s, ", "")
- self.__doc__ = doccer.docformat(self.__doc__, tempdict)
+ self._construct_doc(docdict_discrete)
def _nonzero(self, k, *args):
return floor(k) == k
View
116 scipy/stats/_distr_params.py
@@ -0,0 +1,116 @@
+"""
+Sane parameters for stats.distributions.
+"""
+
+distcont = [
+ ['alpha', (3.5704770516650459,)],
+ ['anglit', ()],
+ ['arcsine', ()],
+ ['beta', (2.3098496451481823, 0.62687954300963677)],
+ ['betaprime', (5, 6)],
+ ['bradford', (0.29891359763170633,)],
+ ['burr', (10.5, 4.3)],
+ ['cauchy', ()],
+ ['chi', (78,)],
+ ['chi2', (55,)],
+ ['cosine', ()],
+ ['dgamma', (1.1023326088288166,)],
+ ['dweibull', (2.0685080649914673,)],
+ ['erlang', (10,)],
+ ['expon', ()],
+ ['exponpow', (2.697119160358469,)],
+ ['exponweib', (2.8923945291034436, 1.9505288745913174)],
+ ['f', (29, 18)],
+ ['fatiguelife', (29,)], # correction numargs = 1
+ ['fisk', (3.0857548622253179,)],
+ ['foldcauchy', (4.7164673455831894,)],
+ ['foldnorm', (1.9521253373555869,)],
+ ['frechet_l', (3.6279911255583239,)],
+ ['frechet_r', (1.8928171603534227,)],
+ ['gamma', (1.9932305483800778,)],
+ ['gausshyper', (13.763771604130699, 3.1189636648681431,
+ 2.5145980350183019, 5.1811649903971615)], # veryslow
+ ['genexpon', (9.1325976465418908, 16.231956600590632, 3.2819552690843983)],
+ ['genextreme', (-0.1,)],
+ ['gengamma', (4.4162385429431925, 3.1193091679242761)],
+ ['genhalflogistic', (0.77274727809929322,)],
+ ['genlogistic', (0.41192440799679475,)],
+ ['genpareto', (0.1,)], # use case with finite moments
+ ['gilbrat', ()],
+ ['gompertz', (0.94743713075105251,)],
+ ['gumbel_l', ()],
+ ['gumbel_r', ()],
+ ['halfcauchy', ()],
+ ['halflogistic', ()],
+ ['halfnorm', ()],
+ ['hypsecant', ()],
+ ['invgamma', (4.0668996136993067,)],
+ ['invgauss', (0.14546264555347513,)],
+ ['invweibull', (10.58,)],
+ ['johnsonsb', (4.3172675099141058, 3.1837781130785063)],
+ ['johnsonsu', (2.554395574161155, 2.2482281679651965)],
+ ['ksone', (1000,)], # replace 22 by 100 to avoid failing range, ticket 956
+ ['kstwobign', ()],
+ ['laplace', ()],
+ ['levy', ()],
+ ['levy_l', ()],
+ ['levy_stable', (0.35667405469844993,
+ -0.67450531578494011)], #NotImplementedError
+ # rvs not tested
+ ['loggamma', (0.41411931826052117,)],
+ ['logistic', ()],
+ ['loglaplace', (3.2505926592051435,)],
+ ['lognorm', (0.95368226960575331,)],
+ ['lomax', (1.8771398388773268,)],
+ ['maxwell', ()],
+ ['mielke', (10.4, 3.6)],
+ ['nakagami', (4.9673794866666237,)],
+ ['ncf', (27, 27, 0.41578441799226107)],
+ ['nct', (14, 0.24045031331198066)],
+ ['ncx2', (21, 1.0560465975116415)],
+ ['norm', ()],
+ ['pareto', (2.621716532144454,)],
+ ['pearson3', (0.1,)],
+ ['powerlaw', (1.6591133289905851,)],
+ ['powerlognorm', (2.1413923530064087, 0.44639540782048337)],
+ ['powernorm', (4.4453652254590779,)],
+ ['rayleigh', ()],
+ ['rdist', (0.9,)], # feels also slow
+ ['recipinvgauss', (0.63004267809369119,)],
+ ['reciprocal', (0.0062309367010521255, 1.0062309367010522)],
+ ['rice', (0.7749725210111873,)],
+ ['semicircular', ()],
+ ['t', (2.7433514990818093,)],
+ ['triang', (0.15785029824528218,)],
+ ['truncexpon', (4.6907725456810478,)],
+ ['truncnorm', (-1.0978730080013919, 2.7306754109031979)],
+ ['truncnorm', (0.1, 2.)],
+ ['tukeylambda', (3.1321477856738267,)],
+ ['uniform', ()],
+ ['vonmises', (3.9939042581071398,)],
+ ['vonmises_line', (3.9939042581071398,)],
+ ['wald', ()],
+ ['weibull_max', (2.8687961709100187,)],
+ ['weibull_min', (1.7866166930421596,)],
+ ['wrapcauchy', (0.031071279018614728,)]]
+
+
+distdiscrete = [
+ ['bernoulli',(0.3,)],
+ ['binom', (5, 0.4)],
+ ['boltzmann',(1.4, 19)],
+ ['dlaplace', (0.8,)], # 0.5
+ ['geom', (0.5,)],
+ ['hypergeom',(30, 12, 6)],
+ ['hypergeom',(21,3,12)], # numpy.random (3,18,12) numpy ticket:921
+ ['hypergeom',(21,18,11)], # numpy.random (18,3,11) numpy ticket:921
+ ['logser', (0.6,)], # reenabled, numpy ticket:921
+ ['nbinom', (5, 0.5)],
+ ['nbinom', (0.4, 0.4)], # from tickets: 583
+ ['planck', (0.51,)], # 4.1
+ ['poisson', (0.6,)],
+ ['randint', (7, 31)],
+ ['skellam', (15, 8)],
+ ['zipf', (6.5,)]
+]
+
View
1  scipy/stats/tests/common_tests.py
@@ -151,3 +151,4 @@ def check_named_args(distfn, x, shape_args, defaults, meths):
# unknown arguments should not go through:
k.update({'kaboom': 42})
npt.assert_raises(TypeError, distfn.cdf, x, **k)
+
View
100 scipy/stats/tests/test_continuous_basic.py
@@ -12,6 +12,8 @@
check_entropy, check_private_entropy, NUMPY_BELOW_1_7,
check_edge_support, check_named_args)
+from scipy.stats._distr_params import distcont
+
"""
Test all continuous distributions.
@@ -25,98 +27,6 @@
DECIMAL = 5 # specify the precision of the tests # increased from 0 to 5
-distcont = [
- ['alpha', (3.5704770516650459,)],
- ['anglit', ()],
- ['arcsine', ()],
- ['beta', (2.3098496451481823, 0.62687954300963677)],
- ['betaprime', (5, 6)],
- ['bradford', (0.29891359763170633,)],
- ['burr', (10.5, 4.3)],
- ['cauchy', ()],
- ['chi', (78,)],
- ['chi2', (55,)],
- ['cosine', ()],
- ['dgamma', (1.1023326088288166,)],
- ['dweibull', (2.0685080649914673,)],
- ['erlang', (10,)],
- ['expon', ()],
- ['exponpow', (2.697119160358469,)],
- ['exponweib', (2.8923945291034436, 1.9505288745913174)],
- ['f', (29, 18)],
- ['fatiguelife', (29,)], # correction numargs = 1
- ['fisk', (3.0857548622253179,)],
- ['foldcauchy', (4.7164673455831894,)],
- ['foldnorm', (1.9521253373555869,)],
- ['frechet_l', (3.6279911255583239,)],
- ['frechet_r', (1.8928171603534227,)],
- ['gamma', (1.9932305483800778,)],
- ['gausshyper', (13.763771604130699, 3.1189636648681431,
- 2.5145980350183019, 5.1811649903971615)], # veryslow
- ['genexpon', (9.1325976465418908, 16.231956600590632, 3.2819552690843983)],
- ['genextreme', (-0.1,)],
- ['gengamma', (4.4162385429431925, 3.1193091679242761)],
- ['genhalflogistic', (0.77274727809929322,)],
- ['genlogistic', (0.41192440799679475,)],
- ['genpareto', (0.1,)], # use case with finite moments
- ['gilbrat', ()],
- ['gompertz', (0.94743713075105251,)],
- ['gumbel_l', ()],
- ['gumbel_r', ()],
- ['halfcauchy', ()],
- ['halflogistic', ()],
- ['halfnorm', ()],
- ['hypsecant', ()],
- ['invgamma', (4.0668996136993067,)],
- ['invgauss', (0.14546264555347513,)],
- ['invweibull', (10.58,)],
- ['johnsonsb', (4.3172675099141058, 3.1837781130785063)],
- ['johnsonsu', (2.554395574161155, 2.2482281679651965)],
- ['ksone', (1000,)], # replace 22 by 100 to avoid failing range, ticket 956
- ['kstwobign', ()],
- ['laplace', ()],
- ['levy', ()],
- ['levy_l', ()],
-# ['levy_stable', (0.35667405469844993,
-# -0.67450531578494011)], #NotImplementedError
- # rvs not tested
- ['loggamma', (0.41411931826052117,)],
- ['logistic', ()],
- ['loglaplace', (3.2505926592051435,)],
- ['lognorm', (0.95368226960575331,)],
- ['lomax', (1.8771398388773268,)],
- ['maxwell', ()],
- ['mielke', (10.4, 3.6)],
- ['nakagami', (4.9673794866666237,)],
- ['ncf', (27, 27, 0.41578441799226107)],
- ['nct', (14, 0.24045031331198066)],
- ['ncx2', (21, 1.0560465975116415)],
- ['norm', ()],
- ['pareto', (2.621716532144454,)],
- ['pearson3', (0.1,)],
- ['powerlaw', (1.6591133289905851,)],
- ['powerlognorm', (2.1413923530064087, 0.44639540782048337)],
- ['powernorm', (4.4453652254590779,)],
- ['rayleigh', ()],
- ['rdist', (0.9,)], # feels also slow
- ['recipinvgauss', (0.63004267809369119,)],
- ['reciprocal', (0.0062309367010521255, 1.0062309367010522)],
- ['rice', (0.7749725210111873,)],
- ['semicircular', ()],
- ['t', (2.7433514990818093,)],
- ['triang', (0.15785029824528218,)],
- ['truncexpon', (4.6907725456810478,)],
- ['truncnorm', (-1.0978730080013919, 2.7306754109031979)],
- ['truncnorm', (0.1, 2.)],
- ['tukeylambda', (3.1321477856738267,)],
- ['uniform', ()],
- ['vonmises', (3.9939042581071398,)],
- ['vonmises_line', (3.9939042581071398,)],
- ['wald', ()],
- ['weibull_max', (2.8687961709100187,)],
- ['weibull_min', (1.7866166930421596,)],
- ['wrapcauchy', (0.031071279018614728,)]]
-
## Last four of these fail all around. Need to be checked
distcont_extra = [
['betaprime', (100, 86)],
@@ -185,6 +95,8 @@ def test_cont_basic():
for distname, arg in distcont[:]:
if distname in distslow:
continue
+ if distname is 'levy_stable':
+ continue
distfn = getattr(stats, distname)
np.random.seed(765456)
sn = 500
@@ -237,6 +149,8 @@ def test_cont_basic_slow():
for distname, arg in distcont[:]:
if distname not in distslow:
continue
+ if distname is 'levy_stable':
+ continue
distfn = getattr(stats, distname)
np.random.seed(765456)
sn = 500
@@ -289,6 +203,8 @@ def test_moments():
fail_normalization = set(['vonmises', 'ksone'])
fail_higher = set(['vonmises', 'ksone', 'ncf'])
for distname, arg in distcont[:]:
+ if distname is 'levy_stable':
+ continue
distfn = getattr(stats, distname)
m, v, s, k = distfn.stats(*arg, moments='mvsk')
cond1, cond2 = distname in fail_normalization, distname in fail_higher
View
21 scipy/stats/tests/test_discrete_basic.py
@@ -9,28 +9,9 @@
check_var_expect, check_skew_expect, check_kurt_expect,
check_entropy, check_private_entropy, check_edge_support,
check_named_args)
+from scipy.stats._distr_params import distdiscrete
knf = npt.dec.knownfailureif
-distdiscrete = [
- ['bernoulli',(0.3,)],
- ['binom', (5, 0.4)],
- ['boltzmann',(1.4, 19)],
- ['dlaplace', (0.8,)], # 0.5
- ['geom', (0.5,)],
- ['hypergeom',(30, 12, 6)],
- ['hypergeom',(21,3,12)], # numpy.random (3,18,12) numpy ticket:921
- ['hypergeom',(21,18,11)], # numpy.random (18,3,11) numpy ticket:921
- ['logser', (0.6,)], # reenabled, numpy ticket:921
- ['nbinom', (5, 0.5)],
- ['nbinom', (0.4, 0.4)], # from tickets: 583
- ['planck', (0.51,)], # 4.1
- ['poisson', (0.6,)],
- ['randint', (7, 31)],
- ['skellam', (15, 8)],
- ['zipf', (6.5,)]
-]
-
-
def test_discrete_basic():
for distname, arg in distdiscrete:
distfn = getattr(stats, distname)
View
1  scipy/stats/tests/test_fit.py
@@ -33,6 +33,7 @@
'tukeylambda',
'vonmises',
'wrapcauchy',
+ 'levy_stable'
]
# Don't run the fit test on these:
Something went wrong with that request. Please try again.