Home > OS >  Matrix determinant
Matrix determinant

Time:03-23

I have this function to get determinant of matrix

    def determinant(self) -> int:
        """
        Calculates the Determinant of matrix objects.
        Parameters
        ----------
        self
        Returns
        -------
        int
        Example
        -------
        >>> _matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
        >>> _matrix = Matrix(_matrix)
        >>> _matrix.determinant()
        0
        """
        if self.row != self.column:
            raise ValueError('Cannot get determinant of this matrix! Must be a square Matrix')
        else:
            def det(matrix):
                row = len(matrix)
                col = len(matrix[0])

                if (row, col) == (1, 1):
                    return matrix[0][0]

                # hard coding for 2x2
                elif (row, col) == (2, 2):
                    return matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0]

                # using sarrus method to solve for 3x3, it's a little faster.
                elif (row, col) == (3, 3):
                    matrix1 = matrix[:]

                    # Extending matrix to use Sarrus Rule.
                    for i in range(row - 1):
                        _col = []
                        for j in range(col):
                            _col.append(matrix1[i][j])
                        matrix1.append(_col)

                    # Calculating Determinant
                    # Adding part
                    add_pointers = [(i, i) for i in range(row)]
                    result = 0
                    for pointer in range(row):
                        temp = 1
                        for tup in add_pointers:
                            i, j = tup
                            temp *= matrix1[i   pointer][j]
                        result  = temp

                    # Subtracting part
                    sub_pointers = [((row - 1) - i, 0   i) for i in range(row)]
                    for pointers in range(row):
                        temp = 1
                        for tup in sub_pointers:
                            i, j = tup
                            temp *= matrix1[i   pointers][j]
                        result -= temp
                    return result

                else:
                    sign = -1
                    result = 0
                    row1 = [matrix[0][i] * (sign ** i) for i in range(col)]
                    for x, y in enumerate(row1):
                        mat = matrix[:][1:]
                        sub_matrix = [[mat[i][j] for j in range(col) if j != x] for i in range(row - 1)]
                        result  = y * det(sub_matrix)
                    return result

            return det(self.matrix)

i have hard-coded determinant of 2x2 and 3x3 matrix, then im recusing through the rest

as u can see its using recursion of nxn matrix(s)... i'm sure there is a faster way, this is extremely slow A python implementation of the method would be recommended, thank you

CodePudding user response:

The most common best ways would be either list comprehension or the numpy module.

Reason: The for loops will almost certainly be slower than a numpy array simply because of the contiguous and homogeneous nature of a numpy array. In simple terms numpy is basically one memory block all of the same type, where as a list points to different memory blocks and can contain any type.

Here is the numpy example (for 2d):

import numpy as np

a = np.array([[1, 2], [3, 4]])
result = np.linalg.det(a)


print(result)

One of the comments already (correctly) points to this: https://numpy.org/doc/stable/reference/generated/numpy.linalg.det.html

For more general larger m*n matricies, the advantages would be significant.

CodePudding user response:

Find determinant for 3x3 matrix using the first row:

"""
M:
    M11 M12 M13
    M21 M22 M23
    M31 M32 M33

detM:
    M11 * det2D([ [M22, M23], [M32, M33] ]) - 
    M12 * det2D([ [M21, M23], [M31, M33] ])   
    M13 * det2D([ [M21, M22], [M31, M32] ])    
"""

import numpy as np

def det3D(M):
    a = M[0][0] * det2D(np.array([ [ M[1][1],M[1][2] ], [ M[2][1],M[2][2] ] ]))
    b = M[0][1] * det2D(np.array([ [ M[1][0],M[1][2] ], [ M[2][0],M[2][2] ] ]))
    c = M[0][2] * det2D(np.array([ [ M[1][0],M[1][1] ], [ M[2][0],M[2][1] ] ]))
    return a - b   c


def det2D(M):
    return M[0][0]*M[1,1] - M[0][1] * M[1][0]


M = [ [1,0,0], [0,2,2], [0,2,4] ]
A = det3D(M)
B = round(np.linalg.det(M))
print(A)
print(B)
print(A == B)

Output:

4
4
True
  • Related