views:

2098

answers:

7

hello, i am looking for a sample code implementation on how to invert a 4x4 matrix. i know there is gaussian eleminiation, LU decomposition, etc. but instead of looking at them in detail i am really just looking for the code to do this.

language ideally C++, data is available in array of 16 floats in cloumn-major order.

thank you!

A: 

FOR 3x3 MATRIX

CHANGE THE CODE ACCORDING TO YOUR REQUIREMENT

http://www.dreamincode.net/code/snippet1156.htm

Kasma
No need to yell.
jason
going from 3x3 to 4x4 seems like a big difference
clamp
To clarify matt's point, that code mentions that it calculates the determinant as part of the algorithm for finding the inverse. There are simplified rules for calculating the determinants of 2x2 and 3x3 matrices that do not apply to larger matrices.
las3rjock
A: 

There appears to be a VB version at this place.

nik
+2  A: 

You can use the GNU Scientific Library or look the code up in it.

Edit: You seem to want the Linear Algebra section.

Svante
i did infact look at the matrix struct from gsl, but it doesnt seem to have a function for determinant or inversion.
clamp
+2  A: 

Here is a small (just one header) C++ vector math library (geared towards 3D programming). If you use it, keep in mind that layout of its matrices in memory is inverted comparing to what OpenGL expects, I had fun time figuring it out...

Eugene
+4  A: 

here:

bool gluInvertMatrix(const double m[16], double invOut[16])
{
double inv[16], det;
int i;

inv[0] =   m[5]*m[10]*m[15] - m[5]*m[11]*m[14] - m[9]*m[6]*m[15]
+ m[9]*m[7]*m[14] + m[13]*m[6]*m[11] - m[13]*m[7]*m[10];
inv[4] =  -m[4]*m[10]*m[15] + m[4]*m[11]*m[14] + m[8]*m[6]*m[15]
- m[8]*m[7]*m[14] - m[12]*m[6]*m[11] + m[12]*m[7]*m[10];
inv[8] =   m[4]*m[9]*m[15] - m[4]*m[11]*m[13] - m[8]*m[5]*m[15]
+ m[8]*m[7]*m[13] + m[12]*m[5]*m[11] - m[12]*m[7]*m[9];
inv[12] = -m[4]*m[9]*m[14] + m[4]*m[10]*m[13] + m[8]*m[5]*m[14]
- m[8]*m[6]*m[13] - m[12]*m[5]*m[10] + m[12]*m[6]*m[9];
inv[1] =  -m[1]*m[10]*m[15] + m[1]*m[11]*m[14] + m[9]*m[2]*m[15]
- m[9]*m[3]*m[14] - m[13]*m[2]*m[11] + m[13]*m[3]*m[10];
inv[5] =   m[0]*m[10]*m[15] - m[0]*m[11]*m[14] - m[8]*m[2]*m[15]
+ m[8]*m[3]*m[14] + m[12]*m[2]*m[11] - m[12]*m[3]*m[10];
inv[9] =  -m[0]*m[9]*m[15] + m[0]*m[11]*m[13] + m[8]*m[1]*m[15]
- m[8]*m[3]*m[13] - m[12]*m[1]*m[11] + m[12]*m[3]*m[9];
inv[13] =  m[0]*m[9]*m[14] - m[0]*m[10]*m[13] - m[8]*m[1]*m[14]
+ m[8]*m[2]*m[13] + m[12]*m[1]*m[10] - m[12]*m[2]*m[9];
inv[2] =   m[1]*m[6]*m[15] - m[1]*m[7]*m[14] - m[5]*m[2]*m[15]
+ m[5]*m[3]*m[14] + m[13]*m[2]*m[7] - m[13]*m[3]*m[6];
inv[6] =  -m[0]*m[6]*m[15] + m[0]*m[7]*m[14] + m[4]*m[2]*m[15]
- m[4]*m[3]*m[14] - m[12]*m[2]*m[7] + m[12]*m[3]*m[6];
inv[10] =  m[0]*m[5]*m[15] - m[0]*m[7]*m[13] - m[4]*m[1]*m[15]
+ m[4]*m[3]*m[13] + m[12]*m[1]*m[7] - m[12]*m[3]*m[5];
inv[14] = -m[0]*m[5]*m[14] + m[0]*m[6]*m[13] + m[4]*m[1]*m[14]
- m[4]*m[2]*m[13] - m[12]*m[1]*m[6] + m[12]*m[2]*m[5];
inv[3] =  -m[1]*m[6]*m[11] + m[1]*m[7]*m[10] + m[5]*m[2]*m[11]
- m[5]*m[3]*m[10] - m[9]*m[2]*m[7] + m[9]*m[3]*m[6];
inv[7] =   m[0]*m[6]*m[11] - m[0]*m[7]*m[10] - m[4]*m[2]*m[11]
+ m[4]*m[3]*m[10] + m[8]*m[2]*m[7] - m[8]*m[3]*m[6];
inv[11] = -m[0]*m[5]*m[11] + m[0]*m[7]*m[9] + m[4]*m[1]*m[11]
- m[4]*m[3]*m[9] - m[8]*m[1]*m[7] + m[8]*m[3]*m[5];
inv[15] =  m[0]*m[5]*m[10] - m[0]*m[6]*m[9] - m[4]*m[1]*m[10]
+ m[4]*m[2]*m[9] + m[8]*m[1]*m[6] - m[8]*m[2]*m[5];

det = m[0]*inv[0] + m[1]*inv[4] + m[2]*inv[8] + m[3]*inv[12];
if (det == 0)
 return false;

det = 1.0 / det;

for (i = 0; i < 16; i++)
 invOut[i] = inv[i] * det;

return true;
}

This was lifted from MESA implementation of the GLU library.

shoosh
Ugh, that code makes me want to stab out my eyes.
Imagist
You probably wouldn't want it any other way.
shoosh
Yes I would. Compilers are perfectly capable of unrolling loops, especially when you tell them to.
Imagist
+3  A: 

If you're looking for 'just works' implementation that is also very optimized without the need to understand the code, I highly reccommend using Intel's optimized SSE matrix inverse routine described here. There's also a reference impelementation for both gaussian elimination and Cramer's rule in C.

I warn though, the SSE code is not pretty if you don't understand MMX/SSE intrinsics.

LiraNuna
A: 

If you need a C++ matrix library with a lot of functions, have a look at Eigen library - http://eigen.tuxfamily.org

Ross