I am making a system of linear equation approximation in python. So I defined a class and made two kinds of iterators. Both use below format.
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)
One works well but one fails to return the right 'itr' value. It counts up to itr=20 than suddenly becomes itr=0 and returns 'itr=1'
For the wierd iterator, I tried counting by appending too, but did not work. Below is the part of the code.
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))
I tried to implement this error work in simpler code, but this error did not occur for simpler code. So I will append my whole class code and the problematic code below.
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)
and below is the wierd count part.
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])
By the way this is my first time asking on stack overflow. I hope this is right way to make questions here.
you're calling the Jacobi_iteration method twice within the print statement, which means it's executed twice, potentially leading to different results.
p_15.Jacobi_iteration() is called twice: once to retrieve the solution ([0]) and once to retrieve the iteration count ([1]). However, because the method is executed separately each time, it can conflict the results yield in both cases, especially if the computation involves randomness or iterative processes.
To ensure consistent results and avoid redundant computation, you should call the Jacobi_iteration method once and store the result in a variable.This way, the method is only executed once, and you get the correct iteration count.
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])
Or if you want much readable or self-explanaotry variables names then you can split the result and assign it to better variables names