Reputation: 10204
I have a 2-parameter python function
def foo(x,y):
// a numeric operation that returns a double
I need to use scipy.optimize.minimize to locate a minimal point of f near a point, say (1.2, 3.4)
I have tried with
scipy.optimize.minimize(foo, (1.2, 3.4))
scipy.optimize.minimize(foo, [1.2, 3.4])
and
scipy.optimize.minimize(foo, *[1.2,3.4])
None of them works, yielding
TypeError: function takes exactly 2 arguments (1 given)
So my only solution seems to be wrapping the function, such as
scipy.optimize.minimize(lambda X:foo(*X), [1.2,3.4]),
The last one works, but I fear that the extra layer with the lambda term introduces unnecessary time overhead. Because my application is highly performance-sensitive, I am asking an efficient solution to let scipy.optimize.minimize accept a input pair for foo, without the potential time overhead. Any idea? Thanks.
Upvotes: 1
Views: 106
Reputation: 66850
You should define your function in terms of a single (possibly multidimensional) argument. Thus you do not use
def foo(x,y):
// a numeric operation that returns a double
but instead
def foo(x):
// use x[0] in place of original x
// and x[1] in place of original y
for example for f(x,y) = x + y^2 you use
def foo(x):
return x[0] + x[1] ** 2
If you are not allowed to modify foo
then you can always wrap it around with another function
def foowrap(x):
return foo(x[0], x[1])
which should be slightly more efficient then unwraping list to positional arguments (* operator)
just to test
>>> timeit.timeit('foowrap([1,2])', setup='from __main__ import foowrap', number=10000000)
5.230706214904785
>>> timeit.timeit('foo([1,2])', setup='from __main__ import foo', number=10000000) # this is your lambda term
5.379893779754639
so very small speedup, but it is.
Upvotes: 3