symengine / symengine.py

Python wrappers for SymEngine
MIT License
163 stars 65 forks source link

Real Symbols not treated as Real in symengine trigonometric functions #286

Open drf777 opened 5 years ago

drf777 commented 5 years ago

My program involves multiple complex variables that are multiplied together, and I will need to separate the Real parts from the Imaginary parts after all the multiplications are done. But this simple test in symengine does not seem to work, and I believe it is because I could not find an equivalent sympy.re and sympy.im functions in symengine:

from symengine import  Symbol, I, exp, cos, sin
from sympy import  im, re

x = Symbol('x', real=True)

print(re(cos(x)))

f=cos(x)+I*sin(x)
print(re(f))

Result:

cos(re(x))*cosh(im(x))

-cos(re(x))*sinh(im(x)) + cos(re(x))*cosh(im(x))

If I use all sympy for the above (i.e. from sympy import Symbol, im, re, cos, sin, I ) it works fine. It seems sympy.re and sympy.im are incompatible with symengine, not recognizing that the Symbol x is declared as Real in symengine.

Is there a symengine method to separate Real and Imaginary parts?

Separately, but related, it seems Functions also cannot be separated into Real and Imaginary parts:

y = symengine.Function("y")
g = y(0) + I* y(1)
print(re(g))

Result: re(g(0)) - im(g(1))

Again, I believe this is all due to no symengine.re or symengine.im, but I may be mistaken. Please advise, otherwise I must manually separate out Real and Imaginary parts of a very complicated equation. Thanks in advance.

isuruf commented 5 years ago

symengine doesn't have support for assumptions yet. So, x = Symbol('x', real=True) is equivalent to x = Symbol('x') (There should be a warning there saying real=True is disregarded.)

drf777 commented 5 years ago

I understand. Any idea if/when assumptions will be implemented?

whipstein commented 4 years ago

Anything on this topic? Without being able to keep a variable as a real number, it effectively eliminates the usefulness of symengine for use in any complex symbolic computation. I have some coding experience, but not a lot in C++. If you want to point me in the right direction for what to update to implement this feature, I'm willing to help out on this.

certik commented 4 years ago

I think the way to do it cleanly is to have an Assumption class in C++ that keeps assumptions, for example that x is Real (or anything more complicated such as x+y>0). Then we should implement the function re in SymEngine, and it would accept an optional argument assumptions and if you pass the Assumption class with x as Real, the re function would take then into account when rewriting the expression. I think that's how Mathematica works (https://reference.wolfram.com/language/ref/Assumptions.html) and that's a clean way to do it. The way SymPy does it is not clean, it tremendously complicates (and slows down) the inner code.