Cofactor of a 3x3 matrix

I need to write a function to calculate the cofactor of the x,y th element in a 3x3 matrix.


1
2
3
4
5
6
int cofactor(int data[][3],int x,int y)
    {
        int cofactor_v;
        cofactor_v[x][y] = data[(x + 1) % 3][(y + 1) % 3] * data[(x + 2) % 3][(y + 2) % 3] - data[(x + 1) % 3][(y + 2) % 3] * data[(x + 2) % 3][(y + 1) % 3];
        return cofactor_v;
    }

I wrote the above function with some help from the web. But the values all come out wrong...Off course I don't understand the logic of the main line of calculation.
What do I do now?
If you don't understand the mathematics of the calculation then you can't debug it because
you don't know how it is supposed to work.

First go figure out how to compute cofactors, then figure out why the above line doesn't
do it right.
Your calculation is correct. Your function works fine for me.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <iostream>
using namespace std;

int cofactor(int data[][3],int x,int y)
{
    int cofactor_v;

    cofactor_v = data[(x + 1) % 3][(y + 1) % 3]
        * data[(x + 2) % 3][(y + 2) % 3]
        - data[(x + 1) % 3][(y + 2) % 3]
        * data[(x + 2) % 3][(y + 1) % 3];

    return cofactor_v;
}

int main()
{
    int matrix[3][3]={
        1,2,3,
        1,3,2,
        3,2,1};

    cout << cofactor(matrix,0,0) << endl;
    //      [3   2]
    //det ( [     ] ) = 3*1 - 2*2 = -1
    //      [2   1]

    cout << cofactor(matrix,1,1) << endl;
    //      [1   3]
    //det ( [     ] ) = 1*1 - 3*3 = -8
    //      [3   1]

    cout << cofactor(matrix,0,2) << endl;
    //      [1   3]
    //det ( [     ] ) = 1*2 - 3*3 = -7
    //      [3   2]

    cout << "\nhit enter to quit..." << endl;
    cin.get();
    return 0;
}

Just fix this -> cofactor_v[x][y]=//... . It should be like this -> cofactor_v=//...

If you don't know what a cofactor is, take a look at this:

http://en.wikipedia.org/wiki/Cofactor_%28linear_algebra%29
Last edited on
I know what a cofactor is. But the logic of this function is not clear to me.
From what I know, Cofactor A(ij)= (-1)^(i+j) * M(ij) where M is the respective minor.

How thus the above code fit in?
If the function is correct, the following program could have calculated the determinant correctly, right? I do hope something else is wrong!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#include<iostream>
using namespace std;
void ind_val_out(int mat[][3]);
void ind_val_in(int mat[][3]);
int cofactor(int data[][3],int x,int y);


class matrix_3x3
{
    public:
    void in_value(void)
    {
        ind_val_in(data);
    };
    const void out_value(void)
    {
       ind_val_out(data);
    }
    const int getdet(void)
    {
        return det(data);
    }

    private:
    int data[3][3];

    int det(int data[][3])
    {
        int determinant;
        int x,y,z;
        x=data[0][1]*cofactor(data,0,1);
        y=data[0][2]*cofactor(data,0,2);
        z=data[0][3]*cofactor(data,0,3);
        determinant=x+y+z;
        return determinant;
    }



};
int main()
{
    int x[3][3];

    matrix_3x3 A;
    A.in_value();
    A.out_value();
    cout<<A.getdet();

}
void ind_val_out(int mat[][3])
{
    int x(0),y(0),z(0);
        abc:
            cout<<mat[x][y]<<" ";
            cout<<mat[x][y+1]<<" ";
            cout<<mat[x][y+2]<<"\n";
            z++;
            if (z<3)
            {
                x++;
                goto abc;
            }


}
void ind_val_in(int mat[][3])
{
    int x(0),y(0),z(0);
        abc:
            cin>>mat[x][y];
            cin>>mat[x][y+1];
            cin>>mat[x][y+2];
            z++;
            if (z<3)
            {
                x++;
                goto abc;
            }


}
int cofactor(int data[][3],int x,int y)
    {
        int cofactor_v;
        cofactor_v = data[(x + 1) % 3][(y + 1) % 3] * data[(x + 2) % 3][(y + 2) % 3] - data[(x + 1) % 3][(y + 2) % 3] * data[(x + 2) % 3][(y + 1) % 3];
        return cofactor_v;
    }
Ah, wait a sec... This isn't totally right... You see, the formula used here only gives the determinant of the remaining matrix (i.e. Mij) . You must also multiply with (-1)^(i+j)... I totally forgot that :/

So, the correct formula would be:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int cofactor(int data[][3],int x,int y)
{
    int cofactor_v;

    cofactor_v = data[(x + 1) % 3][(y + 1) % 3]
        * data[(x + 2) % 3][(y + 2) % 3]
        - data[(x + 1) % 3][(y + 2) % 3]
        * data[(x + 2) % 3][(y + 1) % 3];

    //fix the sign, according to x+y
    int sign=(x+y)%2;
    sign*=-2;
    sign++;

    cofactor_v*=sign;

    return cofactor_v;
}

Ok, now let's see why it works...

Suppose you have the following 3x3 matrix:

a00 a01 a02

a10 a11 a12

a20 a21 a22

