Using scipy to minify a function that also takes nonvariant parameters

I want to use a module scipy.optimize

to minimize a function. Let's say my function is f(x,a)

:

def f(x,a):
 return a*x**2

      

For fixed, a

I want to minimize f(x,a)

in relation to x

.

With, scipy

I can import, for example, a function fmin

(I have an old scipy: v.0.9.0), give an initial value x0

, and then optimize ( documentation ):

from scipy.optimize import fmin
x0 = [1]
xopt = fmin(f, x0, xtol=1e-8)

      

which fails because it f

takes two arguments and fmin

only passes one (actually, I haven't defined yet a

). If I do this:

from scipy.optimize import fmin
x0 = [1]
a = 1
xopt = fmin(f(x,a), x0, xtol=1e-8)

      

the computation will also fail because "x is undefined". However, if I define x

then there is no variation parameter to optimize.

How do I allow non-variant parameters to be used as function arguments here?

+3


source to share


3 answers


Read the argument args

fmin

in your docstring and use



a = 1
x0 = 1
xopt = fmin(f, x0, xtol=1e-8, args=(a,))

      

+7


source


The argument args

is probably the correct approach here, but here's a different approach that is sometimes useful. First, you write a wrapper function for f that will take a function and a value as inputs and return a new function where it is a

fixed.

def fix_a(f, a):
    def f_with_fixed_a(x):
        return f(x, a)
return f_with_fixed_a

      

Then you can call fmin like this:



xopt = fmin(fix_a(f, a), x0, xtol=1e-8)

      

If all you have to do is pass fixed a

using the keyword args

for fmin, this is probably too verbose, but this approach is more flexible and can handle more complex situations (for example, if you wanted to do a

some function x

).

+3


source


In your case, Warren's canonical solution is probably the right choice.

However, it's worth noting that you can also optimize the member functions of the classes. In this case, you have access to class variables that can be used as arguments. This is especially useful if your code is already object-based and adding a member function for optimization makes sense.

In your example, this solution (overkill) would be:

class FunctionHolder(object):
    def __init__(self,a):
        self.a=a
    def f(self, x):
        return x*self.a

f1=FunctionHolder(1)
scipy.optimize.minimize(f1.f, x0)

      

0


source







All Articles