Home || Architecture || Video Search || Visual Search || Scripts || Applications || Important Messages || OGL || Src

MatInverse.h

Go to the documentation of this file.
00001 #ifndef Impala_Core_Matrix_MatInverse_h
00002 #define Impala_Core_Matrix_MatInverse_h
00003 
00004 #include "Core/Matrix/MatFunc.h"
00005 #include "Core/Matrix/MatSet.h"
00006 #include <iostream>
00007 #include <math.h>
00008 
00009 namespace Impala
00010 {
00011 namespace Core
00012 {
00013 namespace Matrix
00014 {
00015 
00016 
00017 static const double Matrix_EPS = 1e-12;
00018 
00019 template<class C> 
00020 inline int
00021 Ludcmp(C* a, int n, short *indx, double *d)
00022 {
00023     double *vv = new double [n];
00024 
00025     *d=1.0;
00026     int i, j, k;
00027     for ( i=0;i<n;i++)
00028     {
00029         double big=0.0;
00030         for (j=0;j<n;j++)
00031         {
00032             double temp = fabs(a[i*n+j]);
00033             if (temp > big)
00034                 big=temp;
00035         }
00036         if (big == 0.0)
00037             return(0); // Singular matrix 
00038         vv[i]=1.0/big;
00039     }
00040     for (j=0;j<n;j++)
00041     {
00042         for (i=0;i<j;i++)
00043         {
00044             double sum=a[i*n+j];
00045             for (k=0;k<i;k++)
00046                 sum -= a[i*n+k]*a[k*n+j];
00047             a[i*n+j]=sum;
00048         }
00049         double big=0.0;
00050         int imax = 0;
00051         for (i=j;i<n;i++)
00052         {
00053             double sum=a[i*n+j];
00054             for (k=0;k<j;k++)
00055                 sum -= a[i*n+k]*a[k*n+j];
00056             a[i*n+j]=sum;
00057 
00058             double dum = vv[i]*fabs(sum);
00059             if ( dum >= big)
00060             {
00061                 big=dum;
00062                 imax=i;
00063             }
00064         }
00065         if (j != imax)
00066         {
00067             for (k=0;k<n;k++)
00068             {
00069                 double dum=a[imax*n+k];
00070                 a[imax*n+k]=a[j*n+k];
00071                 a[j*n+k]=dum;
00072             }
00073             *d = -(*d);
00074             vv[imax]=vv[j];
00075         }
00076         indx[j]=imax;
00077         if (a[j*n+j] == 0.0)
00078             a[j*n+j]=Matrix_EPS;
00079         if (j != n-1)
00080         {
00081             double dum=1.0/a[j*n+j];
00082             for (i=j+1;i<n;i++)
00083                 a[i*n+j] *= dum;
00084         }
00085     }
00086     delete [] vv;
00087 
00088     return(1);
00089 }
00090 
00091 template<class C> 
00092 inline void
00093 Lubksb(C* a, int n, short *indx, double *b)
00094 {
00095     int ii = -1;
00096 
00097     int i;
00098     for (i=0;i<n;i++)
00099     {
00100         int ip=indx[i];
00101         double sum=b[ip];
00102         b[ip]=b[i];
00103         if (ii>=0)
00104             for (int j=ii;j<=i-1;j++)
00105                 sum -= a[i*n+j]*b[j];
00106         else if (sum) ii=i;
00107         b[i]=sum;
00108     }
00109     for (i=n-1;i>=0;i--)
00110     {
00111         double sum=b[i];
00112         for (int j=i+1;j<n;j++)
00113             sum -= a[i*n+j]*b[j];
00114         b[i]=sum/a[i*n+i];
00115     }
00116 }
00117 
00118 template<class ArrayT>
00119 inline ArrayT*
00120 MatInverse(ArrayT* a)
00121 {
00122     if (MatNrCol(a) != MatNrRow(a))
00123     {
00124         std::cerr << "MatInverse: matrix is not square!" << std::endl;
00125         return 0;
00126     }
00127 
00128     int size = MatNrRow(a);
00129     ArrayT* m = MatCreate<ArrayT>(size, size);
00130     ArrayT* tmp = MatCreate<ArrayT>(MatNrRow(a), MatNrCol(a));
00131     MatSet(tmp, a);
00132     short* idx = new short[size];
00133     double d;
00134     if (!Ludcmp(MatE(tmp, 0, 0), size, idx, &d))
00135     {
00136         std::cerr << "MatInverse: singular matrix can't be inverted." << std::endl;
00137         delete [] idx;
00138         return 0;
00139     }
00140     
00141     double* res = new double[size];
00142     for (int j=0 ; j<size ; j++)
00143     {
00144         for (int i=0 ; i<size; i++)
00145             res[i] = 0.0;
00146         res[j] = 1.0;
00147         Lubksb(MatE(tmp, 0, 0), size, idx, res);
00148         for (int k=0 ; k<size ; k++)
00149             *MatE(m, k, j) = res[k];
00150     }
00151 
00152     delete [] res;
00153     delete [] idx;
00154     delete tmp;
00155 
00156     return m;
00157 }
00158 
00159 } // namespace Matrix
00160 } // namespace Core
00161 } // namespace Impala
00162 
00163 #endif

Generated on Fri Mar 19 09:31:15 2010 for ImpalaSrc by  doxygen 1.5.1