Skip to content

Commit

Permalink
Merge pull request #18783 from WarrenWeckesser/hypsecant-sf-isf
Browse files Browse the repository at this point in the history
ENH: stats: Implement _sf and _isf for hypsecant.
  • Loading branch information
mdhaber committed Jul 11, 2023
2 parents 0ffff14 + ea2f19d commit da584a3
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 4 deletions.
8 changes: 7 additions & 1 deletion scipy/stats/_continuous_distns.py
Expand Up @@ -4214,7 +4214,7 @@ class halflogistic_gen(rv_continuous):
References
----------
.. [1] Asgharzadeh et al (2011). "Comparisons of Methods of Estimation for the
Half-Logistic Distribution". Selcuk J. Appl. Math. 93-108.
Half-Logistic Distribution". Selcuk J. Appl. Math. 93-108.
%(example)s
Expand Down Expand Up @@ -4439,6 +4439,12 @@ def _cdf(self, x):
def _ppf(self, q):
return np.log(np.tan(np.pi*q/2.0))

def _sf(self, x):
return 2.0/np.pi*np.arctan(np.exp(-x))

def _isf(self, q):
return -np.log(np.tan(np.pi*q/2.0))

def _stats(self):
return 0, np.pi*np.pi/4, 0, 2

Expand Down
30 changes: 27 additions & 3 deletions scipy/stats/tests/test_distributions.py
Expand Up @@ -841,6 +841,29 @@ def test_pdf_norminvgauss(self):
)


class TestHypSecant:

# Reference values were computed with the mpmath expression
# float((2/mp.pi)*mp.atan(mp.exp(-x)))
# and mp.dps = 50.
@pytest.mark.parametrize('x, reference',
[(30, 5.957247804324683e-14),
(50, 1.2278802891647964e-22)])
def test_sf(self, x, reference):
sf = stats.hypsecant.sf(x)
assert_allclose(sf, reference, rtol=5e-15)

# Reference values were computed with the mpmath expression
# float(-mp.log(mp.tan((mp.pi/2)*p)))
# and mp.dps = 50.
@pytest.mark.parametrize('p, reference',
[(1e-6, 13.363927852673998),
(1e-12, 27.179438410639094)])
def test_isf(self, p, reference):
x = stats.hypsecant.isf(p)
assert_allclose(x, reference, rtol=5e-15)


class TestNormInvGauss:
def setup_method(self):
np.random.seed(1234)
Expand Down Expand Up @@ -1873,14 +1896,14 @@ def test_rvs(self, c):
(1e10, -10.093986931748889),
(1e100, -113.71031611649761)])
def test_entropy(self, c, ref):

# Reference values were calculated with mpmath
# from mpmath import mp
# mp.dps = 500
# def loggamma_entropy_mpmath(c):
# c = mp.mpf(c)
# return float(mp.log(mp.gamma(c)) + c * (mp.one - mp.digamma(c)))

assert_allclose(stats.loggamma.entropy(c), ref, rtol=1e-14)


Expand Down Expand Up @@ -3415,7 +3438,6 @@ def test_t_inf_df_stats_entropy(self, df_infmask):
assert_equal(res[df_infmask], res_ex_inf)
assert_equal(res[~df_infmask], res_ex_noinf)


def test_logpdf_pdf(self):
# reference values were computed via the reference distribution, e.g.
# mp.dps = 500; StudentT(df=df).logpdf(x), StudentT(df=df).pdf(x)
Expand Down Expand Up @@ -4020,6 +4042,7 @@ def test_cdf_ppf(self, x, p, a, b, c):
ppf = stats.genexpon.ppf(p, a, b, c)
assert_allclose(ppf, x, rtol=1e-14)


class TestTruncexpon:

def test_sf_isf(self):
Expand Down Expand Up @@ -5517,6 +5540,7 @@ def test_x_near_zeta(
expected,
)


class TestArrayArgument: # test for ticket:992
def setup_method(self):
np.random.seed(1234)
Expand Down

0 comments on commit da584a3

Please sign in to comment.