我想用Python实现一个伪代码给出的不精确(近似)牛顿算法:
数据:我们有一个x_0 \in R^n
,我们设一个函数f:R^n->R
,正黑森,0<c1<1
,0<\rho<1
结果:结果是估计f的全局最小值x_{k+1}
以下步骤:对于k = 0 ...直到停止条件do:
\eta_k=1/2 min{1/2,\sqrt(∥∇f(x_k)∥)}
\epsilon_k=\eta_k∥∇f(x_k)∥
p_k=conjugate_gradient(∇^2f(x_k),∇f(x_k),\epsilon_k)
\alpha_k=backtrack(x_k,p_k,1.0,c_1,\rho)
x_{k+1}=x_k+\alpha_kp_k
如果很难看到算法,那么我已经把它上传到了我之前的问题中:用Python实现不精确牛顿算法
我已经做了共轭梯度算法如下:
def conjugate_grad(A,b, maxiter = 100000):
n= A.shape[0]
x=np.zeros(n)
r=b-A@x
p=r.copy()
r_old=np.inner(r,r)
for it in range(maxiter):
alpha=r_old/np.inner(p,A@p)
x+=alpha*p
r-=alpha*A@p
r_new=np.inner(r,r)
if np.sqrt(r_new)<1e-100:
break
beta=r_new/r_old
p=r+beta*p
r_old=r_new.copy()
return x
但是我如何在Python中实现不精确(近似)牛顿算法,我如何处理最小值函数,以及我如何用回溯法正确地构建它,有人能帮助我吗?
1条答案
按热度按时间tez616oj1#
下面是一个在Python中使用共轭梯度和回溯线搜索函数实现的不精确(近似)牛顿算法
backtracking_line_search
函数将待最小化的函数f
、f的梯度grad_f
、当前迭代x
、搜索方向d
以及用于初始步长、回溯参数和Armijo条件参数的可选参数alpha
、rho
和c
作为输入,它使用回溯来找到满足Armijo条件的步长。newton_cg
函数类似于前面的实现,但是使用backtracking_line_search
函数而不是固定步长来执行线搜索,这应该提高算法的收敛性。下面是如何使用函数求解方程x3 - x2 - 1 = 0的示例: