在Python中计数失败

问题描述 投票:0回答:1

我正在用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])

顺便说一句,这是我第一次询问堆栈溢出问题。我希望这是在这里提问的正确方式。

python class while-loop
1个回答
0
投票

您在 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])

或者,如果您想要更多可读或不言自明的变量名称,那么您可以拆分结果并将其分配给更好的变量名称

© www.soinside.com 2019 - 2024. All rights reserved.