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
00114
00115
00116 try {
00117 svd(amatA, umatL, vmatL, wvecL, maxIterations, ignoreThreshold);
00118 } catch (SharkException e) {
00119 throw(e);
00120 }
00121 svdsort(umatL, vmatL, wvecL);
00122
00123 r = svdrank(amatA, umatL, vmatL, wvecL);
00124
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
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
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 }