Repository: scipy/scipy
File: scipy/stats/tests/test_distributions.py (Python)

Code before:
        assert_allclose(isf, x)

    def test_stats(self):
        a, b = 1, 0.5
        gamma = np.sqrt(a**2 - b**2)
        v_stats = (b / gamma, a**2 / gamma**3, 3.0 * b / (a * np.sqrt(gamma)),
                   3.0 * (1 + 4 * b**2 / a**2) / gamma)
        assert_equal(v_stats, stats.norminvgauss.stats(a, b, moments='mvsk'))

    def test_ppf(self):
        a, b = 1, 0.5
        x_test = np.array([0.001, 0.5, 0.999])
        vals = stats.norminvgauss.ppf(x_test, a, b)
        assert_allclose(x_test, stats.norminvgauss.cdf(vals, a, b))

    @pytest.mark.parametrize('a', [0.1, 1.0, 10.0])
    @pytest.mark.parametrize('b_a', [-0.9, -0.5, -0.1, 0.1, 0.5, 0.9])
    def test_gh23196_tails_cdf(self, a, b_a):
        # gh-23196 reported that the norminvgauss CDF would drop to zero in the far
        # right tail. The SF had a similar problem, dropping to zero at the far left.
        # Check that this is resolved by checking that values in the deep tails are
        # close to 1.0.
        b = b_a * a
        res = stats.norminvgauss(a=a, b=b).cdf(300)
        np.testing.assert_allclose(res, 1, atol=1e-2)
        res = stats.norminvgauss(a=a, b=b).sf(-300)
        np.testing.assert_allclose(res, 1, atol=1e-2)


class TestGeom:
    def setup_method(self):
        self.rng = np.random.default_rng(7672986002)

    def test_rvs(self):
        vals = stats.geom.rvs(0.75, size=(2, 50), random_state=self.rng)
        assert_(np.all(vals >= 0))
        assert_(np.shape(vals) == (2, 50))
        assert_(vals.dtype.char in typecodes['AllInteger'])
        val = stats.geom.rvs(0.75, random_state=self.rng)
        assert_(isinstance(val, int))
        val = stats.geom(0.75).rvs(3, random_state=self.rng)
        assert_(isinstance(val, np.ndarray))
        assert_(val.dtype.char in typecodes['AllInteger'])

    def test_rvs_9313(self):
        # previously, RVS were converted to `np.int32` on some platforms,
        # causing overflow for moderately large integer output (gh-9313).
        # Check that this is resolved to the extent possible w/ `np.int64`.
        rvs = stats.geom.rvs(np.exp(-35), size=5, random_state=self.rng)
        assert rvs.dtype == np.int64
        assert np.all(rvs > np.iinfo(np.int32).max)

Review comment (suggestion):
```suggestion
        sf_left = stats.norminvgauss(a=a, b=b).sf(-300)
```

Code after:
        assert_allclose(isf, x)

    def test_stats(self):
        a, b = 1, 0.5
        gamma = np.sqrt(a**2 - b**2)
        v_stats = (b / gamma, a**2 / gamma**3, 3.0 * b / (a * np.sqrt(gamma)),
                   3.0 * (1 + 4 * b**2 / a**2) / gamma)
        assert_equal(v_stats, stats.norminvgauss.stats(a, b, moments='mvsk'))

    def test_ppf(self):
        a, b = 1, 0.5
        x_test = np.array([0.001, 0.5, 0.999])
        vals = stats.norminvgauss.ppf(x_test, a, b)
        assert_allclose(x_test, stats.norminvgauss.cdf(vals, a, b))

    @pytest.mark.parametrize('a', [0.1, 1.0, 10.0])
    @pytest.mark.parametrize('b_a', [-0.9, -0.5, -0.1, 0.1, 0.5, 0.9])
    def test_gh23196_tails_cdf_sf(self, a, b_a):
        # gh-23196 reported that the norminvgauss CDF would drop to zero in the far
        # right tail. The SF had a similar problem, dropping to zero at the far left.
        # Check that this is resolved by checking that values in the deep tails are
        # close to 1.0.
        b = b_a * a
        res = stats.norminvgauss(a=a, b=b).cdf(300)
        np.testing.assert_allclose(res, 1, atol=1e-2)
        res = stats.norminvgauss(a=a, b=b).sf(-300)
        np.testing.assert_allclose(res, 1, atol=1e-2)

    @pytest.mark.parametrize("x, a, b, ref", [
        (100, 1.0, 0.0, 1.0),  # originally reported in gh-23196
        (1500, 0.1, 0.09, 0.9999999999418577),  # suggested in gh-24567
    ])
    def test_gh23196_tails_cdf_sf_accuracy(self, x, a, b, ref):
        # Spot check the accuracy of the CDF/SF in the deep tails.
        # library(GeneralizedHyperbolic)
        # options(digits=16)
        # pnig(1500, alpha=0.1, beta=0.09)
        rtol = 1e-14
        np.testing.assert_allclose(stats.norminvgauss(a=a, b=b).cdf(x), ref, rtol=rtol)
        np.testing.assert_allclose(stats.norminvgauss(a=a, b=-b).sf(-x), ref, rtol=rtol)


class TestGeom:
    def setup_method(self):
        self.rng = np.random.default_rng(7672986002)

    def test_rvs(self):
        vals = stats.geom.rvs(0.75, size=(2, 50), random_state=self.rng)
        assert_(np.all(vals >= 0))
        assert_(np.shape(vals) == (2, 50))
        assert_(vals.dtype.char in typecodes['AllInteger'])