python-3.xjupyter-notebooknumerical-analysis

inner function changing the variable value of outer function


def swap(i,r,c,mat):

    for j in range(i+1,c):
        if(abs(mat[j][j])>0):
            mat[[j,i]] = mat[[i,j]]
            break

    return mat


def upper_triMat(matA,r,c):

    np.set_printoptions(precision=4)

    # forward elimination
    for i in range(0,c-1):
        if matA[i][i] == 0:
            matA = swap(i,r,c,matA)
    
    for j in range(i+1,r):
        multiplier = matA[j][i]/matA[i][i]
        for k in range(0,c):
            matA[j][k] = matA[j][k] - multiplier*matA[i][k]
                
    return matA


def dolittle(A):
 
    A = np.array(A)
    r,c = np.shape(A)
    print(A)
    U = upper_triMat(A,r,c) # Here the value of A is changed U. 
    print(A)
    l = np.eye(r,c)
    for i in range(0,r-1):
        for j in range(i+1,r):
            sum = 0
            for k in range(0,r):
                if i != k:
                    sum = sum + U[k][i]*l[j][k]
            l[j][i] = (A[j][i]-sum)/U[i][i]
        
    return l,U


A = [[3,-0.1,-0.2],
    [0.1,7,-0.3],
    [0.3,-0.2,10]]

dolittle(A)

When i call the upper_triMat function "A" changes in dolittle function. Why?? A is A and the upper_triMat function assigning it to U. But A is also getting the value of U. Using Jupyter Notebook. I am doing LU decomposition


Solution

  • upper_triMat mutates its parameter matA. And since matA is a reference to A, it's being modified. Maybe you could fix it that way

    U = upper_triMat(A.copy(),r,c) # pass a copy of the list instead of the reference of the original one.