Blender V2.61 - r43446

svd.h

Go to the documentation of this file.
00001 
00004 #ifndef SVD_H
00005 
00006 #define SVD_H
00007 
00008 // Compute the Single Value Decomposition of an arbitrary matrix A
00009 // That is compute the 3 matrices U,W,V with U column orthogonal (m,n) 
00010 // ,W a diagonal matrix and V an orthogonal square matrix s.t. 
00011 // A = U.W.Vt. From this decomposition it is trivial to compute the 
00012 // inverse of A as Ainv = V.Winv.tranpose(U).
00013 //
00014 // s = diagonal elements of W
00015 // work1 = workspace, length must be A.num_rows
00016 // work2 = workspace, length must be A.num_cols
00017 
00018 #include "tntmath.h"
00019 
00020 #define SVD_MAX_ITER 200
00021 
00022 namespace TNT
00023 {
00024 
00025 template <class MaTRiX, class VecToR >
00026 void SVD(MaTRiX &A, MaTRiX &U, VecToR &s, MaTRiX &V, VecToR &work1, VecToR &work2, int maxiter=SVD_MAX_ITER) {
00027 
00028     int m = A.num_rows();
00029     int n = A.num_cols();
00030     int nu = min(m,n);
00031 
00032     VecToR& work = work1;
00033     VecToR& e = work2;
00034 
00035     U = 0;
00036     s = 0;
00037 
00038     int i=0, j=0, k=0;
00039 
00040     // Reduce A to bidiagonal form, storing the diagonal elements
00041     // in s and the super-diagonal elements in e.
00042 
00043     int nct = min(m-1,n);
00044     int nrt = max(0,min(n-2,m));
00045     for (k = 0; k < max(nct,nrt); k++) {
00046         if (k < nct) {
00047 
00048             // Compute the transformation for the k-th column and
00049             // place the k-th diagonal in s[k].
00050             // Compute 2-norm of k-th column without under/overflow.
00051             s[k] = 0;
00052             for (i = k; i < m; i++) {
00053                 s[k] = hypot(s[k],A[i][k]);
00054             }
00055             if (s[k] != 0.0) {
00056                 if (A[k][k] < 0.0) {
00057                     s[k] = -s[k];
00058                 }
00059                 for (i = k; i < m; i++) {
00060                     A[i][k] /= s[k];
00061                 }
00062                 A[k][k] += 1.0;
00063             }
00064             s[k] = -s[k];
00065         }
00066         for (j = k+1; j < n; j++) {
00067             if ((k < nct) && (s[k] != 0.0))  {
00068 
00069             // Apply the transformation.
00070 
00071                 typename MaTRiX::value_type t = 0;
00072                 for (i = k; i < m; i++) {
00073                     t += A[i][k]*A[i][j];
00074                 }
00075                 t = -t/A[k][k];
00076                 for (i = k; i < m; i++) {
00077                     A[i][j] += t*A[i][k];
00078                 }
00079             }
00080 
00081             // Place the k-th row of A into e for the
00082             // subsequent calculation of the row transformation.
00083 
00084             e[j] = A[k][j];
00085         }
00086         if (k < nct) {
00087 
00088             // Place the transformation in U for subsequent back
00089             // multiplication.
00090 
00091             for (i = k; i < m; i++)
00092                 U[i][k] = A[i][k];
00093         }
00094         if (k < nrt) {
00095 
00096             // Compute the k-th row transformation and place the
00097             // k-th super-diagonal in e[k].
00098             // Compute 2-norm without under/overflow.
00099             e[k] = 0;
00100             for (i = k+1; i < n; i++) {
00101                 e[k] = hypot(e[k],e[i]);
00102             }
00103             if (e[k] != 0.0) {
00104                 if (e[k+1] < 0.0) {
00105                     e[k] = -e[k];
00106                 }
00107                 for (i = k+1; i < n; i++) {
00108                     e[i] /= e[k];
00109                 }
00110                 e[k+1] += 1.0;
00111             }
00112             e[k] = -e[k];
00113             if ((k+1 < m) & (e[k] != 0.0)) {
00114 
00115             // Apply the transformation.
00116 
00117                 for (i = k+1; i < m; i++) {
00118                     work[i] = 0.0;
00119                 }
00120                 for (j = k+1; j < n; j++) {
00121                     for (i = k+1; i < m; i++) {
00122                         work[i] += e[j]*A[i][j];
00123                     }
00124                 }
00125                 for (j = k+1; j < n; j++) {
00126                     typename MaTRiX::value_type t = -e[j]/e[k+1];
00127                     for (i = k+1; i < m; i++) {
00128                         A[i][j] += t*work[i];
00129                     }
00130                 }
00131             }
00132 
00133             // Place the transformation in V for subsequent
00134             // back multiplication.
00135 
00136             for (i = k+1; i < n; i++)
00137                 V[i][k] = e[i];
00138         }
00139     }
00140 
00141     // Set up the final bidiagonal matrix or order p.
00142 
00143     int p = min(n,m+1);
00144     if (nct < n) {
00145         s[nct] = A[nct][nct];
00146     }
00147     if (m < p) {
00148         s[p-1] = 0.0;
00149     }
00150     if (nrt+1 < p) {
00151         e[nrt] = A[nrt][p-1];
00152     }
00153     e[p-1] = 0.0;
00154 
00155     // If required, generate U.
00156 
00157     for (j = nct; j < nu; j++) {
00158         for (i = 0; i < m; i++) {
00159             U[i][j] = 0.0;
00160         }
00161         U[j][j] = 1.0;
00162     }
00163     for (k = nct-1; k >= 0; k--) {
00164         if (s[k] != 0.0) {
00165             for (j = k+1; j < nu; j++) {
00166                 typename MaTRiX::value_type t = 0;
00167                 for (i = k; i < m; i++) {
00168                     t += U[i][k]*U[i][j];
00169                 }
00170                 t = -t/U[k][k];
00171                 for (i = k; i < m; i++) {
00172                     U[i][j] += t*U[i][k];
00173                 }
00174             }
00175             for (i = k; i < m; i++ ) {
00176                 U[i][k] = -U[i][k];
00177             }
00178             U[k][k] = 1.0 + U[k][k];
00179             for (i = 0; i < k-1; i++) {
00180                 U[i][k] = 0.0;
00181             }
00182         } else {
00183             for (i = 0; i < m; i++) {
00184                 U[i][k] = 0.0;
00185             }
00186             U[k][k] = 1.0;
00187         }
00188     }
00189 
00190     // If required, generate V.
00191 
00192     for (k = n-1; k >= 0; k--) {
00193         if ((k < nrt) & (e[k] != 0.0)) {
00194             for (j = k+1; j < nu; j++) {
00195                 typename MaTRiX::value_type t = 0;
00196                 for (i = k+1; i < n; i++) {
00197                     t += V[i][k]*V[i][j];
00198                 }
00199                 t = -t/V[k+1][k];
00200                 for (i = k+1; i < n; i++) {
00201                     V[i][j] += t*V[i][k];
00202                 }
00203             }
00204         }
00205         for (i = 0; i < n; i++) {
00206             V[i][k] = 0.0;
00207         }
00208         V[k][k] = 1.0;
00209     }
00210 
00211     // Main iteration loop for the singular values.
00212 
00213     int pp = p-1;
00214     int iter = 0;
00215     typename MaTRiX::value_type eps = pow(2.0,-52.0);
00216     while (p > 0) {
00217         int kase=0;
00218         k=0;
00219 
00220         // Test for maximum iterations to avoid infinite loop
00221         if(maxiter == 0)
00222             break;
00223         maxiter--;
00224 
00225         // This section of the program inspects for
00226         // negligible elements in the s and e arrays.  On
00227         // completion the variables kase and k are set as follows.
00228 
00229         // kase = 1   if s(p) and e[k-1] are negligible and k<p
00230         // kase = 2   if s(k) is negligible and k<p
00231         // kase = 3   if e[k-1] is negligible, k<p, and
00232         //                s(k), ..., s(p) are not negligible (qr step).
00233         // kase = 4   if e(p-1) is negligible (convergence).
00234 
00235         for (k = p-2; k >= -1; k--) {
00236             if (k == -1) {
00237                 break;
00238             }
00239             if (TNT::abs(e[k]) <= eps*(TNT::abs(s[k]) + TNT::abs(s[k+1]))) {
00240                 e[k] = 0.0;
00241                 break;
00242             }
00243         }
00244         if (k == p-2) {
00245             kase = 4;
00246         } else {
00247             int ks;
00248             for (ks = p-1; ks >= k; ks--) {
00249                 if (ks == k) {
00250                     break;
00251                 }
00252                 typename MaTRiX::value_type t = (ks != p ? TNT::abs(e[ks]) : 0.) + 
00253                               (ks != k+1 ? TNT::abs(e[ks-1]) : 0.);
00254                 if (TNT::abs(s[ks]) <= eps*t)  {
00255                     s[ks] = 0.0;
00256                     break;
00257                 }
00258             }
00259             if (ks == k) {
00260                 kase = 3;
00261             } else if (ks == p-1) {
00262                 kase = 1;
00263             } else {
00264                 kase = 2;
00265                 k = ks;
00266             }
00267         }
00268         k++;
00269 
00270         // Perform the task indicated by kase.
00271 
00272         switch (kase) {
00273 
00274             // Deflate negligible s(p).
00275 
00276             case 1: {
00277                 typename MaTRiX::value_type f = e[p-2];
00278                 e[p-2] = 0.0;
00279                 for (j = p-2; j >= k; j--) {
00280                     typename MaTRiX::value_type t = hypot(s[j],f);
00281                     typename MaTRiX::value_type cs = s[j]/t;
00282                     typename MaTRiX::value_type sn = f/t;
00283                     s[j] = t;
00284                     if (j != k) {
00285                         f = -sn*e[j-1];
00286                         e[j-1] = cs*e[j-1];
00287                     }
00288 
00289                     for (i = 0; i < n; i++) {
00290                         t = cs*V[i][j] + sn*V[i][p-1];
00291                         V[i][p-1] = -sn*V[i][j] + cs*V[i][p-1];
00292                         V[i][j] = t;
00293                     }
00294                 }
00295             }
00296             break;
00297 
00298             // Split at negligible s(k).
00299 
00300             case 2: {
00301                 typename MaTRiX::value_type f = e[k-1];
00302                 e[k-1] = 0.0;
00303                 for (j = k; j < p; j++) {
00304                     typename MaTRiX::value_type t = hypot(s[j],f);
00305                     typename MaTRiX::value_type cs = s[j]/t;
00306                     typename MaTRiX::value_type sn = f/t;
00307                     s[j] = t;
00308                     f = -sn*e[j];
00309                     e[j] = cs*e[j];
00310 
00311                     for (i = 0; i < m; i++) {
00312                         t = cs*U[i][j] + sn*U[i][k-1];
00313                         U[i][k-1] = -sn*U[i][j] + cs*U[i][k-1];
00314                         U[i][j] = t;
00315                     }
00316                 }
00317             }
00318             break;
00319 
00320             // Perform one qr step.
00321 
00322             case 3: {
00323 
00324                 // Calculate the shift.
00325 
00326                 typename MaTRiX::value_type scale = max(max(max(max(
00327                           TNT::abs(s[p-1]),TNT::abs(s[p-2])),TNT::abs(e[p-2])), 
00328                           TNT::abs(s[k])),TNT::abs(e[k]));
00329                 typename MaTRiX::value_type sp = s[p-1]/scale;
00330                 typename MaTRiX::value_type spm1 = s[p-2]/scale;
00331                 typename MaTRiX::value_type epm1 = e[p-2]/scale;
00332                 typename MaTRiX::value_type sk = s[k]/scale;
00333                 typename MaTRiX::value_type ek = e[k]/scale;
00334                 typename MaTRiX::value_type b = ((spm1 + sp)*(spm1 - sp) + epm1*epm1)/2.0;
00335                 typename MaTRiX::value_type c = (sp*epm1)*(sp*epm1);
00336                 typename MaTRiX::value_type shift = 0.0;
00337                 if ((b != 0.0) || (c != 0.0)) {
00338                     shift = sqrt(b*b + c);
00339                     if (b < 0.0) {
00340                         shift = -shift;
00341                     }
00342                     shift = c/(b + shift);
00343                 }
00344                 typename MaTRiX::value_type f = (sk + sp)*(sk - sp) + shift;
00345                 typename MaTRiX::value_type g = sk*ek;
00346 
00347                 // Chase zeros.
00348 
00349                 for (j = k; j < p-1; j++) {
00350                     typename MaTRiX::value_type t = hypot(f,g);
00351                     /* division by zero checks added to avoid NaN (brecht) */
00352                     typename MaTRiX::value_type cs = (t == 0.0f)? 0.0f: f/t;
00353                     typename MaTRiX::value_type sn = (t == 0.0f)? 0.0f: g/t;
00354                     if (j != k) {
00355                         e[j-1] = t;
00356                     }
00357                     f = cs*s[j] + sn*e[j];
00358                     e[j] = cs*e[j] - sn*s[j];
00359                     g = sn*s[j+1];
00360                     s[j+1] = cs*s[j+1];
00361 
00362                     for (i = 0; i < n; i++) {
00363                         t = cs*V[i][j] + sn*V[i][j+1];
00364                         V[i][j+1] = -sn*V[i][j] + cs*V[i][j+1];
00365                         V[i][j] = t;
00366                     }
00367 
00368                     t = hypot(f,g);
00369                     /* division by zero checks added to avoid NaN (brecht) */
00370                     cs = (t == 0.0f)? 0.0f: f/t;
00371                     sn = (t == 0.0f)? 0.0f: g/t;
00372                     s[j] = t;
00373                     f = cs*e[j] + sn*s[j+1];
00374                     s[j+1] = -sn*e[j] + cs*s[j+1];
00375                     g = sn*e[j+1];
00376                     e[j+1] = cs*e[j+1];
00377                     if (j < m-1) {
00378                         for (i = 0; i < m; i++) {
00379                             t = cs*U[i][j] + sn*U[i][j+1];
00380                             U[i][j+1] = -sn*U[i][j] + cs*U[i][j+1];
00381                             U[i][j] = t;
00382                         }
00383                     }
00384                 }
00385                 e[p-2] = f;
00386                 iter = iter + 1;
00387             }
00388             break;
00389 
00390             // Convergence.
00391 
00392             case 4: {
00393 
00394                 // Make the singular values positive.
00395 
00396                 if (s[k] <= 0.0) {
00397                     s[k] = (s[k] < 0.0 ? -s[k] : 0.0);
00398 
00399                     for (i = 0; i <= pp; i++)
00400                         V[i][k] = -V[i][k];
00401                 }
00402 
00403                 // Order the singular values.
00404 
00405                 while (k < pp) {
00406                     if (s[k] >= s[k+1]) {
00407                         break;
00408                     }
00409                     typename MaTRiX::value_type t = s[k];
00410                     s[k] = s[k+1];
00411                     s[k+1] = t;
00412                     if (k < n-1) {
00413                         for (i = 0; i < n; i++) {
00414                             t = V[i][k+1]; V[i][k+1] = V[i][k]; V[i][k] = t;
00415                         }
00416                     }
00417                     if (k < m-1) {
00418                         for (i = 0; i < m; i++) {
00419                             t = U[i][k+1]; U[i][k+1] = U[i][k]; U[i][k] = t;
00420                         }
00421                     }
00422                     k++;
00423                 }
00424                 iter = 0;
00425                 p--;
00426             }
00427             break;
00428         }
00429     }
00430 }
00431 
00432 }
00433 
00434 #endif
00435