Archived

This topic is now archived and is closed to further replies.

4x4 Determinants

This topic is 5372 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

CMatrix3x3 CMatrix4x4:: Minor ( int s,int t )
{
switch ( s )
{
case 0:

switch ( t )
{
case 0:

return CMatrix3x3 (m[ 5],m[ 6],m[ 7],
m[ 9],m[10],m[11],
m[13],m[14],m[15]); break;

case 1:

return CMatrix3x3 (m[ 4],m[ 6],m[ 7],
m[ 8],m[10],m[11],
m[12],m[14],m[15]); break;

case 2:

return CMatrix3x3 (m[ 4],m[ 5],m[ 7],
m[ 8],m[ 9],m[11],
m[12],m[13],m[15]); break;

case 3:

return CMatrix3x3 (m[ 4],m[ 5],m[ 6],
m[ 8],m[ 9],m[10],
m[12],m[13],m[14]); break;
}

break;


case 1:

switch( t )
{
case 0:

return CMatrix3x3 (m[ 1 ],m[ 2],m[ 3],
m[ 9 ],m[10],m[11],
m[ 13],m[14],m[15]);

break;

case 1:

return CMatrix3x3 (m[ 0 ],m[ 2],m[ 3],
m[ 8 ],m[10],m[11],
m[ 12],m[14],m[15]);

break;

case 2:

return CMatrix3x3 (m[ 0 ],m[ 1],m[ 3],
m[ 8 ],m[ 9],m[11],
m[ 12],m[13],m[15]);

break;

case 3:

return CMatrix3x3 (m[ 0 ],m[ 1],m[ 2],
m[ 8 ],m[ 9],m[10],
m[ 12],m[13],m[14]);

break;

}

break;


case 2:

switch ( t )
{
case 0:

return CMatrix3x3 (m[ 1 ],m[ 2],m[ 3],
m[ 5 ],m[ 6],m[ 7],
m[ 13],m[14],m[15]);

break;

case 1:

return CMatrix3x3 (m[ 0 ],m[ 2],m[ 3],
m[ 4 ],m[ 6],m[ 7],
m[ 12],m[14],m[15]);

break;

case 2:

return CMatrix3x3 (m[ 0 ],m[ 1],m[ 3],
m[ 4 ],m[ 5],m[ 7],
m[ 12],m[13],m[15]);

break;

case 3:

return CMatrix3x3 (m[ 0 ],m[ 1],m[ 2],
m[ 4 ],m[ 5],m[ 6],
m[ 12],m[13],m[14]);

break;
}

break;


case 3:

switch (t)
{
case 0:
return CMatrix3x3 (m[ 1 ],m[ 2],m[ 3],
m[ 5 ],m[ 6],m[ 7],
m[ 9 ],m[10],m[11]);

break;

case 1:

return CMatrix3x3 (m[ 0 ],m[ 2],m[ 3],
m[ 4 ],m[ 6],m[ 7],
m[ 8 ],m[10],m[11]);


break;

case 2:

return CMatrix3x3 (m[ 0 ],m[ 1],m[ 3],
m[ 4 ],m[ 5],m[ 7],
m[ 8 ],m[ 9],m[11]);


break;

case 3:

return CMatrix3x3 (m[ 0 ],m[ 1],m[ 2],
m[ 4 ],m[ 5],m[ 6],
m[ 8 ],m[ 9],m[10]);

break;

}

break;


}
////////////////////////////////////
// if s,t are out of range , always
// the first minor is returned

return CMatrix3x3 (m[ 5],m[ 6],m[ 7],
m[ 9],m[10],m[11],
m[13],m[14],m[15]);
}


const float CMatrix4x4::Determinant(void)
{

return ( m[ 0]*(Minor(0,0).Determinant())-
m[ 1]*(Minor(0,1).Determinant())+
m[ 2]*(Minor(0,2).Determinant())-
m[ 3]*(Minor(0,3).Determinant())+
m[ 4]*(Minor(1,0).Determinant())-
m[ 5]*(Minor(1,1).Determinant())+
m[ 6]*(Minor(1,2).Determinant())-
m[ 7]*(Minor(1,3).Determinant())+
m[ 8]*(Minor(2,0).Determinant())-
m[ 9]*(Minor(2,1).Determinant())+
m[10]*(Minor(2,2).Determinant())-
m[11]*(Minor(2,3).Determinant())+
m[12]*(Minor(3,0).Determinant())-
m[13]*(Minor(3,1).Determinant())+
m[14]*(Minor(3,2).Determinant())-
m[15]*(Minor(3,3).Determinant()));

}


here it is

Share this post


Link to post
Share on other sites
v71, that looks wrong. You need only expand one row or one column.


  
const float CMatrix4x4::Determinant(void)
{
return
m[ 0]*(Minor(0,0).Determinant())-
m[ 1]*(Minor(0,1).Determinant())+
m[ 2]*(Minor(0,2).Determinant())-
m[ 3]*(Minor(0,3).Determinant());
}


And it would be faster if you don''t construct the matrices, but just get their determinants directly.

Share this post


Link to post
Share on other sites
thanks for your replys, finally I have made this:

float det4x4 (const float d[16])
{
float det1 = d[10]*(d[15]*d[5] - d[7]*d[13]) + d[11]*(d[13]*d[6] - d[5]*d[14]) + d[9]*(d[14]*d[7] - d[6]*d[15]);

float det2 = d[1]*(d[10]*d[15] - d[11]*d[14]) + d[2]*(d[11]*d[13] - d[9]*d[15]) + d[3]*(d[9]*d[14] - d[10]*d[13]);

float det3 = d[1]*(d[6]*d[15] - d[7]*d[14]) + d[2]*(d[7]*d[13] - d[5]*d[15]) + d[3]*(d[5]*d[14] - d[6]*d[13]);

float det4 = d[1]*(d[6]*d[11] - d[7]*d[10]) + d[2]*(d[7]*d[9] - d[5]*d[11]) + d[3]*(d[5]*d[10] - d[6]*d[9]);

return (d[0]*det1 - d[4]*det2 + d[8]*det3 - d[12]*det4);
}

