Can't get sympy.functions.atan2 to work with _eval_evalf

70 views
Skip to first unread message

Ville Bergholm

unread,
Aug 20, 2019, 10:34:21 AM8/20/19
to sympy
I've been trying to use sympy.Symbol to implement a system where the numerical value of a symbolic quantity is only fixed when it is evaluated using evalf().
To accomplish this I've redefined _eval_evalf() to return the aforementioned value (a fixed 5.0 in the toy example below).

This works fine with basic algebraic operations and most SymPy functions. However, for some reason atan2 seems to behave differently and _eval_evalf is never called.
Is this a bug, or have I misunderstood the purpose of _eval_evalf?


import sympy
import sympy.functions as syf

class A(sympy.Symbol):
   
def _eval_evalf(self, prec):
       
print('*')
       
return sympy.Float(5.0)

x
= A('X')
y
= A('Y')
print('polynomial:')
print((2*x-4+y).evalf())  # works fine
print('atan:')
print(syf.atan(y / x).evalf())  # works fine
print('beta:')
print(syf.beta(y, x).evalf())  # works fine
print('atan2:')
print(syf.atan2(y, x).evalf())  # prints "atan2(Y, X)", does not call A._eval_evalf

Oscar Benjamin

unread,
Aug 20, 2019, 10:43:40 AM8/20/19
to sympy
There's a "return" missing:
$ git diff
diff --git a/sympy/functions/elementary/trigonometric.py
b/sympy/functions/elementary/trigonometric.py
index 635e7f2..b7a0ad1 100644
--- a/sympy/functions/elementary/trigonometric.py
+++ b/sympy/functions/elementary/trigonometric.py
@@ -3070,4 +3070,4 @@ def fdiff(self, argindex):
def _eval_evalf(self, prec):
y, x = self.args
if x.is_extended_real and y.is_extended_real:
- super(atan2, self)._eval_evalf(prec)
+ return super(atan2, self)._eval_evalf(prec)

Also it checks if the args are real so it looks like you might need to
declare your variables a and y with real=True. If you do that then the
result is caculated as: 0.785398163397448

Can you open an issue on Github for this?
> --
> You received this message because you are subscribed to the Google Groups "sympy" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to sympy+un...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/sympy/4480befb-c8d3-48f1-a1be-b5e8bd55a0be%40googlegroups.com.

Kalevi Suominen

unread,
Aug 20, 2019, 10:53:15 AM8/20/19
to sympy
It seems that evalf of atan2 currently expects that its arguments are real. For symbols like x and y, this
means that they have to be initialized with `real=True`. It does not suffice that evalf would return a real
value as assumption code does not try to run evalf.

Kalevi Suominen

Ville Bergholm

unread,
Aug 20, 2019, 11:52:00 AM8/20/19
to sympy

On Tuesday, August 20, 2019 at 5:43:40 PM UTC+3, Oscar wrote:

Can you open an issue on Github for this?


David Bailey

unread,
Aug 20, 2019, 4:08:59 PM8/20/19
to sy...@googlegroups.com

It seems as though the symbolic integration process fails when it can't find a solution:

 integrate(sin(x**n),x)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\SymPyWorkbook\lib\site-packages\sympy\integrals\integrals.py", line 1477, in integrate
    return integral.doit(**doit_flags)
  File "C:\SymPyWorkbook\lib\site-packages\sympy\integrals\integrals.py", line 541, in doit
    function, xab[0], **eval_kwargs)
  File "C:\SymPyWorkbook\lib\site-packages\sympy\integrals\integrals.py", line 1012, in _eval_integral
    h = meijerint_indefinite(g, x)
  File "C:\SymPyWorkbook\lib\site-packages\sympy\integrals\meijerint.py", line 1621, in meijerint_indefinite
    res = _meijerint_indefinite_1(f.subs(x, x + a), x)
  File "C:\SymPyWorkbook\lib\site-packages\sympy\integrals\meijerint.py", line 1684, in _meijerint_indefinite_1
    if b < 0 or f.subs(x, 0).has(nan, zoo):
  File "C:\SymPyWorkbook\lib\site-packages\sympy\core\relational.py", line 304, in __nonzero__
    raise TypeError("cannot determine truth value of Relational")
