Hello,
While debugging a DSP algorithm, I realized the problem is duo to the CMSIS matrix inverse function: arm_mat_inverse_f32. It's really strange and is driving me crazy. arm_mat_inverse_f32 returns the right result for some Matrices but wrong result for some other! I assure you the matrices are not singular or anything like this, the algorithm works just fine with the same input data on MATLAB. I have no idea what the problem could be, any suggestions?
Regards
Hello all,
The fumction arm_mat_init_f32() stores only a pointer to the matrix data in the matrix instance. It does not copy the matrix data. The function arm_mat_inverse_f32() overwrites the matrix data from the source matrix when it generates the inverse matrix. This behaviour is not yet documented in the CMSIS DSP_Lib documentation.
Please see code below for matrix inversion. This test uses the data mentioned above.
#include "arm_math.h" #include "math_helper.h" #define SIZE (6) float32_t Matrix1[SIZE*SIZE] ={ 7.6294, 1.1843, 1.0842, 1.7056, 1.3111, 0.8036, 1.1843, 7.0938, 1.4429, 1.9244, 0.9154, 1.0024, 1.0842, 1.4429, 7.6006, 0.7976, 1.1649, 1.1927, 1.7056, 1.9244, 0.7976, 6.0714, 1.2414, 0.9802, 1.3111, 0.9154, 1.1649, 1.2414, 7.3110, 0.2683, 0.8036, 1.0024, 1.1927, 0.9802, 0.2683, 7.6469 }; float32_t Matrix1S[SIZE*SIZE]; /* Second Matrix */ float32_t Matrix1I[SIZE*SIZE]; /* Inverse Matrix */ float32_t Matrix1U[SIZE*SIZE]; /* Unity Matrix */ arm_matrix_instance_f32 m1; /* Matrix 1 Instance */ arm_matrix_instance_f32 m1S; /* Matrix 1 Second Instance */ arm_matrix_instance_f32 m1I; /* Matrix 1 Inverse Instance */ arm_matrix_instance_f32 m1U; /* Matrix 1 Unity Instance */ int32_t main(void) { uint32_t i; arm_status status = ARM_MATH_TEST_FAILURE; uint16_t rows = SIZE; uint16_t columns = SIZE; /* copy matrix data because arm_mat_inverse_f32(...) overwrites the data from the source matrix */ for (i = 0; i < (SIZE*SIZE); i++) Matrix1S[i] = Matrix1[i]; /* initialize the used matrix instances */ arm_mat_init_f32(&m1, rows, columns, Matrix1); arm_mat_init_f32(&m1S, rows, columns, Matrix1S); arm_mat_init_f32(&m1I, rows, columns, Matrix1I); arm_mat_init_f32(&m1U, rows, columns, Matrix1U); /* generate the inverse matrix */ status = arm_mat_inverse_f32(&m1S ,&m1I); /* matrix * inverse matrix = unity matrix */ status = arm_mat_mult_f32(&m1, &m1I, &m1U); while(1); }
Best regards, Martin Guenther
Missing documentation costs end users huge amounts of money and time. Been there, seen that happen.
I'm glad that KEIL/ARM has stepped up and admitted they did not document something. That is rare in a company. Thumbs up. Now go fix the documentation.
Microchip is one of the worst when it comes to documentation.