在Python中定义动态函数

时间:2017-10-03 11:58:16

标签: python-3.x lambda mathematical-optimization

我正在尝试使用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优化例程兼容的函数,我们需要使用重新调整参数的Python函数来包装sympy.lambdify生成的每个函数。我尝试如下:

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):成为动态的 i = 0 image_decoded = tf.image.decode_jpeg(tf.read_file('3.jpg'), channels=3) cropped = tf.image.crop_to_bounding_box(image = image_decoded, offset_height = tf.cast(bound_box_output[i,0], tf.int32), offset_width = tf.cast(bound_box_output[i,1], tf.int32), target_height = tf.cast(bound_box_output[i,2], tf.int32), target_width = tf.cast(bound_box_output[i,3], tf.int32)) enc = tf.image.encode_jpeg(cropped) fname = tf.constant('4.jpeg') fwrite = tf.write_file(fname, enc)

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

1 个答案:

答案 0 :(得分:2)

使用*-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))