Search code examples
pythonmathmatrixinverse

Finding Inverse of Matrix using Cramer's Rule


I have created a function determinant which outputs a determinant of a 3x3 matrix. I also need to create a function to invert that matrix however the code doesn't seem to work and I can't figure out why.

M = np.array([
 [4.,3.,9.],
 [2.,1.,8.],
 [10.,7.,5.]
 ])

def inverse(M):
'''
This function finds the inverse of a matrix using the Cramers rule.

Input: Matrix - M
Output: The inverse of the Matrix - M.
'''

    d = determinant(M) # Simply returns the determinant of the matrix M.

    counter = 1
    array = []

    for line in M: # This for loop simply creates a co-factor of Matrix M and puts it in a list.
        y = []
        for item in line:
             if counter %2 == 0:
                x = -item
             else:
                x = item
         counter += 1
        y.append(x)
    array.append(y)

    cf = np.matrix(array) # Translating the list into a matrix.
    adj = np.matrix.transpose(cf) # Transposing the matrix.
    inv = (1/d) * adj
    return inv

OUTPUT:

via inverse(M):

 [[ 0.0952381  -0.04761905  0.23809524],
 [-0.07142857  0.02380952 -0.16666667],
 [ 0.21428571 -0.19047619  0.11904762]]

via built-in numpy inverse function:

 [[-1.21428571  1.14285714  0.35714286]
 [ 1.66666667 -1.66666667 -0.33333333]
 [ 0.0952381   0.04761905 -0.04761905]]

As you can see some of the numbers match and I'm just not sure why the answer isn't exact as I'm using the formula correctly.


Solution

  • You co-factor matrix calculation isn't correct.

    def inverse(M):
      d = np.linalg.det(M)
    
      cf_mat = []
      for i in range(M.shape[0]):
          for j in range(M.shape[1]):
              # for each position we need to calculate det
              # of submatrix without current row and column
              # and multiply it on position coefficient
              coef = (-1) ** (i + j)
              new_mat = []
              for i1 in range(M.shape[0]):
                  for j1 in range(M.shape[1]):
                      if i1 != i and j1 != j:
                          new_mat.append(M[i1, j1])
              new_mat = np.array(new_mat).reshape(
                  (M.shape[0] - 1, M.shape[1] - 1))
              new_mat_det = np.linalg.det(new_mat)
              cf_mat.append(new_mat_det * coef)
    
      cf_mat = np.array(cf_mat).reshape(M.shape)
      adj = np.matrix.transpose(cf_mat)
      inv = (1 / d) * adj
      return inv
    

    This code isn't very effective, but here you can see, how it should be calculated. More information and clear formula you can find at Wiki.

    Output matrix:

    [[-1.21428571  1.14285714  0.35714286]
     [ 1.66666667 -1.66666667 -0.33333333]
     [ 0.0952381   0.04761905 -0.04761905]]