Integrals in Python: Add object not callable

有些话、适合烂在心里 提交于 2019-12-12 12:11:54

问题


I'm trying to solve an integral of a taylor approximation of a sin(x) function by using the trapezoid rule. The code seems fine but it keep giving me the following error: "TypeError: 'Add' object is not callable"

This is my code:

 import math
 import numpy
 import sympy as sy
 import numpy as np
 from sympy.functions import sin,cos
 import matplotlib.pyplot as plt
 x = sy.Symbol('x')
 f = sin(x)
 # Factorial function
     if n <= 0:
         return 1
     else:
         return n*factorial(n-1)

 taylor_series = sin(x).series(n=None)
 # Do a trapezoid integration
     xedge = numpy.linspace(a,b,N+1)
     integral = 0.0
     n = 0
     while n < N:
         integral += 0.5*(xedge[n+1] - xedge[n])*(f(xedge[n]) + f(xedge[n+1]))
         n += 1
     return integral

 N = 3
 a = 0.0
 b = 1.0

 z = sum([next(taylor_series) for i in range(N)])
 print("Taylor series:",z)
 # Trapezoid rule result 
 N = 2
 while (N <= 2):
     dd = trap(a,b,z,N)
     print ('Trapezoid rule result:', dd)
     N *= 2

The traceback:

Error: Traceback (most recent call last):
  File "Question1.py", line 86, in <module>
    dd = trap(a,b,z,N)
  File "Question1.py", line 67, in trap
    integral += 0.5*(xedge[n+1] - xedge[n])*(f(xedge[n]) + f(xedge[n+1]))
TypeError: 'Add' object is not callable

回答1:


In your case f is a sympy expression. You cannot just evaluate it by calling it; you have to use the evalf() method:

...
integral += 0.5*(xedge[n+1] - xedge[n])*(f.evalf(xedge[n]) + f.evalf(xedge[n+1]))
...

Produces the output:

Taylor series: x**5/120 - x**3/6 + x
Trapezoid rule result: 0.0079345703125*x**5 - 0.158203125*x**3 + 1.0*x

End



回答2:


Your command f = sin(x) is invalid; the argument is a sympy.Symbol, not a legal argument to the sin function.

For future reference, here's how I broke down the problem to isolate the error. Replacing f with sin worked around the problem ... likely not what you need for your assignment, but useful in debugging.

import math
import numpy
import sympy as sy
import numpy as np
from sympy.functions import sin,cos
import matplotlib.pyplot as plt
x = sy.Symbol('x')
print "sy.Symbol('x') is", x, type(x)
f = sin(x)

# Factorial function that will be used in the Taylor approximation
def factorial(n):
    if n <= 0:
        return 1
    else:
        return n*factorial(n-1)

taylor_series = sin(x).series(n=None)

#def fun(x):
#   return numpy.sin(x)


# Do a trapezoid integration by breaking up the domain [a,b] into N slabs
def trap(a,b,f,N):

    xedge = numpy.linspace(a,b,N+1)

    integral = 0.0

    n = 0
    while n < N:
        x0 = xedge[n]
        x1 = xedge[n+1]
        print x0, x1
        sub1 = x1 - x0
        f0 = math.sin(x0)
        f1 = math.sin(x1)
        sub2 = f0 + f1
        integral = integral + 0.5 * sub1 * sub2
        n += 1

    return integral


N = 3
a = 0.0
b = 1.0
# takes the number of terms desired for your generator
z = sum([next(taylor_series) for i in range(N)])
print("Taylor series:",z)

# Trapezoid rule result and calculaiton of error term
N = 2

while (N <= 2):
    dd = trap(a,b,z,N)
    print ('Trapezoid rule result:', dd)
    N *= 2


来源:https://stackoverflow.com/questions/35468985/integrals-in-python-add-object-not-callable

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!