Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to check if sympy expression contains instance of Integral or NonElementaryIntegral?

Tags:

sympy

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?

like image 721
Nasser Avatar asked Nov 01 '25 15:11

Nasser


1 Answers

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)])

Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!