• Main Page
  • Classes
  • Files
  • Examples
  • File List
  • File Members

g_inverse.cpp

Go to the documentation of this file.
00001 //===========================================================================
00039 //===========================================================================
00040 
00041 #include <cmath>
00042 #include <SharkDefs.h>
00043 #include <LinAlg/LinAlg.h>
00044 
00045 //===========================================================================
00090 unsigned g_inverse
00091 (
00092     const Array2D< double >& amatA,
00093     Array2D< double >& bmatA,
00094     unsigned maxIterations,
00095     double tolerance,
00096     bool ignoreThreshold
00097 )
00098 {
00099     unsigned i, j, k, m, n, r;
00100 
00101     m = amatA.rows();
00102     n = amatA.cols();
00103 
00104     Array2D< double > umatL(m, n);
00105     Array2D< double > vmatL(n, n);
00106     Array  < double > wvecL(n);
00107 
00108     bmatA.resize(n, m, false);
00109 
00110     if (m == 0 || n == 0) {
00111         return 0;
00112     }
00113     //calculate singular value decomposition
00114     //throw exception if the can't be calculated
00115     //within maxIterations iterations
00116     try {
00117         svd(amatA, umatL, vmatL, wvecL, maxIterations, ignoreThreshold);
00118     } catch (SharkException e) { 
00119         throw(e);
00120     }
00121     svdsort(umatL, vmatL, wvecL);
00122     //determine rank
00123     r = svdrank(amatA, umatL, vmatL, wvecL);
00124     //normalize singular values
00125     for (i = 0; i < r; i++) {
00126         if (wvecL(i) < tolerance)
00127             wvecL(i) = 0.;
00128         else
00129             wvecL(i) = 1. / wvecL(i);
00130     }
00131     for (; i < n; i++) {
00132         wvecL(i) = 0.;
00133     }
00134 
00135     for (i = 0; i < n; i++) {
00136         for (j = 0; j < m; j++) {
00137             double  t  = 0.;
00138             //calculate (pseudo-)inverse
00139             for (k = 0; k < n; k++) {
00140                 t += vmatL(i, k) * wvecL(k) * umatL(j, k);
00141             }
00142 
00143             bmatA(i, j) = t;
00144         }
00145     }
00146 
00147     return r;
00148 }
00149 
00150 //===========================================================================
00192 //===========================================================================
00193 
00194 #include <cmath>
00195 #include <SharkDefs.h>
00196 #include <LinAlg/LinAlg.h>
00197 
00198 void invertSymmPositiveDefinite(Array2D<double> &I, const Array2D< double >& ArrSymm) {
00199     Array2D<double> CholArraySymm, CholArraySymmInv, CholArraySymmInvT;
00200 
00201     CholeskyDecomposition(ArrSymm, CholArraySymm);
00202 
00203     CholArraySymmInv.resize(CholArraySymm, false);
00204     CholArraySymmInv = 0;
00205 
00206     unsigned m = CholArraySymm.dim(0);
00207     double s;
00208     unsigned i, j, k;
00209 
00210     for(j = 0; j < m; j++) 
00211         CholArraySymmInv(j ,j) = 1/CholArraySymm(j,j);
00212 
00213     for(j = 0; j < m; j++) {
00214         for(i = j+1; i < m; i++) {
00215             s = 0;
00216             for(k = 0; k < i; k++) {
00217                 s += CholArraySymm(i, k) * CholArraySymmInv(k, j);
00218             }           
00219             CholArraySymmInv(i ,j) = -1/CholArraySymm(i, i)*s;
00220         }
00221     }
00222 
00223     CholArraySymmInvT = CholArraySymmInv;
00224     CholArraySymmInvT.transpose();
00225     
00226     matMat(I, CholArraySymmInvT, CholArraySymmInv);
00227 }
00228 
00229 
00230 //===========================================================================
00254 void g_inverseCholesky(const Array2D< double >& A, Array2D< double >& outA, double thresholdFactor) {
00255     SIZE_CHECK(A.ndim() == 2)
00256 
00257     bool bTranspose = false;
00258     unsigned dimX = A.dim(0);
00259     unsigned dimY = A.dim(1);
00260 
00261     Array2D< double > AT = Array2D<double>(transpose(A));
00262     Array2D< double > AMat;
00263 
00264     if (dimX < dimY) {
00265         bTranspose = true;
00266 
00267         matMat( AMat, A, AT );
00268         dimY = dimX;
00269     }
00270     else 
00271         matMat( AMat, AT, A );
00272     
00273 
00274     double minDiagElem = AMat(0, 0);
00275 
00276     for (unsigned i = 1; i<dimY; ++i) 
00277         if (AMat(i,i) < minDiagElem)
00278             minDiagElem = AMat(i,i);
00279 
00280     minDiagElem = minDiagElem * thresholdFactor;
00281 
00282     unsigned m = dimY;
00283     unsigned n = dimY;
00284     unsigned r = 0;
00285     unsigned i, k, l;
00286     double s;
00287 
00288 
00289     Array2D< double > C;
00290     C.resize(m, m, false);
00291     C=0;
00292 
00293     for(k = 0; k < n; k++) {
00294         r++;
00295         for(i = k; i < n; i++) {
00296             s = 0;
00297             for(l = 0; l < r-1; l++) 
00298                 s += C(i, l) * C(k, l);
00299     
00300             C(i, r-1) = AMat(i, k)  - s;
00301         }
00302         if (C(k, r-1)> minDiagElem) {
00303             C(k, r-1)  = sqrt(C(k, r-1));
00304             if (k<n)
00305                 for(l = k+1; l < n; l++) 
00306                     C(l, r-1) =  C(l, r-1) / C(k, r-1);
00307         }
00308         else
00309             r--;
00310     }
00311 
00312     // delete m-r last cols
00313     Array2D< double > C2(m, r);
00314 
00315     for (unsigned i = 0; i < m; ++i)
00316         for (unsigned j = 0; j < r; ++j)
00317             C2(i,j)  =  C(i,j); 
00318 
00319         
00320     Array2D< double > ArrSymm, ArrSymmInv;
00321     Array2D<double> tmpMatrix, tmpMatrix2;
00322 
00323     Array2D< double > C2T = transpose(C2);
00324     matMat( ArrSymm, C2T, C2 );
00325 
00326 #if 0
00327     invertSymm(ArrSymmInv, ArrSymm);
00328 #else
00329     invertSymmPositiveDefinite(ArrSymmInv, ArrSymm);
00330 #endif
00331 
00332     matMat( tmpMatrix, ArrSymmInv, ArrSymmInv );
00333     matMat( tmpMatrix2, tmpMatrix, C2T );
00334     matMat( tmpMatrix, C2, tmpMatrix2 );
00335 
00336     if (bTranspose) 
00337         matMat(outA, AT, tmpMatrix);
00338     else 
00339         matMat(outA, tmpMatrix, AT);
00340 }
00341 
00342 //===========================================================================
00364 void g_inverseMoorePenrose(const Array2D< double >& A, Array2D< double >& outA) {
00365     SIZE_CHECK(A.ndim() == 2)
00366 
00367     bool bTranspose = false;
00368     unsigned dimX = A.dim(0);
00369     unsigned dimY = A.dim(1);
00370 
00371     Array2D< double > AT = Array2D<double>(transpose(A));
00372     Array2D< double > AMat;
00373 
00374     if (dimX < dimY) {
00375         bTranspose = true;
00376         matMat( AMat, A, AT );
00377         dimY = dimX;
00378     }
00379     else 
00380         matMat( AMat, AT, A );
00381 
00382     Array2D<double> AMatInv;
00383     invertSymmPositiveDefinite(AMatInv, AMat);
00384 
00385     if (bTranspose) 
00386         matMat(outA, AT, AMatInv);
00387     else
00388         matMat(outA, AMatInv, AT);
00389 
00390 }
  • Shark Main Page
  • Array
  • Rng
  • LinAlg
  • FileUtil
  • EALib
  • MOO-EALib
  • ReClaM
  • Fuzzy
  • Mixture
  • Tutorials
  • FAQ