Nasser
Nasser

Reputation: 13141

How to find if expression contains complex number I in it in SymPy?

Given an expression, how do I find (after simplifications if needed) if the expression contains the complex number I which is the square root of −1?

In Maple, this is done using the check has(expression,I); see its help page.

In Mathematica, this is done using the check If[FreeQ[expression, Complex], for example: How to check if expression contains a Complex expression?

But I am not sure how to do similar thing in SymPy.

Using expression.is_complex does not return True even if I in the expression. Also since real is subset of complex, this is not a correct test anyway.

I need to check for an explicit I that shows up in the expression anywhere (after simplification).

Here is an example: I am using SymPy 1.5.

from sympy import *
from sympy.abc import z
ex1=(-(((1 + 3*I) + sqrt(2))*cos(z/2)) + ((1 + I) - I*sqrt(2))*sin(z/2))/(((1 + I) + sqrt(2))*cos(z/2) + I*((-1 -I) + sqrt(2))*sin(z/2))
print(ex1.is_complex)
    #None
print(simplify(ex1).is_complex)
    #None

This is in Maple, for reference:

restart;
result:=(-(((1 + 3*I) + sqrt(2))*cos(z/2)) + ((1 + I) - I*sqrt(2))*sin(z/2))/(((1 + I) + sqrt(2))*cos(z/2) + I*((-1 -I) + sqrt(2))*sin(z/2));
has(simplify(result),I)

Which gives

Mathematica graphics

How to do the above in SymPy?

Upvotes: 1

Views: 661

Answers (1)

Wrzlprmft
Wrzlprmft

Reputation: 4415

has checks whether an expression contains some subexpression, such as I:

ex1.has(I)        # True
sin(z).has(I)     # False
(sin(z)+I).has(I) # True

Note that this does not take into account simplifications that might get rid of the I.

As for checks like is_complex, they consider all possible values of the input variable and return None if there is no clear answer (or if SymPy does not see a relevant simplification). Also, in your case, you want to use is_real (since real numbers are also complex in SymPy’s sense, as you noted). For illustration, consider the following:

z = Symbol("z")
(z+1).is_real  # None
(z+I).is_real  # None

z = Symbol("z", real=True)
(z+1).is_real  # True
(z+I).is_real  # False

Upvotes: 2

Related Questions