1

I'm trying to write some code to carry out the Jacobi method for solving linear equations (I realise my method is not the most efficient way to do this but I am trying to figure out why it's not working).

I have tried to debug the problem and noticed the following issue. The code finishes after 2 iterations because on the second iteration on line 32 when xnew[i] is assigned a new value, the same value is also assigned to x[i], even though x[i] is not referenced. Why is this happening on the second iteration and not the first time the for loop is run and is there a way to fix this?

Thanks in advance

import numpy as np

A = np.array(
    [[0.93, 0.24, 0],
     [0.04, 0.54, 0.26],
     [1, 1, 1]])

b = np.array([[6.0], [2.0], [10.0]])

n , m  = np.shape(A) 

x = np.zeros(shape=(n,1))

xnew = np.zeros(shape=(n,1))

iterlimit = 100 
tol = 0.0000001 


for  iteration in range(iterlimit):

    convergence = True
    for i in range(n):
        sum=0
        for j in range(n):
            if j != i:
                sum = sum + (A[i,j] * x[j])
        
        #on second iteration (iteration =1) below line begins to
        #assign x[i] the same values as it assigns xnew[i] causing the 
        #convergence check below to not run and results in a premature break
        xnew[i] = 1/A[i,i] * (b[i] - sum) 
                     
        if abs(xnew[i]-x[i]) > tol:
            convergence = False
            
    if convergence:
        break
    
    x = xnew

print("Iteration:", iteration+1)
print("Solution:")
print(np.matrix(xnew))
AMC
  • 2,642
  • 7
  • 13
  • 35
dinusha
  • 43
  • 5

2 Answers2

2
x = xnew

This line assigns xnew to x. Not the contents of xnew, but the array itself. So after your first iteration, x and xnew reference the same array in memory.

Try instead x[:] = xnew[:]

Michael
  • 2,344
  • 6
  • 12
  • Thanks! Does this rule of x = xnew assigning both variables to the same thing in memory only apply to objects in python? Because it doesn't apply to simple variables right? For example if x and xnew were integers instead of arrays, this would be fine. – dinusha Oct 29 '20 at 00:40
  • @user157691 This generally applies to all Python variables. If `x` and `xnew` were integers, assigning `x = xnew` would cause both variables to point to the same integer in memory (and you can check this by looking at the `id(x)` and `id(xnew)`, or checking whether `x is xnew` is true, before and after the assignment). If you then ran a function on that integer that altered its value somehow (but without using the python assignment operator `=`, since that creates a new integer in memory) then both variables would appear to be pointing to the same value still. – Michael Oct 29 '20 at 00:50
1

The problem is here : x = xnew

In fact, this way you are referencing to the same object now. So obviously when you will change xnew , you are changing the object represented by xnew which is now also referenced by x.

So to just make a copy you can write :

x = xnew[:]
OR
x = xnew.copy()
kaouther
  • 369
  • 1
  • 11