TypeError: cannot determine truth value of Relational

I suppose I expected it to return an unevaluated integral -  integral(sin(x**n),x)

David

Aaron Meurer

unread,
Aug 20, 2019, 4:10:34 PM8/20/19
to sympy
"TypeError: cannot determine truth value of Relational" generally
indicates a bug in SymPy. And yes, integrate() should always return
unevaluated when it can't compute the integral.

Aaron Meurer
> --
> You received this message because you are subscribed to the Google Groups "sympy" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to sympy+un...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/sympy/b15c771c-5051-225d-bd0d-a655b6952de0%40dbailey.co.uk.

Oscar Benjamin

unread,
Aug 20, 2019, 6:36:06 PM8/20/19
to sympy
Hi David,

Can you open an issue on Github please. That's a bug that should be fixed.

Oscar

David Bailey

unread,
Aug 21, 2019, 5:10:28 AM8/21/19
to sy...@googlegroups.com
On 20/08/2019 23:35, Oscar Benjamin wrote:
Hi David,

Can you open an issue on Github please. That's a bug that should be fixed.

The problem is, I tried to join Github a while back, and then needed a password reset. It said it had sent me an email to reset my password, but it never appeared (and I looked in junk). After that happened several times, I gave up.

However, if that problem is already solved, that's fine, I was really just reporting it - I suspect the integral doesn't have a closed form for variable n. Do you release beta tests of the next version of sympy?

Or did you mean 'should' in the sense of 'needs to be'?

David

Kalevi Suominen

unread,
Aug 21, 2019, 6:41:19 AM8/21/19
to sympy
We should have, for example, `if (b < 0) == True or ...` here
  File "C:\SymPyWorkbook\lib\site-packages\sympy\integrals\meijerint.py", line 1684, in _meijerint_indefinite_1
    if b < 0 or f.subs(x, 0).has(nan, zoo):
Kalevi Suominen

David Bailey

unread,
Aug 21, 2019, 6:50:33 AM8/21/19
to sy...@googlegroups.com
On 20/08/2019 21:10, Aaron Meurer wrote:
"TypeError: cannot determine truth value of Relational" generally
indicates a bug in SymPy. And yes, integrate() should always return
unevaluated when it can't compute the integral.

I imagine that symbolic integration may be littered by tricky problems of this sort, and I wonder if the integrate code should be wrapped in some sort of exception handler so that it exits and returns unevaluated.

David

Oscar Benjamin

unread,
Aug 21, 2019, 7:12:14 AM8/21/19
to sympy
I think that would hide all kinds of bugs. It's better to see the
exception and fix the code. Maybe after that check (if it didn't
raise) something more useful could be done than return unevaluated.

Oscar

Oscar Benjamin

unread,
Aug 21, 2019, 7:20:11 AM8/21/19
to sympy

Aaron Meurer

unread,
Aug 21, 2019, 2:33:47 PM8/21/19
to sympy
We don't do builds, but you can clone the git version of SymPy and try
it. If you run Python from within the repo directory, it will import
the git version. Since SymPy is pure Python there are no builds
required.

Aaron Meurer

>
> Or did you mean 'should' in the sense of 'needs to be'?
>
> David
>
> --
> You received this message because you are subscribed to the Google Groups "sympy" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to sympy+un...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/sympy/1e134532-2e6a-6f55-f5da-19d73cc978bf%40dbailey.co.uk.

Oscar Gustafsson

unread,
Aug 22, 2019, 2:16:49 AM8/22/19
to sy...@googlegroups.com
The bug was fixed in https://github.com/sympy/sympy/pull/17343 but is not merged (yet). 

Hopefully it happens soon.

BR Oscar


Reply all
Reply to author
Forward
0 new messages