-1
$\begingroup$

I have been recently trying to attempt to write an algorithm in C# that would calculate the determinant of a matrix via recursion using the expansion of minors method. I understand that there are other methods such as upper and lower triangular forms which give the same solution, but for the moment I am trying to figure out this problem and I am having grave trouble trying to figure out why my programme is giving me the error that Object Reference is not set after a few iterations:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

class MatrixPractice
{

    public class Matrix
    {
        double[,] entries;

        public double[,] Entries
        {
            get {return entries;}
            set {entries = value;}
        }

        public Matrix(int number_of_rows, int number_of_columns)
        {
            Entries = new double[number_of_rows,number_of_columns];
        }

        static public void Print(Matrix A)
        {
            int counter = 0;
            int second_counter = 0;

            for(; counter < A.Entries.GetLength(0); counter++)
            {
                second_counter = 0;

                Console.WriteLine("\n");

                for(; second_counter < A.Entries.GetLength(1); second_counter++)
                {
                    Console.Write(A.Entries[counter, second_counter] + " ");
                }
            }
        }

        static public Matrix Multiply(Matrix A, double b)
        {
            int counter = 0;
            int second_counter = 0;
            Matrix C;

            C = new Matrix(A.Entries.GetLength(0), A.Entries.GetLength(1));

            for(; counter < A.Entries.GetLength(0); counter++)
            {
                second_counter = 0;

                for(; second_counter < A.Entries.GetLength(1); second_counter++)
                {
                    C.Entries[counter, second_counter] = A.Entries[counter, second_counter] * b;
                }
            }

            return C;
        }

        static bool IsDeterminantCalculationPossible(Matrix A)
        {
            if(A.Entries.GetLength(0) == A.Entries.GetLength(1))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

    static public int MathPow(int i, int j)
    {
        int counter = 1;
        int multiplier = -1;
        int result = 1;
        int limit = i + j;

        while (counter <= limit)
        {
            result = result * multiplier;
            counter++;
        }

        return result;

    }

    static public double Det(Matrix A)
    {
        double determinant = 0.0;
        double cofactor = 0.0;
        int j = 0;
        Matrix[] Array = new Matrix[A.Entries.GetLength(0)];

        if(IsDeterminantCalculationPossible(A))
        {

            for(; j < A.Entries.GetLength(0); j++)
            {
                Array[j] = new Matrix(A.Entries.GetLength(0) - 1, A.Entries.GetLength(0) - 1);

                if(Array[j].Entries.GetLength(0) > 1)
                {
                    Array[j] = Matrix.Multiply(DeleteRowColumn(A, 0, j), MathPow(1, j+1) * A.Entries[0,j]);

                    cofactor = Det(Array[j]);
                    determinant = determinant + cofactor;
                }
                else
                {
                    Array[j] = Matrix.Multiply(DeleteRowColumn(A, 0, j), MathPow(1, j+1) * A.Entries[0, j]);
                    determinant = determinant + Array[j].Entries[0,0];
                }
            }

            return determinant;
        }
        else
        {
            throw new System.ArgumentException("The matrix must be of the square type before its determinant can be calculated.");
        }
    }

    static void Main() 
    {
        Matrix matrix_a = new Matrix(3,3);

        double determinant = 0.0;

        matrix_a.Entries[0,0] = 5;
        matrix_a.Entries[0,1] = -1;
        matrix_a.Entries[0,2] = 2;
        matrix_a.Entries[1,0] = 4;
        matrix_a.Entries[1,1] = 11;
        matrix_a.Entries[1,2] = 2;
        matrix_a.Entries[2,0] = 5;
        matrix_a.Entries[2,1] = 3;
        matrix_a.Entries[2,2] = 7;

        Matrix.Print(matrix_a);
        Console.WriteLine("\n");

        determinant = Matrix.Det(matrix_a);

        Console.WriteLine("\nDeterminant: {0}", determinant);

        Console.ReadLine();
    }


}

I am assuming that my algorithm does the following, that when it comes to a determinant that has dimensions greater than 1x1 it goes through a recursive loop until the determinant of a 1x1 minor is calculated which is then fed back through previous recursions until it returns to the main thread at which point it calculates the next minor and then repeats the process.

I would be much obliged for assistance in this matter for someone to point out wherein lies my mistake.

In the code above I had written a custom Matrix class. I had tested the DeleteRowColumn() method and it works perfectly. However, the Det() function is presenting some problems for me.

Mathematical Pseudo Code

Det(A)
    *Create a Loop which Calculates the Cofactors with n Number of
     Cofactors Being Generated in an nxn matrix
             *Initialise an Array of Minors of Dimensions of A_n-1,n-1

             *If the dimensions of the matrix is greater than 1, then
              use the Standard Definition of Determinant Calculation to
              Calculate Determinant which is (-1)^(i+j) * M_i,j
             {
             *Since the Minor is Too Large to have its Determinant Taken,                 
              then Continue Shaving the minor until a Double Value is Achieved

             Therefore: Det(Matrix representing the Minor)

             *Because of Recursion, a Determinant Value Calculated Down the
              Line would be Fed Back Through Former Recursions
              }
              Else
              {
              *Calculate the Cofactor and Add it to a Pre-existing Sum which
               Represents the Final Determinant     
              }
     *EndForLoop
return Determinant

Edit: I had realised that I had made some mistakes in my code and so I had updated my code presented above. However, although the NullObjectReference exception has now disappeared I am not receiving the correct value for the determinant. According to SymboLab it should be 287 but I am getting 1621.

$\endgroup$
  • $\begingroup$ You should define your algorithm in mathematical pseudo code so we know exactly what you’re trying to do so we can compare against the code you’ve written. $\endgroup$ – spektr Nov 2 '19 at 3:11
0
$\begingroup$

Actually, I give my apologies for bothering the community with this problem. It looks like the solution in the end was actually quite easy. I simply had placed the multiplications of the elements of the matrix in the creation of minors wrongly. They should have actually been placed when calculating the determinant as it should be that the determinant equals itself plus the cofactor multiplied by the appropriate matrix element.

| cite | improve this answer | |
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.