1

I wrote up a recursive function for computing a determinant. I know I could have done it much more efficiently but that is not the point here. I have a variable called "det1" that holds the final value for the determinant at the end of the recursion. The weird part is when I return this value in the det function, I get complete rubbish. BUT, when I just plain and simply print "det1" out, I get my answer. Any guesses here?

int det1 = 0;
int p = 0; 

int det(vector<vector<int> > (&A)){
    if (A.size() != A[0].size()){
        cout << "Determinant Error: non-square matrix. \n";
        return 0; 
    }
    int cF; 
    vector<vector<int> > temp01;
    if (A.size() == 2){
        det1 += (A[0][0]*A[1][1]-A[0][1]*A[1][0]); 
        //cout << "Determinant : " << det1 << "\n";
        int output = det1;                     ///////////////////////////////////////Problem with final return 
        //cout << "Recursion Count : " << p << "\n";  
        //return(output);                        ///////////////////////////////////////
    }else{//extract until a 2x2 is reached
        for (int i = 0; i < A.size(); i++){
             temp01 = extractNext(A,0, i); 
             //printMatrix(temp01); 
             cF = pow(-1, (0)+(i))*A[0][i]; 
             //cout << "Cofactor : " << cF << "\n"; 
             for (int j = 0; j< temp01.size(); j++){
                 temp01[0][j] = cF*temp01[0][j]; //account for cofactor by multiplying it in
             }
             //printMatrix(temp); cout << "\n";
             p++;  
             det(temp01); 
        }
    } 
}

2 Answers2

2

You're not returning a value on all code paths, which will ultimately lead to undefined behaviour when you use a return value that never existed.
(A reasonably modern compiler should warn you about this.)

You should return the determinant from the recursions instead of mutating a global - mixing mutable state and recursion usually only leads to trouble.
(This also makes your code much more similar to the mathematical definition of the determinant, which in turn makes it much easier to understand and verify.)

With some minor changes, I would suggest something like

int det(const vector<vector<int>> &A)
{
    if (A.size() != A[0].size()){
        cout << "Determinant Error: non-square matrix. \n";
        return 0; 
    }

    if (A.size() == 2)
    {
        return A[0][0] * A[1][1] - A[0][1] * A[1][0]; 
    }
    else
    {
        int determinant = 0;
        int sign = -1;
        for (int i = 0; i < A.size(); i++){
            vector<vector<int>> submatrix = extractNext(A, 0, i);
            sign = -sign;
            int cofactor = sign * A[0][i]; 
            for (int j = 0; j < submatrix.size(); j++){
                submatrix[0][j] = cofactor * submatrix[0][j];
            }
            determinant += det(submatrix);
        }
        return determinant;
    } 
}
molbdnilo
  • 64,751
  • 3
  • 43
  • 82
0

Your code is not returning determinant, because you did not create the return path for it. You do rely on side effects, too.

For 2*2 matrix your code should return correct value, provided you only call it once, but only because it immediately takes the "if" part, and does final calculations in one step. However, for 3*3 matrix, the "else" part is taken. But note, that there is no return on that path, so you can expect your function to return garbage.

To fix it, you need to rewrite the else branch such that you calculate the sum of values returned by recursive call, and use a temp variable on stack for this. Finally, you should return this value.