Sign in to follow this  
johnnyBravo

Calculating theinverse of a 3x3 matrix?

Recommended Posts

johnnyBravo    100
Hi, I need to calculate the inverse of a 3x3 matrix. So I've been looking at the Dr Math website, and this is an answer they gave on the topic here Link.
Quote:
Now create a +1 in the upper left-hand corner by multiplying the first row by -1: [ 1 -3 3 -1 0 0] [ 0 -6 5 0 1 0]. [-5 -3 1 0 0 1]
So would I always use -1 or does that depend on the matrix variables?
Quote:
Now create 0's below it by adding a multiple of row 1 to the other rows (in this case 5 times the first row to the third row): [1 -3 3 -1 0 0] [0 -6 5 0 1 0]. [0 -18 16 -5 0 1]
where does the 5 come from?
Quote:
Now the first column looks fine, so we create a +1 at the (2,2) entry by multiplying the second row by -1/6: [1 -3 3 -1 0 0] [0 1 -5/6 0 -1/6 0]. [0 -18 16 -5 0 1]
wheres the -1/6 come from? I haven't gotten to the calculations below yet.
Quote:
Now create 0's above and below that 1 by adding multiples of the second row (3 and 18 times it) to the others (first and third): [1 0 1/2 -1 -1/2 0] [0 1 -5/6 0 -1/6 0]. [0 0 1 -5 -3 1] Now the second column is right, and we already have a +1 at the (3,3) entry. Now create 0's above that by adding multiples of row 3 (-1/2 and 5/6 times it) to the rows above it (first and second): [1 0 0 3/2 1 -1/2] [0 1 0 -25/6 -8/3 5/6]. [0 0 1 -5 -3 1] The left half is now a 3x3 identity matrix, so we stop. Then the inverse of the original matrix is the right half, or [ 3/2 1 -1/2] [-25/6 -8/3 5/6] [ -5 -3 1] You can check this by multiplying it times the original matrix, and getting the identity.
Thanks

Share this post


Link to post
Share on other sites
nmi    978
The Gauß-Jordan Elimination is maybe the simplest algorithm for matrix inversion.

You apply the Gauß elimination to a matrix A, until you end up with an identity matrix. If this is possible, then the matrix can be inverted (swapping rows/columns may be required, also called pivoting). So the transformation from matrix A to identity matrix E can be seen as a multiplication of A with another matrix B: E = A*B
But that would mean that B is the inverse of A. So if you multiply the identity matrix E with B, you will end up with the inverse of A. The Gauß-Jordan Elimination does this in parallel.

Share this post


Link to post
Share on other sites
nmi    978
Quote:
Original post by johnnyBravo
So would I always use -1 or does that depend on the matrix variables?

It depends on your pivot element. You multiply the row with the inverse of your pivot element, so that the new pivot element will become 1. That way you create the identity matrix step by step.

Quote:

where does the 5 come from?

The first row contained 1 in the leftmost column, while the third row contained -5 in the leftmost column. If you add 1*5 to -5, you will end up with zero.

Quote:

wheres the -1/6 come from?


The element in the second row, second column was -6 before. If you multiply the row with -1/6, it will become 1.

Share this post


Link to post
Share on other sites
jyk    2094
Just to add to your options, you might consider using the adjoint method rather than Gauss-Jordan. It's more or less branchless and is simple to implement. It's described at the very end of the link you posted, starting with:

"An explicit formula for the inverse can also be given."

All you need in addition to what is given in the document is to know how to find the determinant of a 2x2 and 3x3 matrix. If you don't already know how to do this, just check the articles section of gamedev, or google for 'matrix determinant'.

Share this post


Link to post
Share on other sites
leoptimus    106
Also, you can use a little trick that can speed your math.

3x3 matrices are often used for rotation and scaling, so you don't need to find their inverse in the righteus way.


If your matrix is only used for rotations, its inverse is its transpose:

R =
[ x1 x2 x3]
[ y1 y2 y3]
[ z1 z2 z3]

Inv(R) =
[ x1 y1 z1]
[ x2 y2 z2]
[ x3 y3 z3]


Else you'd need calculate its determinant, and all the cofactors: its adjoint matrix.

This is the formula:

Inv(R) = Adj(R)/D
Adjoint matrix is the transpose of the cofactor matrix.

Here is the code
///invert a m matrix
///calc the adjoint
minv->_11 = m->_22*m->_33 - m->_23*m->_32;///each cofactor is the determinant of
minv->_21 = m->_23*m->_31 - m->_21*m->_33;//the minor of the corresponding
minv->_31 = m->_21*m->_32 - m->_22*m->_31;//element
minv->_12 = m->_13*m->_32 - m->_12*m->_33;
minv->_22 = m->_11*m->_33 - m->_13*m->_31;
minv->_32 = m->_12*m->_31 - m->_11*m->_32;
minv->_13 = m->_12*m->_23 - m->_13*m->_22;
minv->_23 = m->_13*m->_21 - m->_11*m->_23;
minv->_33 = m->_11*m->_22 - m->_12*m->_21;

