arm_matrix_example_f32.c
| 1 |
/* ----------------------------------------------------------------------
|
|---|---|
| 2 |
* Copyright (C) 2010 ARM Limited. All rights reserved.
|
| 3 |
*
|
| 4 |
* $Date: 29. November 2010
|
| 5 |
* $Revision: V1.0.3
|
| 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 |
*
|
| 16 |
* Version 1.0.3 2010/11/29
|
| 17 |
* Re-organized the CMSIS folders and updated documentation.
|
| 18 |
*
|
| 19 |
* Version 1.0.1 2010/10/05 KK
|
| 20 |
* Production release and review comments incorporated.
|
| 21 |
*
|
| 22 |
* Version 1.0.0 2010/09/20 KK
|
| 23 |
* Production release and review comments incorporated.
|
| 24 |
* ------------------------------------------------------------------- */
|
| 25 |
|
| 26 |
/**
|
| 27 |
* @ingroup groupExamples
|
| 28 |
*/
|
| 29 |
|
| 30 |
/**
|
| 31 |
* @defgroup MatrixExample Matrix Example
|
| 32 |
*
|
| 33 |
* \par Description:
|
| 34 |
* \par
|
| 35 |
* Demonstrates the use of Matrix Transpose, Matrix Muliplication, and Matrix Inverse
|
| 36 |
* functions to apply least squares fitting to input data. Least squares fitting is
|
| 37 |
* the procedure for finding the best-fitting curve that minimizes the sum of the
|
| 38 |
* squares of the offsets (least square error) from a given set of data.
|
| 39 |
*
|
| 40 |
* \par Algorithm:
|
| 41 |
* \par
|
| 42 |
* The linear combination of parameters considered is as follows:
|
| 43 |
* \par
|
| 44 |
* <code>A * X = B</code>, where \c X is the unknown value and can be estimated
|
| 45 |
* from \c A & \c B.
|
| 46 |
* \par
|
| 47 |
* The least squares estimate \c X is given by the following equation:
|
| 48 |
* \par
|
| 49 |
* <code>X = Inverse(A<sup>T</sup> * A) * A<sup>T</sup> * B</code>
|
| 50 |
*
|
| 51 |
* \par Block Diagram:
|
| 52 |
* \par
|
| 53 |
* \image html matrixExample.gif
|
| 54 |
*
|
| 55 |
* \par Variables Description:
|
| 56 |
* \par
|
| 57 |
* \li \c A_f32 input matrix in the linear combination equation
|
| 58 |
* \li \c B_f32 output matrix in the linear combination equation
|
| 59 |
* \li \c X_f32 unknown matrix estimated using \c A_f32 & \c B_f32 matrices
|
| 60 |
*
|
| 61 |
* \par CMSIS DSP Software Library Functions Used:
|
| 62 |
* \par
|
| 63 |
* - arm_mat_init_f32()
|
| 64 |
* - arm_mat_trans_f32()
|
| 65 |
* - arm_mat_mult_f32()
|
| 66 |
* - arm_mat_inverse_f32()
|
| 67 |
*
|
| 68 |
* <b> Refer </b>
|
| 69 |
* \link arm_matrix_example_f32.c \endlink
|
| 70 |
*
|
| 71 |
*/
|
| 72 |
|
| 73 |
|
| 74 |
/** \example arm_matrix_example_f32.c
|
| 75 |
*/
|
| 76 |
|
| 77 |
#include "arm_math.h" |
| 78 |
#include "math_helper.h" |
| 79 |
|
| 80 |
#define SNR_THRESHOLD 90 |
| 81 |
|
| 82 |
/* --------------------------------------------------------------------------------
|
| 83 |
* Test input data(Cycles) taken from FIR Q15 module for differant cases of blockSize
|
| 84 |
* and tapSize
|
| 85 |
* --------------------------------------------------------------------------------- */
|
| 86 |
|
| 87 |
const float32_t B_f32[4] = |
| 88 |
{
|
| 89 |
782.0, 7577.0, 470.0, 4505.0 |
| 90 |
}; |
| 91 |
|
| 92 |
/* --------------------------------------------------------------------------------
|
| 93 |
* Formula to fit is C1 + C2 * numTaps + C3 * blockSize + C4 * numTaps * blockSize
|
| 94 |
* -------------------------------------------------------------------------------- */
|
| 95 |
|
| 96 |
const float32_t A_f32[16] = |
| 97 |
{
|
| 98 |
/* Const, numTaps, blockSize, numTaps*blockSize */
|
| 99 |
1.0, 32.0, 4.0, 128.0, |
| 100 |
1.0, 32.0, 64.0, 2048.0, |
| 101 |
1.0, 16.0, 4.0, 64.0, |
| 102 |
1.0, 16.0, 64.0, 1024.0, |
| 103 |
}; |
| 104 |
|
| 105 |
|
| 106 |
/* ----------------------------------------------------------------------
|
| 107 |
* Temporary buffers for storing intermediate values
|
| 108 |
* ------------------------------------------------------------------- */
|
| 109 |
/* Transpose of A Buffer */
|
| 110 |
float32_t AT_f32[16];
|
| 111 |
/* (Transpose of A * A) Buffer */
|
| 112 |
float32_t ATMA_f32[16];
|
| 113 |
/* Inverse(Transpose of A * A) Buffer */
|
| 114 |
float32_t ATMAI_f32[16];
|
| 115 |
/* Test Output Buffer */
|
| 116 |
float32_t X_f32[4];
|
| 117 |
|
| 118 |
/* ----------------------------------------------------------------------
|
| 119 |
* Reference ouput buffer C1, C2, C3 and C4 taken from MATLAB
|
| 120 |
* ------------------------------------------------------------------- */
|
| 121 |
const float32_t xRef_f32[4] = {73.0, 8.0, 21.25, 2.875}; |
| 122 |
|
| 123 |
float32_t snr; |
| 124 |
|
| 125 |
|
| 126 |
/* ----------------------------------------------------------------------
|
| 127 |
* Max magnitude FFT Bin test
|
| 128 |
* ------------------------------------------------------------------- */
|
| 129 |
|
| 130 |
int32_t main(void)
|
| 131 |
{
|
| 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 |
|
| 140 |
uint32_t srcRows, srcColumns; /* Temporary variables */
|
| 141 |
arm_status status; |
| 142 |
|
| 143 |
/* Initialise A Matrix Instance with numRows, numCols and data array(A_f32) */
|
| 144 |
srcRows = 4;
|
| 145 |
srcColumns = 4;
|
| 146 |
arm_mat_init_f32(&A, srcRows, srcColumns, (float32_t *)A_f32); |
| 147 |
|
| 148 |
/* Initialise Matrix Instance AT with numRows, numCols and data array(AT_f32) */
|
| 149 |
srcRows = 4;
|
| 150 |
srcColumns = 4;
|
| 151 |
arm_mat_init_f32(&AT, srcRows, srcColumns, AT_f32); |
| 152 |
|
| 153 |
/* calculation of A transpose */
|
| 154 |
status = arm_mat_trans_f32(&A, &AT); |
| 155 |
|
| 156 |
|
| 157 |
/* Initialise ATMA Matrix Instance with numRows, numCols and data array(ATMA_f32) */
|
| 158 |
srcRows = 4;
|
| 159 |
srcColumns = 4;
|
| 160 |
arm_mat_init_f32(&ATMA, srcRows, srcColumns, ATMA_f32); |
| 161 |
|
| 162 |
/* calculation of AT Multiply with A */
|
| 163 |
status = arm_mat_mult_f32(&AT, &A, &ATMA); |
| 164 |
|
| 165 |
/* Initialise ATMAI Matrix Instance with numRows, numCols and data array(ATMAI_f32) */
|
| 166 |
srcRows = 4;
|
| 167 |
srcColumns = 4;
|
| 168 |
arm_mat_init_f32(&ATMAI, srcRows, srcColumns, ATMAI_f32); |
| 169 |
|
| 170 |
/* calculation of Inverse((Transpose(A) * A) */
|
| 171 |
status = arm_mat_inverse_f32(&ATMA, &ATMAI); |
| 172 |
|
| 173 |
/* calculation of (Inverse((Transpose(A) * A)) * Transpose(A)) */
|
| 174 |
status = arm_mat_mult_f32(&ATMAI, &AT, &ATMA); |
| 175 |
|
| 176 |
/* Initialise B Matrix Instance with numRows, numCols and data array(B_f32) */
|
| 177 |
srcRows = 4;
|
| 178 |
srcColumns = 1;
|
| 179 |
arm_mat_init_f32(&B, srcRows, srcColumns, (float32_t *)B_f32); |
| 180 |
|
| 181 |
/* Initialise X Matrix Instance with numRows, numCols and data array(X_f32) */
|
| 182 |
srcRows = 4;
|
| 183 |
srcColumns = 1;
|
| 184 |
arm_mat_init_f32(&X, srcRows, srcColumns, X_f32); |
| 185 |
|
| 186 |
/* calculation ((Inverse((Transpose(A) * A)) * Transpose(A)) * B) */
|
| 187 |
status = arm_mat_mult_f32(&ATMA, &B, &X); |
| 188 |
|
| 189 |
/* Comparison of reference with test output */
|
| 190 |
snr = arm_snr_f32((float32_t *)xRef_f32, X_f32, 4);
|
| 191 |
|
| 192 |
/*------------------------------------------------------------------------------
|
| 193 |
* Initialise status depending on SNR calculations
|
| 194 |
*------------------------------------------------------------------------------*/
|
| 195 |
if( snr > SNR_THRESHOLD)
|
| 196 |
{
|
| 197 |
status = ARM_MATH_SUCCESS; |
| 198 |
} |
| 199 |
else
|
| 200 |
{
|
| 201 |
status = ARM_MATH_TEST_FAILURE; |
| 202 |
} |
| 203 |
|
| 204 |
|
| 205 |
/* ----------------------------------------------------------------------
|
| 206 |
** Loop here if the signals fail the PASS check.
|
| 207 |
** This denotes a test failure
|
| 208 |
** ------------------------------------------------------------------- */
|
| 209 |
if( status != ARM_MATH_SUCCESS)
|
| 210 |
{
|
| 211 |
while(1); |
| 212 |
} |
| 213 |
|
| 214 |
while(1); /* main function does not return */ |
| 215 |
} |
| 216 |
|
| 217 |
/** \endlink */
|
| 218 |
|