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

Code before:
        assert_allclose(X.ccdf(x), Y.ccdf(x))
        assert_allclose(X.icdf(p), Y.icdf(p))
        assert_allclose(X.iccdf(p), Y.iccdf(p))
        for kind in ['raw', 'central', 'standardized']:
            for order in range(5):
                assert_allclose(X.moment(order, kind=kind),
                                Y.moment(order, kind=kind))
        for standardized in [False, True]:
            for order in range(1, 5):
                if standardized and order < 3:
                    continue
                assert_allclose(X.lmoment(order, standardized=standardized),
                                Y.lmoment(order, standardized=standardized))

        # Confirm that the `sample` and `moment` methods are overriden as expected
        sample_formula = X.sample(shape=10, rng=0, method='formula')
        sample_inverse = X.sample(shape=10, rng=0, method='inverse_transform')
        assert_allclose(sample_formula, sample_inverse)
        assert not np.all(sample_formula == sample_inverse)

        assert_allclose(X.mean(method='formula'), X.mean(method='quadrature'))
        assert not X.mean(method='formula') == X.mean(method='quadrature')

        assert_allclose(X.lmoment(method='formula'),
                        X.lmoment(method='quadrature_icdf'))
        assert not X.lmoment(method='formula') != X.lmoment(method='quadrature_icdf')

    # pdf and cdf formulas below can warn on boundary of support in some cases.
    # See https://github.com/scipy/scipy/pull/22560#discussion_r1962763840.
    @pytest.mark.slow
    @pytest.mark.filterwarnings("ignore::RuntimeWarning")
    @pytest.mark.parametrize("c", [-1, 0, 1, np.asarray([-2.1, -1., 0., 1., 2.1])])
    def test_custom_variable_support(self, c):
        rng = np.random.default_rng(7548723590230982)

        class MyGenExtreme:
            @property
            def __make_distribution_version__(self):
                return "1.16.0"

            @property
            def parameters(self):
                return {
                    'c': {'endpoints': (-np.inf, np.inf), 'inclusive': (False, False)},
                    'mu': {'endpoints': (-np.inf, np.inf), 'inclusive': (False, False)},
                    'sigma': {'endpoints': (0, np.inf), 'inclusive': (False, False)}
                }

            @property
            def support(self):
                def left(*, c, mu, sigma):

Review comment (suggestion):
```suggestion
        assert not X.lmoment(method='formula') == X.lmoment(method='quadrature_icdf')
```

Code after:
                assert_allclose(X.moment(order, kind=kind),
                                Y.moment(order, kind=kind))
        for standardize in [False, True]:
            for order in range(1, 5):
                if standardize and order < 3:
                    continue
                assert_allclose(X.lmoment(order, standardize=standardize),
                                Y.lmoment(order, standardize=standardize))

        # Confirm that the `sample` and `moment` methods are overriden as expected
        sample_formula = X.sample(shape=10, rng=0, method='formula')
        sample_inverse = X.sample(shape=10, rng=0, method='inverse_transform')
        assert_allclose(sample_formula, sample_inverse)
        assert not np.all(sample_formula == sample_inverse)

        assert_allclose(X.mean(method='formula'), X.mean(method='quadrature'))
        assert not X.mean(method='formula') == X.mean(method='quadrature')

        assert_allclose(X.lmoment(method='formula'),
                        X.lmoment(method='quadrature_icdf'))
        assert not X.lmoment(method='formula') == X.lmoment(method='quadrature_icdf')

    # pdf and cdf formulas below can warn on boundary of support in some cases.
    # See https://github.com/scipy/scipy/pull/22560#discussion_r1962763840.
    @pytest.mark.slow
    @pytest.mark.filterwarnings("ignore::RuntimeWarning")
    @pytest.mark.parametrize("c", [-1, 0, 1, np.asarray([-2.1, -1., 0., 1., 2.1])])
    def test_custom_variable_support(self, c):
        rng = np.random.default_rng(7548723590230982)

        class MyGenExtreme:
            @property
            def __make_distribution_version__(self):
                return "1.16.0"

            @property
            def parameters(self):
                return {
                    'c': {'endpoints': (-np.inf, np.inf), 'inclusive': (False, False)},
                    'mu': {'endpoints': (-np.inf, np.inf), 'inclusive': (False, False)},
                    'sigma': {'endpoints': (0, np.inf), 'inclusive': (False, False)}
                }

            @property
            def support(self):
                def left(*, c, mu, sigma):
                    c, mu, sigma = np.broadcast_arrays(c, mu, sigma)
                    result = np.empty_like(c)
                    result[c >= 0] = -np.inf
                    result[c < 0] = mu[c < 0] + sigma[c < 0] / c[c < 0]
                    return result[()]