Search code examples
pythonsympypolynomialssymbolic-integration

AttributeError: 'poly1d' object has no attribute 'is_commutative'


I am trying to integrate the function I, which contains the Legendre polynomial leg_f:

import math
import numpy as np
from mpmath import *
from sympy import *
from scipy.special import legendre

n = 3

c = lambda h_c,z,R : (z**2+h_c**2)**0.5
c_supp = lambda h_c,z,R : (z**2+h_c**2)**(-n)    
x = lambda h_x,z,R : -4*R*(R-h_x)/c(h_x,z,R)**2

leg_f = lambda h_l,z,R : legendre(n-1,(1-0.5*x(h_l,z,R))/(1-x(h_l,z,R))**0.5)

f_f_symb = lambda h_v,z,R : hyper((n, 0.5), (1), (-4*R*(R-h_v)/(z**2+h_v**2)))

I = lambda h_i,z_i,R_i : c_supp(h_i,z_i,R_i)*(1-x(h_i,z_i,R_i))**(-n/2)*leg_f(h_i,z_i,R_i)

h_i,z_i,R_i = symbols('h_i z_i R_i')

int_result = integrate(I(h_i,z_i,R_i), (z_i, 0, np.inf)) 

But I get the error

Traceback (most recent call last):
  File "test.py", line 99, in <module>
    int_result = integrate(I(h_i,z_i,R_i), (z_i, 0, np.inf)) 
  File "/Users/Library/Python/2.7/lib/python/site-packages/sympy/integrals/integrals.py", line 1276, in integrate
    integral = Integral(*args, **kwargs)
  File "/Users/Library/Python/2.7/lib/python/site-packages/sympy/integrals/integrals.py", line 75, in __new__
    obj = AddWithLimits.__new__(cls, function, *symbols, **assumptions)
  File "/Users/Library/Python/2.7/lib/python/site-packages/sympy/concrete/expr_with_limits.py", line 389, in __new__
    obj.is_commutative = function.is_commutative  # limits already checked
AttributeError: 'poly1d' object has no attribute 'is_commutative'

What could be the problem? Is it the right way to integrate such function in sympy?


Solution

  • There are some issues with your code that I can see:

    1. You do not need to import legendre function from SciPy. SymPy has its own legendre function which gets imported when you write from sympy import *. Also, if you are interested in symbolic results you should not use SciPy or NumPy at all.
    2. If you want symbolic computations you should not write decimal numbers like 0.5 in your code. Instead you should use Rational(1,2) which is SymPy object that represents the fraction 1/2.
    3. Instead of using NumPy's inf for infinity, you should use Sympy's oo for infinity.

    The following code gets rid of the above issues and therefore the original error that you were getting.

    from sympy import *
    
    n = 3
    c = lambda h_c,z,R : (z**2+h_c**2)**Rational(1,2)
    c_supp = lambda h_c,z,R : (z**2+h_c**2)**(-n)    
    x = lambda h_x,z,R : -4*R*(R-h_x)/c(h_x,z,R)**2
    leg_f = lambda h_l,z,R : legendre(n-1,(1-Rational(1,2)*x(h_l,z,R))/(1-x(h_l,z,R))**Rational(1,2))
    I = lambda h_i,z_i,R_i : c_supp(h_i,z_i,R_i)*(1-x(h_i,z_i,R_i))**(-n*Rational(1,2))*leg_f(h_i,z_i,R_i)
    
    h_i,z_i,R_i = symbols('h_i z_i R_i')
    
    int_result = integrate(I(h_i,z_i,R_i), (z_i, 0, inf))
    

    Unfortunately, though SymPy cannot quickly integrate the function that you have. Your integrand looks like this

    Original

    After simplification it becomes a little easier on the eyes but SymPy seems to get stuck trying to evaluate this integral.

    Simplified

    Unless symbolic results are absolutely necessary, I would recommend numerical integration for this problem.