Calculating the Inverse of a 3 by 3 Matrix
amalfiCoast
Posts: 132
in Propeller 1
Hi Everyone,
I'm having a problem calculating the inverse of a matrix. My program is not yet complete but my approach is to first calculate the determinant of a matrix, then the adjoint of the matrix, then multiply the determinant and the adjoint to get the inverse. The error I'm getting is within the matrixInverse function at
Also, this code as well as my other matrixMultiplication program (posted a month ago) seem to be hard-coded for 3 by 3 matrices only. What if I have a situation where I need to manipulate a 2 by 2 matrix, for example? Do I need to make other functions for other dimensioned matrices or is there a standard approach that works for all matrix sizes? In Matlab, for example, you don't need to specify or hard-code the matrix dimension. By the way, I'm developing these functions because I want to implement an Extended Kalman Filter on hardware. We did a project in school designing and simulating a UAV autopilot in Matlab and I've always wanted to be able to implement EKFs in hardware.
Thank you,
David
I'm having a problem calculating the inverse of a matrix. My program is not yet complete but my approach is to first calculate the determinant of a matrix, then the adjoint of the matrix, then multiply the determinant and the adjoint to get the inverse. The error I'm getting is within the matrixInverse function at
adj_p[3][3] = {"error: expected expression before '{' token". Am I not allowed to multiply terms inside an array?
Also, this code as well as my other matrixMultiplication program (posted a month ago) seem to be hard-coded for 3 by 3 matrices only. What if I have a situation where I need to manipulate a 2 by 2 matrix, for example? Do I need to make other functions for other dimensioned matrices or is there a standard approach that works for all matrix sizes? In Matlab, for example, you don't need to specify or hard-code the matrix dimension. By the way, I'm developing these functions because I want to implement an Extended Kalman Filter on hardware. We did a project in school designing and simulating a UAV autopilot in Matlab and I've always wanted to be able to implement EKFs in hardware.
/* Take the inverse of a 3 by 3 matrix */ #include "simpletools.h" float p[3][3] = { // Define matrix p {1, 1, 2}, {3, 4, 5}, {6, 7, 8} }; float r[3][3] = { // Zero matrix r {0, 0, 0}, {0, 0, 0}, {0, 0, 0} }; float det_p[1]; // Define determinant of p (scalar) float adj_p[3][3] = { // Zero matrix adj_p {0, 0, 0}, {0, 0, 0}, {0, 0, 0} }; float matrixInverse(float det_p[1], float adj_p[3][3], float p[3][3], float r[3][3]); // Declare matrixInverse function int main(){ matrixInverse(det_p, adj_p, p, r); // Call matrixInverse function // Print matrix adj_p print("adj_p =\n"); for(int i = 0; i < 3; i++){ for(int k = 0; k < 3; k++){ print("%f ", r[3][3]); } print("\n"); } // Print determinant of p print("\ndet_p = %f\n", det_p[1]); } // matrixInverse function - compute the inverse of a 3 by 3 matrix float matrixInverse(float det_p[1], float adj_p[3][3], float p[3][3], float r[3][3]){ det_p[1] = p[0][0]*p[1][1]*p[2][2]+p[0][1]*p[1][2]*p[2][0]+p[0][2]*p[1][0]*p[2][1] // Calculate determinant of p -p[0][2]*p[1][1]*p[2][0]-p[0][1]*p[1][0]*p[2][2]-p[0][0]*p[1][2]*p[2][1]; adj_p[3][3] = { {p[1][1]*p[2][2]-p[1][2]*p[2][1], p[0][2]*p[2][1]-p[0][1]*p[2][2], p[0][1]*p[1][2]-p[1][1]*p[0][2]} {p[2][0]*p[1][2]-p[1][0]*p[2][2], p[0][0]*p[2][2]-p[2][0]*p[0][2], p[1][0]*p[0][2]-p[0][0]*p[1][2]}, {p[1][0]*p[2][1]-p[2][0]*p[1][1], p[2][0]*p[0][1]-p[0][0]*p[2][1], p[0][0]*p[1][1]-p[0][1]*p[1][0]} }; }
Thank you,
David
Comments
Also, your det_p[1] assignment is invalid, it's accessing outside of the array. It should be det_p[0] = ... In C, array indices are 0 based, so a declaration of float x[3] is accessed with indices from 0 to 2.
David
The code now works as it should. Please see below. I am however still confused about the det_p[1] issue that was discussed. Also, is there a way for this code to be adapted to any size matrix without having to recode the function?
Thank you again, Roy, for your help.
Respectfully,
David
The compiler isn't very smart, however, and likely treating det_p as an array of "some number" of elements. When the code is compiled, det_p[1] is treated as the second index into a table of N elements, so you're accessing the 4 bytes past det_p[0]. Most likely it'll be adj_p[0][0], because that's the next thing declared, but it depends on how the compiler arranges your variables in memory. If it works, you got lucky.
In C, it's actually legal to declare an array of zero elements, like this:
I don't recommend it. :-)
To recode this only once for general matrix sizes, you'd need to code this matrixInverse() function with input parameters being pointers to the arrays rather than copies of the arrays, you'd need to pass an array size parameter, and your code would need to iterate over the arrays in similar way to your matrix printing code.
By identifying the patterns in the array indices used in the operations you should be able to determine algorithms to perform general size matrix operations.
An alternative is to look for code already written that serves the purpose.
Regards,
Anthony.
Anthony: I'll work on modifying the code so that it will work for a general matrix. I'll report back when I have an update.
Thanks,
David