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

Code before:

                right = np.empty_like(c)
                right[c <= 0] = np.inf
                right[c > 0] = mu[c > 0] + sigma[c > 0] / c[c > 0]

                return left[()], right[()]

            @property
            def support_inclusive(self):
                return (False, False)

            def pdf(self, x, *, c, mu, sigma):
                x, c, mu, sigma = np.broadcast_arrays(x, c, mu, sigma)
                t = np.empty_like(x)
                mask = (c == 0)
                t[mask] = np.exp(-(x[mask] - mu[mask])/sigma[mask])
                t[~mask] = (1  - c[~mask]*(x[~mask] - mu[~mask])/sigma[~mask])**(1/c[~mask])
                result = 1/sigma * t**(1 - c)*np.exp(-t)
                return result[()]

            def cdf(self, x, *, c, mu, sigma):
                x, c, mu, sigma = np.broadcast_arrays(x, c, mu, sigma)
                t = np.empty_like(x)
                mask = (c == 0)
                t[mask] = np.exp(-(x[mask] - mu[mask])/sigma[mask])
                t[~mask] = (1  - c[~mask]*(x[~mask] - mu[~mask])/sigma[~mask])**(1/c[~mask])
                return np.exp(-t)[()]

        GenExtreme1 = stats.make_distribution(MyGenExtreme())
        GenExtreme2 = stats.make_distribution(stats.genextreme)

        X1 = GenExtreme1(c=c, mu=0, sigma=1)
        X2 = GenExtreme2(c=c)

        x = X1.sample(shape=10, rng=rng)
        p = X1.cdf(x)

        assert_allclose(X1.support(), X2.support())
        assert_allclose(X1.entropy(), X2.entropy())
        assert_allclose(X1.median(), X2.median())
        assert_allclose(X1.logpdf(x), X2.logpdf(x))
        assert_allclose(X1.pdf(x), X2.pdf(x))
        assert_allclose(X1.logcdf(x), X2.logcdf(x))
        assert_allclose(X1.cdf(x), X2.cdf(x))
        assert_allclose(X1.logccdf(x), X2.logccdf(x))
        assert_allclose(X1.ccdf(x), X2.ccdf(x))
        assert_allclose(X1.icdf(p), X2.icdf(p))
        assert_allclose(X1.iccdf(p), X2.iccdf(p))

    def test_input_validation(self):
        message = '`levy_stable` is not supported.'

Review comment (bug):
The tests currently fail due to this formula not being defined on one endpoint of the support when `c` is negative. Do I just need to ensure the `cdf` formula is defined on the endpoints.

Code after:
            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[()]

                def right(*, 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[()]

                return {"endpoints": (left, right), "inclusive": (False, False)}

            def pdf(self, x, *, c, mu, sigma):
                x, c, mu, sigma = np.broadcast_arrays(x, c, mu, sigma)
                t = np.empty_like(x)
                mask = (c == 0)
                t[mask] = np.exp(-(x[mask] - mu[mask])/sigma[mask])
                t[~mask] = (
                    1  - c[~mask]*(x[~mask] - mu[~mask])/sigma[~mask]
                )**(1/c[~mask])
                result = 1/sigma * t**(1 - c)*np.exp(-t)
                return result[()]

            def cdf(self, x, *, c, mu, sigma):
                x, c, mu, sigma = np.broadcast_arrays(x, c, mu, sigma)
                t = np.empty_like(x)
                mask = (c == 0)
                t[mask] = np.exp(-(x[mask] - mu[mask])/sigma[mask])
                t[~mask] = (
                    1  - c[~mask]*(x[~mask] - mu[~mask])/sigma[~mask]
                )**(1/c[~mask])
                return np.exp(-t)[()]

        GenExtreme1 = stats.make_distribution(MyGenExtreme())
        GenExtreme2 = stats.make_distribution(stats.genextreme)

        X1 = GenExtreme1(c=c, mu=0, sigma=1)
        X2 = GenExtreme2(c=c)

        x = X1.sample(shape=10, rng=rng)
        p = X1.cdf(x)

        assert_allclose(X1.support(), X2.support())
        assert_allclose(X1.entropy(), X2.entropy(), rtol=5e-6)
        assert_allclose(X1.median(), X2.median())
        assert_allclose(X1.logpdf(x), X2.logpdf(x))