matrix_alg.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. //
  2. // Unit tests for the AP_Math rotations code
  3. //
  4. #include <AP_HAL/AP_HAL.h>
  5. #include <AP_Math/AP_Math.h>
  6. #include <stdio.h>
  7. const AP_HAL::HAL& hal = AP_HAL::get_HAL();
  8. #define MAT_ALG_ACCURACY 1e-4f
  9. static uint16_t get_random(void)
  10. {
  11. static uint32_t m_z = 1234;
  12. static uint32_t m_w = 76542;
  13. m_z = 36969 * (m_z & 65535) + (m_z >> 16);
  14. m_w = 18000 * (m_w & 65535) + (m_w >> 16);
  15. return ((m_z << 16) + m_w) & 0xF;
  16. }
  17. static void show_matrix(float *A, int n) {
  18. for (int i = 0; i < n; i++) {
  19. for (int j = 0; j < n; j++)
  20. printf("%.10f ", A[i * n + j]);
  21. printf("\n");
  22. }
  23. }
  24. static bool compare_mat(const float *A, const float *B, const uint8_t n)
  25. {
  26. for(uint8_t i = 0; i < n; i++) {
  27. for(uint8_t j = 0; j < n; j++) {
  28. if(fabsf(A[i*n + j] - B[i*n + j]) > MAT_ALG_ACCURACY) {
  29. return false;
  30. }
  31. }
  32. }
  33. return true;
  34. }
  35. static void test_matrix_inverse(void)
  36. {
  37. //fast inverses
  38. float test_mat[25],ident_mat[25];
  39. float *out_mat;
  40. for(uint8_t i = 0;i<25;i++) {
  41. test_mat[i] = pow(-1,i)*get_random()/0.7f;
  42. }
  43. float mat[25];
  44. //Test for 3x3 matrix
  45. memset(ident_mat,0,sizeof(ident_mat));
  46. for(uint8_t i=0; i<3; i++) {
  47. ident_mat[i*3+i] = 1.0f;
  48. }
  49. if(inverse(test_mat,mat,3)){
  50. out_mat = mat_mul(test_mat,mat,3);
  51. inverse(mat,mat,3);
  52. } else {
  53. hal.console->printf("3x3 Matrix is Singular!\n");
  54. return;
  55. }
  56. printf("\n\n3x3 Test Matrix:\n");
  57. show_matrix(test_mat,3);
  58. printf("\nInverse of Inverse of matrix\n");
  59. show_matrix(mat,3);
  60. printf("\nInv(A) * A\n");
  61. show_matrix(out_mat,3);
  62. printf("\n");
  63. //compare matrix
  64. if(!compare_mat(test_mat,mat,3)) {
  65. printf("Test Failed!!\n");
  66. return;
  67. }
  68. if(!compare_mat(ident_mat,out_mat,3)) {
  69. printf("Identity output Test Failed!!\n");
  70. return;
  71. }
  72. //Test for 4x4 matrix
  73. memset(ident_mat,0,sizeof(ident_mat));
  74. for(uint8_t i=0; i<4; i++) {
  75. ident_mat[i*4+i] = 1.0f;
  76. }
  77. if(inverse(test_mat,mat,4)){
  78. out_mat = mat_mul(test_mat,mat,4);
  79. inverse(mat,mat,4);
  80. } else {
  81. hal.console->printf("4x4 Matrix is Singular!\n");
  82. return;
  83. }
  84. printf("\n\n4x4 Test Matrix:\n");
  85. show_matrix(test_mat,4);
  86. printf("\nInverse of Inverse of matrix\n");
  87. show_matrix(mat,4);
  88. printf("\nInv(A) * A\n");
  89. show_matrix(out_mat,4);
  90. printf("\n");
  91. if(!compare_mat(test_mat,mat,4)) {
  92. printf("Test Failed!!\n");
  93. return;
  94. }
  95. if(!compare_mat(ident_mat,out_mat,4)) {
  96. printf("Identity output Test Failed!!\n");
  97. return;
  98. }
  99. //Test for 5x5 matrix
  100. memset(ident_mat,0,sizeof(ident_mat));
  101. for(uint8_t i=0; i<5; i++) {
  102. ident_mat[i*5+i] = 1.0f;
  103. }
  104. if(inverse(test_mat,mat,5)) {
  105. out_mat = mat_mul(test_mat,mat,5);
  106. inverse(mat,mat,5);
  107. } else {
  108. hal.console->printf("5x5 Matrix is Singular!\n");
  109. return;
  110. }
  111. printf("\n\n5x5 Test Matrix:\n");
  112. show_matrix(test_mat,5);
  113. printf("\nInverse of Inverse of matrix\n");
  114. show_matrix(mat,5);
  115. printf("\nInv(A) * A\n");
  116. show_matrix(out_mat,5);
  117. printf("\n");
  118. if(!compare_mat(test_mat,mat,5)) {
  119. printf("Test Failed!!\n");
  120. return;
  121. }
  122. if(!compare_mat(ident_mat,out_mat,5)) {
  123. printf("Identity output Test Failed!!\n");
  124. return;
  125. }
  126. hal.console->printf("All tests succeeded!!\n");
  127. }
  128. void setup(void)
  129. {
  130. hal.console->printf("Matrix Algebra test\n\n");
  131. test_matrix_inverse();
  132. hal.console->printf("Matrix Algebra tests done\n\n");
  133. }
  134. void loop(void) {}
  135. AP_HAL_MAIN();