can anyone tell me if this is slower or faster than the v71 - alvaro method?

Share this post


Link to post
Share on other sites
alvaro , its not wrong, do the calculations and see for yourself,
yes , its faster if you construct the determinats in place,
but my implementation uses a forceinline method.
i''m wearing my antiflame suit



Share this post


Link to post
Share on other sites
Guest Anonymous Poster
umm, alvaro isn''t wrong, he only tell you that it is unnecessary so many calculations, because for get the determinant, you only need to expand one column or row (4 members), and you have expanded all elements (16), the result is the same, but the calculations are less in alvaro reply and Jess method.

Share this post


Link to post
Share on other sites
I have implemented Laplace method for solving matrix determinat , it comes with a formula, i ''ve never seen a 4x4 determinant for a single column or a single row, unless you are using a massive gaussian elimination, maybe i''m missing something, i have checked and result *aren''t * the same, i assume you are accepting a ''lowered'' formula because you are not taking into account a factor that would have come out using only a adjoint solution, if someone wants to explain to me , why the determinat is the same, i mean THE SAME i would be gratefull and i''ll fire my linear algebra books, as weel signal processing text.
byez and srry for my english

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
This is correct matematically, and I see that its exactly the method that has used Jess:

the numbers are the positions, that must be replaced with the numbers, of course.

| 0 4 8 12 |
| 1 5 9 13 |
| 2 6 10 14 | = 0*det0 - 4*det4 + 8*det8 - 12*det12
| 3 7 11 15 |

to solve with Sarrus:
| 5 9 13 |
| 6 10 14 | = det0 (or minor 0)
| 7 11 15 |

| 1 9 13 |
| 2 10 14 | = det4 (or minor 4)
| 3 11 15 |

| 1 5 13 |
| 2 6 14 | = det8 (or minor 8)
| 3 7 15 |

| 1 5 9 |
| 2 6 10 | = det12 (or minor 12)
| 3 7 11 |

Share this post


Link to post
Share on other sites
i give up . everyone seems to be sure about the solution, have you really tried to do a 4x4 determinat with both methods and compare the results ? i did and the results aren''t the same
check for yourself !!!!
Siete delle teste di cazzo , rincoglioniti

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
I would guess you get four times the correct value.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
v71: Why the vulgar message ? Tu suei un testa di cazzo? Stronso!

Share this post


Link to post
Share on other sites
There''s a recursive algorithm for finding the determinate of any square matrix (well I suppose it''s given that it''s a square) and it uses one row or column. I can''t remember exactly how to right the formula, but it''s something like this:

Choose one row or column. For each element Ai,j in that row/column (I''m going to use rows from now on) find the determinate of the matrix that results by removing the ith row and the jth column, multiply by the value of Ai,j. Once you have done that you add or subtract them, depending on the elements position in the matrix, like this:

| + - + - + - ... |
| - + - + - + ... |
| + - + - + - ... |
| ............... |

So for a 3x3 matrix it would be like this:

| 1 2 3 |
| 4 5 6 |
| 7 8 9 |

choose the first row:

1 * det:
| 5 6 |
| 8 9 |
-
2 * det:
| 4 6 |
| 7 9 |
+
3 * det:
| 4 5 |
| 7 8 |

and you can then break down each resulting matrix the same way, although the determinate of a 2x2 is easy to find, so you get:
0. I checked on a calculate and it agrees with me.

I hope you understood this explaination.

Share this post


Link to post
Share on other sites
Anonymous your italian is good, anyway, you are still a testa di cazzo , rincoglioniti e fetidi luridi cretini, idioti, ciao

Share this post


Link to post
Share on other sites
v71 non capisco lo scopo di scrivere messaggi da raggazzini communque...

Anonymous suggested that your method would yield 4 times the result, I''m inclined to agree. You expand by all 16 elements (ie by four rows/columns) which is 4 times as much work as needs to be done and gives four times what the rest of us testi di cazzo would consider to be the correct result. To find the det of any square matrix you must pick 1 row or 1 column and expand that by the method you used. You might like to put a little debug output into your matrix class to output the value you get each time you complete a row/column''s worth of calcs - you should find that you get the same result each time.

Share this post


Link to post
Share on other sites
Oh yes - an optimisation, particularly when doing dets by hand and possibly applicable in code too if you expect you''re matrices to have a high degree of sparsity (ie lots of zeros)...

Pick the row/column with the greatest number of zeros and only expand by the non-zero terms (in that row/column). Diagonals, for example, are an extreme case of this.

Let D be a nXn diagonal matrix (ie D_ij != 0 <=> i==j) then,

det(D) = product(D_ii), for i = 1 to n

ie the det of a diagonal matrix is the product of its non-zero terms.

Share this post


Link to post
Share on other sites
Looks like you didn''t understand laplacian expansion
*this is the very end of me*
days ago i''ve received an insult email from someone on this forum
i think you are a stupid bunch of kids.
i''m going to delete myself from this site
byez for ever.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
v71, you are who don''t understand how to solve a 4x4 determinant,
one row or one column, its enough to solve it, its the only thing that people have told you, and its true.
no more comments.

Share this post


Link to post
Share on other sites