arm_matrix_example_f32.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. /* ----------------------------------------------------------------------
  2. * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
  3. *
  4. * $Date: 17. January 2013
  5. * $Revision: V1.4.0
  6. *
  7. * Project: CMSIS DSP Library
  8. * Title: arm_matrix_example_f32.c
  9. *
  10. * Description: Example code demonstrating least square fit to data
  11. * using matrix functions
  12. *
  13. * Target Processor: Cortex-M4/Cortex-M3
  14. *
  15. * Redistribution and use in source and binary forms, with or without
  16. * modification, are permitted provided that the following conditions
  17. * are met:
  18. * - Redistributions of source code must retain the above copyright
  19. * notice, this list of conditions and the following disclaimer.
  20. * - Redistributions in binary form must reproduce the above copyright
  21. * notice, this list of conditions and the following disclaimer in
  22. * the documentation and/or other materials provided with the
  23. * distribution.
  24. * - Neither the name of ARM LIMITED nor the names of its contributors
  25. * may be used to endorse or promote products derived from this
  26. * software without specific prior written permission.
  27. *
  28. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  29. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  30. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  31. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  32. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  33. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  34. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  35. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  36. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  37. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  38. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  39. * POSSIBILITY OF SUCH DAMAGE.
  40. * -------------------------------------------------------------------- */
  41. /**
  42. * @ingroup groupExamples
  43. */
  44. /**
  45. * @defgroup MatrixExample Matrix Example
  46. *
  47. * \par Description:
  48. * \par
  49. * Demonstrates the use of Matrix Transpose, Matrix Muliplication, and Matrix Inverse
  50. * functions to apply least squares fitting to input data. Least squares fitting is
  51. * the procedure for finding the best-fitting curve that minimizes the sum of the
  52. * squares of the offsets (least square error) from a given set of data.
  53. *
  54. * \par Algorithm:
  55. * \par
  56. * The linear combination of parameters considered is as follows:
  57. * \par
  58. * <code>A * X = B</code>, where \c X is the unknown value and can be estimated
  59. * from \c A & \c B.
  60. * \par
  61. * The least squares estimate \c X is given by the following equation:
  62. * \par
  63. * <code>X = Inverse(A<sup>T</sup> * A) * A<sup>T</sup> * B</code>
  64. *
  65. * \par Block Diagram:
  66. * \par
  67. *
  68. * \par Variables Description:
  69. * \par
  70. * \li \c A_f32 input matrix in the linear combination equation
  71. * \li \c B_f32 output matrix in the linear combination equation
  72. * \li \c X_f32 unknown matrix estimated using \c A_f32 & \c B_f32 matrices
  73. *
  74. * \par CMSIS DSP Software Library Functions Used:
  75. * \par
  76. * - arm_mat_init_f32()
  77. * - arm_mat_trans_f32()
  78. * - arm_mat_mult_f32()
  79. * - arm_mat_inverse_f32()
  80. *
  81. * <b> Refer </b>
  82. * \link arm_matrix_example_f32.c \endlink
  83. *
  84. */
  85. /** \example arm_matrix_example_f32.c
  86. */
  87. #include "arm_math.h"
  88. #include "math_helper.h"
  89. #if defined(SEMIHOSTING)
  90. #include <stdio.h>
  91. #endif
  92. #define SNR_THRESHOLD 77
  93. /* --------------------------------------------------------------------------------
  94. * Test input data(Cycles) taken from FIR Q15 module for differant cases of blockSize
  95. * and tapSize
  96. * --------------------------------------------------------------------------------- */
  97. const float32_t B_f32[4] =
  98. {
  99. 782.0, 7577.0, 470.0, 4505.0
  100. };
  101. /* --------------------------------------------------------------------------------
  102. * Formula to fit is C1 + C2 * numTaps + C3 * blockSize + C4 * numTaps * blockSize
  103. * -------------------------------------------------------------------------------- */
  104. const float32_t A_f32[16] =
  105. {
  106. /* Const, numTaps, blockSize, numTaps*blockSize */
  107. 1.0, 32.0, 4.0, 128.0,
  108. 1.0, 32.0, 64.0, 2048.0,
  109. 1.0, 16.0, 4.0, 64.0,
  110. 1.0, 16.0, 64.0, 1024.0,
  111. };
  112. /* ----------------------------------------------------------------------
  113. * Temporary buffers for storing intermediate values
  114. * ------------------------------------------------------------------- */
  115. /* Transpose of A Buffer */
  116. float32_t AT_f32[16];
  117. /* (Transpose of A * A) Buffer */
  118. float32_t ATMA_f32[16];
  119. /* Inverse(Transpose of A * A) Buffer */
  120. float32_t ATMAI_f32[16];
  121. /* Test Output Buffer */
  122. float32_t X_f32[4];
  123. /* ----------------------------------------------------------------------
  124. * Reference ouput buffer C1, C2, C3 and C4 taken from MATLAB
  125. * ------------------------------------------------------------------- */
  126. const float32_t xRef_f32[4] = {73.0, 8.0, 21.25, 2.875};
  127. float32_t snr;
  128. /* ----------------------------------------------------------------------
  129. * Max magnitude FFT Bin test
  130. * ------------------------------------------------------------------- */
  131. int32_t main(void)
  132. {
  133. arm_matrix_instance_f32 A; /* Matrix A Instance */
  134. arm_matrix_instance_f32 AT; /* Matrix AT(A transpose) instance */
  135. arm_matrix_instance_f32 ATMA; /* Matrix ATMA( AT multiply with A) instance */
  136. arm_matrix_instance_f32 ATMAI; /* Matrix ATMAI(Inverse of ATMA) instance */
  137. arm_matrix_instance_f32 B; /* Matrix B instance */
  138. arm_matrix_instance_f32 X; /* Matrix X(Unknown Matrix) instance */
  139. uint32_t srcRows, srcColumns; /* Temporary variables */
  140. arm_status status;
  141. /* Initialise A Matrix Instance with numRows, numCols and data array(A_f32) */
  142. srcRows = 4;
  143. srcColumns = 4;
  144. arm_mat_init_f32(&A, srcRows, srcColumns, (float32_t *)A_f32);
  145. /* Initialise Matrix Instance AT with numRows, numCols and data array(AT_f32) */
  146. srcRows = 4;
  147. srcColumns = 4;
  148. arm_mat_init_f32(&AT, srcRows, srcColumns, AT_f32);
  149. /* calculation of A transpose */
  150. status = arm_mat_trans_f32(&A, &AT);
  151. /* Initialise ATMA Matrix Instance with numRows, numCols and data array(ATMA_f32) */
  152. srcRows = 4;
  153. srcColumns = 4;
  154. arm_mat_init_f32(&ATMA, srcRows, srcColumns, ATMA_f32);
  155. /* calculation of AT Multiply with A */
  156. status = arm_mat_mult_f32(&AT, &A, &ATMA);
  157. /* Initialise ATMAI Matrix Instance with numRows, numCols and data array(ATMAI_f32) */
  158. srcRows = 4;
  159. srcColumns = 4;
  160. arm_mat_init_f32(&ATMAI, srcRows, srcColumns, ATMAI_f32);
  161. /* calculation of Inverse((Transpose(A) * A) */
  162. status = arm_mat_inverse_f32(&ATMA, &ATMAI);
  163. /* calculation of (Inverse((Transpose(A) * A)) * Transpose(A)) */
  164. status = arm_mat_mult_f32(&ATMAI, &AT, &ATMA);
  165. /* Initialise B Matrix Instance with numRows, numCols and data array(B_f32) */
  166. srcRows = 4;
  167. srcColumns = 1;
  168. arm_mat_init_f32(&B, srcRows, srcColumns, (float32_t *)B_f32);
  169. /* Initialise X Matrix Instance with numRows, numCols and data array(X_f32) */
  170. srcRows = 4;
  171. srcColumns = 1;
  172. arm_mat_init_f32(&X, srcRows, srcColumns, X_f32);
  173. /* calculation ((Inverse((Transpose(A) * A)) * Transpose(A)) * B) */
  174. status = arm_mat_mult_f32(&ATMA, &B, &X);
  175. /* Comparison of reference with test output */
  176. snr = arm_snr_f32((float32_t *)xRef_f32, X_f32, 4);
  177. /*------------------------------------------------------------------------------
  178. * Initialise status depending on SNR calculations
  179. *------------------------------------------------------------------------------*/
  180. status = (snr < SNR_THRESHOLD) ? ARM_MATH_TEST_FAILURE : ARM_MATH_SUCCESS;
  181. if (status != ARM_MATH_SUCCESS)
  182. {
  183. #if defined (SEMIHOSTING)
  184. printf("FAILURE\n");
  185. #else
  186. while (1); /* main function does not return */
  187. #endif
  188. }
  189. else
  190. {
  191. #if defined (SEMIHOSTING)
  192. printf("SUCCESS\n");
  193. #else
  194. while (1); /* main function does not return */
  195. #endif
  196. }
  197. }
  198. /** \endlink */