0

Just for practice, I am using nested lists (for exaple, [[1, 0], [0, 1]] is the 2*2 identity matrix) as matrices. I am trying to compute determinant by reducing it to an upper triangular matrix and then by multiplying its diagonal entries. To do this:

"""adds two matrices"""
def add(A, B):
    S = []
    for i in range(len(A)):
        row = []
        for j in range(len(A[0])):
            row.append(A[i][j] + B[i][j])
        S.append(row)
    return S

"""scalar multiplication of matrix with n"""
def scale(n, A):
    return [[(n)*x for x in row] for row in A]

def detr(M):
    Mi = M
    #the loops below are supossed to convert Mi
    #to upper triangular form:
    for i in range(len(Mi)):
        for j in range(len(Mi)):
            if j>i:
                k = -(Mi[j][i])/(Mi[i][i])
                Mi[j] = add( scale(k, [Mi[i]]), [Mi[j]] )[0]
    #multiplies diagonal entries of Mi:
    k = 1
    for i in range(len(Mi)):
        k = k*Mi[i][i]
    return k

Here, you can see that I have set M (argument) equal to Mi and and then operated on Mi to take it to upper triangular form. So, M is supposed to stay unmodified. But after using detr(A), print(A) prints the upper triangular matrix. I tried:

  • setting X = M, then Mi = X
  • defining kill(M): return M and then setting Mi = kill(M)

But these approaches are not working. This was causing some problems as I was trying to use detr(M) in another function, problems which I was able to bypass, but why is this happening? What is the compiler doing here, why was M modified even though I operated only on Mi?

(I am using Spyder 3.3.2, Python 3.7.1)

(I am sorry if this question is silly, but I have only started learning python and new to coding in general. This question means a lot to me because I still don't have a deep understanding of this language.)

Hoque
  • 101
  • 1
  • You need to create a copy of `M`. By doing for example: `M[:]`, or `list(M)`. even though you do `Mi = M`, both are still *referencing** the same list in memory – Tomerikoo Jul 18 '19 at 14:45
  • Read this [answer](https://stackoverflow.com/a/17686659/6045800) for a fuller explanation – Tomerikoo Jul 18 '19 at 14:51
  • Possible duplicate of [Function changes list values and not variable values in Python](https://stackoverflow.com/questions/17686596/function-changes-list-values-and-not-variable-values-in-python) – Tomerikoo Jul 18 '19 at 14:51

1 Answers1

0

See python documentation about assignment: https://docs.python.org/3/library/copy.html

Assignment statements in Python do not copy objects, they create bindings between a target and an object. For collections that are mutable or contain mutable items, a copy is sometimes needed so one can change one copy without changing the other.

You need to import copy and then use Mi = copy.deepcopy(M)

See also How to deep copy a list?

Ipiano
  • 234
  • 1
  • 8