Python中的积分:添加不可调用的对象

时间:2016-02-17 22:23:54

标签: python sympy

我试图通过使用梯形规则来解决sin(x)函数的泰勒近似的积分。代码似乎很好,但它一直给我以下错误:" TypeError:' Add'对象不可调用"

这是我的代码:

 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

追溯:

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

2 个答案:

答案 0 :(得分:4)

在您的情况下,fsympy表达式。你不能只是通过调用来评估它;你必须使用evalf()方法:

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

产生输出:

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

End

答案 1 :(得分:0)

您的命令f = sin(x)无效;参数是sympy.Symbol,而不是sin函数的合法参数。

为了将来参考,我在这里解决问题以隔离错误。用f替换sin可以解决问题...可能不是您的任务所需,但在调试中很有用。

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