Skip to content

Commit 290a1ab

Browse files
committed
Better eval for beta
1 parent b1f35f8 commit 290a1ab

File tree

4 files changed

+53
-5
lines changed

4 files changed

+53
-5
lines changed

sympy/functions/special/beta_functions.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from sympy.core.function import Function, ArgumentIndexError
33
from sympy.core.symbol import Dummy
44
from sympy.functions.special.gamma_functions import gamma, digamma
5+
from sympy.functions.combinatorial.numbers import catalan
56
from sympy.functions.elementary.complexes import conjugate
67

78
# See mpmath #569 and SymPy #20569
@@ -120,10 +121,32 @@ def fdiff(self, argindex):
120121
def eval(cls, x, y=None):
121122
if y is None:
122123
return beta(x, x)
124+
if x.is_Number and y.is_Number:
125+
return beta(x, y, evaluate=False).doit()
126+
127+
def doit(self, **hints):
128+
x = xold = self.args[0]
129+
# Deal with unevaluated single argument beta
130+
single_argument = len(self.args) == 1
131+
y = yold = self.args[0] if single_argument else self.args[1]
132+
if hints.get('deep', True):
133+
x = x.doit(**hints)
134+
y = y.doit(**hints)
135+
if y.is_zero or x.is_zero:
136+
return S.ComplexInfinity
123137
if y is S.One:
124138
return 1/x
125139
if x is S.One:
126140
return 1/y
141+
if y == x + 1:
142+
return 1/(x*y*catalan(x))
143+
s = x + y
144+
if (s.is_integer and s.is_negative and x.is_integer is False and
145+
y.is_integer is False):
146+
return S.Zero
147+
if x == xold and y == yold and not single_argument:
148+
return self
149+
return beta(x, y)
127150

128151
def _eval_expand_func(self, **hints):
129152
x, y = self.args

sympy/functions/special/tests/test_beta_functions.py

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
from sympy.core.function import (diff, expand_func)
2-
from sympy.core.numbers import I
2+
from sympy.core.numbers import I, Rational, pi
3+
from sympy.core.singleton import S
34
from sympy.core.symbol import (Dummy, symbols)
5+
from sympy.functions.combinatorial.numbers import catalan
46
from sympy.functions.elementary.complexes import conjugate
7+
from sympy.functions.elementary.miscellaneous import sqrt
58
from sympy.functions.special.beta_functions import (beta, betainc, betainc_regularized)
6-
from sympy.functions.special.gamma_functions import gamma
9+
from sympy.functions.special.gamma_functions import gamma, polygamma
710
from sympy.functions.special.hyper import hyper
811
from sympy.integrals.integrals import Integral
9-
from sympy.functions.special.gamma_functions import polygamma
1012
from sympy.core.function import ArgumentIndexError
1113
from sympy.core.expr import unchanged
1214
from sympy.testing.pytest import raises
@@ -17,6 +19,7 @@ def test_beta():
1719
t = Dummy('t')
1820

1921
assert unchanged(beta, x, y)
22+
assert unchanged(beta, x, x)
2023

2124
assert beta(5, -3).is_real == True
2225
assert beta(3, y).is_real is None
@@ -35,6 +38,24 @@ def test_beta():
3538
assert beta(x, y).rewrite(gamma) == gamma(x)*gamma(y)/gamma(x + y)
3639
assert beta(x).rewrite(gamma) == gamma(x)**2/gamma(2*x)
3740
assert beta(x, y).rewrite(Integral).dummy_eq(Integral(t**(x - 1) * (1 - t)**(y - 1), (t, 0, 1)))
41+
assert beta(Rational(-19, 10), Rational(-1, 10)) == S.Zero
42+
assert beta(Rational(-19, 10), Rational(-9, 10)) == \
43+
800*2**(S(4)/5)*sqrt(pi)*gamma(S.One/10)/(171*gamma(-S(7)/5))
44+
assert beta(Rational(19, 10), Rational(29, 10)) == 100/(551*catalan(Rational(19, 10)))
45+
assert beta(1, 0) == S.ComplexInfinity
46+
assert beta(0, 1) == S.ComplexInfinity
47+
assert beta(2, 3) == S.One/12
48+
assert unchanged(beta, x, x + 1)
49+
assert unchanged(beta, x, 1)
50+
assert unchanged(beta, 1, y)
51+
assert beta(x, x + 1).doit() == 1/(x*(x+1)*catalan(x))
52+
assert beta(1, y).doit() == 1/y
53+
assert beta(x, 1).doit() == 1/x
54+
assert beta(Rational(-19, 10), Rational(-1, 10), evaluate=False).doit() == S.Zero
55+
assert beta(2) == beta(2, 2)
56+
assert beta(x, evaluate=False) != beta(x, x)
57+
assert beta(x, evaluate=False).doit() == beta(x, x)
58+
3859

3960
def test_betainc():
4061
a, b, x1, x2 = symbols('a b x1 x2')
@@ -51,6 +72,7 @@ def test_betainc():
5172

5273
assert betainc(1, 2, 3, 3).evalf() == 0
5374

75+
5476
def test_betainc_regularized():
5577
a, b, x1, x2 = symbols('a b x1 x2')
5678

sympy/printing/latex.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1219,8 +1219,10 @@ def _print_elliptic_pi(self, expr, exp=None):
12191219
return r"\Pi%s" % tex
12201220

12211221
def _print_beta(self, expr, exp=None):
1222-
tex = r"\left(%s, %s\right)" % (self._print(expr.args[0]),
1223-
self._print(expr.args[1]))
1222+
x = expr.args[0]
1223+
# Deal with unevaluated single argument beta
1224+
y = expr.args[0] if len(expr.args) == 1 else expr.args[1]
1225+
tex = rf"\left({x}, {y}\right)"
12241226

12251227
if exp is not None:
12261228
return r"\operatorname{B}^{%s}%s" % (exp, tex)

sympy/printing/tests/test_latex.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,7 @@ def test_latex_functions():
450450
# not to be confused with the beta function
451451
assert latex(mybeta(x, y, z)) == r"\beta{\left(x,y,z \right)}"
452452
assert latex(beta(x, y)) == r'\operatorname{B}\left(x, y\right)'
453+
assert latex(beta(x, evaulate=False)) == r'\operatorname{B}\left(x, x\right)'
453454
assert latex(beta(x, y)**2) == r'\operatorname{B}^{2}\left(x, y\right)'
454455
assert latex(mybeta(x)) == r"\beta{\left(x \right)}"
455456
assert latex(mybeta) == r"\beta"

0 commit comments

Comments
 (0)