Using scipy to minimize a function that also takes non variational parameters

自作多情 提交于 2019-11-30 18:11:59

问题


I want to use the scipy.optimize module to minimize a function. Let's say my function is f(x,a):

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

For a fixed a, I want to minimize f(x,a) with respect to x.

With scipy I can import for example the fmin function (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 f takes two arguments and fmin is passing only one (actually, I haven't even defined a yet). If I do:

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

the calculation will also fail because "x is not defined". However, if I define x then there is no variational parameter to optimize.

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


回答1:


Read about the args argument to fmin in its docstring, and use

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



回答2:


The args argument is probably the right approach here, but here's another approach that's useful sometimes. First you write a wrapper function for f which will take take a function and an a value as inputs and return a new function where a is 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 need to do is pass in a fixed a, using the args keyword of fmin is this is probably too verbose, but this approach is more flexible and can handle more complex situations (for example if you wanted to make a some function of x).




回答3:


For your case the canonical solution by Warren is probably the right choice.

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

In your example this (overkill) solution 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)


来源:https://stackoverflow.com/questions/25206482/using-scipy-to-minimize-a-function-that-also-takes-non-variational-parameters

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!