Skip to content

Commit

Permalink
BUG: stats: Non-central Fisher distribution (fix nan-values when nc=0) (
Browse files Browse the repository at this point in the history
scipy#11667)

* Test for edge case described in scipygh-11660
* ncf_gen docstring updated
* Description of the non-central F-distribution corrected
* Fixes scipygh-11660
  • Loading branch information
scidam authored Mar 29, 2020
1 parent 1150c4c commit f9215eb
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 5 deletions.
8 changes: 5 additions & 3 deletions doc/source/tutorial/stats/continuous_ncf.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ Noncentral F Distribution
=========================

The distribution of :math:`\left(X_{1}/X_{2}\right)\left(\nu_{2}/\nu_{1}\right)`
if :math:`X_{1}` is non-central chi-squared with :math:`v_{1}` degrees of freedom
and parameter :math:`\lambda`, and :math:`X_{2}` is chi-squared with :math:`v_{2}` degrees of freedom.
if :math:`X_{1}` is non-central chi-squared with :math:`\nu_{1}` degrees of freedom
and parameter :math:`\lambda`, and :math:`X_{2}` is chi-squared with :math:`\nu_{2}` degrees of freedom.

There are 3 shape parameters: the degrees of freedom :math:`\nu_{1}>0` and :math:`\nu_{2}>0`; and :math:`\lambda>0`.
There are 3 shape parameters: the degrees of freedom :math:`\nu_{1}>0` and :math:`\nu_{2}>0`; and :math:`\lambda\geq 0`.


.. math::
Expand All @@ -19,4 +19,6 @@ There are 3 shape parameters: the degrees of freedom :math:`\nu_{1}>0` and :math
where :math:`L_{\nu_{2}/2}^{\nu_{1}/2-1}(x)` is an associated Laguerre polynomial.

If :math:`\lambda=0`, the distribution becomes equivalent to the Fisher distribution with :math:`\nu_{1}` and :math:`\nu_{2}` degrees of freedom.

Implementation: `scipy.stats.ncf`
12 changes: 10 additions & 2 deletions scipy/stats/_continuous_distns.py
Original file line number Diff line number Diff line change
Expand Up @@ -5748,19 +5748,27 @@ class ncf_gen(rv_continuous):
(-\lambda v_1 \frac{x}{2(v_1 x+v_2)})}
{B(v_1/2, v_2/2) \gamma(\frac{v_1+v_2}{2})}
for :math:`n_1 > 1`, :math:`n_2, \lambda > 0`. Here :math:`n_1` is the
for :math:`n_1, n_2 > 0`, :math:`\lambda\geq 0`. Here :math:`n_1` is the
degrees of freedom in the numerator, :math:`n_2` the degrees of freedom in
the denominator, :math:`\lambda` the non-centrality parameter,
:math:`\gamma` is the logarithm of the Gamma function, :math:`L_n^k` is a
generalized Laguerre polynomial and :math:`B` is the beta function.
`ncf` takes ``df1``, ``df2`` and ``nc`` as shape parameters.
`ncf` takes ``df1``, ``df2`` and ``nc`` as shape parameters. If ``nc=0``,
the distribution becomes equivalent to the Fisher distribution.
%(after_notes)s
See Also
--------
scipy.stats.f : Fisher distribution
%(example)s
"""
def _argcheck(self, df1, df2, nc):
return (df1 > 0) & (df2 > 0) & (nc >= 0)

def _rvs(self, dfn, dfd, nc):
return self._random_state.noncentral_f(dfn, dfd, nc, self._size)

Expand Down
22 changes: 22 additions & 0 deletions scipy/stats/tests/test_distributions.py
Original file line number Diff line number Diff line change
Expand Up @@ -4145,6 +4145,28 @@ def test_crystalball_function_moments():
assert_allclose(expected_5th_moment, calculated_5th_moment, rtol=0.001)


@pytest.mark.parametrize(
'df1,df2,x',
[(2, 2, [-0.5, 0.2, 1.0, 2.3]),
(4, 11, [-0.5, 0.2, 1.0, 2.3]),
(7, 17, [1, 2, 3, 4, 5])]
)
def test_ncf_edge_case(df1, df2, x):
# Test for edge case described in gh-11660.
# Non-central Fisher distribution when nc = 0
# should be the same as Fisher distribution.
nc = 0
expected_cdf = stats.f.cdf(x, df1, df2)
calculated_cdf = stats.ncf.cdf(x, df1, df2, nc)
assert_allclose(expected_cdf, calculated_cdf, rtol=1e-14)

# when ncf_gen._skip_pdf will be used instead of generic pdf,
# this additional test will be useful.
expected_pdf = stats.f.pdf(x, df1, df2)
calculated_pdf = stats.ncf.pdf(x, df1, df2, nc)
assert_allclose(expected_pdf, calculated_pdf, rtol=1e-6)


def test_ncf_variance():
# Regression test for gh-10658 (incorrect variance formula for ncf).
# The correct value of ncf.var(2, 6, 4), 42.75, can be verified with, for
Expand Down

0 comments on commit f9215eb

Please sign in to comment.