Reputation: 9853
I am trying to create a function called calc(f,a,b)
where x is an equation with the variable f and I want to put this code within the function.
def calc(f, a, b):
limits = [a, b]
integral = odeint(lambda y, x : f, 0, limits)
return integral[1]
This function gets the integral using the built in odeint function. This is what I am trying to do
print calc(x**2, 0, 1)
where x^2
is the function to be integrated. My problem is that this function (x**2
)needs to be passed on to the odeint
function right after y, x: f
where f after the semicolon is the f
from the calc(f,a,b)
what I cant figure out is that how can I pass f
from the calc function input to the odeint inside. It says that f isnt declared and if I put it within strings.. it doest work
When I run this function.. it doesnt work I get this error
NameError: name 'f' is not defined
I am not sure how to pass my equation to be integrated inside odeint
Thanks
Upvotes: 1
Views: 3003
Reputation: 1522
If one were to rewrite the function calc
as follows:
def calc(f, a, b):
limits = [a, b]
integral = odeint(lambda y, x: f(x), 0, limits)
return integral[1][0]
Then one may use this function thus:
>>> calc(lambda x: x ** 2, 0, 1) # Integrate x ** 2 over the interval [0, 1] (expected answer: 0.333...)
0.33333335809177234
>>> calc(lambda x: x, 0, 1) # Integrate x over the interval [0, 1] (expected answer: 0.5)
0.50000001490120016
>>> calc(lambda x: 1, 0, 1) # Integrate 1 over the interval [0, 1] (expected answer: 1.0)
1.0
The odeint
function from the scipy.integrate
module has the signature:
odeint(func, y0, t, ...)
where: func
is a callable that accepts parameters y, t0, ...
and returns dy/dt at the given point; y0
is a sequence representing initial condition of y; t
is a sequence that represents intervals to solve for y (t0 is the first item in the sequence).
It appears that you are solving a first-order differential equation of the form dy/dx = f(x) over the interval [a, b] where y0 = 0. In such a case, when you pass f (which accepts one argument) to the function odeint, you must wrap it in a lambda so that the passed-in function accepts two arguments (y and x--the y parameter is essentially ignored since you need not use it for a first-order differential equation).
Upvotes: 2
Reputation: 123463
I'm not completely sure because odeint()
is not a built-in Python function so I don't know much about it, but the first argument you're passing it in your code is not a function that computes x^2
. An easy way to do something like that would be to pass a lambda
function to calc
that does that sort of calculation. For example:
def calc(f, a, b):
limits = [a, b]
integral = odeint(f, 0, limits)
return integral[1]
print calc(lambda x: x**2, 0, 1)
Upvotes: 0
Reputation: 56644
x cannot have two values; therefore, if you need two values, one of them must be named something else. Rename one of your variables.
Edit:
(smacking forehead): In calc(x**2, 0, 1)
, x**2
is not a function - it is an expression, which gets evaluated before being passed to calc - therefore it complains about it needs to know what x is (in order to calculate x**2).
Try
calc(lambda x: x**2, a, b)
instead. This is equivalent to
def unnamedfunction(x):
return x**2
calc(unnamedfunction, a, b)
Upvotes: 0
Reputation: 184171
I assume odeint
is some function to which you are passing the lambda function. odeint
will presumably call the lambda and needs to pass x
and y
to it. So the answer is, if you want odeint
to call the function and pass it x
and y
, then you need to pass x
and y
to odeint
as arguments, in addition to the function itself.
What exactly are you trying to do here? With more details and more code, we could probably get a better answer.
Upvotes: 1