CMSIS DSP library

Dependents:   performance_timer Surfboard_ gps2rtty Capstone ... more

Legacy Warning

This is an mbed 2 library. To learn more about mbed OS 5, visit the docs.

Committer:
emilmont
Date:
Thu May 30 17:10:11 2013 +0100
Revision:
2:da51fb522205
Parent:
1:fdd22bb7aa52
Child:
3:7a284390b0ce
Keep "cmsis-dsp" module in synch with its source

Who changed what in which revision?

UserRevisionLine numberNew contents of line
emilmont 1:fdd22bb7aa52 1 /* ----------------------------------------------------------------------
emilmont 1:fdd22bb7aa52 2 * Copyright (C) 2010 ARM Limited. All rights reserved.
emilmont 1:fdd22bb7aa52 3 *
emilmont 1:fdd22bb7aa52 4 * $Date: 15. February 2012
emilmont 2:da51fb522205 5 * $Revision: V1.1.0
emilmont 1:fdd22bb7aa52 6 *
emilmont 2:da51fb522205 7 * Project: CMSIS DSP Library
emilmont 2:da51fb522205 8 * Title: arm_mat_inverse_f32.c
emilmont 1:fdd22bb7aa52 9 *
emilmont 2:da51fb522205 10 * Description: Floating-point matrix inverse.
emilmont 1:fdd22bb7aa52 11 *
emilmont 1:fdd22bb7aa52 12 * Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
emilmont 1:fdd22bb7aa52 13 *
emilmont 1:fdd22bb7aa52 14 * Version 1.1.0 2012/02/15
emilmont 1:fdd22bb7aa52 15 * Updated with more optimizations, bug fixes and minor API changes.
emilmont 1:fdd22bb7aa52 16 *
emilmont 1:fdd22bb7aa52 17 * Version 1.0.10 2011/7/15
emilmont 1:fdd22bb7aa52 18 * Big Endian support added and Merged M0 and M3/M4 Source code.
emilmont 1:fdd22bb7aa52 19 *
emilmont 1:fdd22bb7aa52 20 * Version 1.0.3 2010/11/29
emilmont 1:fdd22bb7aa52 21 * Re-organized the CMSIS folders and updated documentation.
emilmont 1:fdd22bb7aa52 22 *
emilmont 1:fdd22bb7aa52 23 * Version 1.0.2 2010/11/11
emilmont 1:fdd22bb7aa52 24 * Documentation updated.
emilmont 1:fdd22bb7aa52 25 *
emilmont 1:fdd22bb7aa52 26 * Version 1.0.1 2010/10/05
emilmont 1:fdd22bb7aa52 27 * Production release and review comments incorporated.
emilmont 1:fdd22bb7aa52 28 *
emilmont 1:fdd22bb7aa52 29 * Version 1.0.0 2010/09/20
emilmont 1:fdd22bb7aa52 30 * Production release and review comments incorporated.
emilmont 1:fdd22bb7aa52 31 * -------------------------------------------------------------------- */
emilmont 1:fdd22bb7aa52 32
emilmont 1:fdd22bb7aa52 33 #include "arm_math.h"
emilmont 1:fdd22bb7aa52 34
emilmont 1:fdd22bb7aa52 35 /**
emilmont 1:fdd22bb7aa52 36 * @ingroup groupMatrix
emilmont 1:fdd22bb7aa52 37 */
emilmont 1:fdd22bb7aa52 38
emilmont 1:fdd22bb7aa52 39 /**
emilmont 1:fdd22bb7aa52 40 * @defgroup MatrixInv Matrix Inverse
emilmont 1:fdd22bb7aa52 41 *
emilmont 1:fdd22bb7aa52 42 * Computes the inverse of a matrix.
emilmont 1:fdd22bb7aa52 43 *
emilmont 1:fdd22bb7aa52 44 * The inverse is defined only if the input matrix is square and non-singular (the determinant
emilmont 1:fdd22bb7aa52 45 * is non-zero). The function checks that the input and output matrices are square and of the
emilmont 1:fdd22bb7aa52 46 * same size.
emilmont 1:fdd22bb7aa52 47 *
emilmont 1:fdd22bb7aa52 48 * Matrix inversion is numerically sensitive and the CMSIS DSP library only supports matrix
emilmont 1:fdd22bb7aa52 49 * inversion of floating-point matrices.
emilmont 1:fdd22bb7aa52 50 *
emilmont 1:fdd22bb7aa52 51 * \par Algorithm
emilmont 1:fdd22bb7aa52 52 * The Gauss-Jordan method is used to find the inverse.
emilmont 1:fdd22bb7aa52 53 * The algorithm performs a sequence of elementary row-operations till it
emilmont 1:fdd22bb7aa52 54 * reduces the input matrix to an identity matrix. Applying the same sequence
emilmont 1:fdd22bb7aa52 55 * of elementary row-operations to an identity matrix yields the inverse matrix.
emilmont 1:fdd22bb7aa52 56 * If the input matrix is singular, then the algorithm terminates and returns error status
emilmont 1:fdd22bb7aa52 57 * <code>ARM_MATH_SINGULAR</code>.
emilmont 1:fdd22bb7aa52 58 * \image html MatrixInverse.gif "Matrix Inverse of a 3 x 3 matrix using Gauss-Jordan Method"
emilmont 1:fdd22bb7aa52 59 */
emilmont 1:fdd22bb7aa52 60
emilmont 1:fdd22bb7aa52 61 /**
emilmont 1:fdd22bb7aa52 62 * @addtogroup MatrixInv
emilmont 1:fdd22bb7aa52 63 * @{
emilmont 1:fdd22bb7aa52 64 */
emilmont 1:fdd22bb7aa52 65
emilmont 1:fdd22bb7aa52 66 /**
emilmont 1:fdd22bb7aa52 67 * @brief Floating-point matrix inverse.
emilmont 1:fdd22bb7aa52 68 * @param[in] *pSrc points to input matrix structure
emilmont 1:fdd22bb7aa52 69 * @param[out] *pDst points to output matrix structure
emilmont 2:da51fb522205 70 * @return The function returns
emilmont 1:fdd22bb7aa52 71 * <code>ARM_MATH_SIZE_MISMATCH</code> if the input matrix is not square or if the size
emilmont 1:fdd22bb7aa52 72 * of the output matrix does not match the size of the input matrix.
emilmont 1:fdd22bb7aa52 73 * If the input matrix is found to be singular (non-invertible), then the function returns
emilmont 1:fdd22bb7aa52 74 * <code>ARM_MATH_SINGULAR</code>. Otherwise, the function returns <code>ARM_MATH_SUCCESS</code>.
emilmont 1:fdd22bb7aa52 75 */
emilmont 1:fdd22bb7aa52 76
emilmont 1:fdd22bb7aa52 77 arm_status arm_mat_inverse_f32(
emilmont 1:fdd22bb7aa52 78 const arm_matrix_instance_f32 * pSrc,
emilmont 1:fdd22bb7aa52 79 arm_matrix_instance_f32 * pDst)
emilmont 1:fdd22bb7aa52 80 {
emilmont 1:fdd22bb7aa52 81 float32_t *pIn = pSrc->pData; /* input data matrix pointer */
emilmont 1:fdd22bb7aa52 82 float32_t *pOut = pDst->pData; /* output data matrix pointer */
emilmont 1:fdd22bb7aa52 83 float32_t *pInT1, *pInT2; /* Temporary input data matrix pointer */
emilmont 1:fdd22bb7aa52 84 float32_t *pInT3, *pInT4; /* Temporary output data matrix pointer */
emilmont 1:fdd22bb7aa52 85 float32_t *pPivotRowIn, *pPRT_in, *pPivotRowDst, *pPRT_pDst; /* Temporary input and output data matrix pointer */
emilmont 1:fdd22bb7aa52 86 uint32_t numRows = pSrc->numRows; /* Number of rows in the matrix */
emilmont 1:fdd22bb7aa52 87 uint32_t numCols = pSrc->numCols; /* Number of Cols in the matrix */
emilmont 1:fdd22bb7aa52 88
emilmont 1:fdd22bb7aa52 89 #ifndef ARM_MATH_CM0
emilmont 1:fdd22bb7aa52 90
emilmont 1:fdd22bb7aa52 91 /* Run the below code for Cortex-M4 and Cortex-M3 */
emilmont 1:fdd22bb7aa52 92
emilmont 1:fdd22bb7aa52 93 float32_t Xchg, in = 0.0f, in1; /* Temporary input values */
emilmont 1:fdd22bb7aa52 94 uint32_t i, rowCnt, flag = 0u, j, loopCnt, k, l; /* loop counters */
emilmont 1:fdd22bb7aa52 95 arm_status status; /* status of matrix inverse */
emilmont 1:fdd22bb7aa52 96
emilmont 1:fdd22bb7aa52 97 #ifdef ARM_MATH_MATRIX_CHECK
emilmont 1:fdd22bb7aa52 98
emilmont 1:fdd22bb7aa52 99
emilmont 1:fdd22bb7aa52 100 /* Check for matrix mismatch condition */
emilmont 1:fdd22bb7aa52 101 if((pSrc->numRows != pSrc->numCols) || (pDst->numRows != pDst->numCols)
emilmont 1:fdd22bb7aa52 102 || (pSrc->numRows != pDst->numRows))
emilmont 1:fdd22bb7aa52 103 {
emilmont 1:fdd22bb7aa52 104 /* Set status as ARM_MATH_SIZE_MISMATCH */
emilmont 1:fdd22bb7aa52 105 status = ARM_MATH_SIZE_MISMATCH;
emilmont 1:fdd22bb7aa52 106 }
emilmont 1:fdd22bb7aa52 107 else
emilmont 1:fdd22bb7aa52 108 #endif /* #ifdef ARM_MATH_MATRIX_CHECK */
emilmont 1:fdd22bb7aa52 109
emilmont 1:fdd22bb7aa52 110 {
emilmont 1:fdd22bb7aa52 111
emilmont 1:fdd22bb7aa52 112 /*--------------------------------------------------------------------------------------------------------------
emilmont 2:da51fb522205 113 * Matrix Inverse can be solved using elementary row operations.
emilmont 2:da51fb522205 114 *
emilmont 2:da51fb522205 115 * Gauss-Jordan Method:
emilmont 2:da51fb522205 116 *
emilmont 2:da51fb522205 117 * 1. First combine the identity matrix and the input matrix separated by a bar to form an
emilmont 2:da51fb522205 118 * augmented matrix as follows:
emilmont 2:da51fb522205 119 * _ _ _ _
emilmont 2:da51fb522205 120 * | a11 a12 | 1 0 | | X11 X12 |
emilmont 2:da51fb522205 121 * | | | = | |
emilmont 2:da51fb522205 122 * |_ a21 a22 | 0 1 _| |_ X21 X21 _|
emilmont 2:da51fb522205 123 *
emilmont 2:da51fb522205 124 * 2. In our implementation, pDst Matrix is used as identity matrix.
emilmont 2:da51fb522205 125 *
emilmont 2:da51fb522205 126 * 3. Begin with the first row. Let i = 1.
emilmont 2:da51fb522205 127 *
emilmont 2:da51fb522205 128 * 4. Check to see if the pivot for row i is zero.
emilmont 2:da51fb522205 129 * The pivot is the element of the main diagonal that is on the current row.
emilmont 2:da51fb522205 130 * For instance, if working with row i, then the pivot element is aii.
emilmont 2:da51fb522205 131 * If the pivot is zero, exchange that row with a row below it that does not
emilmont 2:da51fb522205 132 * contain a zero in column i. If this is not possible, then an inverse
emilmont 2:da51fb522205 133 * to that matrix does not exist.
emilmont 2:da51fb522205 134 *
emilmont 2:da51fb522205 135 * 5. Divide every element of row i by the pivot.
emilmont 2:da51fb522205 136 *
emilmont 2:da51fb522205 137 * 6. For every row below and row i, replace that row with the sum of that row and
emilmont 2:da51fb522205 138 * a multiple of row i so that each new element in column i below row i is zero.
emilmont 2:da51fb522205 139 *
emilmont 2:da51fb522205 140 * 7. Move to the next row and column and repeat steps 2 through 5 until you have zeros
emilmont 2:da51fb522205 141 * for every element below and above the main diagonal.
emilmont 2:da51fb522205 142 *
emilmont 2:da51fb522205 143 * 8. Now an identical matrix is formed to the left of the bar(input matrix, pSrc).
emilmont 2:da51fb522205 144 * Therefore, the matrix to the right of the bar is our solution(pDst matrix, pDst).
emilmont 2:da51fb522205 145 *----------------------------------------------------------------------------------------------------------------*/
emilmont 1:fdd22bb7aa52 146
emilmont 1:fdd22bb7aa52 147 /* Working pointer for destination matrix */
emilmont 1:fdd22bb7aa52 148 pInT2 = pOut;
emilmont 1:fdd22bb7aa52 149
emilmont 1:fdd22bb7aa52 150 /* Loop over the number of rows */
emilmont 1:fdd22bb7aa52 151 rowCnt = numRows;
emilmont 1:fdd22bb7aa52 152
emilmont 1:fdd22bb7aa52 153 /* Making the destination matrix as identity matrix */
emilmont 1:fdd22bb7aa52 154 while(rowCnt > 0u)
emilmont 1:fdd22bb7aa52 155 {
emilmont 1:fdd22bb7aa52 156 /* Writing all zeroes in lower triangle of the destination matrix */
emilmont 1:fdd22bb7aa52 157 j = numRows - rowCnt;
emilmont 1:fdd22bb7aa52 158 while(j > 0u)
emilmont 1:fdd22bb7aa52 159 {
emilmont 1:fdd22bb7aa52 160 *pInT2++ = 0.0f;
emilmont 1:fdd22bb7aa52 161 j--;
emilmont 1:fdd22bb7aa52 162 }
emilmont 1:fdd22bb7aa52 163
emilmont 1:fdd22bb7aa52 164 /* Writing all ones in the diagonal of the destination matrix */
emilmont 1:fdd22bb7aa52 165 *pInT2++ = 1.0f;
emilmont 1:fdd22bb7aa52 166
emilmont 1:fdd22bb7aa52 167 /* Writing all zeroes in upper triangle of the destination matrix */
emilmont 1:fdd22bb7aa52 168 j = rowCnt - 1u;
emilmont 1:fdd22bb7aa52 169 while(j > 0u)
emilmont 1:fdd22bb7aa52 170 {
emilmont 1:fdd22bb7aa52 171 *pInT2++ = 0.0f;
emilmont 1:fdd22bb7aa52 172 j--;
emilmont 1:fdd22bb7aa52 173 }
emilmont 1:fdd22bb7aa52 174
emilmont 1:fdd22bb7aa52 175 /* Decrement the loop counter */
emilmont 1:fdd22bb7aa52 176 rowCnt--;
emilmont 1:fdd22bb7aa52 177 }
emilmont 1:fdd22bb7aa52 178
emilmont 1:fdd22bb7aa52 179 /* Loop over the number of columns of the input matrix.
emilmont 1:fdd22bb7aa52 180 All the elements in each column are processed by the row operations */
emilmont 1:fdd22bb7aa52 181 loopCnt = numCols;
emilmont 1:fdd22bb7aa52 182
emilmont 1:fdd22bb7aa52 183 /* Index modifier to navigate through the columns */
emilmont 1:fdd22bb7aa52 184 l = 0u;
emilmont 1:fdd22bb7aa52 185
emilmont 1:fdd22bb7aa52 186 while(loopCnt > 0u)
emilmont 1:fdd22bb7aa52 187 {
emilmont 1:fdd22bb7aa52 188 /* Check if the pivot element is zero..
emilmont 1:fdd22bb7aa52 189 * If it is zero then interchange the row with non zero row below.
emilmont 1:fdd22bb7aa52 190 * If there is no non zero element to replace in the rows below,
emilmont 1:fdd22bb7aa52 191 * then the matrix is Singular. */
emilmont 1:fdd22bb7aa52 192
emilmont 1:fdd22bb7aa52 193 /* Working pointer for the input matrix that points
emilmont 1:fdd22bb7aa52 194 * to the pivot element of the particular row */
emilmont 1:fdd22bb7aa52 195 pInT1 = pIn + (l * numCols);
emilmont 1:fdd22bb7aa52 196
emilmont 1:fdd22bb7aa52 197 /* Working pointer for the destination matrix that points
emilmont 1:fdd22bb7aa52 198 * to the pivot element of the particular row */
emilmont 1:fdd22bb7aa52 199 pInT3 = pOut + (l * numCols);
emilmont 1:fdd22bb7aa52 200
emilmont 1:fdd22bb7aa52 201 /* Temporary variable to hold the pivot value */
emilmont 1:fdd22bb7aa52 202 in = *pInT1;
emilmont 1:fdd22bb7aa52 203
emilmont 1:fdd22bb7aa52 204 /* Destination pointer modifier */
emilmont 1:fdd22bb7aa52 205 k = 1u;
emilmont 1:fdd22bb7aa52 206
emilmont 1:fdd22bb7aa52 207 /* Check if the pivot element is zero */
emilmont 1:fdd22bb7aa52 208 if(*pInT1 == 0.0f)
emilmont 1:fdd22bb7aa52 209 {
emilmont 1:fdd22bb7aa52 210 /* Loop over the number rows present below */
emilmont 1:fdd22bb7aa52 211 i = numRows - (l + 1u);
emilmont 1:fdd22bb7aa52 212
emilmont 1:fdd22bb7aa52 213 while(i > 0u)
emilmont 1:fdd22bb7aa52 214 {
emilmont 1:fdd22bb7aa52 215 /* Update the input and destination pointers */
emilmont 1:fdd22bb7aa52 216 pInT2 = pInT1 + (numCols * l);
emilmont 1:fdd22bb7aa52 217 pInT4 = pInT3 + (numCols * k);
emilmont 1:fdd22bb7aa52 218
emilmont 1:fdd22bb7aa52 219 /* Check if there is a non zero pivot element to
emilmont 1:fdd22bb7aa52 220 * replace in the rows below */
emilmont 1:fdd22bb7aa52 221 if(*pInT2 != 0.0f)
emilmont 1:fdd22bb7aa52 222 {
emilmont 1:fdd22bb7aa52 223 /* Loop over number of columns
emilmont 1:fdd22bb7aa52 224 * to the right of the pilot element */
emilmont 1:fdd22bb7aa52 225 j = numCols - l;
emilmont 1:fdd22bb7aa52 226
emilmont 1:fdd22bb7aa52 227 while(j > 0u)
emilmont 1:fdd22bb7aa52 228 {
emilmont 1:fdd22bb7aa52 229 /* Exchange the row elements of the input matrix */
emilmont 1:fdd22bb7aa52 230 Xchg = *pInT2;
emilmont 1:fdd22bb7aa52 231 *pInT2++ = *pInT1;
emilmont 1:fdd22bb7aa52 232 *pInT1++ = Xchg;
emilmont 1:fdd22bb7aa52 233
emilmont 1:fdd22bb7aa52 234 /* Decrement the loop counter */
emilmont 1:fdd22bb7aa52 235 j--;
emilmont 1:fdd22bb7aa52 236 }
emilmont 1:fdd22bb7aa52 237
emilmont 1:fdd22bb7aa52 238 /* Loop over number of columns of the destination matrix */
emilmont 1:fdd22bb7aa52 239 j = numCols;
emilmont 1:fdd22bb7aa52 240
emilmont 1:fdd22bb7aa52 241 while(j > 0u)
emilmont 1:fdd22bb7aa52 242 {
emilmont 1:fdd22bb7aa52 243 /* Exchange the row elements of the destination matrix */
emilmont 1:fdd22bb7aa52 244 Xchg = *pInT4;
emilmont 1:fdd22bb7aa52 245 *pInT4++ = *pInT3;
emilmont 1:fdd22bb7aa52 246 *pInT3++ = Xchg;
emilmont 1:fdd22bb7aa52 247
emilmont 1:fdd22bb7aa52 248 /* Decrement the loop counter */
emilmont 1:fdd22bb7aa52 249 j--;
emilmont 1:fdd22bb7aa52 250 }
emilmont 1:fdd22bb7aa52 251
emilmont 1:fdd22bb7aa52 252 /* Flag to indicate whether exchange is done or not */
emilmont 1:fdd22bb7aa52 253 flag = 1u;
emilmont 1:fdd22bb7aa52 254
emilmont 1:fdd22bb7aa52 255 /* Break after exchange is done */
emilmont 1:fdd22bb7aa52 256 break;
emilmont 1:fdd22bb7aa52 257 }
emilmont 1:fdd22bb7aa52 258
emilmont 1:fdd22bb7aa52 259 /* Update the destination pointer modifier */
emilmont 1:fdd22bb7aa52 260 k++;
emilmont 1:fdd22bb7aa52 261
emilmont 1:fdd22bb7aa52 262 /* Decrement the loop counter */
emilmont 1:fdd22bb7aa52 263 i--;
emilmont 1:fdd22bb7aa52 264 }
emilmont 1:fdd22bb7aa52 265 }
emilmont 1:fdd22bb7aa52 266
emilmont 1:fdd22bb7aa52 267 /* Update the status if the matrix is singular */
emilmont 1:fdd22bb7aa52 268 if((flag != 1u) && (in == 0.0f))
emilmont 1:fdd22bb7aa52 269 {
emilmont 1:fdd22bb7aa52 270 status = ARM_MATH_SINGULAR;
emilmont 1:fdd22bb7aa52 271
emilmont 1:fdd22bb7aa52 272 break;
emilmont 1:fdd22bb7aa52 273 }
emilmont 1:fdd22bb7aa52 274
emilmont 1:fdd22bb7aa52 275 /* Points to the pivot row of input and destination matrices */
emilmont 1:fdd22bb7aa52 276 pPivotRowIn = pIn + (l * numCols);
emilmont 1:fdd22bb7aa52 277 pPivotRowDst = pOut + (l * numCols);
emilmont 1:fdd22bb7aa52 278
emilmont 1:fdd22bb7aa52 279 /* Temporary pointers to the pivot row pointers */
emilmont 1:fdd22bb7aa52 280 pInT1 = pPivotRowIn;
emilmont 1:fdd22bb7aa52 281 pInT2 = pPivotRowDst;
emilmont 1:fdd22bb7aa52 282
emilmont 1:fdd22bb7aa52 283 /* Pivot element of the row */
emilmont 1:fdd22bb7aa52 284 in = *(pIn + (l * numCols));
emilmont 1:fdd22bb7aa52 285
emilmont 1:fdd22bb7aa52 286 /* Loop over number of columns
emilmont 1:fdd22bb7aa52 287 * to the right of the pilot element */
emilmont 1:fdd22bb7aa52 288 j = (numCols - l);
emilmont 1:fdd22bb7aa52 289
emilmont 1:fdd22bb7aa52 290 while(j > 0u)
emilmont 1:fdd22bb7aa52 291 {
emilmont 1:fdd22bb7aa52 292 /* Divide each element of the row of the input matrix
emilmont 1:fdd22bb7aa52 293 * by the pivot element */
emilmont 1:fdd22bb7aa52 294 in1 = *pInT1;
emilmont 1:fdd22bb7aa52 295 *pInT1++ = in1 / in;
emilmont 1:fdd22bb7aa52 296
emilmont 1:fdd22bb7aa52 297 /* Decrement the loop counter */
emilmont 1:fdd22bb7aa52 298 j--;
emilmont 1:fdd22bb7aa52 299 }
emilmont 1:fdd22bb7aa52 300
emilmont 1:fdd22bb7aa52 301 /* Loop over number of columns of the destination matrix */
emilmont 1:fdd22bb7aa52 302 j = numCols;
emilmont 1:fdd22bb7aa52 303
emilmont 1:fdd22bb7aa52 304 while(j > 0u)
emilmont 1:fdd22bb7aa52 305 {
emilmont 1:fdd22bb7aa52 306 /* Divide each element of the row of the destination matrix
emilmont 1:fdd22bb7aa52 307 * by the pivot element */
emilmont 1:fdd22bb7aa52 308 in1 = *pInT2;
emilmont 1:fdd22bb7aa52 309 *pInT2++ = in1 / in;
emilmont 1:fdd22bb7aa52 310
emilmont 1:fdd22bb7aa52 311 /* Decrement the loop counter */
emilmont 1:fdd22bb7aa52 312 j--;
emilmont 1:fdd22bb7aa52 313 }
emilmont 1:fdd22bb7aa52 314
emilmont 1:fdd22bb7aa52 315 /* Replace the rows with the sum of that row and a multiple of row i
emilmont 1:fdd22bb7aa52 316 * so that each new element in column i above row i is zero.*/
emilmont 1:fdd22bb7aa52 317
emilmont 1:fdd22bb7aa52 318 /* Temporary pointers for input and destination matrices */
emilmont 1:fdd22bb7aa52 319 pInT1 = pIn;
emilmont 1:fdd22bb7aa52 320 pInT2 = pOut;
emilmont 1:fdd22bb7aa52 321
emilmont 1:fdd22bb7aa52 322 /* index used to check for pivot element */
emilmont 1:fdd22bb7aa52 323 i = 0u;
emilmont 1:fdd22bb7aa52 324
emilmont 1:fdd22bb7aa52 325 /* Loop over number of rows */
emilmont 1:fdd22bb7aa52 326 /* to be replaced by the sum of that row and a multiple of row i */
emilmont 1:fdd22bb7aa52 327 k = numRows;
emilmont 1:fdd22bb7aa52 328
emilmont 1:fdd22bb7aa52 329 while(k > 0u)
emilmont 1:fdd22bb7aa52 330 {
emilmont 1:fdd22bb7aa52 331 /* Check for the pivot element */
emilmont 1:fdd22bb7aa52 332 if(i == l)
emilmont 1:fdd22bb7aa52 333 {
emilmont 1:fdd22bb7aa52 334 /* If the processing element is the pivot element,
emilmont 1:fdd22bb7aa52 335 only the columns to the right are to be processed */
emilmont 1:fdd22bb7aa52 336 pInT1 += numCols - l;
emilmont 1:fdd22bb7aa52 337
emilmont 1:fdd22bb7aa52 338 pInT2 += numCols;
emilmont 1:fdd22bb7aa52 339 }
emilmont 1:fdd22bb7aa52 340 else
emilmont 1:fdd22bb7aa52 341 {
emilmont 1:fdd22bb7aa52 342 /* Element of the reference row */
emilmont 1:fdd22bb7aa52 343 in = *pInT1;
emilmont 1:fdd22bb7aa52 344
emilmont 1:fdd22bb7aa52 345 /* Working pointers for input and destination pivot rows */
emilmont 1:fdd22bb7aa52 346 pPRT_in = pPivotRowIn;
emilmont 1:fdd22bb7aa52 347 pPRT_pDst = pPivotRowDst;
emilmont 1:fdd22bb7aa52 348
emilmont 1:fdd22bb7aa52 349 /* Loop over the number of columns to the right of the pivot element,
emilmont 1:fdd22bb7aa52 350 to replace the elements in the input matrix */
emilmont 1:fdd22bb7aa52 351 j = (numCols - l);
emilmont 1:fdd22bb7aa52 352
emilmont 1:fdd22bb7aa52 353 while(j > 0u)
emilmont 1:fdd22bb7aa52 354 {
emilmont 1:fdd22bb7aa52 355 /* Replace the element by the sum of that row
emilmont 1:fdd22bb7aa52 356 and a multiple of the reference row */
emilmont 1:fdd22bb7aa52 357 in1 = *pInT1;
emilmont 1:fdd22bb7aa52 358 *pInT1++ = in1 - (in * *pPRT_in++);
emilmont 1:fdd22bb7aa52 359
emilmont 1:fdd22bb7aa52 360 /* Decrement the loop counter */
emilmont 1:fdd22bb7aa52 361 j--;
emilmont 1:fdd22bb7aa52 362 }
emilmont 1:fdd22bb7aa52 363
emilmont 1:fdd22bb7aa52 364 /* Loop over the number of columns to
emilmont 1:fdd22bb7aa52 365 replace the elements in the destination matrix */
emilmont 1:fdd22bb7aa52 366 j = numCols;
emilmont 1:fdd22bb7aa52 367
emilmont 1:fdd22bb7aa52 368 while(j > 0u)
emilmont 1:fdd22bb7aa52 369 {
emilmont 1:fdd22bb7aa52 370 /* Replace the element by the sum of that row
emilmont 1:fdd22bb7aa52 371 and a multiple of the reference row */
emilmont 1:fdd22bb7aa52 372 in1 = *pInT2;
emilmont 1:fdd22bb7aa52 373 *pInT2++ = in1 - (in * *pPRT_pDst++);
emilmont 1:fdd22bb7aa52 374
emilmont 1:fdd22bb7aa52 375 /* Decrement the loop counter */
emilmont 1:fdd22bb7aa52 376 j--;
emilmont 1:fdd22bb7aa52 377 }
emilmont 1:fdd22bb7aa52 378
emilmont 1:fdd22bb7aa52 379 }
emilmont 1:fdd22bb7aa52 380
emilmont 1:fdd22bb7aa52 381 /* Increment the temporary input pointer */
emilmont 1:fdd22bb7aa52 382 pInT1 = pInT1 + l;
emilmont 1:fdd22bb7aa52 383
emilmont 1:fdd22bb7aa52 384 /* Decrement the loop counter */
emilmont 1:fdd22bb7aa52 385 k--;
emilmont 1:fdd22bb7aa52 386
emilmont 1:fdd22bb7aa52 387 /* Increment the pivot index */
emilmont 1:fdd22bb7aa52 388 i++;
emilmont 1:fdd22bb7aa52 389 }
emilmont 1:fdd22bb7aa52 390
emilmont 1:fdd22bb7aa52 391 /* Increment the input pointer */
emilmont 1:fdd22bb7aa52 392 pIn++;
emilmont 1:fdd22bb7aa52 393
emilmont 1:fdd22bb7aa52 394 /* Decrement the loop counter */
emilmont 1:fdd22bb7aa52 395 loopCnt--;
emilmont 1:fdd22bb7aa52 396
emilmont 1:fdd22bb7aa52 397 /* Increment the index modifier */
emilmont 1:fdd22bb7aa52 398 l++;
emilmont 1:fdd22bb7aa52 399 }
emilmont 1:fdd22bb7aa52 400
emilmont 1:fdd22bb7aa52 401
emilmont 1:fdd22bb7aa52 402 #else
emilmont 1:fdd22bb7aa52 403
emilmont 1:fdd22bb7aa52 404 /* Run the below code for Cortex-M0 */
emilmont 1:fdd22bb7aa52 405
emilmont 1:fdd22bb7aa52 406 float32_t Xchg, in = 0.0f; /* Temporary input values */
emilmont 1:fdd22bb7aa52 407 uint32_t i, rowCnt, flag = 0u, j, loopCnt, k, l; /* loop counters */
emilmont 1:fdd22bb7aa52 408 arm_status status; /* status of matrix inverse */
emilmont 1:fdd22bb7aa52 409
emilmont 1:fdd22bb7aa52 410 #ifdef ARM_MATH_MATRIX_CHECK
emilmont 1:fdd22bb7aa52 411
emilmont 1:fdd22bb7aa52 412 /* Check for matrix mismatch condition */
emilmont 1:fdd22bb7aa52 413 if((pSrc->numRows != pSrc->numCols) || (pDst->numRows != pDst->numCols)
emilmont 1:fdd22bb7aa52 414 || (pSrc->numRows != pDst->numRows))
emilmont 1:fdd22bb7aa52 415 {
emilmont 1:fdd22bb7aa52 416 /* Set status as ARM_MATH_SIZE_MISMATCH */
emilmont 1:fdd22bb7aa52 417 status = ARM_MATH_SIZE_MISMATCH;
emilmont 1:fdd22bb7aa52 418 }
emilmont 1:fdd22bb7aa52 419 else
emilmont 1:fdd22bb7aa52 420 #endif /* #ifdef ARM_MATH_MATRIX_CHECK */
emilmont 1:fdd22bb7aa52 421 {
emilmont 1:fdd22bb7aa52 422
emilmont 1:fdd22bb7aa52 423 /*--------------------------------------------------------------------------------------------------------------
emilmont 2:da51fb522205 424 * Matrix Inverse can be solved using elementary row operations.
emilmont 2:da51fb522205 425 *
emilmont 2:da51fb522205 426 * Gauss-Jordan Method:
emilmont 2:da51fb522205 427 *
emilmont 2:da51fb522205 428 * 1. First combine the identity matrix and the input matrix separated by a bar to form an
emilmont 2:da51fb522205 429 * augmented matrix as follows:
emilmont 2:da51fb522205 430 * _ _ _ _ _ _ _ _
emilmont 2:da51fb522205 431 * | | a11 a12 | | | 1 0 | | | X11 X12 |
emilmont 2:da51fb522205 432 * | | | | | | | = | |
emilmont 2:da51fb522205 433 * |_ |_ a21 a22 _| | |_0 1 _| _| |_ X21 X21 _|
emilmont 2:da51fb522205 434 *
emilmont 2:da51fb522205 435 * 2. In our implementation, pDst Matrix is used as identity matrix.
emilmont 2:da51fb522205 436 *
emilmont 2:da51fb522205 437 * 3. Begin with the first row. Let i = 1.
emilmont 2:da51fb522205 438 *
emilmont 2:da51fb522205 439 * 4. Check to see if the pivot for row i is zero.
emilmont 2:da51fb522205 440 * The pivot is the element of the main diagonal that is on the current row.
emilmont 2:da51fb522205 441 * For instance, if working with row i, then the pivot element is aii.
emilmont 2:da51fb522205 442 * If the pivot is zero, exchange that row with a row below it that does not
emilmont 2:da51fb522205 443 * contain a zero in column i. If this is not possible, then an inverse
emilmont 2:da51fb522205 444 * to that matrix does not exist.
emilmont 2:da51fb522205 445 *
emilmont 2:da51fb522205 446 * 5. Divide every element of row i by the pivot.
emilmont 2:da51fb522205 447 *
emilmont 2:da51fb522205 448 * 6. For every row below and row i, replace that row with the sum of that row and
emilmont 2:da51fb522205 449 * a multiple of row i so that each new element in column i below row i is zero.
emilmont 2:da51fb522205 450 *
emilmont 2:da51fb522205 451 * 7. Move to the next row and column and repeat steps 2 through 5 until you have zeros
emilmont 2:da51fb522205 452 * for every element below and above the main diagonal.
emilmont 2:da51fb522205 453 *
emilmont 2:da51fb522205 454 * 8. Now an identical matrix is formed to the left of the bar(input matrix, src).
emilmont 2:da51fb522205 455 * Therefore, the matrix to the right of the bar is our solution(dst matrix, dst).
emilmont 2:da51fb522205 456 *----------------------------------------------------------------------------------------------------------------*/
emilmont 1:fdd22bb7aa52 457
emilmont 1:fdd22bb7aa52 458 /* Working pointer for destination matrix */
emilmont 1:fdd22bb7aa52 459 pInT2 = pOut;
emilmont 1:fdd22bb7aa52 460
emilmont 1:fdd22bb7aa52 461 /* Loop over the number of rows */
emilmont 1:fdd22bb7aa52 462 rowCnt = numRows;
emilmont 1:fdd22bb7aa52 463
emilmont 1:fdd22bb7aa52 464 /* Making the destination matrix as identity matrix */
emilmont 1:fdd22bb7aa52 465 while(rowCnt > 0u)
emilmont 1:fdd22bb7aa52 466 {
emilmont 1:fdd22bb7aa52 467 /* Writing all zeroes in lower triangle of the destination matrix */
emilmont 1:fdd22bb7aa52 468 j = numRows - rowCnt;
emilmont 1:fdd22bb7aa52 469 while(j > 0u)
emilmont 1:fdd22bb7aa52 470 {
emilmont 1:fdd22bb7aa52 471 *pInT2++ = 0.0f;
emilmont 1:fdd22bb7aa52 472 j--;
emilmont 1:fdd22bb7aa52 473 }
emilmont 1:fdd22bb7aa52 474
emilmont 1:fdd22bb7aa52 475 /* Writing all ones in the diagonal of the destination matrix */
emilmont 1:fdd22bb7aa52 476 *pInT2++ = 1.0f;
emilmont 1:fdd22bb7aa52 477
emilmont 1:fdd22bb7aa52 478 /* Writing all zeroes in upper triangle of the destination matrix */
emilmont 1:fdd22bb7aa52 479 j = rowCnt - 1u;
emilmont 1:fdd22bb7aa52 480 while(j > 0u)
emilmont 1:fdd22bb7aa52 481 {
emilmont 1:fdd22bb7aa52 482 *pInT2++ = 0.0f;
emilmont 1:fdd22bb7aa52 483 j--;
emilmont 1:fdd22bb7aa52 484 }
emilmont 1:fdd22bb7aa52 485
emilmont 1:fdd22bb7aa52 486 /* Decrement the loop counter */
emilmont 1:fdd22bb7aa52 487 rowCnt--;
emilmont 1:fdd22bb7aa52 488 }
emilmont 1:fdd22bb7aa52 489
emilmont 1:fdd22bb7aa52 490 /* Loop over the number of columns of the input matrix.
emilmont 1:fdd22bb7aa52 491 All the elements in each column are processed by the row operations */
emilmont 1:fdd22bb7aa52 492 loopCnt = numCols;
emilmont 1:fdd22bb7aa52 493
emilmont 1:fdd22bb7aa52 494 /* Index modifier to navigate through the columns */
emilmont 1:fdd22bb7aa52 495 l = 0u;
emilmont 1:fdd22bb7aa52 496 //for(loopCnt = 0u; loopCnt < numCols; loopCnt++)
emilmont 1:fdd22bb7aa52 497 while(loopCnt > 0u)
emilmont 1:fdd22bb7aa52 498 {
emilmont 1:fdd22bb7aa52 499 /* Check if the pivot element is zero..
emilmont 1:fdd22bb7aa52 500 * If it is zero then interchange the row with non zero row below.
emilmont 1:fdd22bb7aa52 501 * If there is no non zero element to replace in the rows below,
emilmont 1:fdd22bb7aa52 502 * then the matrix is Singular. */
emilmont 1:fdd22bb7aa52 503
emilmont 1:fdd22bb7aa52 504 /* Working pointer for the input matrix that points
emilmont 1:fdd22bb7aa52 505 * to the pivot element of the particular row */
emilmont 1:fdd22bb7aa52 506 pInT1 = pIn + (l * numCols);
emilmont 1:fdd22bb7aa52 507
emilmont 1:fdd22bb7aa52 508 /* Working pointer for the destination matrix that points
emilmont 1:fdd22bb7aa52 509 * to the pivot element of the particular row */
emilmont 1:fdd22bb7aa52 510 pInT3 = pOut + (l * numCols);
emilmont 1:fdd22bb7aa52 511
emilmont 1:fdd22bb7aa52 512 /* Temporary variable to hold the pivot value */
emilmont 1:fdd22bb7aa52 513 in = *pInT1;
emilmont 1:fdd22bb7aa52 514
emilmont 1:fdd22bb7aa52 515 /* Destination pointer modifier */
emilmont 1:fdd22bb7aa52 516 k = 1u;
emilmont 1:fdd22bb7aa52 517
emilmont 1:fdd22bb7aa52 518 /* Check if the pivot element is zero */
emilmont 1:fdd22bb7aa52 519 if(*pInT1 == 0.0f)
emilmont 1:fdd22bb7aa52 520 {
emilmont 1:fdd22bb7aa52 521 /* Loop over the number rows present below */
emilmont 1:fdd22bb7aa52 522 for (i = (l + 1u); i < numRows; i++)
emilmont 1:fdd22bb7aa52 523 {
emilmont 1:fdd22bb7aa52 524 /* Update the input and destination pointers */
emilmont 1:fdd22bb7aa52 525 pInT2 = pInT1 + (numCols * l);
emilmont 1:fdd22bb7aa52 526 pInT4 = pInT3 + (numCols * k);
emilmont 1:fdd22bb7aa52 527
emilmont 1:fdd22bb7aa52 528 /* Check if there is a non zero pivot element to
emilmont 1:fdd22bb7aa52 529 * replace in the rows below */
emilmont 1:fdd22bb7aa52 530 if(*pInT2 != 0.0f)
emilmont 1:fdd22bb7aa52 531 {
emilmont 1:fdd22bb7aa52 532 /* Loop over number of columns
emilmont 1:fdd22bb7aa52 533 * to the right of the pilot element */
emilmont 1:fdd22bb7aa52 534 for (j = 0u; j < (numCols - l); j++)
emilmont 1:fdd22bb7aa52 535 {
emilmont 1:fdd22bb7aa52 536 /* Exchange the row elements of the input matrix */
emilmont 1:fdd22bb7aa52 537 Xchg = *pInT2;
emilmont 1:fdd22bb7aa52 538 *pInT2++ = *pInT1;
emilmont 1:fdd22bb7aa52 539 *pInT1++ = Xchg;
emilmont 1:fdd22bb7aa52 540 }
emilmont 1:fdd22bb7aa52 541
emilmont 1:fdd22bb7aa52 542 for (j = 0u; j < numCols; j++)
emilmont 1:fdd22bb7aa52 543 {
emilmont 1:fdd22bb7aa52 544 Xchg = *pInT4;
emilmont 1:fdd22bb7aa52 545 *pInT4++ = *pInT3;
emilmont 1:fdd22bb7aa52 546 *pInT3++ = Xchg;
emilmont 1:fdd22bb7aa52 547 }
emilmont 1:fdd22bb7aa52 548
emilmont 1:fdd22bb7aa52 549 /* Flag to indicate whether exchange is done or not */
emilmont 1:fdd22bb7aa52 550 flag = 1u;
emilmont 1:fdd22bb7aa52 551
emilmont 1:fdd22bb7aa52 552 /* Break after exchange is done */
emilmont 1:fdd22bb7aa52 553 break;
emilmont 1:fdd22bb7aa52 554 }
emilmont 1:fdd22bb7aa52 555
emilmont 1:fdd22bb7aa52 556 /* Update the destination pointer modifier */
emilmont 1:fdd22bb7aa52 557 k++;
emilmont 1:fdd22bb7aa52 558 }
emilmont 1:fdd22bb7aa52 559 }
emilmont 1:fdd22bb7aa52 560
emilmont 1:fdd22bb7aa52 561 /* Update the status if the matrix is singular */
emilmont 1:fdd22bb7aa52 562 if((flag != 1u) && (in == 0.0f))
emilmont 1:fdd22bb7aa52 563 {
emilmont 1:fdd22bb7aa52 564 status = ARM_MATH_SINGULAR;
emilmont 1:fdd22bb7aa52 565
emilmont 1:fdd22bb7aa52 566 break;
emilmont 1:fdd22bb7aa52 567 }
emilmont 1:fdd22bb7aa52 568
emilmont 1:fdd22bb7aa52 569 /* Points to the pivot row of input and destination matrices */
emilmont 1:fdd22bb7aa52 570 pPivotRowIn = pIn + (l * numCols);
emilmont 1:fdd22bb7aa52 571 pPivotRowDst = pOut + (l * numCols);
emilmont 1:fdd22bb7aa52 572
emilmont 1:fdd22bb7aa52 573 /* Temporary pointers to the pivot row pointers */
emilmont 1:fdd22bb7aa52 574 pInT1 = pPivotRowIn;
emilmont 1:fdd22bb7aa52 575 pInT2 = pPivotRowDst;
emilmont 1:fdd22bb7aa52 576
emilmont 1:fdd22bb7aa52 577 /* Pivot element of the row */
emilmont 1:fdd22bb7aa52 578 in = *(pIn + (l * numCols));
emilmont 1:fdd22bb7aa52 579
emilmont 1:fdd22bb7aa52 580 /* Loop over number of columns
emilmont 1:fdd22bb7aa52 581 * to the right of the pilot element */
emilmont 1:fdd22bb7aa52 582 for (j = 0u; j < (numCols - l); j++)
emilmont 1:fdd22bb7aa52 583 {
emilmont 1:fdd22bb7aa52 584 /* Divide each element of the row of the input matrix
emilmont 1:fdd22bb7aa52 585 * by the pivot element */
emilmont 1:fdd22bb7aa52 586 *pInT1++ = *pInT1 / in;
emilmont 1:fdd22bb7aa52 587 }
emilmont 1:fdd22bb7aa52 588 for (j = 0u; j < numCols; j++)
emilmont 1:fdd22bb7aa52 589 {
emilmont 1:fdd22bb7aa52 590 /* Divide each element of the row of the destination matrix
emilmont 1:fdd22bb7aa52 591 * by the pivot element */
emilmont 1:fdd22bb7aa52 592 *pInT2++ = *pInT2 / in;
emilmont 1:fdd22bb7aa52 593 }
emilmont 1:fdd22bb7aa52 594
emilmont 1:fdd22bb7aa52 595 /* Replace the rows with the sum of that row and a multiple of row i
emilmont 1:fdd22bb7aa52 596 * so that each new element in column i above row i is zero.*/
emilmont 1:fdd22bb7aa52 597
emilmont 1:fdd22bb7aa52 598 /* Temporary pointers for input and destination matrices */
emilmont 1:fdd22bb7aa52 599 pInT1 = pIn;
emilmont 1:fdd22bb7aa52 600 pInT2 = pOut;
emilmont 1:fdd22bb7aa52 601
emilmont 1:fdd22bb7aa52 602 for (i = 0u; i < numRows; i++)
emilmont 1:fdd22bb7aa52 603 {
emilmont 1:fdd22bb7aa52 604 /* Check for the pivot element */
emilmont 1:fdd22bb7aa52 605 if(i == l)
emilmont 1:fdd22bb7aa52 606 {
emilmont 1:fdd22bb7aa52 607 /* If the processing element is the pivot element,
emilmont 1:fdd22bb7aa52 608 only the columns to the right are to be processed */
emilmont 1:fdd22bb7aa52 609 pInT1 += numCols - l;
emilmont 1:fdd22bb7aa52 610 pInT2 += numCols;
emilmont 1:fdd22bb7aa52 611 }
emilmont 1:fdd22bb7aa52 612 else
emilmont 1:fdd22bb7aa52 613 {
emilmont 1:fdd22bb7aa52 614 /* Element of the reference row */
emilmont 1:fdd22bb7aa52 615 in = *pInT1;
emilmont 1:fdd22bb7aa52 616
emilmont 1:fdd22bb7aa52 617 /* Working pointers for input and destination pivot rows */
emilmont 1:fdd22bb7aa52 618 pPRT_in = pPivotRowIn;
emilmont 1:fdd22bb7aa52 619 pPRT_pDst = pPivotRowDst;
emilmont 1:fdd22bb7aa52 620
emilmont 1:fdd22bb7aa52 621 /* Loop over the number of columns to the right of the pivot element,
emilmont 1:fdd22bb7aa52 622 to replace the elements in the input matrix */
emilmont 1:fdd22bb7aa52 623 for (j = 0u; j < (numCols - l); j++)
emilmont 1:fdd22bb7aa52 624 {
emilmont 1:fdd22bb7aa52 625 /* Replace the element by the sum of that row
emilmont 1:fdd22bb7aa52 626 and a multiple of the reference row */
emilmont 1:fdd22bb7aa52 627 *pInT1++ = *pInT1 - (in * *pPRT_in++);
emilmont 1:fdd22bb7aa52 628 }
emilmont 1:fdd22bb7aa52 629 /* Loop over the number of columns to
emilmont 1:fdd22bb7aa52 630 replace the elements in the destination matrix */
emilmont 1:fdd22bb7aa52 631 for (j = 0u; j < numCols; j++)
emilmont 1:fdd22bb7aa52 632 {
emilmont 1:fdd22bb7aa52 633 /* Replace the element by the sum of that row
emilmont 1:fdd22bb7aa52 634 and a multiple of the reference row */
emilmont 1:fdd22bb7aa52 635 *pInT2++ = *pInT2 - (in * *pPRT_pDst++);
emilmont 1:fdd22bb7aa52 636 }
emilmont 1:fdd22bb7aa52 637
emilmont 1:fdd22bb7aa52 638 }
emilmont 1:fdd22bb7aa52 639 /* Increment the temporary input pointer */
emilmont 1:fdd22bb7aa52 640 pInT1 = pInT1 + l;
emilmont 1:fdd22bb7aa52 641 }
emilmont 1:fdd22bb7aa52 642 /* Increment the input pointer */
emilmont 1:fdd22bb7aa52 643 pIn++;
emilmont 1:fdd22bb7aa52 644
emilmont 1:fdd22bb7aa52 645 /* Decrement the loop counter */
emilmont 1:fdd22bb7aa52 646 loopCnt--;
emilmont 1:fdd22bb7aa52 647 /* Increment the index modifier */
emilmont 1:fdd22bb7aa52 648 l++;
emilmont 1:fdd22bb7aa52 649 }
emilmont 1:fdd22bb7aa52 650
emilmont 1:fdd22bb7aa52 651
emilmont 1:fdd22bb7aa52 652 #endif /* #ifndef ARM_MATH_CM0 */
emilmont 1:fdd22bb7aa52 653
emilmont 1:fdd22bb7aa52 654 /* Set status as ARM_MATH_SUCCESS */
emilmont 1:fdd22bb7aa52 655 status = ARM_MATH_SUCCESS;
emilmont 1:fdd22bb7aa52 656
emilmont 1:fdd22bb7aa52 657 if((flag != 1u) && (in == 0.0f))
emilmont 1:fdd22bb7aa52 658 {
emilmont 1:fdd22bb7aa52 659 status = ARM_MATH_SINGULAR;
emilmont 1:fdd22bb7aa52 660 }
emilmont 1:fdd22bb7aa52 661 }
emilmont 1:fdd22bb7aa52 662 /* Return to application */
emilmont 1:fdd22bb7aa52 663 return (status);
emilmont 1:fdd22bb7aa52 664 }
emilmont 1:fdd22bb7aa52 665
emilmont 1:fdd22bb7aa52 666 /**
emilmont 1:fdd22bb7aa52 667 * @} end of MatrixInv group
emilmont 1:fdd22bb7aa52 668 */