///calc the determinant, with the diagonal
double D;

D = m->_11*minv->_11 + m->_12*minv->_21 + m->_13*minv->_31;

///divide adjoint by determinant
minv->_11/=D;
minv->_21/=D;
minv->_31/=D;
minv->_12/=D;
minv->_22/=D;
minv->_32/=D;
minv->_13/=D;
minv->_23/=D;
minv->_33/=D;


Share this post


Link to post
Share on other sites
Sneftel    1788
As leoptimus alluded to: The fastest way to invert a matrix is to already have the inverse computed. Virtually all matrices in computer graphics take the form:

M = M1 * M2 * ... * Mn

Where M1 .. Mn are matrices with easy, closed-form inverses. Then M-1 is simply:

M-1 = Mn-1 * ... * M2-1 * M1-1.

So if you know you're going to need the inverse of a matrix, just build the inverse at the same time as you're building the original matrix.

Share this post


Link to post
Share on other sites
dawidjoubert    161
Quote:

As leoptimus alluded to: The fastest way to invert a matrix is to already have the inverse computed. Virtually all matrices in computer graphics take the form:

M = M1 * M2 * ... * Mn

Where M1 .. Mn are matrices with easy, closed-form inverses. Then M-1 is simply:

M-1 = Mn-1 * ... * M2-1 * M1-1.

So if you know you're going to need the inverse of a matrix, just build the inverse at the same time as you're building the original matrix.


That is the smartest thing to do absolutely. It simple means for every rotation transformation and so on u do twice.. In normal case this is only done for the camera and other player objects so that wouldnt be a 2 heavy load.

Share this post


Link to post
Share on other sites
__fold    202
Quote:
Original post by Sneftel
As leoptimus alluded to: The fastest way to invert a matrix is to already have the inverse computed. Virtually all matrices in computer graphics take the form:

M = M1 * M2 * ... * Mn

Where M1 .. Mn are matrices with easy, closed-form inverses. Then M-1 is simply:

M-1 = Mn-1 * ... * M2-1 * M1-1.

So if you know you're going to need the inverse of a matrix, just build the inverse at the same time as you're building the original matrix.


I think that the results from this solution can get bad if the matrix is composed with several matrices.

Consider a rotation matrix R (created with sin and cos) and then a scale matrix. Sin and cos is not that accurate and R * R-1 might differ a bit from I. Then with the scale matrix you will actually scale the error.

(If the matrix can be kept ortonormal then M-1 == MT)

Share this post


Link to post
Share on other sites
Sneftel    1788
Quote:
Original post by __fold
I think that the results from this solution can get bad if the matrix is composed with several matrices.

Consider a rotation matrix R (created with sin and cos) and then a scale matrix. Sin and cos is not that accurate and R * R-1 might differ a bit from I. Then with the scale matrix you will actually scale the error.

(If the matrix can be kept ortonormal then M-1 == MT)

Even if sin and cos are inaccurate (and they aren't... at least, not inaccurate enough to visibly affect the results, even with a scaling), you'd still be using the special-case inversions for the individual matrices. In other words, to compute (R(v, θ)*S(w))-1 you'd end up computing S(1/w)*R(v, θ)T, not S(1/w)*R(v, -θ).

Share this post


Link to post
Share on other sites
__fold    202
Quote:
Original post by Sneftel
Quote:
Original post by __fold
I think that the results from this solution can get bad if the matrix is composed with several matrices.

Consider a rotation matrix R (created with sin and cos) and then a scale matrix. Sin and cos is not that accurate and R * R-1 might differ a bit from I. Then with the scale matrix you will actually scale the error.

(If the matrix can be kept ortonormal then M-1 == MT)

you'd end up computing S(1/w)*R(v, θ)T



Ok, if you do that then there is no problem. I got the feeling from your first post that you created the inverses in the same way as you created the matrices (just by changing the signs). I don't really know where I got that from. Must be the heat...

Share this post


Link to post
Share on other sites
Quote:
Original post by johnnyBravo
Hi, I need to calculate the inverse of a 3x3 matrix.
Someone posted an algebraic answer already, but there's an equivalent geometric answer, in terms of vectors.

Let M = [u v w] be the 3x3 matrix consisting of the three column vectors u, v, and w. Then inv(M) is the result of multiplying matrix A with 1/dot(u, cross(v, w)) where A = [r; s; t] is a 3x3 matrix consisting of the three row vectors r = cross(v, w), s = cross(w, u), and t = cross(u, v).

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this