Repository: scipy/scipy
File: scipy/special/tests/test_cdflib.py (Python)

Code before:
         (np.nan, np.nan, np.nan)]
    )
    def test_nan_propagation(self, args):
        assert np.isnan(sp.nbdtrin(*args))

    @pytest.mark.parametrize("args",
        [(-1, 1, 1), (1, -1, 1), (1, 1, -1), (-1, -1, 1),
         (-1, 1, -1), (1, -1, -1), (-1, -1, -1),
         (1, 1.1, 0.9), (1, 0.9, 1.1)]
    )  
    def test_domain_error(self, args):
        with sp.errstate(domain="raise"):
            with pytest.raises(sp.SpecialFunctionError, match="domain"):
                sp.nbdtrin(*args)

    @pytest.mark.parametrize(
            "k, y, p, n, rtol",
            [(5, 0.3214569091796875, 0.25, 3, 1e-18),
             (10, 3.820379007878081089302022753626e-70, 0.15, 100, 1e-15),
             (100, 0.97557472292704298255653906603083, 0.15, 10, 1e-14),
             (2, 3.5032532500000018230123192269914e-73, 0.001, 25, 1e-18),
             (2, 0.99999932710299546878804333774717, 0.999, 15, 1e-10),
             (500, 0.99999999986031784927135792193089, 0.1, 15, 1e-8),
             (0, 1.0000000000000005551115123125784e-10, 0.1, 10, 1e-18)])
    def test_inverse_n(self, k, y, p, n, rtol):
        assert_allclose(sp.nbdtrin(k, y, p), n, rtol)

class TestNoncentralChiSquaredFunctions:

    def test_chndtr_and_inverses_against_wolfram_alpha(self):
        # Each row holds (x, nu, lam, expected_value)
        # These values were computed using Wolfram Alpha with
        #     CDF[NoncentralChiSquareDistribution[nu, lam], x]
        values = np.array([
            [25.00, 20.0, 400, 4.1210655112396197139e-57],
            [25.00, 8.00, 250, 2.3988026526832425878e-29],
            [0.001, 8.00, 40., 5.3761806201366039084e-24],
            [0.010, 8.00, 40., 5.45396231055999457039e-20],
            [20.00, 2.00, 107, 1.39390743555819597802e-9],
            [22.50, 2.00, 107, 7.11803307138105870671e-9],
            [25.00, 2.00, 107, 3.11041244829864897313e-8],
            [3.000, 2.00, 1.0, 0.62064365321954362734],
            [350.0, 300., 10., 0.93880128006276407710],
            [100.0, 13.5, 10., 0.99999999650104210949],
            [700.0, 20.0, 400, 0.99999999925680650105],
            [150.0, 13.5, 10., 0.99999999999999983046],
            [160.0, 13.5, 10., 0.99999999999999999518],  # 1.0
        ])
        cdf = sp.chndtr(values[:, 0], values[:, 1], values[:, 2])
        assert_allclose(cdf, values[:, 3], rtol=1e-13)
        # the last two values are very close to 1.0, so we do not

Review comment (suggestion):
We should only use double precision numbers for test values, so could you reduce the number of decimal digits? 

Also, please include the code you used to calculate the reference values.

Code after:
        assert np.isnan(sp.nbdtrin(*args))

    @pytest.mark.parametrize("args",
        [(-1, 1, 1), (1, -1, 1), (1, 1, -1), (-1, -1, 1),
         (-1, 1, -1), (1, -1, -1), (-1, -1, -1),
         (1, 1.1, 0.9), (1, 0.9, 1.1)]
    )  
    def test_domain_error(self, args):
        with sp.errstate(domain="raise"):
            with pytest.raises(sp.SpecialFunctionError, match="domain"):
                sp.nbdtrin(*args)

    @pytest.mark.parametrize(
            "k, y, p, n, rtol",
            [(5, 0.3214569091796875, 0.25, 3, 5e-16),
             (10, 3.820379007878081e-70, 0.15, 100, 1e-15),
             (100, 0.975574722927043, 0.15, 10, 1e-14),
             (2, 3.503253250000002e-73, 0.001, 25, 5e-16),
             (2, 0.9999993271029954, 0.999, 15, 1e-10),
             (500, 0.9999999998603178, 0.1, 15, 1e-8),
             (0, 1.0000000000000006e-10, 0.1, 10, 5e-16)])
    def test_inverse_n(self, k, y, p, n, rtol):
        # The following code was used to generate the values. 
        # import mpmath
        # import scipy
        # mpmath.mp.dps = 1000

        # def neg_binomial_cdf(k, n, p):
        #     return mpmath.betainc(n, k+1, x1=0, x2=p, regularized=True)
        # n = 3
        # p = 0.25
        # k = 5
        # cdf = neg_binomial_cdf(k, n, p)
        # print("y = ", float(cdf))
        # nval = (scipy.special.nbdtrin(k, float(cdf), p))
        # print("Relative Error:", (n - nval) / n)

        assert_allclose(sp.nbdtrin(k, y, p), n, rtol)

class TestNoncentralChiSquaredFunctions:

    def test_chndtr_and_inverses_against_wolfram_alpha(self):
        # Each row holds (x, nu, lam, expected_value)
        # These values were computed using Wolfram Alpha with
        #     CDF[NoncentralChiSquareDistribution[nu, lam], x]
        values = np.array([
            [25.00, 20.0, 400, 4.1210655112396197139e-57],
            [25.00, 8.00, 250, 2.3988026526832425878e-29],
            [0.001, 8.00, 40., 5.3761806201366039084e-24],
            [0.010, 8.00, 40., 5.45396231055999457039e-20],
            [20.00, 2.00, 107, 1.39390743555819597802e-9],