import numpy as np
import matplotlib.pyplot as plt
import numdifftools as nd
from numpy import linalg as LA
from numpy import array
# Function definition
#function = ((x2-x1)**4)+(8*x1*x2)-x1+x2+3
def funct(x):
return ((x[1]-x[0])**4)+(8*x[0]*x[1])-x[0]+x[1]+3
x = np.array([1.5, 1.5]) # initial Value
y=funct(x)
grad=nd.Gradient(funct)(x)
norm_grad_square=np.dot(grad,grad)
p=-grad
N=15000
epsilon = 10^(-6)
alpha_bar=5
c=0.1
rho=0.8
alpha=alpha_bar
curve_x = [x]
curve_y = [y]
i=1
while(i<=N) or (norm_grad_square>=epsilon):
p= -grad
misc=np.dot(grad,p)
j=1
while (funct(x+alpha*p)>(funct(x)+(c*alpha*misc)) or j<=1000):
alpha_new=rho*c
alpha=alpha_new
j+=1
x=x+(alpha*p)
y=funct(x)
grad=nd.Gradient(funct)(x)
norm_grad_square=np.dot(grad,grad)
curve_x.append(x)
curve_y.append(y)
i+=1
if i==N:
print("Maximun iterations reached but convergence did not happen")
print("x= ", x,"function= ",y,"Gradient= ",grad)
else:
print("x= ",x,"function= ",y,"Gradient= ",grad)
我的代码没有运行,也没有显示任何错误。我正在运行一个算法来计算数组,直到达到函数的最小值数组包含自变量。我正在使用内置函数计算函数的梯度。
你有一个无限循环或无限循环,对吧?
当症状";"无限循环";,然后,如注释所示,调试(while-(循环的退出条件。
使用打印进行调试
例如:
- 减少到所需的变量和语句
- 然后在循环中添加print语句以监视退出条件
import numpy as np
import numdifftools as nd
def funct(x):
return ((x[1]-x[0])**4)+(8*x[0]*x[1])-x[0]+x[1]+3
x = np.array([1.5, 1.5]) # initial Value
# ..
grad=nd.Gradient(funct)(x)
norm_grad_square=np.dot(grad,grad) # used in exit-condition of loop
# ..
N=15000 # used in exit-condition of loop
epsilon = 10^(-6) # used in exit-condition of loop
# ...
i=1 # used in exit-condition of loop
while(i<=N) or (norm_grad_square>=epsilon):
print(i,N,norm_grad_square,epsilon) # debug print
print(f"{(i<=N)} or {(norm_grad_square>=epsilon)}")
# remainder of your loop body: removed for simplicity
i+=1
打印一个无休止的循环:
1 15000 289.9999999999993 -16
True or True
2 15000 289.9999999999993 -16
True or True
..
15000 15000 289.9999999999993 -16
True or True
15001 15000 289.9999999999993 -16
False or True
..
356977 15000 289.9999999999993 -16
False or True
省略号显示了省略的输出,几秒钟后我用CTRL+C中断了查看。
我们可以观察到i
是如何超过N
而不是15000
的。
逻辑分析
我们不是期望让循环计数器变量i
随着每次迭代而增加并近似于常数最大值N
吗。
让我们隔离循环及其退出条件,只检查i
。
N=15000
# omitted to focus on: i, N
i=1
while(i<=N):
# loop body
i+=1
# end of loop
if i==N:
print("Maximun iterations reached but convergence did not happen")
print(i, N) # debug final i compared to N
是否未打印预期的最大消息,但:
15001 15000
好消息是,循环以有限的i
结束。这不是(i<=N)
也不是i==N
而是i > N
或者至少是i >= N
。
现在我们可以得出结论:退出条件的另一侧(or
的右侧(似乎未得到满足或包含错误。
待办事项
我把进一步的调试留给了你。我会开始将N
设置得更低,从N = 3
开始,并在密切监控其他退出条件(例如(的情况下略微增加
N = 3
i = 1
while(i<=N) or (norm_grad_square>=epsilon):
print(i,N,norm_grad_square,epsilon) # debug print
# gradually insert loop-body
i += 1
您甚至可以逐渐添加循环体的语句,以观察它们在每次迭代中的演变以及对退出条件的影响。