Reputation: 715
In Python I'm trying
from scipy.integrate import quad
time_start = 0
fun = lambda time: [cos(time), sin(time)]
integral = lambda time: quad(fun, time_start, time)
and would like the program to return integral
as a list of which the elements are the element wise integration of fun
, so [quad(cos, time_start, time), quad(sin, time_start, time)]
.
I, however, get TypeError: must be real number, not list
.
How do I solve this?
Upvotes: 0
Views: 1258
Reputation: 22544
Don't use quad
on a function that returns a list of two functions--instead, use it twice on two functions then compose the results into a list. The documentation for scipy.integrate.quad gives the possible signatures for the function to be integrated, and each signature shows that the function must return a double
value (called float
in Python), not a list.
If you cannot change the definitions of time_start
or fun
or the parameters or return value of integral
, you could use this code.
from math import cos, sin
from scipy.integrate import quad
# Global variables and constants used in function `integral`
time_start = 0
fun = lambda time: [cos(time), sin(time)]
# The desired function
def integral(time):
"""Return a list of two items containing the integrals of the two
components of the `fun` function from `start_time` to `time`.
"""
def fun0(time):
return fun(time)[0]
def fun1(time):
return fun(time)[1]
integral0 = quad(fun0, time_start, time)[0]
integral1 = quad(fun1, time_start, time)[0]
return [integral0, integral1]
Then the result of the statement
print(integral(0), integral(pi/2), integral(pi))
is
[0.0, 0.0] [0.9999999999999999, 0.9999999999999999] [3.6775933888827275e-17, 2.0]
which is what you want, within precision error.
By the way, using a lambda
expression to create a function then assigning it to a name is considered to be poor programming practice in Python. See here, the fifth bullet point. Use a regular def
block instead:
def fun(time):
return [cos(time), sin(time)]
def integral(time):
# as shown above
Of course, the use of time_start
and fun
as global variables, rather than as parameters of integral
, is also bad practice, but I kept to the way you used them.
Upvotes: 1