How to check if an expression returned from sympy integrate command still contain an instance of integrals.Integral or ? NonElementaryIntegral
I am trying to check the antiderivative from sympy to see if it was successful or not, by checking if it remains unevaluated or not
For example:
from sympy import *
x=symbols('x')
isinstance(Integral(x**2, x),integrals.Integral)
Works and returns True. But if the expression has one instance Integral inside other expressions, how to check?
I need a way to look at the expression tree and see if at least one instance of integrals.Integral exist in it, and return True. I am not sure how to iterate over it and do this at this time.
I tried the following (I am very much a newbie in Python and sympy).
from sympy import *
x=symbols('x')
expr=integrate((-x**2+2)*exp(x/(x**2+2))/(x**3+2*x),x)
which gives
-Integral(-2*exp(x/(x**2 + 2))/(x**3 + 2*x), x) -
Integral(x**2*exp(x/(x**2 + 2))/(x**3 + 2*x), x)
expr.args #which is tuple
(-Integral(-2*exp(x/(x**2 + 2))/(x**3 + 2*x), x), -
Integral(x**2*exp(x/(x**2 + 2))/(x**3 + 2*x), x))
any(isinstance(m, integrals.Integral) for m in expr.args)
But this gave False, why?
I also tried
for m in expr.args:
isinstance(m, integrals.Integral)
And this gaves
False
False
I was expecting both to be True.
How to check if an expression contains at least one instance of integrals.Integral any where in it?
Update
Ok, found something. The integrals above are actually NonElementaryIntegral
and not Integral. Looking at the expression tree of expr
srepr(expr)
"Add(Mul(Integer(-1), NonElementaryIntegral(Mul(Integer(-1), Integer(2),
Pow(Add(Pow(Symbol('x'), Integer(3)), Mul(Integer(2), Symbol('x'))),
Integer(-1)), exp(Mul(Symbol('x'), Pow(Add(Pow(Symbol('x'), Integer(2)),
Integer(2)), Integer(-1))))), Tuple(Symbol('x')))), Mul(Integer(-1),
NonElementaryIntegral(Mul(Pow(Symbol('x'), Integer(2)),
Pow(Add(Pow(Symbol('x'), Integer(3)), Mul(Integer(2), Symbol('x'))),
Integer(-1)), exp(Mul(Symbol('x'), Pow(Add(Pow(Symbol('x'), Integer(2)),
Integer(2)), Integer(-1))))), Tuple(Symbol('x')))))"
So I need to look for both Integral and NonElementaryIntegral. But so far, I do not know how to check for NonElementaryIntegral since I do not know in which class it is supposed to be. It is not integral.NonElementaryIntegral and need to find where this lives.
any(isinstance(mx, integrals.NonElementaryIntegral) for mx in anti.args)
gives
error: module 'sympy.integrals.integrals' has no attribute
'NonElementaryIntegral'
The page http://docs.sympy.org/latest/modules/integrals/integrals.html only says
If the indefinite Integral returned by this function is an instance of
NonElementaryIntegral, that means that the Risch algorithm has proven that
integral to be non-elementary.
Ok, but how to check for it?
expr.has(Integral)
does this. The class NonElementaryIntegral inherits from Integral, so according to inheritance rules it suffices to check for Integral.
A self-contained example would be
from sympy import *
x = symbols('x')
expr = integrate(exp(x**4)/(x**2+1), x)
print(expr.has(Integral))
You can find detailed information about the class names by using
print([type(a) for a in preorder_traversal(expr)])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With