Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

BUG: stats: make beta and betaprime pdfs work for a larger parameter range #473

Closed
wants to merge 1 commit into from

2 participants

@pv
Owner
pv commented

Gets rid of spurious 0/0 occurrence in the formula.

Closes Trac #1866

@pbrod

Should also fix the 0*log(0) situations: e.g.
beta.logpdf= special.xlogy(a-1, x) + special.xlog1py(b-1, -x) - special.betaln(a,b)

similiar change for betaprime

See #467

@pv
Owner
pv commented

Went in dbaaad3

@pv pv closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Mar 16, 2013
  1. @pv
This page is out of date. Refresh to see the latest.
View
10 scipy/stats/distributions.py
@@ -2186,12 +2186,10 @@ class beta_gen(rv_continuous):
def _rvs(self, a, b):
return mtrand.beta(a,b,self._size)
def _pdf(self, x, a, b):
- Px = (1.0-x)**(b-1.0) * x**(a-1.0)
- Px /= special.beta(a,b)
- return Px
+ return np.exp(self._logpdf(x, a, b))
def _logpdf(self, x, a, b):
lPx = (b-1.0)*log(1.0-x) + (a-1.0)*log(x)
- lPx -= log(special.beta(a,b))
+ lPx -= special.betaln(a,b)
return lPx
def _cdf(self, x, a, b):
return special.btdtr(a,b,x)
@@ -2256,9 +2254,9 @@ def _rvs(self, a, b):
u2 = gamma.rvs(b,size=self._size)
return (u1 / u2)
def _pdf(self, x, a, b):
- return 1.0/special.beta(a,b)*x**(a-1.0)/(1+x)**(a+b)
+ return np.exp(self._logpdf(x, a, b))
def _logpdf(self, x, a, b):
- return (a-1.0)*log(x) - (a+b)*log(1+x) - log(special.beta(a,b))
+ return (a-1.0)*log(x) - (a+b)*log(1+x) - special.betaln(a,b)
def _cdf_skip(self, x, a, b):
# remove for now: special.hyp2f1 is incorrect for large a
x = where(x==1.0, 1.0-1e-6,x)
View
22 scipy/stats/tests/test_distributions.py
@@ -693,20 +693,20 @@ def test_beta(self):
## (array(6.333333333333333), array(0.055555555555555552))
v = stats.beta.expect(lambda x: (x-19/3.)*(x-19/3.), args=(10,5),
loc=5, scale=2)
- assert_almost_equal(v, 1./18., decimal=14)
+ assert_almost_equal(v, 1./18., decimal=13)
m = stats.beta.expect(lambda x: x, args=(10,5), loc=5., scale=2.)
- assert_almost_equal(m, 19/3., decimal=14)
+ assert_almost_equal(m, 19/3., decimal=13)
ub = stats.beta.ppf(0.95, 10, 10, loc=5, scale=2)
lb = stats.beta.ppf(0.05, 10, 10, loc=5, scale=2)
prob90 = stats.beta.expect(lambda x: 1., args=(10,10), loc=5.,
scale=2.,lb=lb, ub=ub, conditional=False)
- assert_almost_equal(prob90, 0.9, decimal=14)
+ assert_almost_equal(prob90, 0.9, decimal=13)
prob90c = stats.beta.expect(lambda x: 1, args=(10,10), loc=5,
scale=2, lb=lb, ub=ub, conditional=True)
- assert_almost_equal(prob90c, 1., decimal=14)
+ assert_almost_equal(prob90c, 1., decimal=13)
def test_hypergeom(self):
@@ -1031,5 +1031,19 @@ def test_ncx2_tails_ticket_955():
b = stats.ncx2.veccdf(np.arange(20, 25, 0.2), 2, 1.07458615e+02)
assert_allclose(a, b, rtol=1e-3, atol=0)
+def test_beta_logpdf_ticket_1866():
+ alpha, beta = 267, 1472
+ x = np.array([0.2, 0.5, 0.6])
+ b = stats.beta(alpha, beta)
+ assert_allclose(b.logpdf(x).sum(), -1201.699061824062)
+ assert_allclose(b.pdf(x), np.exp(b.logpdf(x)))
+
+def test_betaprime_logpdf():
+ alpha, beta = 267, 1472
+ x = np.array([0.2, 0.5, 0.6])
+ b = stats.betaprime(alpha, beta)
+ assert_(np.isfinite(b.logpdf(x)).all())
+ assert_allclose(b.pdf(x), np.exp(b.logpdf(x)))
+
if __name__ == "__main__":
run_module_suite()
Something went wrong with that request. Please try again.