From 847010aeecbbf9e513530a1d772a13ee0ee3e15c Mon Sep 17 00:00:00 2001 From: chrisb83 Date: Sun, 18 Aug 2019 19:27:39 +0200 Subject: [PATCH] MAINT: link rdist and semicircular in scipy.stats stats.semicircular is a special case of rdist with c=3 --- scipy/stats/_continuous_distns.py | 19 ++++++++++++++++--- scipy/stats/_distr_params.py | 2 +- scipy/stats/tests/test_distributions.py | 2 +- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/scipy/stats/_continuous_distns.py b/scipy/stats/_continuous_distns.py index 7002c62bc79e..96a58ff2fae2 100644 --- a/scipy/stats/_continuous_distns.py +++ b/scipy/stats/_continuous_distns.py @@ -5950,6 +5950,7 @@ class rdist_gen(rv_continuous): special cases:: c = 2: uniform + c = 3: `semicircular` c = 4: Epanechnikov (parabolic) c = 6: quartic (biweight) c = 8: triweight @@ -5961,13 +5962,13 @@ class rdist_gen(rv_continuous): """ # use relation to the beta distribution for pdf, cdf, etc def _pdf(self, x, c): - return 0.5*beta._pdf((x+1)/2, c/2, c/2) + return 0.5*beta._pdf((x + 1)/2, c/2, c/2) def _logpdf(self, x, c): - return -np.log(2) + beta._logpdf((x+1)/2, c/2, c/2) + return -np.log(2) + beta._logpdf((x + 1)/2, c/2, c/2) def _cdf(self, x, c): - return beta._cdf((x+1)/2, c/2, c/2) + return beta._cdf((x + 1)/2, c/2, c/2) def _ppf(self, q, c): return 2*beta._ppf(q, c/2, c/2) - 1 @@ -6222,8 +6223,14 @@ class semicircular_gen(rv_continuous): for :math:`-1 \le x \le 1`. + The distribution is a special case of `rdist` with `c = 3`. + %(after_notes)s + See Also + -------- + rdist + References ---------- .. [1] "Wigner semicircle distribution", @@ -6235,9 +6242,15 @@ class semicircular_gen(rv_continuous): def _pdf(self, x): return 2.0/np.pi*np.sqrt(1-x*x) + def _logpdf(self, x): + return np.log(2/np.pi) + 0.5*np.log1p(-x*x) + def _cdf(self, x): return 0.5+1.0/np.pi*(x*np.sqrt(1-x*x) + np.arcsin(x)) + def _ppf(self, q): + return rdist._ppf(q, 3) + def _rvs(self): # generate values uniformly distributed on the area under the pdf # (semi-circle) by randomly generating the radius and angle diff --git a/scipy/stats/_distr_params.py b/scipy/stats/_distr_params.py index 52976ecdc776..37e696fd65fe 100644 --- a/scipy/stats/_distr_params.py +++ b/scipy/stats/_distr_params.py @@ -87,7 +87,7 @@ ['powerlognorm', (2.1413923530064087, 0.44639540782048337)], ['powernorm', (4.4453652254590779,)], ['rayleigh', ()], - ['rdist', (0.9,)], # feels also slow + ['rdist', (1.6,)], ['recipinvgauss', (0.63004267809369119,)], ['reciprocal', (0.0062309367010521255, 1.0062309367010522)], ['rice', (0.7749725210111873,)], diff --git a/scipy/stats/tests/test_distributions.py b/scipy/stats/tests/test_distributions.py index d49317ef6708..bc376e3b8713 100644 --- a/scipy/stats/tests/test_distributions.py +++ b/scipy/stats/tests/test_distributions.py @@ -2754,7 +2754,7 @@ def test_rdist_beta(self): # rdist is a special case of stats.beta x = np.linspace(-0.99, 0.99, 10) c = 2.7 - assert_almost_equal(0.5*stats.beta(c/2, c/2).pdf((x+1)/2), + assert_almost_equal(0.5*stats.beta(c/2, c/2).pdf((x + 1)/2), stats.rdist(c).pdf(x))