ML Reference
MeVis/Foundation/Sources/MLLinearAlgebra/mlLinearAlgebraTools.h
Go to the documentation of this file.
00001 // **InsertLicense** code 
00002 //=====================================================================================
00004 
00009 //=====================================================================================
00010 
00011 #ifndef __mlLinearAlgebraTools_H
00012 #define __mlLinearAlgebraTools_H
00013 
00014 // Include system independency file and project settings.
00015 #ifndef __mlLinearAlgebraSystem_H
00016 #include "mlLinearAlgebraSystem.h"
00017 #endif
00018 #ifndef __mlLinearAlgebraDefs_H
00019 #include "mlLinearAlgebraDefs.h"
00020 #endif
00021 
00022 
00023 // All declarations of this header will be in the ML_LA_NAMESPACE namespace.
00024 ML_LA_START_NAMESPACE
00025     
00026   //-------------------------------------------------------------------
00029   //-------------------------------------------------------------------
00030   template <class OBJ_TYPE>
00031   void MLSwap(OBJ_TYPE &obj1, OBJ_TYPE &obj2)
00032   {
00033     ML_TRACE_IN_TIME_CRITICAL("mlLinearAlgebraTools.h: MLSwap()");
00034 
00035     OBJ_TYPE buf = obj1;
00036     obj1 = obj2;
00037     obj2 = buf;
00038   }
00039 
00040   //-------------------------------------------------------------------
00058   //-------------------------------------------------------------------
00059   template <class BASE_TYPE>
00060   BASE_TYPE MLInverseMatHelper(const BASE_TYPE                            &origMat,
00061                                bool                                       *isInvertible, 
00062                                const ML_TYPENAME BASE_TYPE::ComponentType  /*ZeroEpsilon*/,
00063                                const char * const                          ZeroDetErrString,
00064                                const BASE_TYPE                            &Identity,
00065                                const size_t                                Dim
00066                               )
00067   {
00068     ML_TRACE_IN("mlLinearAlgebraTools.h: MLInverseMatHelper()");
00069 
00070     BASE_TYPE retVal;
00071     ML_TRY
00072     {
00073 
00074 
00075       BASE_TYPE a(origMat);  // As a evolves from original mat into identity
00076       BASE_TYPE b(Identity); // b evolves from identity into inverse(a)
00077       size_t i=0, j=0, i1=0; // Index counters.
00078 
00079       // Loop over columns of a from left to right, eliminating above and below diagonal
00080       for (j=0; j<Dim; j++){
00081         // Find largest pivot in column j among rows j..DIM-1
00082         i1 = j;       // Row with largest pivot candidate
00083         for (i=j+1; i<Dim; i++){
00084           if (MLAbs(a[i][j]) > MLAbs(a[i1][j])){
00085             i1 = i;
00086           }
00087         }
00088         // Swap rows i1 and j in a and b to put pivot on diagonal
00089         MLSwap(a[i1], a[j]);
00090         MLSwap(b[i1], b[j]);      
00091 
00092         // Scale row j to have a identity diagonal
00093         const ML_TYPENAME BASE_TYPE::ComponentType avjj = a[j][j];
00094         if (MLValueIs0WOM(avjj)){
00095           if (isInvertible == NULL){
00096             ML_PRINT_ERROR(ZeroDetErrString,
00097                            ML_BAD_PARAMETER,
00098                            "Returning identity");
00099           }
00100           else{
00101             *isInvertible = false;
00102           }
00103           return Identity;
00104         }
00105         b[j] /= avjj;
00106         a[j] /= avjj;
00107       
00108         // Eliminate off-diagonal elements in col j of a, 
00109         // applying identical operations to b
00110         for (i=0; i<Dim; i++){
00111           if (i!=j){
00112             b[i] -= a[i][j]*b[j];
00113             a[i] -= a[i][j]*a[j];
00114           }
00115         }
00116       }
00117 
00118       // Set state and return inverse.
00119       if (isInvertible != NULL){ *isInvertible = true; }
00120       retVal = b;
00121     }
00122     ML_CATCH_RETHROW;
00123 
00124     return retVal;
00125   }
00126 
00127 ML_LA_END_NAMESPACE
00128 
00129 #endif // __mlLinearAlgebraTools_H