00001 #ifndef TNT_LINALG_H_
00002 #define TNT_LINALG_H_
00003
00004 #include <algorithm>
00005
00006
00007 #include <cmath>
00008
00009
00010
00011 namespace TNT {
00012 namespace Linear_Algebra {
00013
00014 using namespace std;
00015
00049 template <class Real>
00050 class Cholesky
00051 {
00052 Matrix<Real> L_;
00053 int isspd;
00054
00055 public:
00056
00057 Cholesky();
00058 Cholesky(const Matrix<Real> &A);
00059 Matrix<Real> getL() const;
00060 Vector<Real> solve(const Vector<Real> &B);
00061 Matrix<Real> solve(const Matrix<Real> &B);
00062 int is_spd() const;
00063
00064 };
00065
00066 template <class Real>
00067 Cholesky<Real>::Cholesky() : L_(Real(0.0)), isspd(0) {}
00068
00073 template <class Real>
00074 int Cholesky<Real>::is_spd() const
00075 {
00076 return isspd;
00077 }
00078
00082 template <class Real>
00083 Matrix<Real> Cholesky<Real>::getL() const
00084 {
00085 return L_;
00086 }
00087
00094 template <class Real>
00095 Cholesky<Real>::Cholesky(const Matrix<Real> &A)
00096 {
00097
00098
00099 int m = A.num_rows();
00100 int n = A.num_cols();
00101
00102 isspd = (m == n);
00103
00104 if (m != n)
00105 {
00106 L_ = Matrix<Real>(Real(0.0));
00107 return;
00108 }
00109
00110 L_ = Matrix<Real>(n,n);
00111
00112
00113
00114 for (int j = 0; j < n; j++)
00115 {
00116 Real d = Real(0.0);
00117 for (int k = 0; k < j; k++)
00118 {
00119 Real s = Real(0.0);
00120 for (int i = 0; i < k; i++)
00121 {
00122 s += L_[k][i]*L_[j][i];
00123 }
00124 L_[j][k] = s = (A[j][k] - s)/L_[k][k];
00125 d = d + s*s;
00126 isspd = isspd && (A[k][j] == A[j][k]);
00127 }
00128 d = A[j][j] - d;
00129 isspd = isspd && (d > Real(0.0));
00130 L_[j][j] = sqrt(d > Real(0.0) ? d : Real(0.0));
00131 for (int k = j+1; k < n; k++)
00132 {
00133 L_[j][k] = Real(0.0);
00134 }
00135 }
00136 }
00137
00148 template <class Real>
00149 Vector<Real> Cholesky<Real>::solve(const Vector<Real> &b)
00150 {
00151 int n = L_.num_rows();
00152 if (b.dim() != n)
00153 return Vector<Real>();
00154
00155
00156 Vector<Real> x = b;
00157
00158
00159
00160 for (int k = 0; k < n; k++)
00161 {
00162 for (int i = 0; i < k; i++)
00163 x[k] -= x[i]*L_[k][i];
00164 x[k] /= L_[k][k];
00165
00166 }
00167
00168
00169 for (int k = n-1; k >= 0; k--)
00170 {
00171 for (int i = k+1; i < n; i++)
00172 x[k] -= x[i]*L_[i][k];
00173 x[k] /= L_[k][k];
00174 }
00175
00176 return x;
00177 }
00178
00179
00190 template <class Real>
00191 Matrix<Real> Cholesky<Real>::solve(const Matrix<Real> &B)
00192 {
00193 int n = L_.num_rows();
00194 if (B.num_rows() != n)
00195 return Matrix<Real>();
00196
00197
00198 Matrix<Real> X = B;
00199 int nx = B.num_cols();
00200
00201
00202 for (int j=0; j< nx; j++)
00203 {
00204 for (int k = 0; k < n; k++)
00205 {
00206 for (int i = 0; i < k; i++)
00207 X[k][j] -= X[i][j]*L_[k][i];
00208 X[k][j] /= L_[k][k];
00209 }
00210 }
00211
00212
00213 for (int j=0; j<nx; j++)
00214 {
00215 for (int k = n-1; k >= 0; k--)
00216 {
00217 for (int i = k+1; i < n; i++)
00218 X[k][j] -= X[i][j]*L_[i][k];
00219 X[k][j] /= L_[k][k];
00220 }
00221 }
00222
00223
00224
00225 return X;
00226 }
00227
00228
00229
00230
00282 template <class Real>
00283 class Eigenvalue
00284 {
00285
00286
00288 int n;
00289
00290 int issymmetric;
00291
00294 Vector<Real> d;
00295 Vector<Real> e;
00296
00298 Matrix<Real> V;
00299
00300
00301
00302
00303 Matrix<Real> H;
00304
00305
00306
00307
00308
00309 Vector<Real> ort;
00310
00311
00312
00313
00314 void tred2() {
00315
00316
00317
00318
00319
00320
00321 for (int j = 0; j < n; j++) {
00322 d[j] = V[n-1][j];
00323 }
00324
00325
00326
00327 for (int i = n-1; i > 0; i--) {
00328
00329
00330
00331 Real scale = Real(0.0);
00332 Real h = Real(0.0);
00333 for (int k = 0; k < i; k++) {
00334 scale = scale + abs(d[k]);
00335 }
00336 if (scale == Real(0.0)) {
00337 e[i] = d[i-1];
00338 for (int j = 0; j < i; j++) {
00339 d[j] = V[i-1][j];
00340 V[i][j] = Real(0.0);
00341 V[j][i] = Real(0.0);
00342 }
00343 } else {
00344
00345
00346
00347 for (int k = 0; k < i; k++) {
00348 d[k] /= scale;
00349 h += d[k] * d[k];
00350 }
00351 Real f = d[i-1];
00352 Real g = sqrt(h);
00353 if (f > 0) {
00354 g = -g;
00355 }
00356 e[i] = scale * g;
00357 h = h - f * g;
00358 d[i-1] = f - g;
00359 for (int j = 0; j < i; j++) {
00360 e[j] = Real(0.0);
00361 }
00362
00363
00364
00365 for (int j = 0; j < i; j++) {
00366 f = d[j];
00367 V[j][i] = f;
00368 g = e[j] + V[j][j] * f;
00369 for (int k = j+1; k <= i-1; k++) {
00370 g += V[k][j] * d[k];
00371 e[k] += V[k][j] * f;
00372 }
00373 e[j] = g;
00374 }
00375 f = Real(0.0);
00376 for (int j = 0; j < i; j++) {
00377 e[j] /= h;
00378 f += e[j] * d[j];
00379 }
00380 Real hh = f / (h + h);
00381 for (int j = 0; j < i; j++) {
00382 e[j] -= hh * d[j];
00383 }
00384 for (int j = 0; j < i; j++) {
00385 f = d[j];
00386 g = e[j];
00387 for (int k = j; k <= i-1; k++) {
00388 V[k][j] -= (f * e[k] + g * d[k]);
00389 }
00390 d[j] = V[i-1][j];
00391 V[i][j] = Real(0.0);
00392 }
00393 }
00394 d[i] = h;
00395 }
00396
00397
00398
00399 for (int i = 0; i < n-1; i++) {
00400 V[n-1][i] = V[i][i];
00401 V[i][i] = Real(1.0);
00402 Real h = d[i+1];
00403 if (h != Real(0.0)) {
00404 for (int k = 0; k <= i; k++) {
00405 d[k] = V[k][i+1] / h;
00406 }
00407 for (int j = 0; j <= i; j++) {
00408 Real g = Real(0.0);
00409 for (int k = 0; k <= i; k++) {
00410 g += V[k][i+1] * V[k][j];
00411 }
00412 for (int k = 0; k <= i; k++) {
00413 V[k][j] -= g * d[k];
00414 }
00415 }
00416 }
00417 for (int k = 0; k <= i; k++) {
00418 V[k][i+1] = Real(0.0);
00419 }
00420 }
00421 for (int j = 0; j < n; j++) {
00422 d[j] = V[n-1][j];
00423 V[n-1][j] = Real(0.0);
00424 }
00425 V[n-1][n-1] = Real(1.0);
00426 e[0] = Real(0.0);
00427 }
00428
00429
00430
00431 void tql2 () {
00432
00433
00434
00435
00436
00437
00438 for (int i = 1; i < n; i++) {
00439 e[i-1] = e[i];
00440 }
00441 e[n-1] = Real(0.0);
00442
00443 Real f = Real(0.0);
00444 Real tst1 = Real(0.0);
00445 Real eps = pow(2.0,-52.0);
00446 for (int l = 0; l < n; l++) {
00447
00448
00449
00450 tst1 = max(tst1,abs(d[l]) + abs(e[l]));
00451 int m = l;
00452
00453
00454 while (m < n) {
00455 if (abs(e[m]) <= eps*tst1) {
00456 break;
00457 }
00458 m++;
00459 }
00460
00461
00462
00463
00464
00465 if (m > l) {
00466 int iter = 0;
00467 do {
00468 iter = iter + 1;
00469
00470
00471
00472 Real g = d[l];
00473 Real p = (d[l+1] - g) / (2.0 * e[l]);
00474 Real r = hypot(p, static_cast<Real>(Real(1.0)));
00475 if (p < 0) {
00476 r = -r;
00477 }
00478 d[l] = e[l] / (p + r);
00479 d[l+1] = e[l] * (p + r);
00480 Real dl1 = d[l+1];
00481 Real h = g - d[l];
00482 for (int i = l+2; i < n; i++) {
00483 d[i] -= h;
00484 }
00485 f = f + h;
00486
00487
00488
00489 p = d[m];
00490 Real c = Real(1.0);
00491 Real c2 = c;
00492 Real c3 = c;
00493 Real el1 = e[l+1];
00494 Real s = Real(0.0);
00495 Real s2 = Real(0.0);
00496 for (int i = m-1; i >= l; i--) {
00497 c3 = c2;
00498 c2 = c;
00499 s2 = s;
00500 g = c * e[i];
00501 h = c * p;
00502 r = hypot(p,e[i]);
00503 e[i+1] = s * r;
00504 s = e[i] / r;
00505 c = p / r;
00506 p = c * d[i] - s * g;
00507 d[i+1] = h + s * (c * g + s * d[i]);
00508
00509
00510
00511 for (int k = 0; k < n; k++) {
00512 h = V[k][i+1];
00513 V[k][i+1] = s * V[k][i] + c * h;
00514 V[k][i] = c * V[k][i] - s * h;
00515 }
00516 }
00517 p = -s * s2 * c3 * el1 * e[l] / dl1;
00518 e[l] = s * p;
00519 d[l] = c * p;
00520
00521
00522
00523 } while (abs(e[l]) > eps*tst1);
00524 }
00525 d[l] = d[l] + f;
00526 e[l] = Real(0.0);
00527 }
00528
00529
00530
00531 for (int i = 0; i < n-1; i++) {
00532 int k = i;
00533 Real p = d[i];
00534 for (int j = i+1; j < n; j++) {
00535 if (d[j] < p) {
00536 k = j;
00537 p = d[j];
00538 }
00539 }
00540 if (k != i) {
00541 d[k] = d[i];
00542 d[i] = p;
00543 for (int j = 0; j < n; j++) {
00544 p = V[j][i];
00545 V[j][i] = V[j][k];
00546 V[j][k] = p;
00547 }
00548 }
00549 }
00550 }
00551
00552
00553
00554 void orthes () {
00555
00556
00557
00558
00559
00560
00561 int low = 0;
00562 int high = n-1;
00563
00564 for (int m = low+1; m <= high-1; m++) {
00565
00566
00567
00568 Real scale = Real(0.0);
00569 for (int i = m; i <= high; i++) {
00570 scale = scale + abs(H[i][m-1]);
00571 }
00572 if (scale != Real(0.0)) {
00573
00574
00575
00576 Real h = Real(0.0);
00577 for (int i = high; i >= m; i--) {
00578 ort[i] = H[i][m-1]/scale;
00579 h += ort[i] * ort[i];
00580 }
00581 Real g = sqrt(h);
00582 if (ort[m] > 0) {
00583 g = -g;
00584 }
00585 h = h - ort[m] * g;
00586 ort[m] = ort[m] - g;
00587
00588
00589
00590
00591 for (int j = m; j < n; j++) {
00592 Real f = Real(0.0);
00593 for (int i = high; i >= m; i--) {
00594 f += ort[i]*H[i][j];
00595 }
00596 f = f/h;
00597 for (int i = m; i <= high; i++) {
00598 H[i][j] -= f*ort[i];
00599 }
00600 }
00601
00602 for (int i = 0; i <= high; i++) {
00603 Real f = Real(0.0);
00604 for (int j = high; j >= m; j--) {
00605 f += ort[j]*H[i][j];
00606 }
00607 f = f/h;
00608 for (int j = m; j <= high; j++) {
00609 H[i][j] -= f*ort[j];
00610 }
00611 }
00612 ort[m] = scale*ort[m];
00613 H[m][m-1] = scale*g;
00614 }
00615 }
00616
00617
00618
00619 for (int i = 0; i < n; i++) {
00620 for (int j = 0; j < n; j++) {
00621 V[i][j] = (i == j ? Real(1.0) : Real(0.0));
00622 }
00623 }
00624
00625 for (int m = high-1; m >= low+1; m--) {
00626 if (H[m][m-1] != Real(0.0)) {
00627 for (int i = m+1; i <= high; i++) {
00628 ort[i] = H[i][m-1];
00629 }
00630 for (int j = m; j <= high; j++) {
00631 Real g = Real(0.0);
00632 for (int i = m; i <= high; i++) {
00633 g += ort[i] * V[i][j];
00634 }
00635
00636 g = (g / ort[m]) / H[m][m-1];
00637 for (int i = m; i <= high; i++) {
00638 V[i][j] += g * ort[i];
00639 }
00640 }
00641 }
00642 }
00643 }
00644
00645
00646
00647
00648 Real cdivr, cdivi;
00649 void cdiv(Real xr, Real xi, Real yr, Real yi) {
00650 Real r,d;
00651 if (abs(yr) > abs(yi)) {
00652 r = yi/yr;
00653 d = yr + r*yi;
00654 cdivr = (xr + r*xi)/d;
00655 cdivi = (xi - r*xr)/d;
00656 } else {
00657 r = yr/yi;
00658 d = yi + r*yr;
00659 cdivr = (r*xr + xi)/d;
00660 cdivi = (r*xi - xr)/d;
00661 }
00662 }
00663
00664
00665
00666
00667 void hqr2 () {
00668
00669
00670
00671
00672
00673
00674
00675
00676 int nn = this->n;
00677 int n = nn-1;
00678 int low = 0;
00679 int high = nn-1;
00680 Real eps = pow(2.0,-52.0);
00681 Real exshift = Real(0.0);
00682 Real p=0,q=0,r=0,s=0,z=0,t,w,x,y;
00683
00684
00685
00686 Real norm = Real(0.0);
00687 for (int i = 0; i < nn; i++) {
00688 if ((i < low) || (i > high)) {
00689 d[i] = H[i][i];
00690 e[i] = Real(0.0);
00691 }
00692 for (int j = max(i-Real(1.0)); j < nn; j++) {
00693 norm = norm + abs(H[i][j]);
00694 }
00695 }
00696
00697
00698
00699 int iter = 0;
00700 while (n >= low) {
00701
00702
00703
00704 int l = n;
00705 while (l > low) {
00706 s = abs(H[l-1][l-1]) + abs(H[l][l]);
00707 if (s == Real(0.0)) {
00708 s = norm;
00709 }
00710 if (abs(H[l][l-1]) < eps * s) {
00711 break;
00712 }
00713 l--;
00714 }
00715
00716
00717
00718
00719 if (l == n) {
00720 H[n][n] = H[n][n] + exshift;
00721 d[n] = H[n][n];
00722 e[n] = Real(0.0);
00723 n--;
00724 iter = 0;
00725
00726
00727
00728 } else if (l == n-1) {
00729 w = H[n][n-1] * H[n-1][n];
00730 p = (H[n-1][n-1] - H[n][n]) / 2.0;
00731 q = p * p + w;
00732 z = sqrt(abs(q));
00733 H[n][n] = H[n][n] + exshift;
00734 H[n-1][n-1] = H[n-1][n-1] + exshift;
00735 x = H[n][n];
00736
00737
00738
00739 if (q >= 0) {
00740 if (p >= 0) {
00741 z = p + z;
00742 } else {
00743 z = p - z;
00744 }
00745 d[n-1] = x + z;
00746 d[n] = d[n-1];
00747 if (z != Real(0.0)) {
00748 d[n] = x - w / z;
00749 }
00750 e[n-1] = Real(0.0);
00751 e[n] = Real(0.0);
00752 x = H[n][n-1];
00753 s = abs(x) + abs(z);
00754 p = x / s;
00755 q = z / s;
00756 r = sqrt(p * p+q * q);
00757 p = p / r;
00758 q = q / r;
00759
00760
00761
00762 for (int j = n-1; j < nn; j++) {
00763 z = H[n-1][j];
00764 H[n-1][j] = q * z + p * H[n][j];
00765 H[n][j] = q * H[n][j] - p * z;
00766 }
00767
00768
00769
00770 for (int i = 0; i <= n; i++) {
00771 z = H[i][n-1];
00772 H[i][n-1] = q * z + p * H[i][n];
00773 H[i][n] = q * H[i][n] - p * z;
00774 }
00775
00776
00777
00778 for (int i = low; i <= high; i++) {
00779 z = V[i][n-1];
00780 V[i][n-1] = q * z + p * V[i][n];
00781 V[i][n] = q * V[i][n] - p * z;
00782 }
00783
00784
00785
00786 } else {
00787 d[n-1] = x + p;
00788 d[n] = x + p;
00789 e[n-1] = z;
00790 e[n] = -z;
00791 }
00792 n = n - 2;
00793 iter = 0;
00794
00795
00796
00797 } else {
00798
00799
00800
00801 x = H[n][n];
00802 y = Real(0.0);
00803 w = Real(0.0);
00804 if (l < n) {
00805 y = H[n-1][n-1];
00806 w = H[n][n-1] * H[n-1][n];
00807 }
00808
00809
00810
00811 if (iter == 10) {
00812 exshift += x;
00813 for (int i = low; i <= n; i++) {
00814 H[i][i] -= x;
00815 }
00816 s = abs(H[n][n-1]) + abs(H[n-1][n-2]);
00817 x = y = 0.75 * s;
00818 w = -0.4375 * s * s;
00819 }
00820
00821
00822
00823 if (iter == 30) {
00824 s = (y - x) / 2.0;
00825 s = s * s + w;
00826 if (s > 0) {
00827 s = sqrt(s);
00828 if (y < x) {
00829 s = -s;
00830 }
00831 s = x - w / ((y - x) / 2.0 + s);
00832 for (int i = low; i <= n; i++) {
00833 H[i][i] -= s;
00834 }
00835 exshift += s;
00836 x = y = w = 0.964;
00837 }
00838 }
00839
00840 iter = iter + 1;
00841
00842
00843
00844 int m = n-2;
00845 while (m >= l) {
00846 z = H[m][m];
00847 r = x - z;
00848 s = y - z;
00849 p = (r * s - w) / H[m+1][m] + H[m][m+1];
00850 q = H[m+1][m+1] - z - r - s;
00851 r = H[m+2][m+1];
00852 s = abs(p) + abs(q) + abs(r);
00853 p = p / s;
00854 q = q / s;
00855 r = r / s;
00856 if (m == l) {
00857 break;
00858 }
00859 if (abs(H[m][m-1]) * (abs(q) + abs(r)) <
00860 eps * (abs(p) * (abs(H[m-1][m-1]) + abs(z) +
00861 abs(H[m+1][m+1])))) {
00862 break;
00863 }
00864 m--;
00865 }
00866
00867 for (int i = m+2; i <= n; i++) {
00868 H[i][i-2] = Real(0.0);
00869 if (i > m+2) {
00870 H[i][i-3] = Real(0.0);
00871 }
00872 }
00873
00874
00875
00876 for (int k = m; k <= n-1; k++) {
00877 int notlast = (k != n-1);
00878 if (k != m) {
00879 p = H[k][k-1];
00880 q = H[k+1][k-1];
00881 r = (notlast ? H[k+2][k-1] : Real(0.0));
00882 x = abs(p) + abs(q) + abs(r);
00883 if (x != Real(0.0)) {
00884 p = p / x;
00885 q = q / x;
00886 r = r / x;
00887 }
00888 }
00889 if (x == Real(0.0)) {
00890 break;
00891 }
00892 s = sqrt(p * p + q * q + r * r);
00893 if (p < 0) {
00894 s = -s;
00895 }
00896 if (s != 0) {
00897 if (k != m) {
00898 H[k][k-1] = -s * x;
00899 } else if (l != m) {
00900 H[k][k-1] = -H[k][k-1];
00901 }
00902 p = p + s;
00903 x = p / s;
00904 y = q / s;
00905 z = r / s;
00906 q = q / p;
00907 r = r / p;
00908
00909
00910
00911 for (int j = k; j < nn; j++) {
00912 p = H[k][j] + q * H[k+1][j];
00913 if (notlast) {
00914 p = p + r * H[k+2][j];
00915 H[k+2][j] = H[k+2][j] - p * z;
00916 }
00917 H[k][j] = H[k][j] - p * x;
00918 H[k+1][j] = H[k+1][j] - p * y;
00919 }
00920
00921
00922
00923 for (int i = 0; i <= min(n,k+3); i++) {
00924 p = x * H[i][k] + y * H[i][k+1];
00925 if (notlast) {
00926 p = p + z * H[i][k+2];
00927 H[i][k+2] = H[i][k+2] - p * r;
00928 }
00929 H[i][k] = H[i][k] - p;
00930 H[i][k+1] = H[i][k+1] - p * q;
00931 }
00932
00933
00934
00935 for (int i = low; i <= high; i++) {
00936 p = x * V[i][k] + y * V[i][k+1];
00937 if (notlast) {
00938 p = p + z * V[i][k+2];
00939 V[i][k+2] = V[i][k+2] - p * r;
00940 }
00941 V[i][k] = V[i][k] - p;
00942 V[i][k+1] = V[i][k+1] - p * q;
00943 }
00944 }
00945 }
00946 }
00947 }
00948
00949
00950
00951 if (norm == Real(0.0)) {
00952 return;
00953 }
00954
00955 for (n = nn-1; n >= 0; n--) {
00956 p = d[n];
00957 q = e[n];
00958
00959
00960
00961 if (q == 0) {
00962 int l = n;
00963 H[n][n] = Real(1.0);
00964 for (int i = n-1; i >= 0; i--) {
00965 w = H[i][i] - p;
00966 r = Real(0.0);
00967 for (int j = l; j <= n; j++) {
00968 r = r + H[i][j] * H[j][n];
00969 }
00970 if (e[i] < Real(0.0)) {
00971 z = w;
00972 s = r;
00973 } else {
00974 l = i;
00975 if (e[i] == Real(0.0)) {
00976 if (w != Real(0.0)) {
00977 H[i][n] = -r / w;
00978 } else {
00979 H[i][n] = -r / (eps * norm);
00980 }
00981
00982
00983
00984 } else {
00985 x = H[i][i+1];
00986 y = H[i+1][i];
00987 q = (d[i] - p) * (d[i] - p) + e[i] * e[i];
00988 t = (x * s - z * r) / q;
00989 H[i][n] = t;
00990 if (abs(x) > abs(z)) {
00991 H[i+1][n] = (-r - w * t) / x;
00992 } else {
00993 H[i+1][n] = (-s - y * t) / z;
00994 }
00995 }
00996
00997
00998
00999 t = abs(H[i][n]);
01000 if ((eps * t) * t > 1) {
01001 for (int j = i; j <= n; j++) {
01002 H[j][n] = H[j][n] / t;
01003 }
01004 }
01005 }
01006 }
01007
01008
01009
01010 } else if (q < 0) {
01011 int l = n-1;
01012
01013
01014
01015 if (abs(H[n][n-1]) > abs(H[n-1][n])) {
01016 H[n-1][n-1] = q / H[n][n-1];
01017 H[n-1][n] = -(H[n][n] - p) / H[n][n-1];
01018 } else {
01019 cdiv(Real(0.0),-H[n-1][n],H[n-1][n-1]-p,q);
01020 H[n-1][n-1] = cdivr;
01021 H[n-1][n] = cdivi;
01022 }
01023 H[n][n-1] = Real(0.0);
01024 H[n][n] = Real(1.0);
01025 for (int i = n-2; i >= 0; i--) {
01026 Real ra,sa,vr,vi;
01027 ra = Real(0.0);
01028 sa = Real(0.0);
01029 for (int j = l; j <= n; j++) {
01030 ra = ra + H[i][j] * H[j][n-1];
01031 sa = sa + H[i][j] * H[j][n];
01032 }
01033 w = H[i][i] - p;
01034
01035 if (e[i] < Real(0.0)) {
01036 z = w;
01037 r = ra;
01038 s = sa;
01039 } else {
01040 l = i;
01041 if (e[i] == 0) {
01042 cdiv(-ra,-sa,w,q);
01043 H[i][n-1] = cdivr;
01044 H[i][n] = cdivi;
01045 } else {
01046
01047
01048
01049 x = H[i][i+1];
01050 y = H[i+1][i];
01051 vr = (d[i] - p) * (d[i] - p) + e[i] * e[i] - q * q;
01052 vi = (d[i] - p) * 2.0 * q;
01053 if ((vr == Real(0.0)) && (vi == Real(0.0))) {
01054 vr = eps * norm * (abs(w) + abs(q) +
01055 abs(x) + abs(y) + abs(z));
01056 }
01057 cdiv(x*r-z*ra+q*sa,x*s-z*sa-q*ra,vr,vi);
01058 H[i][n-1] = cdivr;
01059 H[i][n] = cdivi;
01060 if (abs(x) > (abs(z) + abs(q))) {
01061 H[i+1][n-1] = (-ra - w * H[i][n-1] + q * H[i][n]) / x;
01062 H[i+1][n] = (-sa - w * H[i][n] - q * H[i][n-1]) / x;
01063 } else {
01064 cdiv(-r-y*H[i][n-1],-s-y*H[i][n],z,q);
01065 H[i+1][n-1] = cdivr;
01066 H[i+1][n] = cdivi;
01067 }
01068 }
01069
01070
01071
01072 t = max(abs(H[i][n-1]),abs(H[i][n]));
01073 if ((eps * t) * t > 1) {
01074 for (int j = i; j <= n; j++) {
01075 H[j][n-1] = H[j][n-1] / t;
01076 H[j][n] = H[j][n] / t;
01077 }
01078 }
01079 }
01080 }
01081 }
01082 }
01083
01084
01085
01086 for (int i = 0; i < nn; i++) {
01087 if (i < low || i > high) {
01088 for (int j = i; j < nn; j++) {
01089 V[i][j] = H[i][j];
01090 }
01091 }
01092 }
01093
01094
01095
01096 for (int j = nn-1; j >= low; j--) {
01097 for (int i = low; i <= high; i++) {
01098 z = Real(0.0);
01099 for (int k = low; k <= min(j,high); k++) {
01100 z = z + V[i][k] * H[k][j];
01101 }
01102 V[i][j] = z;
01103 }
01104 }
01105 }
01106
01107 public:
01108
01109
01114 Eigenvalue(const Matrix<Real> &A) {
01115 n = A.num_cols();
01116 V = Matrix<Real>(n,n);
01117 d = Vector<Real>(n);
01118 e = Vector<Real>(n);
01119
01120 issymmetric = 1;
01121 for (int j = 0; (j < n) && issymmetric; j++) {
01122 for (int i = 0; (i < n) && issymmetric; i++) {
01123 issymmetric = (A[i][j] == A[j][i]);
01124 }
01125 }
01126
01127 if (issymmetric) {
01128 for (int i = 0; i < n; i++) {
01129 for (int j = 0; j < n; j++) {
01130 V[i][j] = A[i][j];
01131 }
01132 }
01133
01134
01135 tred2();
01136
01137
01138 tql2();
01139
01140 } else {
01141 H = Matrix<Real>(n,n);
01142 ort = Vector<Real>(n);
01143
01144 for (int j = 0; j < n; j++) {
01145 for (int i = 0; i < n; i++) {
01146 H[i][j] = A[i][j];
01147 }
01148 }
01149
01150
01151 orthes();
01152
01153
01154 hqr2();
01155 }
01156 }
01157
01158
01163 void getV (Matrix<Real> &V_) {
01164 V_ = V;
01165 return;
01166 }
01167
01172 void getRealEigenvalues (Vector<Real> &d_) {
01173 d_ = d;
01174 return ;
01175 }
01176
01182 void getImagEigenvalues (Vector<Real> &e_) {
01183 e_ = e;
01184 return;
01185 }
01186
01187
01221 void getD (Matrix<Real> &D) {
01222 D = Matrix<Real>(n,n);
01223 for (int i = 0; i < n; i++) {
01224 for (int j = 0; j < n; j++) {
01225 D[i][j] = Real(0.0);
01226 }
01227 D[i][i] = d[i];
01228 if (e[i] > 0) {
01229 D[i][i+1] = e[i];
01230 } else if (e[i] < 0) {
01231 D[i][i-1] = e[i];
01232 }
01233 }
01234 }
01235 };
01236
01237
01250 template <class Real>
01251 class LU
01252 {
01253
01254 private:
01255
01256
01257 Matrix<Real> LU_;
01258 int m, n, pivsign;
01259 Vector<int> piv;
01260
01261
01262 Matrix<Real> permute_copy( const Matrix<Real> &A,
01263 const Vector<int> &piv, int j0, int j1)
01264 {
01265 int piv_length = piv.dim();
01266
01267 Matrix<Real> X(piv_length, j1-j0+1);
01268
01269
01270 for (int i = 0; i < piv_length; i++)
01271 for (int j = j0; j <= j1; j++)
01272 X[i][j-j0] = A[piv[i]][j];
01273
01274 return X;
01275 }
01276
01277 Vector<Real> permute_copy( const Vector<Real> &A,
01278 const Vector<int> &piv)
01279 {
01280 int piv_length = piv.dim();
01281 if (piv_length != A.dim())
01282 return Vector<Real>();
01283
01284 Vector<Real> x(piv_length);
01285
01286
01287 for (int i = 0; i < piv_length; i++)
01288 x[i] = A[piv[i]];
01289
01290 return x;
01291 }
01292
01293
01294 public :
01295
01301 LU (const Matrix<Real> &A) : LU_(A), m(A.num_rows()), n(A.num_cols()),
01302 piv(A.num_rows())
01303
01304 {
01305
01306
01307
01308
01309 for (int i = 0; i < m; i++) {
01310 piv[i] = i;
01311 }
01312 pivsign = 1;
01313 Real *LUrowi = 0;;
01314 Vector<Real> LUcolj(m);
01315
01316
01317
01318 for (int j = 0; j < n; j++) {
01319
01320
01321
01322 for (int i = 0; i < m; i++) {
01323 LUcolj[i] = LU_[i][j];
01324 }
01325
01326
01327
01328 for (int i = 0; i < m; i++) {
01329 LUrowi = LU_[i];
01330
01331
01332
01333 int kmax = min(i,j);
01334 double s = Real(0.0);
01335 for (int k = 0; k < kmax; k++) {
01336 s += LUrowi[k]*LUcolj[k];
01337 }
01338
01339 LUrowi[j] = LUcolj[i] -= s;
01340 }
01341
01342
01343
01344 int p = j;
01345 for (int i = j+1; i < m; i++) {
01346 if (abs(LUcolj[i]) > abs(LUcolj[p])) {
01347 p = i;
01348 }
01349 }
01350 if (p != j) {
01351 int k=0;
01352 for (k = 0; k < n; k++) {
01353 double t = LU_[p][k];
01354 LU_[p][k] = LU_[j][k];
01355 LU_[j][k] = t;
01356 }
01357 k = piv[p];
01358 piv[p] = piv[j];
01359 piv[j] = k;
01360 pivsign = -pivsign;
01361 }
01362
01363
01364
01365 if ((j < m) && (LU_[j][j] != Real(0.0))) {
01366 for (int i = j+1; i < m; i++) {
01367 LU_[i][j] /= LU_[j][j];
01368 }
01369 }
01370 }
01371 }
01372
01373
01379 int isNonsingular () {
01380 for (int j = 0; j < n; j++) {
01381 if (LU_[j][j] == 0)
01382 return 0;
01383 }
01384 return 1;
01385 }
01386
01391 Matrix<Real> getL () {
01392 Matrix<Real> L_(m,n);
01393 for (int i = 0; i < m; i++) {
01394 for (int j = 0; j < n; j++) {
01395 if (i > j) {
01396 L_[i][j] = LU_[i][j];
01397 } else if (i == j) {
01398 L_[i][j] = Real(1.0);
01399 } else {
01400 L_[i][j] = Real(0.0);
01401 }
01402 }
01403 }
01404 return L_;
01405 }
01406
01411 Matrix<Real> getU () {
01412 Matrix<Real> U_(n,n);
01413 for (int i = 0; i < n; i++) {
01414 for (int j = 0; j < n; j++) {
01415 if (i <= j) {
01416 U_[i][j] = LU_[i][j];
01417 } else {
01418 U_[i][j] = Real(0.0);
01419 }
01420 }
01421 }
01422 return U_;
01423 }
01424
01429 Vector<int> getPivot () {
01430 return piv;
01431 }
01432
01433
01438 Real det () {
01439 if (m != n) {
01440 return Real(0);
01441 }
01442 Real d = Real(pivsign);
01443 for (int j = 0; j < n; j++) {
01444 d *= LU_[j][j];
01445 }
01446 return d;
01447 }
01448
01455 Matrix<Real> solve (const Matrix<Real> &B)
01456 {
01457
01458
01459
01460 if (B.num_rows() != m) {
01461 return Matrix<Real>(Real(0.0));
01462 }
01463 if (!isNonsingular()) {
01464 return Matrix<Real>(Real(0.0));
01465 }
01466
01467
01468 int nx = B.num_cols();
01469
01470
01471 Matrix<Real> X = permute_copy(B, piv, 0, nx-1);
01472
01473
01474 for (int k = 0; k < n; k++) {
01475 for (int i = k+1; i < n; i++) {
01476 for (int j = 0; j < nx; j++) {
01477 X[i][j] -= X[k][j]*LU_[i][k];
01478 }
01479 }
01480 }
01481
01482 for (int k = n-1; k >= 0; k--) {
01483 for (int j = 0; j < nx; j++) {
01484 X[k][j] /= LU_[k][k];
01485 }
01486 for (int i = 0; i < k; i++) {
01487 for (int j = 0; j < nx; j++) {
01488 X[i][j] -= X[k][j]*LU_[i][k];
01489 }
01490 }
01491 }
01492 return X;
01493 }
01494
01495
01505 Vector<Real> solve (const Vector<Real> &b)
01506 {
01507
01508
01509
01510 if (b.dim() != m) {
01511 return Vector<Real>();
01512 }
01513 if (!isNonsingular()) {
01514 return Vector<Real>();
01515 }
01516
01517
01518 Vector<Real> x = permute_copy(b, piv);
01519
01520
01521 for (int k = 0; k < n; k++) {
01522 for (int i = k+1; i < n; i++) {
01523 x[i] -= x[k]*LU_[i][k];
01524 }
01525 }
01526
01527
01528 for (int k = n-1; k >= 0; k--) {
01529 x[k] /= LU_[k][k];
01530 for (int i = 0; i < k; i++)
01531 x[i] -= x[k]*LU_[i][k];
01532 }
01533
01534
01535 return x;
01536 }
01537
01538 };
01539
01540
01564 template <class Real>
01565 class QR {
01566
01567
01568
01569
01570
01571
01572 Matrix<Real> QR_;
01573
01574
01575
01576
01577
01578 int m, n;
01579
01580
01581
01582
01583 Vector<Real> Rdiag;
01584
01585
01586 public:
01587
01593 QR(const Matrix<Real> &A)
01594 {
01595 QR_ = A;
01596 m = A.num_rows();
01597 n = A.num_cols();
01598 Rdiag = Vector<Real>(n);
01599 int i=0, j=0, k=0;
01600
01601
01602 for (k = 0; k < n; k++) {
01603
01604 Real nrm = 0;
01605 for (i = k; i < m; i++) {
01606 nrm = hypot(nrm,QR_[i][k]);
01607 }
01608
01609 if (nrm != Real(0.0)) {
01610
01611 if (QR_[k][k] < 0) {
01612 nrm = -nrm;
01613 }
01614 for (i = k; i < m; i++) {
01615 QR_[i][k] /= nrm;
01616 }
01617 QR_[k][k] += Real(1.0);
01618
01619
01620 for (j = k+1; j < n; j++) {
01621 Real s = Real(0.0);
01622 for (i = k; i < m; i++) {
01623 s += QR_[i][k]*QR_[i][j];
01624 }
01625 s = -s/QR_[k][k];
01626 for (i = k; i < m; i++) {
01627 QR_[i][j] += s*QR_[i][k];
01628 }
01629 }
01630 }
01631 Rdiag[k] = -nrm;
01632 }
01633 }
01634
01635
01641 int isFullRank() const
01642 {
01643 for (int j = 0; j < n; j++)
01644 {
01645 if (Rdiag[j] == 0)
01646 return 0;
01647 }
01648 return 1;
01649 }
01650
01651
01652
01653
01660 Matrix<Real> getHouseholder (void) const
01661 {
01662 Matrix<Real> H(m,n);
01663
01664
01665
01666
01667 for (int i = 0; i < m; i++)
01668 {
01669 for (int j = 0; j < n; j++)
01670 {
01671 if (i >= j) {
01672 H[i][j] = QR_[i][j];
01673 } else {
01674 H[i][j] = Real(0.0);
01675 }
01676 }
01677 }
01678 return H;
01679 }
01680
01681
01682
01687 Matrix<Real> getR() const
01688 {
01689 Matrix<Real> R(n,n);
01690 for (int i = 0; i < n; i++) {
01691 for (int j = 0; j < n; j++) {
01692 if (i < j) {
01693 R[i][j] = QR_[i][j];
01694 } else if (i == j) {
01695 R[i][j] = Rdiag[i];
01696 } else {
01697 R[i][j] = Real(0.0);
01698 }
01699 }
01700 }
01701 return R;
01702 }
01703
01704
01705
01706
01707
01712 Matrix<Real> getQ() const
01713 {
01714 int i=0, j=0, k=0;
01715
01716 Matrix<Real> Q(m,n);
01717 for (k = n-1; k >= 0; k--) {
01718 for (i = 0; i < m; i++) {
01719 Q[i][k] = Real(0.0);
01720 }
01721 Q[k][k] = Real(1.0);
01722 for (j = k; j < n; j++) {
01723 if (QR_[k][k] != 0) {
01724 Real s = Real(0.0);
01725 for (i = k; i < m; i++) {
01726 s += QR_[i][k]*Q[i][j];
01727 }
01728 s = -s/QR_[k][k];
01729 for (i = k; i < m; i++) {
01730 Q[i][j] += s*QR_[i][k];
01731 }
01732 }
01733 }
01734 }
01735 return Q;
01736 }
01737
01738
01746 Vector<Real> solve(const Vector<Real> &b) const
01747 {
01748 if (b.dim() != m)
01749 return Vector<Real>();
01750
01751 if ( !isFullRank() )
01752 {
01753 return Vector<Real>();
01754 }
01755
01756 Vector<Real> x = b;
01757
01758
01759 for (int k = 0; k < n; k++)
01760 {
01761 Real s = Real(0.0);
01762 for (int i = k; i < m; i++)
01763 {
01764 s += QR_[i][k]*x[i];
01765 }
01766 s = -s/QR_[k][k];
01767 for (int i = k; i < m; i++)
01768 {
01769 x[i] += s*QR_[i][k];
01770 }
01771 }
01772
01773 for (int k = n-1; k >= 0; k--)
01774 {
01775 x[k] /= Rdiag[k];
01776 for (int i = 0; i < k; i++) {
01777 x[i] -= x[k]*QR_[i][k];
01778 }
01779 }
01780
01781
01782
01783 Vector<Real> x_(n);
01784 for (int i=0; i<n; i++)
01785 x_[i] = x[i];
01786
01787 return x_;
01788 }
01789
01797 Matrix<Real> solve(const Matrix<Real> &B) const
01798 {
01799 if (B.num_rows() != m)
01800 return Matrix<Real>(Real(0.0));
01801
01802 if ( !isFullRank() )
01803 {
01804 return Matrix<Real>(Real(0.0));
01805 }
01806
01807 int nx = B.num_cols();
01808 Matrix<Real> X = B;
01809 int i=0, j=0, k=0;
01810
01811
01812 for (k = 0; k < n; k++) {
01813 for (j = 0; j < nx; j++) {
01814 Real s = Real(0.0);
01815 for (i = k; i < m; i++) {
01816 s += QR_[i][k]*X[i][j];
01817 }
01818 s = -s/QR_[k][k];
01819 for (i = k; i < m; i++) {
01820 X[i][j] += s*QR_[i][k];
01821 }
01822 }
01823 }
01824
01825 for (k = n-1; k >= 0; k--) {
01826 for (j = 0; j < nx; j++) {
01827 X[k][j] /= Rdiag[k];
01828 }
01829 for (i = 0; i < k; i++) {
01830 for (j = 0; j < nx; j++) {
01831 X[i][j] -= X[k][j]*QR_[i][k];
01832 }
01833 }
01834 }
01835
01836
01837
01838 Matrix<Real> X_(n,nx);
01839 for (i=0; i<n; i++)
01840 for (j=0; j<nx; j++)
01841 X_[i][j] = X[i][j];
01842
01843 return X_;
01844 }
01845
01846
01847 };
01848
01849
01867 template <class Real>
01868 class SVD
01869 {
01870
01871
01872 Matrix<Real> U, V;
01873 Vector<Real> s;
01874 int m, n;
01875
01876 public:
01877
01878
01879 SVD (const Matrix<Real> &Arg) {
01880
01881
01882 m = Arg.num_rows();
01883 n = Arg.num_cols();
01884 int nu = min(m,n);
01885 s = Vector<Real>(min(m+1,n));
01886 U = Matrix<Real>(m, nu, Real(0));
01887 V = Matrix<Real>(n,n);
01888 Vector<Real> e(n);
01889 Vector<Real> work(m);
01890 Matrix<Real> A(Arg);
01891 int wantu = 1;
01892 int wantv = 1;
01893 int i=0, j=0, k=0;
01894
01895
01896
01897
01898 int nct = min(m-1,n);
01899 int nrt = max(0,min(n-2,m));
01900 for (k = 0; k < max(nct,nrt); k++) {
01901 if (k < nct) {
01902
01903
01904
01905
01906 s[k] = 0;
01907 for (i = k; i < m; i++) {
01908 s[k] = hypot(s[k],A[i][k]);
01909 }
01910 if (s[k] != Real(0.0)) {
01911 if (A[k][k] < Real(0.0)) {
01912 s[k] = -s[k];
01913 }
01914 for (i = k; i < m; i++) {
01915 A[i][k] /= s[k];
01916 }
01917 A[k][k] += Real(1.0);
01918 }
01919 s[k] = -s[k];
01920 }
01921 for (j = k+1; j < n; j++) {
01922 if ((k < nct) && (s[k] != Real(0.0))) {
01923
01924
01925
01926 double t = 0;
01927 for (i = k; i < m; i++) {
01928 t += A[i][k]*A[i][j];
01929 }
01930 t = -t/A[k][k];
01931 for (i = k; i < m; i++) {
01932 A[i][j] += t*A[i][k];
01933 }
01934 }
01935
01936
01937
01938
01939 e[j] = A[k][j];
01940 }
01941 if (wantu & (k < nct)) {
01942
01943
01944
01945
01946 for (i = k; i < m; i++) {
01947 U[i][k] = A[i][k];
01948 }
01949 }
01950 if (k < nrt) {
01951
01952
01953
01954
01955 e[k] = 0;
01956 for (i = k+1; i < n; i++) {
01957 e[k] = hypot(e[k],e[i]);
01958 }
01959 if (e[k] != Real(0.0)) {
01960 if (e[k+1] < Real(0.0)) {
01961 e[k] = -e[k];
01962 }
01963 for (i = k+1; i < n; i++) {
01964 e[i] /= e[k];
01965 }
01966 e[k+1] += Real(1.0);
01967 }
01968 e[k] = -e[k];
01969 if ((k+1 < m) & (e[k] != Real(0.0))) {
01970
01971
01972
01973 for (i = k+1; i < m; i++) {
01974 work[i] = Real(0.0);
01975 }
01976 for (j = k+1; j < n; j++) {
01977 for (i = k+1; i < m; i++) {
01978 work[i] += e[j]*A[i][j];
01979 }
01980 }
01981 for (j = k+1; j < n; j++) {
01982 double t = -e[j]/e[k+1];
01983 for (i = k+1; i < m; i++) {
01984 A[i][j] += t*work[i];
01985 }
01986 }
01987 }
01988 if (wantv) {
01989
01990
01991
01992
01993 for (i = k+1; i < n; i++) {
01994 V[i][k] = e[i];
01995 }
01996 }
01997 }
01998 }
01999
02000
02001
02002 int p = min(n,m+1);
02003 if (nct < n) {
02004 s[nct] = A[nct][nct];
02005 }
02006 if (m < p) {
02007 s[p-1] = Real(0.0);
02008 }
02009 if (nrt+1 < p) {
02010 e[nrt] = A[nrt][p-1];
02011 }
02012 e[p-1] = Real(0.0);
02013
02014
02015
02016 if (wantu) {
02017 for (j = nct; j < nu; j++) {
02018 for (i = 0; i < m; i++) {
02019 U[i][j] = Real(0.0);
02020 }
02021 U[j][j] = Real(1.0);
02022 }
02023 for (k = nct-1; k >= 0; k--) {
02024 if (s[k] != Real(0.0)) {
02025 for (j = k+1; j < nu; j++) {
02026 double t = 0;
02027 for (i = k; i < m; i++) {
02028 t += U[i][k]*U[i][j];
02029 }
02030 t = -t/U[k][k];
02031 for (i = k; i < m; i++) {
02032 U[i][j] += t*U[i][k];
02033 }
02034 }
02035 for (i = k; i < m; i++ ) {
02036 U[i][k] = -U[i][k];
02037 }
02038 U[k][k] = Real(1.0) + U[k][k];
02039 for (i = 0; i < k-1; i++) {
02040 U[i][k] = Real(0.0);
02041 }
02042 } else {
02043 for (i = 0; i < m; i++) {
02044 U[i][k] = Real(0.0);
02045 }
02046 U[k][k] = Real(1.0);
02047 }
02048 }
02049 }
02050
02051
02052
02053 if (wantv) {
02054 for (k = n-1; k >= 0; k--) {
02055 if ((k < nrt) & (e[k] != Real(0.0))) {
02056 for (j = k+1; j < nu; j++) {
02057 double t = 0;
02058 for (i = k+1; i < n; i++) {
02059 t += V[i][k]*V[i][j];
02060 }
02061 t = -t/V[k+1][k];
02062 for (i = k+1; i < n; i++) {
02063 V[i][j] += t*V[i][k];
02064 }
02065 }
02066 }
02067 for (i = 0; i < n; i++) {
02068 V[i][k] = Real(0.0);
02069 }
02070 V[k][k] = Real(1.0);
02071 }
02072 }
02073
02074
02075
02076 int pp = p-1;
02077 int iter = 0;
02078 double eps = pow(2.0,-52.0);
02079 while (p > 0) {
02080 int k=0;
02081 int kase=0;
02082
02083
02084
02085
02086
02087
02088
02089
02090
02091
02092
02093
02094
02095 for (k = p-2; k >= -1; k--) {
02096 if (k == -1) {
02097 break;
02098 }
02099 if (abs(e[k]) <= eps*(abs(s[k]) + abs(s[k+1]))) {
02100 e[k] = Real(0.0);
02101 break;
02102 }
02103 }
02104 if (k == p-2) {
02105 kase = 4;
02106 } else {
02107 int ks;
02108 for (ks = p-1; ks >= k; ks--) {
02109 if (ks == k) {
02110 break;
02111 }
02112 double t = (ks != p ? abs(e[ks]) : 0.) +
02113 (ks != k+1 ? abs(e[ks-1]) : 0.);
02114 if (abs(s[ks]) <= eps*t) {
02115 s[ks] = Real(0.0);
02116 break;
02117 }
02118 }
02119 if (ks == k) {
02120 kase = 3;
02121 } else if (ks == p-1) {
02122 kase = 1;
02123 } else {
02124 kase = 2;
02125 k = ks;
02126 }
02127 }
02128 k++;
02129
02130
02131
02132 switch (kase) {
02133
02134
02135
02136 case 1: {
02137 double f = e[p-2];
02138 e[p-2] = Real(0.0);
02139 for (j = p-2; j >= k; j--) {
02140 double t = hypot(s[j],f);
02141 double cs = s[j]/t;
02142 double sn = f/t;
02143 s[j] = t;
02144 if (j != k) {
02145 f = -sn*e[j-1];
02146 e[j-1] = cs*e[j-1];
02147 }
02148 if (wantv) {
02149 for (i = 0; i < n; i++) {
02150 t = cs*V[i][j] + sn*V[i][p-1];
02151 V[i][p-1] = -sn*V[i][j] + cs*V[i][p-1];
02152 V[i][j] = t;
02153 }
02154 }
02155 }
02156 }
02157 break;
02158
02159
02160
02161 case 2: {
02162 double f = e[k-1];
02163 e[k-1] = Real(0.0);
02164 for (j = k; j < p; j++) {
02165 double t = hypot(s[j],f);
02166 double cs = s[j]/t;
02167 double sn = f/t;
02168 s[j] = t;
02169 f = -sn*e[j];
02170 e[j] = cs*e[j];
02171 if (wantu) {
02172 for (i = 0; i < m; i++) {
02173 t = cs*U[i][j] + sn*U[i][k-1];
02174 U[i][k-1] = -sn*U[i][j] + cs*U[i][k-1];
02175 U[i][j] = t;
02176 }
02177 }
02178 }
02179 }
02180 break;
02181
02182
02183
02184 case 3: {
02185
02186
02187
02188 double scale = max(max(max(max(
02189 abs(s[p-1]),abs(s[p-2])),abs(e[p-2])),
02190 abs(s[k])),abs(e[k]));
02191 double sp = s[p-1]/scale;
02192 double spm1 = s[p-2]/scale;
02193 double epm1 = e[p-2]/scale;
02194 double sk = s[k]/scale;
02195 double ek = e[k]/scale;
02196 double b = ((spm1 + sp)*(spm1 - sp) + epm1*epm1)/2.0;
02197 double c = (sp*epm1)*(sp*epm1);
02198 double shift = Real(0.0);
02199 if ((b != Real(0.0)) || (c != Real(0.0))) {
02200 shift = sqrt(b*b + c);
02201 if (b < Real(0.0)) {
02202 shift = -shift;
02203 }
02204 shift = c/(b + shift);
02205 }
02206 double f = (sk + sp)*(sk - sp) + shift;
02207 double g = sk*ek;
02208
02209
02210
02211 for (j = k; j < p-1; j++) {
02212 double t = hypot(f,g);
02213 double cs = f/t;
02214 double sn = g/t;
02215 if (j != k) {
02216 e[j-1] = t;
02217 }
02218 f = cs*s[j] + sn*e[j];
02219 e[j] = cs*e[j] - sn*s[j];
02220 g = sn*s[j+1];
02221 s[j+1] = cs*s[j+1];
02222 if (wantv) {
02223 for (i = 0; i < n; i++) {
02224 t = cs*V[i][j] + sn*V[i][j+1];
02225 V[i][j+1] = -sn*V[i][j] + cs*V[i][j+1];
02226 V[i][j] = t;
02227 }
02228 }
02229 t = hypot(f,g);
02230 cs = f/t;
02231 sn = g/t;
02232 s[j] = t;
02233 f = cs*e[j] + sn*s[j+1];
02234 s[j+1] = -sn*e[j] + cs*s[j+1];
02235 g = sn*e[j+1];
02236 e[j+1] = cs*e[j+1];
02237 if (wantu && (j < m-1)) {
02238 for (i = 0; i < m; i++) {
02239 t = cs*U[i][j] + sn*U[i][j+1];
02240 U[i][j+1] = -sn*U[i][j] + cs*U[i][j+1];
02241 U[i][j] = t;
02242 }
02243 }
02244 }
02245 e[p-2] = f;
02246 iter = iter + 1;
02247 }
02248 break;
02249
02250
02251
02252 case 4: {
02253
02254
02255
02256 if (s[k] <= Real(0.0)) {
02257 s[k] = (s[k] < Real(0.0) ? -s[k] : Real(0.0));
02258 if (wantv) {
02259 for (i = 0; i <= pp; i++) {
02260 V[i][k] = -V[i][k];
02261 }
02262 }
02263 }
02264
02265
02266
02267 while (k < pp) {
02268 if (s[k] >= s[k+1]) {
02269 break;
02270 }
02271 double t = s[k];
02272 s[k] = s[k+1];
02273 s[k+1] = t;
02274 if (wantv && (k < n-1)) {
02275 for (i = 0; i < n; i++) {
02276 t = V[i][k+1]; V[i][k+1] = V[i][k]; V[i][k] = t;
02277 }
02278 }
02279 if (wantu && (k < m-1)) {
02280 for (i = 0; i < m; i++) {
02281 t = U[i][k+1]; U[i][k+1] = U[i][k]; U[i][k] = t;
02282 }
02283 }
02284 k++;
02285 }
02286 iter = 0;
02287 p--;
02288 }
02289 break;
02290 }
02291 }
02292 }
02293
02294
02295 void getU (Matrix<Real> &A)
02296 {
02297 int minm = min(m+1,n);
02298
02299 A = Matrix<Real>(m, minm);
02300
02301 for (int i=0; i<m; i++)
02302 for (int j=0; j<minm; j++)
02303 A[i][j] = U[i][j];
02304
02305 }
02306
02307
02308
02309 void getV (Matrix<Real> &A)
02310 {
02311 A = V;
02312 }
02313
02316 void getSingularValues (Vector<Real> &x)
02317 {
02318 x = s;
02319 }
02320
02325 void getS (Matrix<Real> &A) {
02326 A = Matrix<Real>(n,n);
02327 for (int i = 0; i < n; i++) {
02328 for (int j = 0; j < n; j++) {
02329 A[i][j] = Real(0.0);
02330 }
02331 A[i][i] = s[i];
02332 }
02333 }
02334
02337 double norm2 () {
02338 return s[0];
02339 }
02340
02343 double cond () {
02344 return s[0]/s[min(m,n)-1];
02345 }
02346
02351 int rank ()
02352 {
02353 double eps = pow(2.0,-52.0);
02354 double tol = max(m,n)*s[0]*eps;
02355 int r = 0;
02356 for (int i = 0; i < s.dim(); i++) {
02357 if (s[i] > tol) {
02358 r++;
02359 }
02360 }
02361 return r;
02362 }
02363 };
02364
02365 }
02366 }
02367
02368 #endif
02369