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

Code before:
            (1e20, 2, -44.47448619497938, 1e-14),
            (1e20, 5, -43.89811870326017, 1e-14),
            (1e50, 10, -112.59320047122131, 1e-14),
        ]
    )
    def test_extreme_entropy(self, a, b, ref, tol):
        # Reference values were calculated with mpmath:
        # from mpmath import mp
        # mp.dps = 500
        #
        # def beta_entropy_mpmath(a, b):
        #     a = mp.mpf(a)
        #     b = mp.mpf(b)
        #     entropy = (
        #       mp.log(mp.beta(a, b)) - (a - 1) * mp.digamma(a)
        #       - (b - 1) * mp.digamma(b) + (a + b - 2) * mp.digamma(a + b)
        #     )
        #     return float(entropy)
        assert_allclose(stats.beta(a, b).entropy(), ref, rtol=tol)

    def test_entropy_broadcasting(self):
        # gh-23127 reported that the entropy method of the beta
        # distribution did not broadcast correctly.
        beta_dist = stats.make_distribution(stats.beta)
        b = beta_dist(a=np.zeros(10), b=np.ones(10))
        b.entropy()


class TestBetaPrime:
    # the test values are used in test_cdf_gh_17631 / test_ppf_gh_17631
    # They are computed with mpmath. Example:
    # from mpmath import mp
    # mp.dps = 50
    # a, b = mp.mpf(0.05), mp.mpf(0.1)
    # x = mp.mpf(1e22)
    # float(mp.betainc(a, b, 0.0, x/(1+x), regularized=True))
    # note: we use the values computed by the cdf to test whether
    # ppf(cdf(x)) == x (up to a small tolerance)
    # since the ppf can be very sensitive to small variations of the input,
    # it can be required to generate the test case for the ppf separately,
    # see self.test_ppf
    cdf_vals = [
        (1e22, 100.0, 0.05, 0.8973027435427167),
        (1e10, 100.0, 0.05, 0.5911548582766262),
        (1e8, 0.05, 0.1, 0.9467768090820048),
        (1e8, 100.0, 0.05, 0.4852944858726726),
        (1e-10, 0.05, 0.1, 0.21238845427095),
        (1e-10, 1.5, 1.5, 1.697652726007973e-15),
        (1e-10, 0.05, 100.0, 0.40884514172337383),
        (1e-22, 0.05, 0.1, 0.053349567649287326),
        (1e-22, 1.5, 1.5, 1.6976527263135503e-33),

Review comment (suggestion):
I've been using camelcase distribution names as the output of `make_distribution` and capital names for the random variables once they're instantiated. Also, This is probably overkill, but I wanted to try it, so I thought I might as well include it here.
```suggestion
        Beta = stats.make_distribution(stats.beta)
        a = np.asarray([5e6, 100, 1e9, 10])
        b = np.asarray([5e6, 1e9, 100, 20])
        res = Beta(a=a, b=b).entropy()
        ref = np.asarray([Beta(a=a[0], b=b[0]).entropy(),
                          Beta(a=a[1], b=b[1]).entropy(),
                          Beta(a=a[2], b=b[2]).entropy(),
                          Beta(a=a[3], b=b[3]).entropy()])
        assert_allclose(res, ref)
```
It might be good to at least check the shape of the output, though.


Code after:
            (1e20, 2, -44.47448619497938, 1e-14),
            (1e20, 5, -43.89811870326017, 1e-14),
            (1e50, 10, -112.59320047122131, 1e-14),
        ]
    )
    def test_extreme_entropy(self, a, b, ref, tol):
        # Reference values were calculated with mpmath:
        # from mpmath import mp
        # mp.dps = 500
        #
        # def beta_entropy_mpmath(a, b):
        #     a = mp.mpf(a)
        #     b = mp.mpf(b)
        #     entropy = (
        #       mp.log(mp.beta(a, b)) - (a - 1) * mp.digamma(a)
        #       - (b - 1) * mp.digamma(b) + (a + b - 2) * mp.digamma(a + b)
        #     )
        #     return float(entropy)
        assert_allclose(stats.beta(a, b).entropy(), ref, rtol=tol)

    def test_entropy_broadcasting(self):
        # gh-23127 reported that the entropy method of the beta
        # distribution did not broadcast correctly.
        Beta = stats.make_distribution(stats.beta)
        a = np.asarray([5e6, 100, 1e9, 10])
        b = np.asarray([5e6, 1e9, 100, 20])
        res = Beta(a=a, b=b).entropy()
        ref = np.asarray([Beta(a=a[0], b=b[0]).entropy(),
                          Beta(a=a[1], b=b[1]).entropy(),
                          Beta(a=a[2], b=b[2]).entropy(),
                          Beta(a=a[3], b=b[3]).entropy()])
        assert_allclose(res, ref)


class TestBetaPrime:
    # the test values are used in test_cdf_gh_17631 / test_ppf_gh_17631
    # They are computed with mpmath. Example:
    # from mpmath import mp
    # mp.dps = 50
    # a, b = mp.mpf(0.05), mp.mpf(0.1)
    # x = mp.mpf(1e22)
    # float(mp.betainc(a, b, 0.0, x/(1+x), regularized=True))
    # note: we use the values computed by the cdf to test whether
    # ppf(cdf(x)) == x (up to a small tolerance)
    # since the ppf can be very sensitive to small variations of the input,
    # it can be required to generate the test case for the ppf separately,
    # see self.test_ppf
    cdf_vals = [
        (1e22, 100.0, 0.05, 0.8973027435427167),
        (1e10, 100.0, 0.05, 0.5911548582766262),
        (1e8, 0.05, 0.1, 0.9467768090820048),