1

I have a function that returns an array:

def fun(x,a):
    return [a*x,a*x**2]

and I want to integrate it (using scipy quad):

def integrate(a):
    return quad(fun[0],0,1,args=a)
print integrate(1)

This gives TypeError: 'function' object is not subscriptable.
What's the right, pythonic way to do this?

5
  • So you want to integrate over ax? Commented Oct 30, 2015 at 18:17
  • fun[0] is trying to subscript the function. Did you want to subscript the results of the function? In that case the syntax is fun(param1, param2)[0] Commented Oct 30, 2015 at 18:19
  • @tzaman: yes, integrate over the first (or any other) array element Commented Oct 30, 2015 at 18:20
  • @RobertB: 'quad(fun(x,a)[0],0,1,args=a)' gives 'NameError: global name 'x' is not defined' Commented Oct 30, 2015 at 18:24
  • Looking at 'quad', the first param is a function. So fun is your funciton, not fun[0]. Also, do not call the second function "int" since that clobbers the standard python "int" type in your namespace. Commented Oct 30, 2015 at 18:27

2 Answers 2

5

Create a wrapper function around fun to select an element of the array. For example, the following will integrate the first element of the array.

from scipy.integrate import quad

# The function you want to integrate
def fun(x, a):
    return np.asarray([a * x, a * x * x])

# The wrapper function
def wrapper(x, a, index):
    return fun(x, a)[index]

# The integration
quad(wrapper, 0, 1, args=(1, 0))

Following @RobertB's suggestion, you should avoid defining a function int because it messes with the builtin names.

Sign up to request clarification or add additional context in comments.

4 Comments

I think 'wrapper' is probably the wrong term, but the solution is valid enough
@Stick, what would you suggest as an alternative? Happy to make changes.
imho - It's just a function that calls another function. A wrapper would suggest a situation where you can use the @my_func syntax, or make use of an enclosure or something, right?
That's part of it, but you couldn't use a decorator in your example (which is part of the reason I don't know about calling it a "wrapper function", it's not wrapping anything). It really doesn't change the validity of the answer, so it probably just doesn't matter
3

Your function returns an array, integrate.quad needs a float to integrate. So you want to give it a function that returns one of the elements from your array instead of the function itself. You can do that via a quick lambda:

def integrate(a, index=0)
    return quad(lambda x,y: fun(x, y)[index], 0, 1, args=a)

1 Comment

In this answer, I would not encourage the OP to define a function called 'int' since that will clobber the 'int' type. I know that it is what the OP did, but in your answer, perhaps you could use a different name?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.