Search code examples
c#mathmatrixdeterminants

Next step in calculating a matrix determinant


I am writing a method that will calculate the determinant of a matrix (here, a two-dimensional array) containing doubles. Here is what I've written:

/// <summary>
/// Checks to see if a matrix is square, and then computes its determinant
/// </summary>
/// <returns></returns>
public double Determinant()
{
    // Check to make sure the matrix is square.  Only square matrices 
    // have determinants.
    if (!this.isSquare())
    {
        throw new Exception("The matrix does not have a determinant");
    }

    // Check to see if the matrix has dimensions 1x1.  
    // The determinant of a 1x1 matrix is equal to the value stored at (0,0).
    if (this.NumberOfRows == 1)
    {
        return this.GetElement(0, 0);
    }

    double determinant = 0;

    // Loop through the top row of the matrix.
    for (int columnIndex = 0; columnIndex < this.NumberOfColumns; columnIndex++)
    {
        Matrix cofactor = new Matrix(this.NumberOfRows - 1, this.NumberOfColumns - 1);

        //fill cofactor
        //I dont Know what to do here?


        determinant += this.GetElement(1, columnIndex) * cofactor.Determinant();
    }

    return determinant;
}

What I am missing is what should go at the line fill cofactor.

Can someone suggest what I should do there? Basically, what is the best way to add elements to cofactor from the original matrix while ignoring those that appear in the row or column of my current location in the matrix?


Solution

  • You just need to remove the first (zeroth) row and the column which you don't want. The following may be of use to you:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace ConsoleApplication1
    {
        class Program
        {
            /// <summary>
            /// Helper to show array.
            /// </summary>
            /// <param name="mat"></param>
            static void ShowArray(double[,] mat)
            {
                int ubound = mat.GetUpperBound(0);
    
                for (int row = 0; row <= ubound; row++)
                {
                    for (int col = 0; col <= ubound; col++)
                    {
                        Console.Write(string.Format("{0,2} ", mat[col, row]));
                    }
                    Console.WriteLine();
                };
    
                Console.WriteLine();
    
            }
    
            /// <summary>
            /// Get an array without the zeroth row and without a specified column.
            /// </summary>
            /// <param name="mat">The square array to remove items from.</param>
            /// <param name="knockoutCol">The column to eliminate.</param>
            /// <returns>A square array of size one less than the input array.</returns>
            static double[,] SubMatrix(double[,] mat, int knockoutCol)
            {
                if (mat.GetUpperBound(0) != mat.GetUpperBound(1))
                {
                    throw new ArgumentException("Array is not square.");
                }
    
                int ubound = mat.GetUpperBound(0);
                double[,] m = new double[ubound, ubound];
    
                int mCol = 0;
                int mRow = 0;
    
                for (int row = 1; row <= ubound; row++)
                {
                    mCol = 0;
                    for (int col = 0; col <= ubound; col++)
                    {
                        if (col == knockoutCol)
                        {
                            continue;
                        }
                        else
                        {
                            m[mCol, mRow] = mat[col, row];
                            mCol += 1;
                        }
                    }
                    mRow += 1;
    
                };
    
                return m;
            }
    
            static void Main(string[] args)
            {
                int arraySize = 4;
                double[,] mat = new double[arraySize, arraySize];
                int ubound = mat.GetUpperBound(0);
    
                // Initialise array for inspection.
                for (int row = 0; row <= ubound; row++)
                {
                    for (int col = 0; col <= ubound; col++)
                    {
                        mat[col, row] = (arraySize * row) + col;
                    }
                };
    
                ShowArray(mat);
    
                ShowArray(SubMatrix(mat, 0));
                ShowArray(SubMatrix(mat, 1));
                ShowArray(SubMatrix(mat, 2));
    
                Console.ReadLine();
    
            }
        }
    }
    

    Outputs:

     0  1  2  3
     4  5  6  7
     8  9 10 11
    12 13 14 15
    
     5  6  7
     9 10 11
    13 14 15
    
     4  6  7
     8 10 11
    12 14 15
    
     4  5  7
     8  9 11
    12 13 15
    

    If I was thinking about it more carefully when I started out, I might have swapped the rows and columns.