在 Python 中定义动态函数

Defining a dynamic function in Python

我正在尝试使用 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 函数,该函数重新洗牌 arguments.I 尝试过的函数如下:

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

这解决了函数和 returns 新的变量值数组。

如果只有一个函数表达式,这个过程可以手动完成。 但是如果这发生在循环内部,每个函数表达式中的变量数量就会不同。因此,我需要使我的 def func_XY_to_X_Y(f): 成为一个动态的。

有人可以帮我把它变成动态的吗?

使用 *-argument unpacking operator:

def func_XY_to_X_Y(f):
    """ Wrapper for f(X) -> f(X[0], X[1], ..., X[n])"""
    return lambda X: np.array(f(*X))