【发布时间】:2017-10-03 11:58:15
【问题描述】:
我正在尝试使用 BFGS 方法最小化一个函数。最初,我将函数创建为表达式。在第一次迭代中,我的第一个表达式是
f_sym = ((x0 - x6)**2 + (y0 - y6)**2)**0.5 + ((x0 - x9)**2 + (y0 - y9)**2)**0.5 + ((-x1 + 36)**2 + (-y1 + 9)**2)**0.5 + ((x1 - x7)**2 + (y1 - y7)**2)**0.5 + ((-x10 + x3)**2 + (-y10 + y3)**2)**0.5 + ((-x10 + x7)**2 + (-y10 + y7)**2)**0.5 + ((-x12 + x3)**2 + (-y12 + y3)**2)**0.5 + ((-x12 + x6)**2 + (-y12 + y6)**2)**0.5 + ((-x9 + 48)**2 + (-y9 + 97)**2)**0.5
variables = [x1, y1, x9, y9, x0, y0, x6, y6, x7, y7, x3, y3, x10, y10, x12, y12] #variables of the function expression f_sym
fprime_sym = [f_sym.diff(x_) for x_ in variables] # derivative of f_sym
要为上述符号表达式创建向量化函数,我使用sympy.lamdify,如下所示:
f_lmbda = sympy.lambdify(symvar, f_sym, 'numpy')
fprime_lmbda = sympy.lambdify(symvar, fprime_sym, 'numpy')
sympy.lambdify 生成的函数为相应表达式中的每个变量采用一个参数。此外,SciPy 优化函数需要一个矢量化函数,其中所有坐标都打包到一个数组中。为了获得与 SciPy 优化例程兼容的函数,我们需要将 sympy.lambdify 生成的每个函数都用一个重新洗牌的 Python 函数包装参数。我尝试如下:
def func_XY_to_X_Y(f):
""" Wrapper for f(X) -> f(X[0], X[1])"""
return lambda X: np.array(f(X[0],X[1],X[2],X[3],X[4],X[5],X[6],X[7],X[8],X[9],X[10],X[11],X[12],X[13],X[14])) #since f_sym has 14 parameters we need 14 X[i]s
f = func_XY_to_X_Y(f_lmbda)
fprime = func_XY_to_X_Y(fprime_lmbda)
现在函数 f 和 fprime 是向量化的 Python 函数。那么,
x_opt = optimize.fmin_ncg(f, x_0, fprime=fprime, fhess=fhess) #x_0 is the initial condition for all the variables
这解决了函数并返回变量值的新数组。
如果只有一个函数表达式,这个过程可以手动完成。
但是如果这发生在一个循环中,每个函数表达式中的变量数量将是不同的。因此,我需要使我的def func_XY_to_X_Y(f): 成为动态的。
有人可以帮我把它变成一个动态的吗?
【问题讨论】:
标签: python-3.x lambda mathematical-optimization