CMSIS DSP library

Dependents:   performance_timer Surfboard_ gps2rtty Capstone ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers arm_mat_inverse_f32.c Source File

arm_mat_inverse_f32.c

00001 /* ----------------------------------------------------------------------    
00002 * Copyright (C) 2010-2014 ARM Limited. All rights reserved.    
00003 *    
00004 * $Date:        19. March 2015
00005 * $Revision:    V.1.4.5
00006 *    
00007 * Project:      CMSIS DSP Library    
00008 * Title:        arm_mat_inverse_f32.c    
00009 *    
00010 * Description:  Floating-point matrix inverse.    
00011 *    
00012 * Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
00013 *  
00014 * Redistribution and use in source and binary forms, with or without 
00015 * modification, are permitted provided that the following conditions
00016 * are met:
00017 *   - Redistributions of source code must retain the above copyright
00018 *     notice, this list of conditions and the following disclaimer.
00019 *   - Redistributions in binary form must reproduce the above copyright
00020 *     notice, this list of conditions and the following disclaimer in
00021 *     the documentation and/or other materials provided with the 
00022 *     distribution.
00023 *   - Neither the name of ARM LIMITED nor the names of its contributors
00024 *     may be used to endorse or promote products derived from this
00025 *     software without specific prior written permission.
00026 *
00027 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00028 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00029 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00030 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
00031 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00032 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00033 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00034 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00035 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00036 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00037 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00038 * POSSIBILITY OF SUCH DAMAGE.    
00039 * -------------------------------------------------------------------- */
00040 
00041 #include "arm_math.h"
00042 
00043 /**    
00044  * @ingroup groupMatrix    
00045  */
00046 
00047 /**    
00048  * @defgroup MatrixInv Matrix Inverse    
00049  *    
00050  * Computes the inverse of a matrix.    
00051  *    
00052  * The inverse is defined only if the input matrix is square and non-singular (the determinant    
00053  * is non-zero). The function checks that the input and output matrices are square and of the    
00054  * same size.    
00055  *    
00056  * Matrix inversion is numerically sensitive and the CMSIS DSP library only supports matrix    
00057  * inversion of floating-point matrices.    
00058  *    
00059  * \par Algorithm    
00060  * The Gauss-Jordan method is used to find the inverse.    
00061  * The algorithm performs a sequence of elementary row-operations until it    
00062  * reduces the input matrix to an identity matrix. Applying the same sequence    
00063  * of elementary row-operations to an identity matrix yields the inverse matrix.    
00064  * If the input matrix is singular, then the algorithm terminates and returns error status    
00065  * <code>ARM_MATH_SINGULAR</code>.    
00066  * \image html MatrixInverse.gif "Matrix Inverse of a 3 x 3 matrix using Gauss-Jordan Method"    
00067  */
00068 
00069 /**    
00070  * @addtogroup MatrixInv    
00071  * @{    
00072  */
00073 
00074 /**    
00075  * @brief Floating-point matrix inverse.    
00076  * @param[in]       *pSrc points to input matrix structure    
00077  * @param[out]      *pDst points to output matrix structure    
00078  * @return          The function returns    
00079  * <code>ARM_MATH_SIZE_MISMATCH</code> if the input matrix is not square or if the size    
00080  * of the output matrix does not match the size of the input matrix.    
00081  * If the input matrix is found to be singular (non-invertible), then the function returns    
00082  * <code>ARM_MATH_SINGULAR</code>.  Otherwise, the function returns <code>ARM_MATH_SUCCESS</code>.    
00083  */
00084 
00085 arm_status arm_mat_inverse_f32(
00086   const arm_matrix_instance_f32 * pSrc,
00087   arm_matrix_instance_f32 * pDst)
00088 {
00089   float32_t *pIn = pSrc->pData;                  /* input data matrix pointer */
00090   float32_t *pOut = pDst->pData;                 /* output data matrix pointer */
00091   float32_t *pInT1, *pInT2;                      /* Temporary input data matrix pointer */
00092   float32_t *pOutT1, *pOutT2;                    /* Temporary output data matrix pointer */
00093   float32_t *pPivotRowIn, *pPRT_in, *pPivotRowDst, *pPRT_pDst;  /* Temporary input and output data matrix pointer */
00094   uint32_t numRows = pSrc->numRows;              /* Number of rows in the matrix  */
00095   uint32_t numCols = pSrc->numCols;              /* Number of Cols in the matrix  */
00096 
00097 #ifndef ARM_MATH_CM0_FAMILY
00098   float32_t maxC;                                /* maximum value in the column */
00099 
00100   /* Run the below code for Cortex-M4 and Cortex-M3 */
00101 
00102   float32_t Xchg, in = 0.0f, in1;                /* Temporary input values  */
00103   uint32_t i, rowCnt, flag = 0u, j, loopCnt, k, l;      /* loop counters */
00104   arm_status status;                             /* status of matrix inverse */
00105 
00106 #ifdef ARM_MATH_MATRIX_CHECK
00107 
00108 
00109   /* Check for matrix mismatch condition */
00110   if((pSrc->numRows != pSrc->numCols) || (pDst->numRows != pDst->numCols)
00111      || (pSrc->numRows != pDst->numRows))
00112   {
00113     /* Set status as ARM_MATH_SIZE_MISMATCH */
00114     status = ARM_MATH_SIZE_MISMATCH;
00115   }
00116   else
00117 #endif /*    #ifdef ARM_MATH_MATRIX_CHECK    */
00118 
00119   {
00120 
00121     /*--------------------------------------------------------------------------------------------------------------    
00122      * Matrix Inverse can be solved using elementary row operations.    
00123      *    
00124      *  Gauss-Jordan Method:    
00125      *    
00126      *     1. First combine the identity matrix and the input matrix separated by a bar to form an    
00127      *        augmented matrix as follows:    
00128      *                      _                  _         _         _    
00129      *                     |  a11  a12 | 1   0  |       |  X11 X12  |    
00130      *                     |           |        |   =   |           |    
00131      *                     |_ a21  a22 | 0   1 _|       |_ X21 X21 _|    
00132      *    
00133      *      2. In our implementation, pDst Matrix is used as identity matrix.    
00134      *    
00135      *      3. Begin with the first row. Let i = 1.    
00136      *    
00137      *      4. Check to see if the pivot for column i is the greatest of the column.    
00138      *         The pivot is the element of the main diagonal that is on the current row.    
00139      *         For instance, if working with row i, then the pivot element is aii.    
00140      *         If the pivot is not the most significant of the columns, exchange that row with a row
00141      *         below it that does contain the most significant value in column i. If the most
00142      *         significant value of the column is zero, then an inverse to that matrix does not exist.
00143      *         The most significant value of the column is the absolute maximum.
00144      *    
00145      *      5. Divide every element of row i by the pivot.    
00146      *    
00147      *      6. For every row below and  row i, replace that row with the sum of that row and    
00148      *         a multiple of row i so that each new element in column i below row i is zero.    
00149      *    
00150      *      7. Move to the next row and column and repeat steps 2 through 5 until you have zeros    
00151      *         for every element below and above the main diagonal.    
00152      *    
00153      *      8. Now an identical matrix is formed to the left of the bar(input matrix, pSrc).    
00154      *         Therefore, the matrix to the right of the bar is our solution(pDst matrix, pDst).    
00155      *----------------------------------------------------------------------------------------------------------------*/
00156 
00157     /* Working pointer for destination matrix */
00158     pOutT1 = pOut;
00159 
00160     /* Loop over the number of rows */
00161     rowCnt = numRows;
00162 
00163     /* Making the destination matrix as identity matrix */
00164     while(rowCnt > 0u)
00165     {
00166       /* Writing all zeroes in lower triangle of the destination matrix */
00167       j = numRows - rowCnt;
00168       while(j > 0u)
00169       {
00170         *pOutT1++ = 0.0f;
00171         j--;
00172       }
00173 
00174       /* Writing all ones in the diagonal of the destination matrix */
00175       *pOutT1++ = 1.0f;
00176 
00177       /* Writing all zeroes in upper triangle of the destination matrix */
00178       j = rowCnt - 1u;
00179       while(j > 0u)
00180       {
00181         *pOutT1++ = 0.0f;
00182         j--;
00183       }
00184 
00185       /* Decrement the loop counter */
00186       rowCnt--;
00187     }
00188 
00189     /* Loop over the number of columns of the input matrix.    
00190        All the elements in each column are processed by the row operations */
00191     loopCnt = numCols;
00192 
00193     /* Index modifier to navigate through the columns */
00194     l = 0u;
00195 
00196     while(loopCnt > 0u)
00197     {
00198       /* Check if the pivot element is zero..    
00199        * If it is zero then interchange the row with non zero row below.    
00200        * If there is no non zero element to replace in the rows below,    
00201        * then the matrix is Singular. */
00202 
00203       /* Working pointer for the input matrix that points    
00204        * to the pivot element of the particular row  */
00205       pInT1 = pIn + (l * numCols);
00206 
00207       /* Working pointer for the destination matrix that points    
00208        * to the pivot element of the particular row  */
00209       pOutT1 = pOut + (l * numCols);
00210 
00211       /* Temporary variable to hold the pivot value */
00212       in = *pInT1;
00213 
00214       /* Grab the most significant value from column l */
00215       maxC = 0;
00216       for (i = l; i < numRows; i++)
00217       {
00218         maxC = *pInT1 > 0 ? (*pInT1 > maxC ? *pInT1 : maxC) : (-*pInT1 > maxC ? -*pInT1 : maxC);
00219         pInT1 += numCols;
00220       }
00221 
00222       /* Update the status if the matrix is singular */
00223       if(maxC == 0.0f)
00224       {
00225         return ARM_MATH_SINGULAR;
00226       }
00227 
00228       /* Restore pInT1  */
00229       pInT1 = pIn;
00230 
00231       /* Destination pointer modifier */
00232       k = 1u;
00233       
00234       /* Check if the pivot element is the most significant of the column */
00235       if( (in > 0.0f ? in : -in) != maxC)
00236       {
00237         /* Loop over the number rows present below */
00238         i = numRows - (l + 1u);
00239 
00240         while(i > 0u)
00241         {
00242           /* Update the input and destination pointers */
00243           pInT2 = pInT1 + (numCols * l);
00244           pOutT2 = pOutT1 + (numCols * k);
00245 
00246           /* Look for the most significant element to    
00247            * replace in the rows below */
00248           if((*pInT2 > 0.0f ? *pInT2: -*pInT2) == maxC)
00249           {
00250             /* Loop over number of columns    
00251              * to the right of the pilot element */
00252             j = numCols - l;
00253 
00254             while(j > 0u)
00255             {
00256               /* Exchange the row elements of the input matrix */
00257               Xchg = *pInT2;
00258               *pInT2++ = *pInT1;
00259               *pInT1++ = Xchg;
00260 
00261               /* Decrement the loop counter */
00262               j--;
00263             }
00264 
00265             /* Loop over number of columns of the destination matrix */
00266             j = numCols;
00267 
00268             while(j > 0u)
00269             {
00270               /* Exchange the row elements of the destination matrix */
00271               Xchg = *pOutT2;
00272               *pOutT2++ = *pOutT1;
00273               *pOutT1++ = Xchg;
00274 
00275               /* Decrement the loop counter */
00276               j--;
00277             }
00278 
00279             /* Flag to indicate whether exchange is done or not */
00280             flag = 1u;
00281 
00282             /* Break after exchange is done */
00283             break;
00284           }
00285 
00286           /* Update the destination pointer modifier */
00287           k++;
00288 
00289           /* Decrement the loop counter */
00290           i--;
00291         }
00292       }
00293 
00294       /* Update the status if the matrix is singular */
00295       if((flag != 1u) && (in == 0.0f))
00296       {
00297         return ARM_MATH_SINGULAR;
00298       }
00299 
00300       /* Points to the pivot row of input and destination matrices */
00301       pPivotRowIn = pIn + (l * numCols);
00302       pPivotRowDst = pOut + (l * numCols);
00303 
00304       /* Temporary pointers to the pivot row pointers */
00305       pInT1 = pPivotRowIn;
00306       pInT2 = pPivotRowDst;
00307 
00308       /* Pivot element of the row */
00309       in = *pPivotRowIn;
00310 
00311       /* Loop over number of columns    
00312        * to the right of the pilot element */
00313       j = (numCols - l);
00314 
00315       while(j > 0u)
00316       {
00317         /* Divide each element of the row of the input matrix    
00318          * by the pivot element */
00319         in1 = *pInT1;
00320         *pInT1++ = in1 / in;
00321 
00322         /* Decrement the loop counter */
00323         j--;
00324       }
00325 
00326       /* Loop over number of columns of the destination matrix */
00327       j = numCols;
00328 
00329       while(j > 0u)
00330       {
00331         /* Divide each element of the row of the destination matrix    
00332          * by the pivot element */
00333         in1 = *pInT2;
00334         *pInT2++ = in1 / in;
00335 
00336         /* Decrement the loop counter */
00337         j--;
00338       }
00339 
00340       /* Replace the rows with the sum of that row and a multiple of row i    
00341        * so that each new element in column i above row i is zero.*/
00342 
00343       /* Temporary pointers for input and destination matrices */
00344       pInT1 = pIn;
00345       pInT2 = pOut;
00346 
00347       /* index used to check for pivot element */
00348       i = 0u;
00349 
00350       /* Loop over number of rows */
00351       /*  to be replaced by the sum of that row and a multiple of row i */
00352       k = numRows;
00353 
00354       while(k > 0u)
00355       {
00356         /* Check for the pivot element */
00357         if(i == l)
00358         {
00359           /* If the processing element is the pivot element,    
00360              only the columns to the right are to be processed */
00361           pInT1 += numCols - l;
00362 
00363           pInT2 += numCols;
00364         }
00365         else
00366         {
00367           /* Element of the reference row */
00368           in = *pInT1;
00369 
00370           /* Working pointers for input and destination pivot rows */
00371           pPRT_in = pPivotRowIn;
00372           pPRT_pDst = pPivotRowDst;
00373 
00374           /* Loop over the number of columns to the right of the pivot element,    
00375              to replace the elements in the input matrix */
00376           j = (numCols - l);
00377 
00378           while(j > 0u)
00379           {
00380             /* Replace the element by the sum of that row    
00381                and a multiple of the reference row  */
00382             in1 = *pInT1;
00383             *pInT1++ = in1 - (in * *pPRT_in++);
00384 
00385             /* Decrement the loop counter */
00386             j--;
00387           }
00388 
00389           /* Loop over the number of columns to    
00390              replace the elements in the destination matrix */
00391           j = numCols;
00392 
00393           while(j > 0u)
00394           {
00395             /* Replace the element by the sum of that row    
00396                and a multiple of the reference row  */
00397             in1 = *pInT2;
00398             *pInT2++ = in1 - (in * *pPRT_pDst++);
00399 
00400             /* Decrement the loop counter */
00401             j--;
00402           }
00403 
00404         }
00405 
00406         /* Increment the temporary input pointer */
00407         pInT1 = pInT1 + l;
00408 
00409         /* Decrement the loop counter */
00410         k--;
00411 
00412         /* Increment the pivot index */
00413         i++;
00414       }
00415 
00416       /* Increment the input pointer */
00417       pIn++;
00418 
00419       /* Decrement the loop counter */
00420       loopCnt--;
00421 
00422       /* Increment the index modifier */
00423       l++;
00424     }
00425 
00426 
00427 #else
00428 
00429   /* Run the below code for Cortex-M0 */
00430 
00431   float32_t Xchg, in = 0.0f;                     /* Temporary input values  */
00432   uint32_t i, rowCnt, flag = 0u, j, loopCnt, k, l;      /* loop counters */
00433   arm_status status;                             /* status of matrix inverse */
00434 
00435 #ifdef ARM_MATH_MATRIX_CHECK
00436 
00437   /* Check for matrix mismatch condition */
00438   if((pSrc->numRows != pSrc->numCols) || (pDst->numRows != pDst->numCols)
00439      || (pSrc->numRows != pDst->numRows))
00440   {
00441     /* Set status as ARM_MATH_SIZE_MISMATCH */
00442     status = ARM_MATH_SIZE_MISMATCH;
00443   }
00444   else
00445 #endif /*      #ifdef ARM_MATH_MATRIX_CHECK    */
00446   {
00447 
00448     /*--------------------------------------------------------------------------------------------------------------       
00449      * Matrix Inverse can be solved using elementary row operations.        
00450      *        
00451      *  Gauss-Jordan Method:       
00452      *             
00453      *     1. First combine the identity matrix and the input matrix separated by a bar to form an        
00454      *        augmented matrix as follows:        
00455      *                      _  _          _     _      _   _         _         _       
00456      *                     |  |  a11  a12  | | | 1   0  |   |       |  X11 X12  |         
00457      *                     |  |            | | |        |   |   =   |           |        
00458      *                     |_ |_ a21  a22 _| | |_0   1 _|  _|       |_ X21 X21 _|       
00459      *                            
00460      *      2. In our implementation, pDst Matrix is used as identity matrix.    
00461      *       
00462      *      3. Begin with the first row. Let i = 1.       
00463      *       
00464      *      4. Check to see if the pivot for row i is zero.       
00465      *         The pivot is the element of the main diagonal that is on the current row.       
00466      *         For instance, if working with row i, then the pivot element is aii.       
00467      *         If the pivot is zero, exchange that row with a row below it that does not        
00468      *         contain a zero in column i. If this is not possible, then an inverse        
00469      *         to that matrix does not exist.       
00470      *         
00471      *      5. Divide every element of row i by the pivot.       
00472      *         
00473      *      6. For every row below and  row i, replace that row with the sum of that row and        
00474      *         a multiple of row i so that each new element in column i below row i is zero.       
00475      *         
00476      *      7. Move to the next row and column and repeat steps 2 through 5 until you have zeros       
00477      *         for every element below and above the main diagonal.        
00478      *                        
00479      *      8. Now an identical matrix is formed to the left of the bar(input matrix, src).       
00480      *         Therefore, the matrix to the right of the bar is our solution(dst matrix, dst).         
00481      *----------------------------------------------------------------------------------------------------------------*/
00482 
00483     /* Working pointer for destination matrix */
00484     pOutT1 = pOut;
00485 
00486     /* Loop over the number of rows */
00487     rowCnt = numRows;
00488 
00489     /* Making the destination matrix as identity matrix */
00490     while(rowCnt > 0u)
00491     {
00492       /* Writing all zeroes in lower triangle of the destination matrix */
00493       j = numRows - rowCnt;
00494       while(j > 0u)
00495       {
00496         *pOutT1++ = 0.0f;
00497         j--;
00498       }
00499 
00500       /* Writing all ones in the diagonal of the destination matrix */
00501       *pOutT1++ = 1.0f;
00502 
00503       /* Writing all zeroes in upper triangle of the destination matrix */
00504       j = rowCnt - 1u;
00505       while(j > 0u)
00506       {
00507         *pOutT1++ = 0.0f;
00508         j--;
00509       }
00510 
00511       /* Decrement the loop counter */
00512       rowCnt--;
00513     }
00514 
00515     /* Loop over the number of columns of the input matrix.     
00516        All the elements in each column are processed by the row operations */
00517     loopCnt = numCols;
00518 
00519     /* Index modifier to navigate through the columns */
00520     l = 0u;
00521     //for(loopCnt = 0u; loopCnt < numCols; loopCnt++)   
00522     while(loopCnt > 0u)
00523     {
00524       /* Check if the pivot element is zero..    
00525        * If it is zero then interchange the row with non zero row below.   
00526        * If there is no non zero element to replace in the rows below,   
00527        * then the matrix is Singular. */
00528 
00529       /* Working pointer for the input matrix that points     
00530        * to the pivot element of the particular row  */
00531       pInT1 = pIn + (l * numCols);
00532 
00533       /* Working pointer for the destination matrix that points     
00534        * to the pivot element of the particular row  */
00535       pOutT1 = pOut + (l * numCols);
00536 
00537       /* Temporary variable to hold the pivot value */
00538       in = *pInT1;
00539 
00540       /* Destination pointer modifier */
00541       k = 1u;
00542 
00543       /* Check if the pivot element is zero */
00544       if(*pInT1 == 0.0f)
00545       {
00546         /* Loop over the number rows present below */
00547         for (i = (l + 1u); i < numRows; i++)
00548         {
00549           /* Update the input and destination pointers */
00550           pInT2 = pInT1 + (numCols * l);
00551           pOutT2 = pOutT1 + (numCols * k);
00552 
00553           /* Check if there is a non zero pivot element to     
00554            * replace in the rows below */
00555           if(*pInT2 != 0.0f)
00556           {
00557             /* Loop over number of columns     
00558              * to the right of the pilot element */
00559             for (j = 0u; j < (numCols - l); j++)
00560             {
00561               /* Exchange the row elements of the input matrix */
00562               Xchg = *pInT2;
00563               *pInT2++ = *pInT1;
00564               *pInT1++ = Xchg;
00565             }
00566 
00567             for (j = 0u; j < numCols; j++)
00568             {
00569               Xchg = *pOutT2;
00570               *pOutT2++ = *pOutT1;
00571               *pOutT1++ = Xchg;
00572             }
00573 
00574             /* Flag to indicate whether exchange is done or not */
00575             flag = 1u;
00576 
00577             /* Break after exchange is done */
00578             break;
00579           }
00580 
00581           /* Update the destination pointer modifier */
00582           k++;
00583         }
00584       }
00585 
00586       /* Update the status if the matrix is singular */
00587       if((flag != 1u) && (in == 0.0f))
00588       {
00589         return ARM_MATH_SINGULAR;
00590       }
00591 
00592       /* Points to the pivot row of input and destination matrices */
00593       pPivotRowIn = pIn + (l * numCols);
00594       pPivotRowDst = pOut + (l * numCols);
00595 
00596       /* Temporary pointers to the pivot row pointers */
00597       pInT1 = pPivotRowIn;
00598       pOutT1 = pPivotRowDst;
00599 
00600       /* Pivot element of the row */
00601       in = *(pIn + (l * numCols));
00602 
00603       /* Loop over number of columns     
00604        * to the right of the pilot element */
00605       for (j = 0u; j < (numCols - l); j++)
00606       {
00607         /* Divide each element of the row of the input matrix     
00608          * by the pivot element */
00609         *pInT1 = *pInT1 / in;
00610         pInT1++;
00611       }
00612       for (j = 0u; j < numCols; j++)
00613       {
00614         /* Divide each element of the row of the destination matrix     
00615          * by the pivot element */
00616         *pOutT1 = *pOutT1 / in;
00617         pOutT1++;
00618       }
00619 
00620       /* Replace the rows with the sum of that row and a multiple of row i     
00621        * so that each new element in column i above row i is zero.*/
00622 
00623       /* Temporary pointers for input and destination matrices */
00624       pInT1 = pIn;
00625       pOutT1 = pOut;
00626 
00627       for (i = 0u; i < numRows; i++)
00628       {
00629         /* Check for the pivot element */
00630         if(i == l)
00631         {
00632           /* If the processing element is the pivot element,     
00633              only the columns to the right are to be processed */
00634           pInT1 += numCols - l;
00635           pOutT1 += numCols;
00636         }
00637         else
00638         {
00639           /* Element of the reference row */
00640           in = *pInT1;
00641 
00642           /* Working pointers for input and destination pivot rows */
00643           pPRT_in = pPivotRowIn;
00644           pPRT_pDst = pPivotRowDst;
00645 
00646           /* Loop over the number of columns to the right of the pivot element,     
00647              to replace the elements in the input matrix */
00648           for (j = 0u; j < (numCols - l); j++)
00649           {
00650             /* Replace the element by the sum of that row     
00651                and a multiple of the reference row  */
00652             *pInT1 = *pInT1 - (in * *pPRT_in++);
00653             pInT1++;
00654           }
00655           /* Loop over the number of columns to     
00656              replace the elements in the destination matrix */
00657           for (j = 0u; j < numCols; j++)
00658           {
00659             /* Replace the element by the sum of that row     
00660                and a multiple of the reference row  */
00661             *pOutT1 = *pOutT1 - (in * *pPRT_pDst++);
00662             pOutT1++;
00663           }
00664 
00665         }
00666         /* Increment the temporary input pointer */
00667         pInT1 = pInT1 + l;
00668       }
00669       /* Increment the input pointer */
00670       pIn++;
00671 
00672       /* Decrement the loop counter */
00673       loopCnt--;
00674       /* Increment the index modifier */
00675       l++;
00676     }
00677 
00678 
00679 #endif /* #ifndef ARM_MATH_CM0_FAMILY */
00680 
00681     /* Set status as ARM_MATH_SUCCESS */
00682     status = ARM_MATH_SUCCESS;
00683 
00684     if((flag != 1u) && (in == 0.0f))
00685     {
00686       pIn = pSrc->pData;
00687       for (i = 0; i < numRows * numCols; i++)
00688       {
00689         if (pIn[i] != 0.0f)
00690             break;
00691       }
00692       
00693       if (i == numRows * numCols)
00694         status = ARM_MATH_SINGULAR;
00695     }
00696   }
00697   /* Return to application */
00698   return (status);
00699 }
00700 
00701 /**    
00702  * @} end of MatrixInv group    
00703  */