import numpy as np
from scipy import optimize
- 定义要求最小值的函数,这里以 为例
# 定义目标函数
def target_function(x,y):
return (1-x)**2+100*(y-x**2)**2
- 计算出定义函数的Jacobian矩阵和Hessian矩阵(BFGS不需要Hessian矩阵,但是其他算法需要,所有可以提前计算出来)
- 由于 ,所以Jacobian矩阵为
+ 由于 ,所有Hessian矩阵为
- 使用一个类来保存函数、函数的Jacobian矩阵、函数的Hessian矩阵
class TargetFunction(object):
def __init__(self):
self.f_points = []
self.fjac_points = []
self.fhess_points = []
def f(self,p):
'''
给定点p(x,y),返回函数值f(x,y)
'''
x,y = p.tolist()
z = target_function(x,y)
self.f_points.append((x,y))
return z
def fjac(self,p):
'''
给定点p(x,y),返回函数在点p处的Jacobian矩阵
'''
x,y = p.tolist()
self.fjac_points.append((x,y))
dx = -2 + 2*x -400*x*(y-x**2)
dy = 200*y -200*x**2
return np.array([dx,dy])
def fhess(self,p):
'''
给定点p(x,y),返回函数在点p处的Hessian矩阵
'''
x,y = p.tolist()
self.fhess_points.append((x,y))
hess = np.array([[2*(600*x**2-200*y+1),-400*x],
[-400*x,200]])
return hess
函数原型:scipy.optimize.minimize(fun, x0, args=(), method=None, jac=None, hess=None, hessp=None, bounds=None, constraints=(), tol=None, callback=None, options=None);常用参数解释如下:
fun:取局部最小值的函数
x0:初始点
method:优化方法,包括Nelder-Mead、Powell、CG、BFGS、Newtom-CG、L-BFGS-B、TNC、COBYLA、SLSQP、dogleg、trust-ncg、
jac:计算函数fun的Jacobian矩阵
hessian:计算函数fun的Hessian矩阵
target = TargetFunction()
# 初始点
init_point = (-1,-1)
# 使用BFGS求局部极小值
res = optimize.minimize(target.f,init_point,method="BFGS",jac=target.fjac)
print(res)
fun: 1.8499217223747175e-16
hess_inv: array([[ 0.50825961, 1.01607777],
[ 1.01607777, 2.03629519]])
jac: array([ 2.76270214e-07, -1.26083165e-07])
message: 'Optimization terminated successfully.'
nfev: 40
nit: 31
njev: 40
status: 0
success: True
x: array([ 1.00000001, 1.00000002])