-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
(1/x).evalf(subs={x: 0}) produces 0 #8242
Comments
Another interesting and related issue: while In [3]: x = Symbol('x', real=True)
In [4]: (1/x).subs({x: 0.})
Out[4]: +inf
In [5]: (1/x).xreplace({x: 0.})
Out[5]: +inf the following (1/x).evalf(subs={x: 0.}) raises Traceback (most recent call last):
File "<ipython-input-6-226388149257>", line 1, in <module>
(1/x).evalf(subs={x: 0.})
File "sympy/core/evalf.py", line 1326, in evalf
result = evalf(self, prec + 4, options)
File "sympy/core/evalf.py", line 1220, in evalf
r = rf(x, prec, options)
File "sympy/core/evalf.py", line 622, in evalf_pow
return mpf_pow_int(re, p, target_prec), None, target_prec, None
File "sympy/mpmath/libmp/libmpf.py", line 1044, in mpf_pow_int
if n == -1: return mpf_div(fone, s, prec, rnd)
File "sympy/mpmath/libmp/libmpf.py", line 934, in mpf_div
raise ZeroDivisionError
ZeroDivisionError |
I get these results
with these mods (which are suggestive as to where the problem lies) diff --git a/sympy/core/evalf.py b/sympy/core/evalf.py
index c794656..233bbe5 100644
--- a/sympy/core/evalf.py
+++ b/sympy/core/evalf.py
@@ -821,6 +821,8 @@ def evalf_log(expr, prec, options):
imaginary_term = (mpf_cmp(xre, fzero) < 0)
+ if xre == (0,)*4:
+ return S.ComplexInfinity
re = mpf_log(mpf_abs(xre), prec, rnd)
size = fastlog(re)
if prec - size > workprec and re != fzero:
@@ -1284,13 +1286,25 @@ def evalf(x, prec, options):
try:
rf = evalf_table[x.func]
r = rf(x, prec, options)
- except KeyError:
+ if r is S.ComplexInfinity:
+ return r
+ if x and r[0] == r[1] == None:
+ assert not 'subs' in options
+ except (KeyError, AssertionError):
try:
# Fall back to ordinary evalf if possible
if 'subs' in options:
x = x.subs(evalf_subs(prec, options['subs']))
- xe = x._eval_evalf(prec)
- re, im = xe.as_real_imag()
+ if x is S.ComplexInfinity:
+ return x
+ if x:
+ if not x.is_number:
+ return (None,)*4
+ x = evalf(x, prec, options)
+ xe = x._eval_evalf(prec)
+ re, im = xe.as_real_imag()
+ else:
+ return (0, 0, 0, 0), None, None, None
if re.has(re_) or im.has(im_):
raise NotImplementedError
if re == 0:
@@ -1306,6 +1320,8 @@ def evalf(x, prec, options):
im = im._to_mpmath(prec, allow_ints=False)._mpf_
imprec = prec
r = re, im, reprec, imprec
+ if re == im == None:
+ return (0, 0, 0, 0), None, None, None
except AttributeError:
raise NotImplementedError
if options.get("verbose"):
@@ -1392,6 +1408,8 @@ def evalf(self, n=15, subs=None, maxn=100, chop=False, strict=False, quad=None,
options['quad'] = quad
try:
result = evalf(self, prec + 4, options)
+ if result is S.ComplexInfinity:
+ return result
except NotImplementedError:
# Fall back to the ordinary evalf
v = self._eval_evalf(prec) Whoever tackles this beware: there is the |
I believe the problem is here. We could also make it return diff --git a/sympy/core/evalf.py b/sympy/core/evalf.py
index c79465651..9437c9c17 100644
--- a/sympy/core/evalf.py
+++ b/sympy/core/evalf.py
@@ -670,7 +670,12 @@ def evalf_pow(v, prec, options):
return None, mpf_neg(z), None, target_prec
# Zero raised to an integer power
if not re:
- return None, None, None, None
+ if exp > 0:
+ return None, None, None, None
+ elif exp < 0:
+ return mpmath_inf._mpf_, None, target_prec, None
+ else:
+ return mpf(1)._mpf_, None, target_prec, None
# General complex number to arbitrary integer power
re, im = libmp.mpc_pow_int((re, im), p, prec)
# Assumes full accuracy in input Maybe we should apply the above as a simpler fix for now ( |
SO reports this issue, too. |
I want to work on this. Ideally mpmath should provide a tuple that represents |
I've found the same issue when using numeric evaluation on parser with import sympy as sp
parser = sp.parsing.sympy_parser.parse_expr
expr = '1/0'
sp.N(parser(expr, evaluate=False)) >>> 0 sympy==1.11.1 |
Are you sure about this? I tried with 1.11.1 and also with current master: In [1]: import sympy as sp
...: parser = sp.parsing.sympy_parser.parse_expr
...: expr = '1/0'
...: sp.N(parser(expr, evaluate=False))
Out[1]: zoo |
Here's how it looks like:
I did investigate it some time ago and, AFAIR, it happens in
Pow
evaluation that short-circuits to 0 whenever the base is 0 while it should return infs if the exponent is negative.The text was updated successfully, but these errors were encountered: