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
You may either post the source code here that allows us to duplicate the issue or report the problem to support.intl@keil.com.
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.