00001
00043
00044
00045 #include <cmath>
00046 #include <cstdlib>
00047 #include <SharkDefs.h>
00048 #include <LinAlg/LinAlg.h>
00049
00050 static double SIGN(double a, double b)
00051 {
00052 return b > 0 ? fabs(a) : -fabs(a);
00053 }
00054
00055
00109 void svd
00110 (
00111 const Array2D< double >& amatA,
00112 Array2D< double >& umatA,
00113 Array2D< double >& vmatA,
00114 Array < double >& w,
00115 unsigned maxIterations,
00116 bool ignoreThreshold
00117 )
00118 {
00119 unsigned m = amatA.rows();
00120 unsigned n = amatA.cols();
00121
00122
00123
00124
00125 int flag;
00126 unsigned i, its, j, jj, k, l, nm(0);
00127 double anorm, c, f, g, h, s, scale, x, y, z;
00128
00129 Array< double > rv1(n);
00130
00131
00132 for (i = 0; i < m; i++) {
00133 for (j = 0; j < n; j++) {
00134 umatA(i, j) = amatA(i, j);
00135 }
00136 }
00137
00138
00139 g = scale = anorm = 0.0;
00140
00141 for (i = 0; i < n; i++) {
00142 l = i + 1;
00143 rv1(i) = scale * g;
00144 g = s = scale = 0.0;
00145
00146 if (i < m) {
00147 for (k = i; k < m; k++) {
00148 scale += fabs(umatA(k, i));
00149 }
00150
00151 if (scale != 0.0) {
00152 for (k = i; k < m; k++) {
00153 umatA(k, i) /= scale;
00154 s += umatA(k, i) * umatA(k, i);
00155 }
00156
00157 f = umatA(i, i);
00158 g = -SIGN(sqrt(s), f);
00159 h = f * g - s;
00160 umatA(i, i) = f - g;
00161
00162 for (j = l; j < n; j++) {
00163 s = 0.0;
00164 for (k = i; k < m; k++) {
00165 s += umatA(k, i) * umatA(k, j);
00166 }
00167
00168 f = s / h;
00169 for (k = i; k < m; k++) {
00170 umatA(k, j) += f * umatA(k, i);
00171 }
00172 }
00173
00174 for (k = i; k < m; k++) {
00175 umatA(k, i) *= scale;
00176 }
00177 }
00178 }
00179
00180 w(i) = scale * g;
00181 g = s = scale = 0.0;
00182
00183 if (i < m && i != n - 1) {
00184 for (k = l; k < n; k++) {
00185 scale += fabs(umatA(i, k));
00186 }
00187
00188 if (scale != 0.0) {
00189 for (k = l; k < n; k++) {
00190 umatA(i, k) /= scale;
00191 s += umatA(i, k) * umatA(i, k);
00192 }
00193
00194 f = umatA(i, l);
00195 g = -SIGN(sqrt(s), f);
00196 h = f * g - s;
00197 umatA(i, l) = f - g;
00198
00199 for (k = l; k < n; k++) {
00200 rv1(k) = umatA(i, k) / h;
00201 }
00202
00203 for (j = l; j < m; j++) {
00204 s = 0.0;
00205 for (k = l; k < n; k++) {
00206 s += umatA(j, k) * umatA(i, k);
00207 }
00208
00209 for (k = l; k < n; k++) {
00210 umatA(j, k) += s * rv1(k);
00211 }
00212 }
00213
00214 for (k = l; k < n; k++) {
00215 umatA(i, k) *= scale;
00216 }
00217 }
00218 }
00219
00220 anorm = Shark::max(anorm, fabs(w(i)) + fabs(rv1(i)));
00221 }
00222
00223
00224 for (l = i = n; i--; l--) {
00225 if (l < n) {
00226 if (g != 0.0) {
00227 for (j = l; j < n; j++) {
00228
00229 vmatA(j, i) = (umatA(i, j) / umatA(i, l)) / g;
00230 }
00231
00232 for (j = l; j < n; j++) {
00233 s = 0.0;
00234 for (k = l; k < n; k++) {
00235 s += umatA(i, k) * vmatA(k, j);
00236 }
00237
00238 for (k = l; k < n; k++) {
00239 vmatA(k, j) += s * vmatA(k, i);
00240 }
00241 }
00242 }
00243
00244 for (j = l; j < n; j++) {
00245 vmatA(i, j) = vmatA(j, i) = 0.0;
00246 }
00247 }
00248
00249 vmatA(i, i) = 1.0;
00250 g = rv1(i);
00251 }
00252
00253
00254 for (l = i = Shark::min(m, n); i--; l--) {
00255 g = w(i);
00256
00257 for (j = l; j < n; j++) {
00258 umatA(i, j) = 0.0;
00259 }
00260
00261 if (g != 0.0) {
00262 g = 1.0 / g;
00263
00264 for (j = l; j < n; j++) {
00265 s = 0.0;
00266 for (k = l; k < m; k++) {
00267 s += umatA(k, i) * umatA(k, j);
00268 }
00269
00270
00271 f = (s / umatA(i, i)) * g;
00272
00273 for (k = i; k < m; k++) {
00274 umatA(k, j) += f * umatA(k, i);
00275 }
00276 }
00277
00278 for (j = i; j < m; j++) {
00279 umatA(j, i) *= g;
00280 }
00281 }
00282 else {
00283 for (j = i; j < m; j++) {
00284 umatA(j, i) = 0.0;
00285 }
00286 }
00287
00288 umatA(i, i)++;
00289 }
00290
00291
00292 for (k = n; k--;) {
00293 for (its = 1; its <= maxIterations; its++) {
00294 flag = 1;
00295
00296
00297
00298
00299
00300
00301
00302
00303 for (l = k; l > 0; l--) {
00304
00305 nm = l - 1;
00306
00307 if (fabs(rv1(l)) + anorm == anorm) {
00308 flag = 0;
00309 break;
00310 }
00311
00312 if (fabs(w(nm)) + anorm == anorm) {
00313 break;
00314 }
00315 }
00316
00317 if (flag) {
00318
00319 c = 0.0;
00320 s = 1.0;
00321
00322 for (i = l; i <= k; i++) {
00323 f = s * rv1(i);
00324 rv1(i) *= c;
00325
00326 if (fabs(f) + anorm == anorm) {
00327 break;
00328 }
00329
00330 g = w(i);
00331 h = hypot(f, g);
00332 w(i) = h;
00333 h = 1.0 / h;
00334 c = g * h;
00335 s = -f * h;
00336
00337 for (j = 0; j < m; j++) {
00338 y = umatA(j, nm);
00339 z = umatA(j, i);
00340 umatA(j, nm) = y * c + z * s;
00341 umatA(j, i ) = z * c - y * s;
00342 }
00343 }
00344 }
00345
00346
00347 z = w(k);
00348
00349 if (l == k) {
00350 if (z < 0.0) {
00351 w(k) = -z;
00352 for (j = 0; j < n; j++) {
00353 vmatA(j, k) = -vmatA(j, k);
00354 }
00355 }
00356 break;
00357 }
00358
00359 if( its == maxIterations ) {
00360 if(ignoreThreshold)
00361 break ;
00362 else
00363 throw SHARKEXCEPTION("too many iterations for diagonalization of the bidiagonal form during SVD");
00364 }
00365
00366
00367
00368 x = w(l);
00369 nm = k - 1;
00370 y = w(nm);
00371 g = rv1(nm);
00372 h = rv1(k);
00373 f = ((y - z) * (y + z) + (g - h) * (g + h)) / (2.0 * h * y);
00374 g = hypot(f, 1.0);
00375 f = ((x - z) * (x + z) + h * ((y / (f + SIGN(g, f))) - h)) / x;
00376
00377
00378 c = s = 1.0;
00379
00380 for (j = l; j < k; j++) {
00381 i = j + 1;
00382 g = rv1(i);
00383 y = w(i);
00384 h = s * g;
00385 g *= c;
00386 z = hypot(f, h);
00387 rv1(j) = z;
00388 c = f / z;
00389 s = h / z;
00390 f = x * c + g * s;
00391 g = g * c - x * s;
00392 h = y * s;
00393 y *= c;
00394
00395 for (jj = 0; jj < n; jj++) {
00396 x = vmatA(jj, j);
00397 z = vmatA(jj, i);
00398 vmatA(jj, j) = x * c + z * s;
00399 vmatA(jj, i) = z * c - x * s;
00400 }
00401
00402 z = hypot(f, h);
00403 w(j) = z;
00404
00405
00406 if (z != 0.0) {
00407 z = 1.0 / z;
00408 c = f * z;
00409 s = h * z;
00410 }
00411
00412 f = c * g + s * y;
00413 x = c * y - s * g;
00414
00415 for (jj = 0; jj < m; jj++) {
00416 y = umatA(jj, j);
00417 z = umatA(jj, i);
00418 umatA(jj, j) = y * c + z * s;
00419 umatA(jj, i) = z * c - y * s;
00420 }
00421 }
00422
00423 rv1(l) = 0.0;
00424 rv1(k) = f;
00425 w(k) = x;
00426 }
00427 }
00428 }
00429
00430
00431
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482