If you want C01 for example, you'll have to calculate M01.

M01 is equal to a10*a22 - a12*a20,

which is a(0+1)(1+2)*a(0+2)(1+1) - a(0+1)(1+1)*a(0+2)(1+2),

i.e. a13*a22 - a12*a23,

i.e. a10*a22 - a12*a20 (modulo 3)

Mmm... So, there's one more thing to be fixed... To sum up, the formula should be like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int cofactor(int data[][3],int x,int y)
{
    int cofactor_v;

    cofactor_v = - data[(x + 1) % 3][(y + 1) % 3] // minus here
        * data[(x + 2) % 3][(y + 2) % 3]
        + data[(x + 1) % 3][(y + 2) % 3] // plus here
        * data[(x + 2) % 3][(y + 1) % 3];

    //fix the sign, according to x+y
    int sign=(x+y)%2;
    sign*=-2;
    sign++;

    cofactor_v*=sign;

    return cofactor_v;
}

Let me know if it works.

EDIT: Don't use goto if you don't want to end up like this -> http://xkcd.com/292/
Last edited on
Careful here:

1
2
3
4
5
6
7
8
9
10
int det(int data[][3])
{
    int determinant;
    int x,y,z;
    x=data[0][1]*cofactor(data,0,1);
    y=data[0][2]*cofactor(data,0,2);
    z=data[0][3]*cofactor(data,0,3);
    determinant=x+y+z;
    return determinant;
}

It should be:

1
2
3
4
5
6
7
8
9
10
int det(int data[][3])
{
    int determinant;
    int x,y,z;
    x=data[0][0]*cofactor(data,0,0);
    y=data[0][1]*cofactor(data,0,1);
    z=data[0][2]*cofactor(data,0,2);
    determinant=x+y+z;
    return determinant;
}

But it still doesn't work... I tried some examples and it outputs the determinant with wrong sign :/
Not only the sign, the values are also wrong.
Could there be a mistake somewhere else?
I must be missing something. The code given for the cofactor() seems to be fine ( in fact, it's brilliant ), except for the error 1st noted by m4ster r0shi re. use of cofactor_ in place of the erroneous
cofactor_v[x][y]. After fixing that I found it works fine. NOTE: the cofactor includes the factor of (-1)^(i+j) so the determinant of M may simply be found as:
|M| = M00*cofactor(M,0,0) + M01*cofactor(M,0,1) + M02*cofactor(M,0,2) since it does not matter along which row or column a determinant is expanded.
I wrote the following program around your code to test it out. It gave me correct values for |M| for the 1st several test cases. This could be coincidence though.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// ** finding cofactors ina 3x3 matrix - then display the determinant **
#include<iostream>
using namespace std;

int cofactor(int data[][3],int x,int y)
    {
        int cofactor_v;
        cofactor_v = data[(x + 1) % 3][(y + 1) % 3] * data[(x + 2) % 3][(y + 2) % 3] - data[(x + 1) % 3][(y + 2) % 3] * data[(x + 2) % 3][(y + 1) % 3];
        return cofactor_v;
    }

int main()
{
	int M[3][3] = {0};
	int r=0, c=0;// cofactor of M
	char repeat = 'n';// user queried to repeat for another case
	
	for(int j=0; j<3; j++)
	{
		cout << "Enter array elements for row " << j << endl;
		for(int k=0; k<3; k++)
			cin >> M[j][k];
	}

	do// allows repeat runs and keeps window open so results can be seen
	{
		cout<<"Enter row for cofactor: ";
		cin >> r;
		cout<<"Enter col for cofactor: ";
		cin >> c;
		cout << "The cofactor is: " << cofactor( M, r, c ) << endl;
		cout << "the determinant is: " << M[0][0]*cofactor( M, 0, 0 ) + M[0][1]*cofactor( M, 0, 1 ) + M[0][2]*cofactor( M, 0, 2 ) << endl;
		cout << endl << "repeat (y/n)? " << flush;
		cin >> repeat;
	}while( repeat=='y');
    return 0;

}

Got it !!
When calculating the minor for the 2nd column. It is calculated by considering the first column first,
but this code considers the 3rd column. So the sign for that case must be reversed..
I had to write it elaborately to spot the error.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int cofactor(int data[][3],int x,int y)
{
    int cofactor_v;
    int minor;
    int minor_mat[2][2];
    minor_mat[0][0]=data[(x+1)%3][(y+1)%3];
    minor_mat[1][1]=data[(x+2)%3][(y+2)%3];
    minor_mat[0][1]=data[(x+1)%3][(y+2)%3];
    minor_mat[1][0]=data[(x+2)%3][(y+1)%3];
    minor=min_mat[0][0]*min_mat[1][1]-min_mat[1][0]*min_mat[0][1];

    cofactor_v=pow((-1),(x+y+2)) * minor;
    if(y==1)
    {
        cofactor_v=0 - cofactor_v;
    }
    return cofactor_v;
}

The pow needs the math header file though.Would it be better if the sign assignment was done through another 'if' clause?
Ah, nice!

manasij7479 wrote:
The pow needs the math header file though.Would it be better if the sign assignment was done through another 'if' clause?

Actually, yes. You can just write:

if ((x+y)%2==1) cofactor_v*=-1;
Topic archived. No new replies allowed.