00001 #ifndef OPENTISSUE_CORE_MATH_BIG_SVD_IMPL1_H
00002 #define OPENTISSUE_CORE_MATH_BIG_SVD_IMPL1_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/core/math/big/big_types.h>
00013 #include <OpenTissue/core/math/math_value_traits.h>
00014
00015 #include <boost/cast.hpp>
00016 #include <cmath>
00017 #include <stdexcept>
00018
00019 namespace OpenTissue
00020 {
00021 namespace math
00022 {
00023 namespace big
00024 {
00025 namespace details
00026 {
00027
00036 template <class T>
00037 inline T hypot(T const &a, T const &b)
00038 {
00039 using std::fabs;
00040 using std::sqrt;
00041
00042 T const zero = boost::numeric_cast<T>( 0.0 );
00043 T const one = boost::numeric_cast<T>( 1.0 );
00044
00045 if (a == zero)
00046 return fabs(b);
00047 else
00048 {
00049 T const c = b/a;
00050
00051 return fabs(a) * sqrt(one + c*c);
00052 }
00053 }
00054
00078 template<typename ME>
00079 inline void svd_impl1(
00080 ublas::matrix_expression<ME> const & AE
00081 , ublas::matrix<typename ME::value_type> & U
00082 , ublas::vector<typename ME::value_type> & s
00083 , ublas::matrix<typename ME::value_type> & V
00084 )
00085 {
00086 using std::fabs;
00087 using std::max;
00088 using std::min;
00089 using std::pow;
00090 using std::sqrt;
00091
00092 typedef typename ME::size_type size_type;
00093 typedef typename ME::value_type value_type;
00094 typedef ublas::matrix<value_type> matrix_type;
00095 typedef ublas::vector<typename ME::value_type> vector_type;
00096
00097 value_type const zero = boost::numeric_cast< value_type >( 0.0 );
00098 value_type const one = boost::numeric_cast< value_type >( 1.0 );
00099 value_type const two = boost::numeric_cast< value_type >( 2.0 );
00100 value_type const eps = boost::numeric_cast<value_type>( pow( 2.0, -52.0 ) );
00101
00102
00103 int const m = static_cast<int>( AE().size1() );
00104 int const n = static_cast<int>( AE().size2() );
00105
00106 if(m<1)
00107 throw std::invalid_argument("svd(): A did not have any rows?");
00108 if(n<1)
00109 throw std::invalid_argument("svd(): A did not have any columns?");
00110
00111 matrix_type A;
00112 vector_type e;
00113 vector_type work;
00114
00115 int const nu = min(m,n);
00116
00117 e.resize(n);
00118 work.resize( m );
00119 A.resize( m, n );
00120 U.resize( m, nu );
00121 s.resize( min(m+1,n) );
00122 V.resize( n,n);
00123
00124 A = AE();
00125 U.clear();
00126 s.clear();
00127 V.clear();
00128 e.clear();
00129 work.clear();
00130
00131 int const wantu = 1;
00132 int const wantv = 1;
00133
00134
00135
00136
00137 int const nct = min( m-1, n);
00138 int const nrt = max( 0, min( n-2, m ) );
00139
00140 for (int k = 0; k < max(nct,nrt); ++k)
00141 {
00142 if (k < nct)
00143 {
00144
00145
00146
00147
00148 s(k) = zero;
00149 for (int i = k; i < m; ++i)
00150 {
00151 s(k) = details::hypot( s(k), A(i,k) );
00152 }
00153
00154 if (s(k) != zero)
00155 {
00156 if (A(k,k) < zero)
00157 {
00158 s(k) = -s(k);
00159 }
00160 for (int i = k; i < m; ++i)
00161 {
00162 A(i,k) /= s(k);
00163 }
00164 A(k,k) += one;
00165 }
00166
00167 s(k) = -s(k);
00168 }
00169
00170 for (int j = k+1; j < n; ++j)
00171 {
00172 if ( (k < nct) && (s(k) != zero) )
00173 {
00174
00175 value_type t = zero;
00176
00177 for (int i = k; i < m; ++i)
00178 {
00179 t += A(i,k) * A(i,j);
00180 }
00181
00182 t = - t / A(k,k);
00183
00184 for (int i = k; i < m; ++i)
00185 {
00186 A(i,j) += t * A(i,k);
00187 }
00188 }
00189
00190
00191
00192 e(j) = A(k,j);
00193 }
00194
00195
00196 if ( wantu & (k < nct) )
00197 {
00198
00199
00200 for (int i = k; i < m; ++i)
00201 {
00202 U(i,k) = A(i,k);
00203 }
00204 }
00205
00206
00207 if (k < nrt)
00208 {
00209
00210
00211
00212
00213 e(k) = zero;
00214
00215 for (int i = k+1; i < n; ++i)
00216 {
00217 e(k) = details::hypot( e(k), e(i) );
00218 }
00219
00220 if ( e(k) != zero )
00221 {
00222 if ( e(k+1) < zero )
00223 {
00224 e(k) = -e(k);
00225 }
00226
00227 for (int i = k+1; i < n; ++i)
00228 {
00229 e(i) /= e(k);
00230 }
00231
00232 e(k+1) += one;
00233 }
00234
00235 e(k) = -e(k);
00236
00237 if ( (k+1 < m) & (e(k) != zero))
00238 {
00239
00240
00241 for (int i = k+1; i < m; ++i)
00242 {
00243 work(i) = zero;
00244 }
00245
00246 for (int j = k+1; j < n; ++j)
00247 {
00248 for (int i = k+1; i < m; ++i)
00249 {
00250 work(i) += e(j) * A(i,j);
00251 }
00252 }
00253
00254 for (int j = k+1; j < n; ++j)
00255 {
00256 value_type t = - e(j) / e(k+1);
00257 for (int i = k+1; i < m; ++i)
00258 {
00259 A(i,j) += t * work(i);
00260 }
00261 }
00262 }
00263 if (wantv)
00264 {
00265
00266
00267
00268 for (int i = k+1; i < n; ++i)
00269 {
00270 V(i,k) = e(i);
00271 }
00272 }
00273 }
00274 }
00275
00276
00277
00278 int p = min( n, m+1 );
00279
00280 if (nct < n)
00281 {
00282 s(nct) = A(nct,nct);
00283 }
00284
00285 if (m < p)
00286 {
00287 s(p-1) = zero;
00288 }
00289
00290 if (nrt+1 < p)
00291 {
00292 e(nrt) = A(nrt,p-1);
00293 }
00294
00295 e(p-1) = zero;
00296
00297
00298
00299 if (wantu)
00300 {
00301 for (int j = nct; j < nu; ++j)
00302 {
00303 for (int i = 0; i < m; ++i)
00304 {
00305 U(i,j) = zero;
00306 }
00307 U(j,j) = one;
00308 }
00309
00310 for (int k = nct-1; k >= 0; --k)
00311 {
00312 if (s(k) != zero)
00313 {
00314 for (int j = k+1; j < nu; ++j)
00315 {
00316 value_type t = zero;
00317
00318 for (int i = k; i < m; ++i)
00319 {
00320 t += U(i,k) * U(i,j);
00321 }
00322
00323 t = -t / U(k,k);
00324
00325 for (int i = k; i < m; ++i)
00326 {
00327 U(i,j) += t * U(i,k);
00328 }
00329 }
00330
00331 for (int i = k; i < m; ++i )
00332 {
00333 U(i,k) = -U(i,k);
00334 }
00335
00336 U(k,k) = one + U(k,k);
00337
00338 for (int i = 0; i < k-1; ++i)
00339 {
00340 U(i,k) = zero;
00341 }
00342
00343 }
00344 else
00345 {
00346 for (int i = 0; i < m; ++i)
00347 {
00348 U(i,k) = zero;
00349 }
00350 U(k,k) = one;
00351 }
00352 }
00353 }
00354
00355
00356
00357 if (wantv)
00358 {
00359 for (int k = n-1; k >= 0; --k)
00360 {
00361 if ((k < nrt) & (e(k) != zero))
00362 {
00363 for (int j = k+1; j < nu; ++j)
00364 {
00365 value_type t = zero;
00366
00367 for (int i = k+1; i < n; ++i)
00368 {
00369 t += V(i,k) * V(i,j);
00370 }
00371
00372 t = - t / V(k+1,k);
00373
00374 for (int i = k+1; i < n; ++i)
00375 {
00376 V(i,j) += t * V(i,k);
00377 }
00378 }
00379 }
00380
00381 for (int i = 0; i < n; ++i)
00382 {
00383 V(i,k) = zero;
00384 }
00385 V(k,k) = one;
00386 }
00387 }
00388
00389
00390 int const pp = p - 1;
00391 int iteration = 0;
00392
00393 while (p > 0)
00394 {
00395 int k = 0;
00396 int kase = 0;
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410 for (k = p-2; k >= -1; --k)
00411 {
00412 if (k == -1)
00413 {
00414 break;
00415 }
00416 if ( fabs( e(k) ) <= eps * ( fabs(s(k) ) + fabs( s(k+1) ) ) )
00417 {
00418 e(k) = zero;
00419 break;
00420 }
00421 }
00422 if (k == p-2)
00423 {
00424 kase = 4;
00425 }
00426 else
00427 {
00428 int ks;
00429 for (ks = p-1; ks >= k; --ks)
00430 {
00431 if (ks == k)
00432 {
00433 break;
00434 }
00435
00436 value_type t = (ks != p ? fabs( e(ks) ) : zero ) + (ks != k+1 ? fabs( e(ks-1) ) : zero);
00437
00438 if (fabs( s(ks) ) <= eps*t)
00439 {
00440 s(ks) = zero;
00441 break;
00442 }
00443
00444 }
00445
00446 if (ks == k)
00447 {
00448 kase = 3;
00449 }
00450 else if (ks == p-1)
00451 {
00452 kase = 1;
00453 }
00454 else
00455 {
00456 kase = 2;
00457 k = ks;
00458 }
00459 }
00460 ++k;
00461
00462
00463 switch (kase)
00464 {
00465
00466
00467 case 1:
00468 {
00469 value_type f = e(p-2);
00470
00471 e(p-2) = zero;
00472
00473 for (int j = p-2; j >= k; --j)
00474 {
00475 value_type t = hypot( s(j), f);
00476 value_type cs = s(j) / t;
00477 value_type sn = f / t;
00478
00479 s(j) = t;
00480
00481 if (j != k)
00482 {
00483 f = -sn*e(j-1);
00484 e(j-1) = cs*e(j-1);
00485 }
00486 if (wantv)
00487 {
00488 for (int i = 0; i < n; ++i)
00489 {
00490 t = cs*V(i,j) + sn*V(i,p-1);
00491 V(i,p-1) = -sn*V(i,j) + cs*V(i,p-1);
00492 V(i,j) = t;
00493 }
00494 }
00495 }
00496 }
00497 break;
00498
00499
00500 case 2:
00501 {
00502 value_type f = e(k-1);
00503 e(k-1) = zero;
00504 for (int j = k; j < p; ++j)
00505 {
00506 value_type t = hypot( s(j), f);
00507 value_type cs = s(j) / t;
00508 value_type sn = f / t;
00509 s(j) = t;
00510 f = -sn*e(j);
00511 e(j) = cs*e(j);
00512 if (wantu)
00513 {
00514 for (int i = 0; i < m; ++i)
00515 {
00516 t = cs*U(i,j) + sn*U(i,k-1);
00517 U(i,k-1) = -sn*U(i,j) + cs*U(i,k-1);
00518 U(i,j) = t;
00519 }
00520 }
00521 }
00522 }
00523 break;
00524
00525
00526 case 3:
00527 {
00528
00529 value_type scale = max(max(max(max( fabs(s(p-1)),fabs(s(p-2))),fabs(e(p-2))), fabs(s(k))), fabs(e(k)));
00530
00531 value_type sp = s(p-1) / scale;
00532 value_type spm1 = s(p-2) / scale;
00533 value_type epm1 = e(p-2) / scale;
00534 value_type sk = s(k) / scale;
00535 value_type ek = e(k) / scale;
00536 value_type b = ((spm1 + sp)*(spm1 - sp) + epm1*epm1) / two;
00537 value_type c = (sp*epm1)*(sp*epm1);
00538 value_type shift = zero;
00539 if ((b != zero) || (c != zero))
00540 {
00541 shift = sqrt(b*b + c);
00542 if ( b < zero )
00543 {
00544 shift = -shift;
00545 }
00546 shift = c/(b + shift);
00547 }
00548 value_type f = (sk + sp)*(sk - sp) + shift;
00549 value_type g = sk*ek;
00550
00551
00552 for (int j = k; j < p-1; ++j)
00553 {
00554 value_type t = hypot(f,g);
00555 value_type cs = f/t;
00556 value_type sn = g/t;
00557 if (j != k)
00558 {
00559 e(j-1) = t;
00560 }
00561 f = cs*s(j) + sn*e(j);
00562 e(j) = cs*e(j) - sn*s(j);
00563 g = sn*s(j+1);
00564 s(j+1) = cs*s(j+1);
00565 if (wantv)
00566 {
00567 for (int i = 0; i < n; ++i)
00568 {
00569 t = cs*V(i,j) + sn*V(i,j+1);
00570 V(i,j+1) = -sn*V(i,j) + cs*V(i,j+1);
00571 V(i,j) = t;
00572 }
00573 }
00574 t = hypot(f,g);
00575 cs = f/t;
00576 sn = g/t;
00577 s(j) = t;
00578 f = cs*e(j) + sn*s(j+1);
00579 s(j+1) = -sn*e(j) + cs*s(j+1);
00580 g = sn*e(j+1);
00581 e(j+1) = cs*e(j+1);
00582 if (wantu && (j < m-1))
00583 {
00584 for (int i = 0; i < m; ++i)
00585 {
00586 t = cs*U(i,j) + sn*U(i,j+1);
00587 U(i,j+1) = -sn*U(i,j) + cs*U(i,j+1);
00588 U(i,j) = t;
00589 }
00590 }
00591 }
00592 e(p-2) = f;
00593 iteration = iteration + 1;
00594 }
00595 break;
00596
00597
00598 case 4:
00599 {
00600
00601 if (s(k) <= zero)
00602 {
00603 s(k) = (s(k) < zero ? -s(k) : zero);
00604 if (wantv)
00605 {
00606 for (int i = 0; i <= pp; ++i)
00607 {
00608 V(i,k) = -V(i,k);
00609 }
00610 }
00611 }
00612
00613 while (k < pp)
00614 {
00615 if (s(k) >= s(k+1))
00616 {
00617 break;
00618 }
00619 value_type t = s(k);
00620 s(k) = s(k+1);
00621 s(k+1) = t;
00622 if (wantv && (k < n-1))
00623 {
00624 for (int i = 0; i < n; ++i)
00625 {
00626 t = V(i,k+1);
00627 V(i,k+1) = V(i,k);
00628 V(i,k) = t;
00629 }
00630 }
00631 if (wantu && (k < m-1))
00632 {
00633 for (int i = 0; i < m; ++i)
00634 {
00635 t = U(i,k+1);
00636 U(i,k+1) = U(i,k);
00637 U(i,k) = t;
00638 }
00639 }
00640 ++k;
00641 }
00642 iteration = 0;
00643 --p;
00644 }
00645 break;
00646 }
00647 }
00648 }
00649
00650 }
00651
00652
00653 }
00654 }
00655 }
00656
00657
00658 #endif