我正在用Python制作一个线性方程近似系统。 所以我定义了一个类并制作了两种迭代器。 两者都使用以下格式。
itr=0
while acc_test==False:
#updating a solution#for i in range(curr_sol.shape[0]):
#curr_sol=copy.deepcopy(next_sol)
#next_sol[i,0]=(1-self.w)*curr_sol[i,0]+self.w*self.nthsol_update(curr_sol,i)
acc_test=self.acc_test(curr_sol,next_sol)
itr+=1
return(next_sol,itr)
其中一个运行良好,但无法返回正确的“itr”值。 它计数到 itr=20 然后突然变成 itr=0 并返回 'itr=1'
对于奇怪的迭代器,我也尝试通过附加进行计数,但没有成功。以下是部分代码。
itr=list([])
while acc_test==False:
#updating part#curr_sol=copy.deepcopy(next_sol)
#for i in range(curr_sol.shape[0]):
#next_sol[i,0]=self.nthsol_update(curr_sol,i)
#acc_test=self.acc_test(curr_sol,next_sol)
print('!')
itr.append(0)
print(itr)
print('?')
return(next_sol,len(itr))
我尝试用更简单的代码实现此错误工作,但更简单的代码不会发生此错误。所以我将在下面附加我的整个类代码和有问题的代码。
class diag_iterator:
def __init__(self,mat,rst,ini,acc,relaxation_coeff=1.0):
self.mat=np.array(mat,float)
self.rst=np.reshape(np.array(rst,float),[-1,1])
self.aug_mat=np.concatenate((np.array(mat,float),np.reshape(np.array(rst,float),[-1,1])),axis=1)
self.size=np.array(mat).shape[0]
self.ini=np.reshape(np.array(ini,float),[-1,1])
self.acc=acc
self.w=relaxation_coeff
def scarborough(self,ini_sol,next_sol,acc):
if ini_sol!=0:
return(abs((ini_sol-next_sol)/ini_sol)<0.5*10**(-acc))
else:
return(abs((ini_sol-next_sol)/0.00001)<0.5*10**(-acc))
def acc_test(self,ini_vec,next_vec):
work_ini=copy.deepcopy(ini_vec)
work_next=copy.deepcopy(next_vec)
acc_test=1
for i in range(work_ini.shape[0]):
acc_test*=self.scarborough(work_ini[i,0],work_next[i,0],self.acc+math.log10(2))
return(bool(acc_test))
def nthsol_update(self,sol_vec,n):
work_mat=copy.deepcopy(self.mat)
work_sol=copy.deepcopy(sol_vec)
work_mat=np.delete(work_mat,n-1,axis=1)[n-1,:]
work_sol=np.delete(work_sol,n-1,axis=0)
the_sum=work_mat@work_sol
nthsol=(self.mat[n-1,n-1]**(-1))*(self.rst[n-1,0]-the_sum)
return(nthsol)
def Jacobi_iteration(self):
curr_sol=copy.deepcopy(self.ini)
next_sol=np.empty_like(curr_sol)
acc_test=False
itr=list([])
while acc_test==False:
curr_sol=copy.deepcopy(next_sol)
for i in range(curr_sol.shape[0]):
next_sol[i,0]=self.nthsol_update(curr_sol,i)
acc_test=self.acc_test(curr_sol,next_sol)
print('!')
itr.append(0)
print(itr)
print('?')
return(next_sol,len(itr))
def gssSeidel_iteration(self):
curr_sol=copy.deepcopy(self.ini)
next_sol=curr_sol
acc_test=False
itr=0
while acc_test==False:
for i in range(curr_sol.shape[0]):
curr_sol=copy.deepcopy(next_sol)
next_sol[i,0]=(1-self.w)*curr_sol[i,0]+self.w*self.nthsol_update(curr_sol,i)
acc_test=self.acc_test(curr_sol,next_sol)
itr+=1
return(next_sol,itr)
下面是奇怪的计数部分。
mat_15=np.array([[4.63,-1.21,3.22],[-3.07,5.48,2.11],[1.26,3.11,4.57]])
p_15=diag_iterator(mat_15,np.array([2.22,-3.17,5.11]),np.zeros(3),1)
print('(a) Jacobi solution:',p_15.Jacobi_iteration()[0],'\n iteration count:',p_15.Jacobi_iteration()[1])
顺便说一句,这是我第一次询问堆栈溢出问题。我希望这是在这里提问的正确方式。
您在 print 语句中调用 Jacobi_iteration 方法两次,这意味着它执行了两次,可能会导致不同的结果。
p_15.Jacobi_iteration() 被调用两次:一次检索解 ([0]),一次检索迭代计数 ([1])。然而,由于该方法每次都是单独执行的,因此两种情况下的结果产量可能会发生冲突,特别是当计算涉及随机性或迭代过程时。
为了确保结果一致并避免冗余计算,您应该调用一次 Jacobi_iteration 方法并将结果存储在变量中。这样,该方法仅执行一次,您就可以获得正确的迭代计数。
mat_15=np.array([[4.63,-1.21,3.22],[-3.07,5.48,2.11],[1.26,3.11,4.57]])
p_15=diag_iterator(mat_15,np.array([2.22,-3.17,5.11]),np.zeros(3),1)
result_jacobi_itr=p_15.Jacobi_iteration()
print('(a) Jacobi solution:',result_jacobi_itr[0],'\n iteration
count:',result_jacobi_itr[1])
或者,如果您想要更多可读或不言自明的变量名称,那么您可以拆分结果并将其分配给更好的变量名称