Reputation: 434
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
Upvotes: 4
Views: 17678
Reputation: 77837
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
Upvotes: 0
Reputation: 9726
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
Upvotes: 4