1

I can't figure it out what's wrong with my code, it's rly frustrating. I have to make inverse matrix function, what I thought I've done. I don't know why it doesn't work. The problem is probably in line with stars, after this step my matrix named mat is changed to identity matrix, but why? Before stars it prints my mat matrix normaly which I gave to function, but after stars it's a identity matrix, I don't understand why it happend. Here's what I have:

def identity_matrix_convertion(m):
    x = m[:]
    for i in range(len(x)):
        for j in range(len(x[0])):
            if i == j:
                x[i][j] = 1
            else:
                x[i][j] = 0
    return x

def inverse_matrix(mat):
    n = len(mat)
    am = mat[:]
    show_matrix(mat)
    **i = identity_matrix_convertion(am)**
    show_matrix(mat)
    im = i[:]
    ind = list(range(n))
    print(len(mat))
    if determinant(mat) == 0:
        print("This matrix doesn't have an inverse.")
    if len(mat) == len(mat[0]):
        for i in range(n):
            scal = 1.0 / am[i][i]
            for j in range(n):
                am[i][j] *= scal
                im[i][j] *= scal
            for k in ind[0:i] + ind[i + 1:]:
                current_scal = am[k][i]
                for l in range(n):
                    am[k][l] = am[k][l] - current_scal * am[i][j]
                    im[k][l] = im[k][l] - current_scal * im[i][j]
    return im

so after line **i = identity_matrix_convertion(am)** my mat matrix is changed into identity matrix, but why?

    The result is:
    
    1.0 2.0 3.0 
    2.0 1.0 3.0 
    4.0 3.0 2.0 
    
    The result is:
    1 0 0 
    0 1 0 
    0 0 1 
Joe
  • 69
  • 1
  • 8
  • 1
    provide some sample input and show what error are you getting – Rahul Vishwakarma Jun 26 '20 at 14:27
  • Please reduce and enhance this into the expected [MRE](https://stackoverflow.com/help/minimal-reproducible-example). Show where the intermediate results deviate from the ones you expect. Also, please learn to format and label your output; you have buried your operations within unreadable `print` commands. – Prune Jun 26 '20 at 14:30
  • Will this be used for only 2x2 matrices or larger? Do you need this code to work for any and all dimensions or do you know the dimensions of the matrices you will be given? – NumberC Jun 26 '20 at 14:36
  • It works for higher dimensions too. User have to specify dim and input matrix before, it's a part of larger program. – Joe Jun 26 '20 at 14:46
  • Are you sure the matrix has an inverse? If not, you may want to add this to the top of `identity_matrix_conertion()`: `if len(m) == 0: return None if len(m[0]) != len(m): return None` – NumberC Jun 26 '20 at 14:50

2 Answers2

1

Instead of saying x = m[:] in the identity_matrix_convertion() function, you should add the following snippet:

x = []
for i in m:
    arr = [a for a in i]
    x.append(arr)

x = m[:] is still referencing m instead of just making a copy.

NumberC
  • 596
  • 7
  • 17
  • Oh. Tohught that x = m[:] is a proper way if I want to make a new copy. Thx – Joe Jun 26 '20 at 15:07
  • 1
    We have to be precise here. `x = m[:]` does not reference m, but it only creates a shallow copy. Try `a = [1,2,3]`, `b = a[:]`, `a[1] = 4` and then `print b` it'll print `[1,2,3]`. What causes the trouble is the shallowness of the copy, so the elements within the list are references, since we deal with a 2D matrix as list of lists. https://docs.python.org/3/library/copy.html – Csaba Toth Feb 10 '22 at 00:53
0

Following up on @NumberC's answer, the x = m[:] does make a copy, but only a shallow copy. The copied list will contain references to internal lists of the other list, and so manipulating those lists within x cause change in m too. This is because we represent the 2D matrix as list of lists. If someone would reorder the lists in m (so not the items within the lists but just the pure order of the lists within m) the order would stay the same in the x copy. However any change within the list of the lists is mutating the other too. I hope this is not confusing, List changes unexpectedly after assignment. Why is this and how can I prevent it? has some figures.

Since we don't have to scare away from [:] we can still say:

x = new_list = [y[:] for y in m]

Or even better: we can use the built-in copy module (available everywhere):

import copy
x = copy.deepcopy(m)

See also: Copying nested lists in Python

Csaba Toth
  • 10,021
  • 5
  • 75
  • 121