Python 求解非线性方程组的信赖域折线法
您好,我正在尝试为我拥有的一个类编写一个信赖域算法,该算法使用python中的dogleg方法。我有一个牛顿法算法和布罗登法算法,它们彼此一致,但我似乎无法让这个狗腿法工作 以下是我试图找到解决方案的函数:Python 求解非线性方程组的信赖域折线法,python,Python,您好,我正在尝试为我拥有的一个类编写一个信赖域算法,该算法使用python中的dogleg方法。我有一个牛顿法算法和布罗登法算法,它们彼此一致,但我似乎无法让这个狗腿法工作 以下是我试图找到解决方案的函数: def test_function(x): x1 = float(x[0]) x2 = float(x[1]) r = np.array([[x2**2 - 1], [np.sin(x1) - x2]]) return r
def test_function(x):
x1 = float(x[0])
x2 = float(x[1])
r = np.array([[x2**2 - 1],
[np.sin(x1) - x2]])
return r
这是我写的雅可比矩阵
def Test_Jacobian(x, size):
e = create_ID_vec(size)
#print(e[0])
epsilon = 10e-8
J = np.zeros([size,size])
#print (J)
for i in range(0, size):
for j in range(0, size):
J[i][j] = ((test_function(x[i]*e[j] + epsilon*e[j])[i] - test_function(x[i]*e[j])[i])/epsilon)
return J
这是我的信赖域算法:
def Trust_Region(x):
trust_radius = 1
max_trust = 300
eta = rand.uniform(0,.25)
r = test_function(x) # change to correspond with the function you want
J = Test_Jacobian(r, r.size) # change to correspond with function
i = 0
iteration_table = [i]
function_table = [vector_norm(r, r.size)]
while vector_norm(r, r.size) > 10e-10:
print(x, 'at iteration', i, "norm of r is", vector_norm(r, r.size))
p = dogleg(x, r, J, trust_radius)
rho = ratio(x, J, p)
if rho < 0.25:
print('first')
trust_radius = 0.25*vector_norm(p,p.size)
elif rho > 0.75 and vector_norm(p,p.size) == trust_radius:
print('second')
trust_radius = min(2*trust_radius, max_trust)
else:
print('third')
trust_radius = trust_radius
if rho > eta:
print('x changed')
x = x + p
#r = test_function(x)
#J = Test_Jacobian(r, r.size)
else:
print('x did not change')
x = x
r = test_function(x) # change to correspond with the function you want
J = Test_Jacobian(r, r.size) # change to correspond with function
i = i + 1
#print(r)
#print(J)
#print(vector_norm(p,p.size))
print(rho)
#print(trust_radius)
iteration_table.append(i)
function_table.append(vector_norm(r,r.size))
print ('The solution to the non-linear equation is: ', x)
print ('This solution was obtained in ', i, 'iteratations')
plt.figure(figsize=(10,10))
plt.plot(iteration_table, np.log10(function_table))
plt.xlabel('iteration number')
plt.ylabel('function value')
plt.title('Semi-Log Plot for Convergence')
return x, iteration_table, function_table
def dogleg(x, r, J, trust_radius):
tau_k = min(1, vector_norm(J.transpose().dot(r), r.size)**3/(trust_radius*r.transpose().dot(J).dot(J.transpose().dot(J)).dot(J.transpose()).dot(r)))
p_c = -tau_k*(trust_radius/vector_norm(J.transpose().dot(r), r.size))*J.transpose().dot(r)
if vector_norm(p_c, p_c.size) == trust_radius:
print('using p_c')
p_k = p_c
else:
p_j = -np.linalg.inv(J.transpose().dot(J)).dot(J.transpose().dot(r))
print ('using p_j')
tau = tau_finder(x, p_c, p_j, trust_radius, r.size)
p_k = p_c + tau*(p_j-p_c)
return p_k
def ratio(x, J, p):
r = test_function(x)
r_p = test_function(x + p)
print (vector_norm(r, r.size)**2)
print (vector_norm(r_p, r_p.size)**2)
print (vector_norm(r + J.dot(p), r.size)**2)
rho_k =(vector_norm(r, r.size)**2 - vector_norm(r_p, r_p.size)**2)/(vector_norm(r, r.size)**2 - vector_norm(r + J.dot(p), r.size)**2)
return rho_k
def tau_finder(x, p_c, p_j, trust_radius, size):
a = 0
b = 0
c = 0
for i in range(0, size):
a = a + (p_j[i] - p_c[i])**2
b = b + 2*(p_j[i] - p_c[i])*(p_c[i] - x[i])
c = (p_c[i] - x[i])**2
c = c - trust_radius**2
tau_p = (-b + np.sqrt(b**2 - 4*a*c))/(2*a)
tau_m = (-b - np.sqrt(b**2 - 4*a*c))/(2*a)
#print(tau_p)
#print(tau_m)
if tau_p <= 1 and tau_p >=0:
return tau_p
elif tau_m <= 1 and tau_m >=0:
return tau_m
else:
print('error')
return 'error'
def model_function(p):
r = test_function(x)
J = Test_Jacobian(r, r.size)
return 0.5*vector_norm(r + J.dot(p), r.size)**2
def信任区域(x):
信任半径=1
最大信任度=300
eta=平均兰特(0.25)
r=测试功能(x)#更改以符合所需的功能
J=测试_雅可比矩阵(r,r.size)#与函数相对应的变化
i=0
迭代_表=[i]
函数\u表=[向量\u范数(r,r.size)]
当向量_范数(r,r.size)>10e-10时:
打印(x,‘在迭代中’,i,“r的范数为”,向量_范数(r,r.size))
p=狗腿(x,r,J,信赖半径)
rho=比率(x,J,p)
如果rho<0.25:
打印('第一个')
信任半径=0.25*向量标准(p,p.size)
elifρ>0.75且向量_范数(p,p.size)=信任半径:
打印('秒')
信任半径=最小值(2*信任半径,最大信任)
其他:
打印('第三')
信任半径=信任半径
如果rho>eta:
打印('x已更改')
x=x+p
#r=测试功能(x)
#J=测试_雅可比矩阵(r,r.尺寸)
其他:
打印('x未更改')
x=x
r=测试功能(x)#更改以符合所需的功能
J=测试_雅可比矩阵(r,r.size)#与函数相对应的变化
i=i+1
#印刷品(r)
#印刷品(J)
#打印(向量_范数(p,p.size))
打印(rho)
#打印(信任半径)
迭代_table.append(i)
函数\表.追加(向量\范数(r,r.size))
print('非线性方程的解为:',x)
print('此解决方案是在'i'迭代'中获得的)
plt.图(figsize=(10,10))
plt.plot(迭代表,np.log10(函数表))
plt.xlabel('迭代编号')
plt.ylabel('函数值')
plt.title(‘收敛的半对数图’)
返回x,迭代表,函数表
def狗腿(x,r,J,信赖半径):
tau_k=min(1,向量_范数(J.transpose().dot(r),r.size)**3/(信任半径*r.transpose().dot(J.transpose().dot(J)).dot(J.transpose().dot(J)).dot(J.transpose().dot(r)))
p_c=-tau_k*(信赖半径/向量_范数(J.transpose().dot(r),r.size))*J.transpose().dot(r)
如果向量_范数(p_c,p_c.size)=信任半径:
打印('使用p_c')
p_k=p_c
其他:
p_j=-np.linalg.inv(j.transpose().dot(j)).dot(j.transpose().dot(r))
打印('使用p_j')
tau=tau_查找器(x,p_c,p_j,信任半径,r.size)
p_k=p_c+tau*(p_j-p_c)
返回Pk
def比率(x,J,p):
r=测试功能(x)
r_p=测试函数(x+p)
打印(向量_范数(r,r.尺寸)**2)
打印(矢量规格(r\U p,r\U p.尺寸)**2)
打印(矢量_范数(r+J点(p),r尺寸)**2)
rho_k=(向量_范数(r,r.size)**2-向量_范数(r_p,r_p.size)**2)/(向量_范数(r,r.size)**2-向量_范数(r+J.dot(p),r.size)**2)
返回rho_k
def tau_finder(x、p_c、p_j、信任半径、大小):
a=0
b=0
c=0
对于范围内的i(0,大小):
a=a+(p_j[i]-p_c[i])**2
b=b+2*(p_j[i]-p_c[i])*(p_c[i]-x[i])
c=(p_c[i]-x[i])**2
c=c-信任半径**2
tau_p=(-b+np.sqrt(b**2-4*a*c))/(2*a)
tau_m=(-b-np.sqrt(b**2-4*a*c))/(2*a)
#印刷品(陶普)
#印刷品(头像)
如果tau_p=0:
返回头p
elif tau_m=0:
返回塔乌姆
其他:
打印('错误')
返回“错误”
def型号_功能(p):
r=测试功能(x)
J=测试_雅可比矩阵(r,r.尺寸)
返回0.5*向量_范数(r+J.dot(p),r.size)**2
答案应该是[1.57076525],[1.]]
但这是大约28-30次迭代后的输出:
ZeroDivisionError Traceback (most recent call last)
<ipython-input-359-a414711a1671> in <module>
1 x = create_point(2,1)
----> 2 Trust_Region(x)
<ipython-input-358-7cb77bd44d7b> in Trust_Region(x)
11 print(x, 'at iteration', i, "norm of r is", vector_norm(r, r.size))
12 p = dogleg(x, r, J, trust_radius)
---> 13 rho = ratio(x, J, p)
14
15 if rho < 0.25:
<ipython-input-358-7cb77bd44d7b> in ratio(x, J, p)
71 print (vector_norm(r_p, r_p.size)**2)
72 print (vector_norm(r + J.dot(p), r.size)**2)
---> 73 rho_k =(vector_norm(r, r.size)**2 - vector_norm(r_p, r_p.size)**2)/(vector_norm(r, r.size)**2 - vector_norm(r + J.dot(p), r.size)**2)
74 return rho_k
75
ZeroDivisionError: float division by zero
ZeroDivisionError回溯(最近一次调用)
在里面
1 x=创建_点(2,1)
---->2信任区(x)
在信任区(x)
11打印(x,'在迭代',i,“r的范数为”,向量_范数(r,r.size))
12 p=狗腿(x,r,J,信赖半径)
--->13ρ=比值(x,J,p)
14
15如果rho<0.25:
比例(x,J,p)
71打印(矢量标准(r\u p,r\u p.大小)**2)
72打印(矢量_范数(r+J点(p),r尺寸)**2)
--->73 rho_k=(向量_范数(r,r.大小)**2-向量_范数(r_p,r.大小)**2)/(向量_范数(r,r.大小)**2-向量_范数(r+J.点(p),r.大小)**2)
74返回rho_k
75
ZeroDivisionError:浮点除以零