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

Code before:
    with pytest.raises(TypeError, match=re.escape(err)):
        fun(*args, method='exact', mode='exact')


@make_xp_test_case(stats.expectile)
class TestExpectile:
    @pytest.mark.parametrize('dtype', [None, 'float32', 'float64'])
    def test_same_as_mean(self, dtype, xp):
        dtype = dtype if dtype is None else getattr(xp, dtype)
        rng = np.random.default_rng(42)

        x = xp.asarray(rng.random(size=20).tolist(), dtype=dtype)
        xp_assert_close(stats.expectile(x, 0.5), xp.mean(x))

        w = xp.asarray(rng.random(size=20).tolist(), dtype=dtype)
        xp_assert_close(stats.expectile(x, 0.5, weights=w), _xp_mean(x, weights=w))

    def test_minimum(self, xp):
        rng = np.random.default_rng(42)
        x = xp.asarray(rng.random(size=20))
        xp_assert_close(stats.expectile(x, alpha=0), xp.min(x))

    def test_maximum(self, xp):
        rng = np.random.default_rng(42)
        x = xp.asarray(rng.random(size=20))
        assert_allclose(stats.expectile(x, alpha=1), xp.max(x))

    def test_weights(self, xp):
        # expectile should minimize `fun` defined below; see
        # F. Sobotka and T. Kneib, "Geoadditive expectile regression",
        # Computational Statistics and Data Analysis 56 (2012) 755-767
        # https://doi.org/10.1016/j.csda.2010.11.015
        rng = np.random.default_rng(1856392524598679138)

        def fun(u, a, alpha, weights):
            w = np.full_like(a, fill_value=alpha)
            w[a <= u] = 1 - alpha
            return np.sum(w * weights * (a - u)**2)

        def expectile2(a, alpha, weights):
            bracket = np.min(a), np.max(a)
            return optimize.minimize_scalar(fun, bracket=bracket,
                                            args=(a, alpha, weights)).x

        n = 10
        a = rng.random(n)
        alpha = rng.random()
        weights = rng.random(n)

        res = stats.expectile(xp.asarray(a), alpha, weights=xp.asarray(weights))
        ref = expectile2(a, alpha, weights)

Review comment (suggestion):
```suggestion
        xp_assert_close(stats.expectile(x, alpha=1), xp.max(x))
```

Code after:
    with pytest.raises(TypeError, match=re.escape(err)):
        fun(*args, method='exact', mode='exact')


@make_xp_test_case(stats.expectile)
class TestExpectile:
    @pytest.mark.parametrize('dtype', [None, 'float32', 'float64'])
    def test_same_as_mean(self, dtype, xp):
        dtype = dtype if dtype is None else getattr(xp, dtype)
        rng = np.random.default_rng(42)

        x = xp.asarray(rng.random(size=20).tolist(), dtype=dtype)
        xp_assert_close(stats.expectile(x, 0.5), xp.mean(x))

        w = xp.asarray(rng.random(size=20).tolist(), dtype=dtype)
        xp_assert_close(stats.expectile(x, 0.5, weights=w), _xp_mean(x, weights=w))

    def test_minimum(self, xp):
        rng = np.random.default_rng(42)
        x = xp.asarray(rng.random(size=20))
        xp_assert_close(stats.expectile(x, alpha=0), xp.min(x))

    def test_maximum(self, xp):
        rng = np.random.default_rng(42)
        x = xp.asarray(rng.random(size=20))
        xp_assert_close(stats.expectile(x, alpha=1), xp.max(x))

    def test_weights(self, xp):
        # expectile should minimize `fun` defined below; see
        # F. Sobotka and T. Kneib, "Geoadditive expectile regression",
        # Computational Statistics and Data Analysis 56 (2012) 755-767
        # https://doi.org/10.1016/j.csda.2010.11.015
        rng = np.random.default_rng(1856392524598679138)

        def fun(u, a, alpha, weights):
            w = np.full_like(a, fill_value=alpha)
            w[a <= u] = 1 - alpha
            return np.sum(w * weights * (a - u)**2)

        def expectile2(a, alpha, weights):
            bracket = np.min(a), np.max(a)
            return optimize.minimize_scalar(fun, bracket=bracket,
                                            args=(a, alpha, weights)).x

        n = 10
        a = rng.random(n)
        alpha = rng.random()
        weights = rng.random(n)

        res = stats.expectile(xp.asarray(a), alpha, weights=xp.asarray(weights))
        ref = expectile2(a, alpha, weights)