What's the easiest way to compute a 3x3 matrix inverse?
I'm just looking for a short code snippet that'll do the trick for non-singular matrices, possibly using Cramer's rule. It doesn't need to be highly optimized. I'd prefer simplicity over speed. I'd rather not link in additional libraries.
With all due respect to our unknown (yahoo) poster, I look at code like that and just die a little inside. Alphabet soup is just so insanely difficult to debug. A single typo anywhere in there can really ruin your whole day. Sadly, this particular example lacked variables with underscores. It's so much more fun when we have a_b-c_d*e_f-g_h. Especially when using a font where _ and - have the same pixel length.
Taking up Suvesh Pratapa on his suggestion, I note:
(A) When taking a minor of a 3x3 array, we have 4 values of interest. The lower X/Y index is always 0 or 1. The higher X/Y index is always 1 or 2. Always! Therefore:
(B) Determinant is now: (Note the minus sign!)
(C) And the inverse is now:
And round it out with a little lower-quality testing code:
Afterthought:
You may also want to detect very large determinants as round-off errors will affect your accuracy!
I went ahead and wrote it in python since I think it's a lot more readable than in c++ for a problem like this. The function order is in order of operations for solving this by hand via this video. Just import this and call "print_invert" on your matrix.
Copy and save the above code as Matrix.h then try the following code:
Why don't you try to code it yourself? Take it as a challenge. :)
For a 3×3 matrix
alt text http://mathworld.wolfram.com/images/equations/MatrixInverse/NumberedEquation3.gif
the matrix inverse is
alt text http://mathworld.wolfram.com/images/equations/MatrixInverse/NumberedEquation4.gif
I'm assuming you know what the determinant of a matrix |A| is.
Don't try to do this yourself if you're serious about getting edge cases right. So while they many naive/simple methods are theoretically exact, they can have nasty numerical behavior for nearly singular matrices. In particular you can get cancelation/round-off errors that cause you to get arbitrarily bad results.
A "correct" way is Gaussian elimination with row and column pivoting so that you're always dividing by the largest remaining numerical value. (This is also stable for NxN matrices.). Note that row pivoting alone doesn't catch all the bad cases.
However IMO implementing this right and fast is not worth your time - use a well tested library and there are a heap of header only ones.