Reputation: 137
The aim of the program is to:
"Write a python function J(m,x) that calculates the value of Jm(x) using the trapezium rule, with N = 10000. Use your function in a program to make a plot of the Bessel functions J0(x), J1(x) and J2(x) as a function of x from x = 0 to x = 20."
Jm(x) = (1/pi) . integrate[cos(m.theta - x.sin(theta))] from 0 --> pi
and is part of an intro to python module for a 1st year physics degree.
The line the type error originates from is from my function to integrate a function using the trapezium rule:
def integrate(f, a, b, N:int):
h = (b-a) / N
s = 0
for i in range(1,N):
c = f(a + i*h)
s = s + c
Area = h*(0.5*f(a) + 0.5*f(b) + s)
return Area
The error refers to the line " c = f(a + i*h) ": "TypeError: 'numpy.float64' object is not callable".
Given this function works in other programs I've made, I'm not sure what the origin of this error is. I am aware that scipy.integrate.quad could do the integration better, however we've been asked not to use it to demonstrate learning different techniques.
One possibility is that the problem is caused by other parts of the larger program. As someone very new to programming in general it seems likely that other problems exist which I haven't run into yet as the program doesn't reach them before turning up an error. The rest of the code is as follows:
import numpy as np
#Defining how to integrate a function using the trapezium rule
def integrate(f, a, b, N:int):
h = (b-a) / N
s = 0
for i in range(1,N):
c = f(a + i*h)
s = s + c
Area = h*(0.5*f(a) + 0.5*f(b) + s)
return Area
def func(o, m, x):
return np.cos(m*o - x*np.sin(o)) #1st attempt at defining the bessel function
def J(m,x):
return (1 / np.pi) * integrate(func(0, m, x), 0, np.pi, 10000)
#Produce range of x-values from 0 to 20.
xvals = np.linspace(0,20,200)
#Calculating the value of the bessel function for each value of x and m
for i in range(200):
for j in range(3):
bessel = J(j, xvals[i])
print("x: {}, m: {}, Val: {}".format(xvals[i], j, bessel)) #Print statement to check the program is functioning correctly before moving on to the next stage
Upvotes: 2
Views: 258
Reputation: 819
return (1 / np.pi) * integrate(func(0, m, x), 0, np.pi, 10000)
In your function J
, you are giving a function call as a parameter, i.e. its return value. Change func(0, m, x)
to func
and it should work.
Edit:
The correct answer was to pass a lambda expression: lambda i: func(i, m, x)
. Credit goes to Barmar.
Upvotes: 1