00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <it/linalg.h>
00026 #include <it/mat.h>
00027 #include <it/vec.h>
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 static void ccdiv (double xr, double xi, double yr, double yi, double *cdivr,
00041 double *cdivi)
00042 {
00043 double r, d;
00044
00045 if (fabs (yr) > fabs (yi)) {
00046 r = yi / yr;
00047 d = yr + r * yi;
00048 *cdivr = (xr + r * xi) / d;
00049 *cdivi = (xi - r * xr) / d;
00050 }
00051 else {
00052 r = yr / yi;
00053 d = yi + r * yr;
00054 *cdivr = (r * xr + xi) / d;
00055 *cdivi = (r * xi - xr) / d;
00056 }
00057 }
00058
00059
00060 static double maxx (double a, double b)
00061 {
00062 if (a > b)
00063 return (a);
00064 else
00065 return (b);
00066 }
00067
00068 int mat_is_symmetric( mat a )
00069 {
00070
00071 idx_t i, j;
00072
00073 if( mat_width(a)!=mat_height(a) )
00074 return 0;
00075
00076 for ( i= 0; i< mat_width(a); i++ )
00077 for ( j= 0; j< i; j++ )
00078 if ( a[i][j]!=a[j][i] ) return 0;
00079
00080 return 1;
00081 }
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103 vec mat_svd (mat M, mat U, mat V)
00104 {
00105
00106
00107 int i, j, k, kase, ks, m, n, p, pp, iter, nu, nct, nrt, wantu = 0, wantv =
00108 0;
00109 int mmax;
00110
00111 double t, f, g, cs, sn, eps, scale, sp, spm1, epm1, sk, ek, b, c, shift;
00112 mat A;
00113 vec s, e, work;
00114
00115 m = mat_height (M);
00116 n = mat_width (M);
00117
00118
00119 it_assert (m >= n, "This SVD is meant for m > n matrices");
00120
00121 nu = m > n ? n : m;
00122
00123 s = vec_new_zeros (m + 1 > n ? n : m + 1);
00124
00125 if (U) {
00126 it_assert (mat_height (U) == m
00127 && mat_width (U) == nu,
00128 "U matrix should be a m by min(m+1,n) real matrix");
00129 mat_zeros (U);
00130 wantu = 1;
00131 }
00132
00133 if (V) {
00134 it_assert (mat_height (V) == mat_width (V), "Matrix V must be square");
00135 it_assert (mat_height (V) == n, "Size mismatch for matrix V");
00136 mat_zeros (V);
00137 wantv = 1;
00138 }
00139
00140 A = mat_clone( M );
00141
00142 e = vec_new_zeros (n);
00143 work = vec_new_zeros (m);
00144
00145
00146
00147
00148
00149
00150 nct = m - 1 > n ? n : m - 1;
00151 nrt = 0 > (n - 2 > m ? m : n - 2) ? 0 : (n - 2 > m ? m : n - 2);
00152
00153 mmax = nct > nrt ? nct : nrt;
00154
00155 for (k = 0; k < mmax; k++) {
00156 if (k < nct) {
00157
00158
00159
00160
00161
00162
00163 s[k] = 0;
00164 for (i = k; i < m; i++)
00165 s[k] = sqrt (s[k] * s[k] + A[i][k] * A[i][k]);
00166
00167 if (s[k]) {
00168 if (A[k][k] < 0.0)
00169 s[k] = -s[k];
00170
00171 for (i = k; i < m; i++)
00172 A[i][k] /= s[k];
00173
00174 A[k][k] += 1.0;
00175 }
00176 s[k] = -s[k];
00177 }
00178 for (j = k + 1; j < n; j++) {
00179 if ((k < nct) && (s[k] != 0.0)) {
00180
00181
00182 t = 0.;
00183 for (i = k; i < m; i++)
00184 t += A[i][k] * A[i][j];
00185
00186 t = -t / A[k][k];
00187 for (i = k; i < m; i++)
00188 A[i][j] += t * A[i][k];
00189
00190 }
00191
00192
00193
00194
00195
00196
00197 e[j] = A[k][j];
00198 }
00199 if (wantu && (k < nct)) {
00200
00201
00202
00203
00204
00205 for (i = k; i < m; i++)
00206 U[i][k] = A[i][k];
00207
00208 }
00209 if (k < nrt) {
00210
00211
00212
00213
00214
00215
00216 e[k] = 0;
00217 for (i = k + 1; i < n; i++)
00218 e[k] = sqrt (e[k] * e[k] + e[i] * e[i]);
00219
00220 if (e[k]) {
00221 if (e[k + 1] < 0.0)
00222 e[k] = -e[k];
00223
00224 for (i = k + 1; i < n; i++)
00225 e[i] /= e[k];
00226
00227 e[k + 1] += 1.0;
00228 }
00229 e[k] = -e[k];
00230 if ((k + 1 < m) && e[k]) {
00231
00232
00233
00234 for (i = k + 1; i < m; i++)
00235 work[i] = 0.0;
00236
00237 for (j = k + 1; j < n; j++)
00238 for (i = k + 1; i < m; i++)
00239 work[i] += e[j] * A[i][j];
00240
00241 for (j = k + 1; j < n; j++) {
00242 t = -e[j] / e[k + 1];
00243 for (i = k + 1; i < m; i++)
00244 A[i][j] += t * work[i];
00245 }
00246 }
00247 if (wantv) {
00248
00249
00250
00251
00252
00253 for (i = k + 1; i < n; i++)
00254 V[i][k] = e[i];
00255
00256 }
00257 }
00258 }
00259
00260
00261
00262 p = n > m + 1 ? m + 1 : n;
00263
00264 if (nct < n)
00265 s[nct] = A[nct][nct];
00266 if (m < p)
00267 s[p - 1] = 0.0;
00268 if (nrt + 1 < p)
00269 e[nrt] = A[nrt][p - 1];
00270
00271 e[p - 1] = 0.0;
00272
00273
00274
00275 if (wantu) {
00276 for (j = nct; j < nu; j++) {
00277 for (i = 0; i < m; i++)
00278 U[i][j] = 0.0;
00279
00280 U[j][j] = 1.0;
00281 }
00282 for (k = nct - 1; k >= 0; k--) {
00283 if (s[k]) {
00284 for (j = k + 1; j < nu; j++) {
00285 t = 0.;
00286 for (i = k; i < m; i++)
00287 t += U[i][k] * U[i][j];
00288
00289 t = -t / U[k][k];
00290 for (i = k; i < m; i++)
00291 U[i][j] += t * U[i][k];
00292
00293 }
00294 for (i = k; i < m; i++)
00295 U[i][k] = -U[i][k];
00296
00297 U[k][k] = 1.0 + U[k][k];
00298 for (i = 0; i < k - 1; i++)
00299 U[i][k] = 0.0;
00300
00301 }
00302 else {
00303 for (i = 0; i < m; i++)
00304 U[i][k] = 0.0;
00305
00306 U[k][k] = 1.0;
00307 }
00308 }
00309 }
00310
00311
00312
00313 if (wantv) {
00314 for (k = n - 1; k >= 0; k--) {
00315 if ((k < nrt) && e[k]) {
00316 for (j = k + 1; j < nu; j++) {
00317 t = 0.;
00318 for (i = k + 1; i < n; i++)
00319 t += V[i][k] * V[i][j];
00320
00321 t = -t / V[k + 1][k];
00322 for (i = k + 1; i < n; i++)
00323 V[i][j] += t * V[i][k];
00324
00325 }
00326 }
00327 for (i = 0; i < n; i++)
00328 V[i][k] = 0.0;
00329
00330 V[k][k] = 1.0;
00331 }
00332 }
00333
00334
00335
00336
00337 pp = p - 1;
00338 iter = 0;
00339 eps = pow (2.0, -52.0);
00340
00341 while (p > 0) {
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356 for (k = p - 2; k >= -1; k--) {
00357 if (k == -1)
00358 break;
00359
00360 if (fabs (e[k]) <= eps * (fabs (s[k]) + fabs (s[k + 1]))) {
00361 e[k] = 0.0;
00362 break;
00363 }
00364 }
00365
00366 if (k == p - 2)
00367 kase = 4;
00368
00369 else {
00370 for (ks = p - 1; ks >= k; ks--) {
00371 if (ks == k)
00372 break;
00373
00374 t =
00375 (ks != p ? fabs (e[ks]) : 0.) + (ks !=
00376 k + 1 ? fabs (e[ks - 1]) : 0.);
00377 if (fabs (s[ks]) <= eps * t) {
00378 s[ks] = 0.0;
00379 break;
00380 }
00381 }
00382 if (ks == k)
00383 kase = 3;
00384 else if (ks == p - 1)
00385 kase = 1;
00386 else {
00387 kase = 2;
00388 k = ks;
00389 }
00390 }
00391 k++;
00392
00393
00394
00395 switch (kase) {
00396
00397
00398 case 1:{
00399 f = e[p - 2];
00400 e[p - 2] = 0.;
00401 for (j = p - 2; j >= k; j--) {
00402 t = sqrt (s[j] * s[j] + f * f);
00403 cs = s[j] / t;
00404 sn = f / t;
00405 s[j] = t;
00406 if (j != k) {
00407 f = -sn * e[j - 1];
00408 e[j - 1] = cs * e[j - 1];
00409 }
00410 if (wantv) {
00411 for (i = 0; i < n; i++) {
00412 t = cs * V[i][j] + sn * V[i][p - 1];
00413 V[i][p - 1] = -sn * V[i][j] + cs * V[i][p - 1];
00414 V[i][j] = t;
00415 }
00416 }
00417 }
00418 }
00419 break;
00420
00421
00422
00423 case 2:{
00424 f = e[k - 1];
00425 e[k - 1] = 0.0;
00426 for (j = k; j < p; j++) {
00427 t = sqrt (s[j] * s[j] + f * f);
00428 cs = s[j] / t;
00429 sn = f / t;
00430 s[j] = t;
00431 f = -sn * e[j];
00432 e[j] = cs * e[j];
00433 if (wantu) {
00434 for (i = 0; i < m; i++) {
00435 t = cs * U[i][j] + sn * U[i][k - 1];
00436 U[i][k - 1] = -sn * U[i][j] + cs * U[i][k - 1];
00437 U[i][j] = t;
00438 }
00439 }
00440 }
00441 }
00442 break;
00443
00444
00445
00446 case 3:{
00447
00448
00449 scale =
00450 maxx (maxx
00451 (maxx
00452 (maxx (fabs (s[p - 1]), fabs (s[p - 2])), fabs (e[p - 2])),
00453 fabs (s[k])), fabs (e[k]));
00454
00455 sp = s[p - 1] / scale;
00456 spm1 = s[p - 2] / scale;
00457 epm1 = e[p - 2] / scale;
00458 sk = s[k] / scale;
00459 ek = e[k] / scale;
00460 b = ((spm1 + sp) * (spm1 - sp) + epm1 * epm1) / 2.0;
00461 c = (sp * epm1) * (sp * epm1);
00462 shift = 0.;
00463 if (b || c) {
00464 shift = sqrt (b * b + c);
00465 if (b < 0.0)
00466 shift = -shift;
00467
00468 shift = c / (b + shift);
00469 }
00470 f = (sk + sp) * (sk - sp) + shift;
00471 g = sk * ek;
00472
00473
00474
00475 for (j = k; j < p - 1; j++) {
00476 t = sqrt (f * f + g * g);
00477 cs = f / t;
00478 sn = g / t;
00479 if (j != k)
00480 e[j - 1] = t;
00481
00482 f = cs * s[j] + sn * e[j];
00483 e[j] = cs * e[j] - sn * s[j];
00484 g = sn * s[j + 1];
00485 s[j + 1] = cs * s[j + 1];
00486 if (wantv) {
00487 for (i = 0; i < n; i++) {
00488 t = cs * V[i][j] + sn * V[i][j + 1];
00489 V[i][j + 1] = -sn * V[i][j] + cs * V[i][j + 1];
00490 V[i][j] = t;
00491 }
00492 }
00493 t = sqrt (f * f + g * g);
00494 cs = f / t;
00495 sn = g / t;
00496 s[j] = t;
00497 f = cs * e[j] + sn * s[j + 1];
00498 s[j + 1] = -sn * e[j] + cs * s[j + 1];
00499 g = sn * e[j + 1];
00500 e[j + 1] = cs * e[j + 1];
00501 if (wantu && (j < m - 1)) {
00502 for (i = 0; i < m; i++) {
00503 t = cs * U[i][j] + sn * U[i][j + 1];
00504 U[i][j + 1] = -sn * U[i][j] + cs * U[i][j + 1];
00505 U[i][j] = t;
00506 }
00507 }
00508 }
00509 e[p - 2] = f;
00510 iter = iter + 1;
00511 }
00512
00513 break;
00514
00515
00516
00517 case 4:{
00518
00519
00520
00521 if (s[k] <= 0.0) {
00522 s[k] = (s[k] < 0.0 ? -s[k] : 0.0);
00523 if (wantv)
00524 for (i = 0; i <= pp; i++)
00525 V[i][k] = -V[i][k];
00526 }
00527
00528
00529
00530 while (k < pp) {
00531 if (s[k] >= s[k + 1])
00532 break;
00533
00534 t = s[k];
00535 s[k] = s[k + 1];
00536 s[k + 1] = t;
00537
00538 if (wantv && (k < n - 1)) {
00539 for (i = 0; i < n; i++)
00540 {
00541 t = V[i][k + 1];
00542 V[i][k + 1] = V[i][k];
00543 V[i][k] = t;
00544 }
00545 }
00546
00547 if (wantu && (k < m - 1)) {
00548 for (i = 0; i < m; i++)
00549 {
00550 t = U[i][k + 1];
00551 U[i][k + 1] = U[i][k];
00552 U[i][k] = t;
00553 }
00554 }
00555
00556 k++;
00557 }
00558 iter = 0;
00559 p--;
00560 }
00561 break;
00562 }
00563 }
00564
00565 vec_delete (e);
00566 vec_delete (work);
00567
00568 return (s);
00569 }
00570
00571
00572
00573
00574
00575
00576 int mat_rank (mat a)
00577 {
00578 int i, r = 0;
00579 double eps = pow (2., -52.);
00580 double tol;
00581 vec s = mat_svd (a, NULL, NULL);
00582
00583 tol = (double) (mat_height (a) >
00584 mat_width (a) ? mat_height (a) : mat_width (a)) * s[0] * eps;
00585
00586 for (i = 0; i < vec_length (s); i++)
00587 if (s[i] > tol)
00588 r++;
00589
00590 vec_delete (s);
00591
00592 return (r);
00593 }
00594
00595
00596
00597
00598
00599 double mat_cond (mat a)
00600 {
00601 double cond;
00602 vec s = mat_svd (a, NULL, NULL);
00603
00604 cond =
00605 s[0] / s[mat_height (a) >
00606 mat_width (a) ? mat_width (a) - 1 : mat_height (a) - 1];
00607
00608 vec_delete (s);
00609
00610 return (cond);
00611
00612 }
00613
00614
00615
00616
00617
00618 double mat_norm2 (mat a)
00619 {
00620
00621 double norm2;
00622 vec s = mat_svd (a, NULL, NULL);
00623
00624 norm2 = s[0];
00625
00626 vec_delete (s);
00627
00628 return (norm2);
00629
00630 }
00631
00632 static mat mat_tridiag (vec e, vec d, mat evec)
00633 {
00634
00635 int i, j, k, n;
00636 double scale, f, g, h, hh;
00637
00638 it_assert (mat_width (evec) == mat_height (evec), "Matrix must be square");
00639
00640 n = mat_height (evec);
00641
00642 vec_zeros (e);
00643
00644 for (j = 0; j < n; j++)
00645 d[j] = evec[n - 1][j];
00646
00647
00648
00649 for (i = n - 1; i > 0; i--) {
00650
00651
00652 scale = 0.0;
00653 h = 0.0;
00654
00655 for (k = 0; k < i; k++)
00656 scale += fabs (d[k]);
00657
00658 if (!scale) {
00659 e[i] = d[i - 1];
00660 for (j = 0; j < i; j++) {
00661 d[j] = evec[i - 1][j];
00662 evec[i][j] = 0.0;
00663 evec[j][i] = 0.0;
00664 }
00665 }
00666 else {
00667
00668
00669 for (k = 0; k < i; k++) {
00670 d[k] /= scale;
00671 h += d[k] * d[k];
00672 }
00673 f = d[i - 1];
00674 g = sqrt (h);
00675 if (f > 0)
00676 g = -g;
00677
00678 e[i] = scale * g;
00679 h = h - f * g;
00680 d[i - 1] = f - g;
00681 for (j = 0; j < i; j++)
00682 e[j] = 0.0;
00683
00684
00685
00686 for (j = 0; j < i; j++) {
00687 f = d[j];
00688 evec[j][i] = f;
00689 g = e[j] + evec[j][j] * f;
00690 for (k = j + 1; k <= i - 1; k++) {
00691 g += evec[k][j] * d[k];
00692 e[k] += evec[k][j] * f;
00693 }
00694 e[j] = g;
00695 }
00696 f = 0.0;
00697 for (j = 0; j < i; j++) {
00698 e[j] /= h;
00699 f += e[j] * d[j];
00700 }
00701 hh = f / (h + h);
00702 for (j = 0; j < i; j++)
00703 e[j] -= hh * d[j];
00704
00705 for (j = 0; j < i; j++) {
00706 f = d[j];
00707 g = e[j];
00708 for (k = j; k <= i - 1; k++)
00709 evec[k][j] -= (f * e[k] + g * d[k]);
00710
00711 d[j] = evec[i - 1][j];
00712 evec[i][j] = 0.0;
00713 }
00714 }
00715 d[i] = h;
00716 }
00717
00718
00719
00720 for (i = 0; i < n - 1; i++) {
00721 evec[n - 1][i] = evec[i][i];
00722 evec[i][i] = 1.0;
00723 h = d[i + 1];
00724 if (h != 0.0) {
00725 for (k = 0; k <= i; k++)
00726 d[k] = evec[k][i + 1] / h;
00727
00728 for (j = 0; j <= i; j++) {
00729 g = 0.0;
00730 for (k = 0; k <= i; k++)
00731 g += evec[k][i + 1] * evec[k][j];
00732
00733 for (k = 0; k <= i; k++)
00734 evec[k][j] -= g * d[k];
00735
00736 }
00737 }
00738
00739 for (k = 0; k <= i; k++)
00740 evec[k][i + 1] = 0.0;
00741
00742 }
00743 for (j = 0; j < n; j++) {
00744 d[j] = evec[n - 1][j];
00745 evec[n - 1][j] = 0.0;
00746 }
00747 evec[n - 1][n - 1] = 1.0;
00748 e[0] = 0.0;
00749
00750 return (evec);
00751
00752 }
00753
00754
00755
00756 static vec mat_tridiag_ql (vec e, vec d, mat evec)
00757 {
00758 int i, j, k, l, m, n, iter;
00759 double f, tst1, eps, p, g, r, el1, dl1, h, c, c2, c3, s, s2;
00760
00761 n = mat_height (evec);
00762
00763 for (i = 1; i < n; i++)
00764 e[i - 1] = e[i];
00765
00766 e[n - 1] = 0.0;
00767
00768 f = 0.0;
00769 tst1 = 0.0;
00770 eps = pow (2.0, -52.0);
00771
00772 for (l = 0; l < n; l++) {
00773
00774
00775 tst1 =
00776 tst1 > fabs (d[l]) + fabs (e[l]) ? tst1 : fabs (d[l]) + fabs (e[l]);
00777 m = l;
00778
00779 while (m < n) {
00780 if (fabs (e[m]) <= eps * tst1)
00781 break;
00782
00783 m++;
00784 }
00785
00786
00787
00788
00789
00790
00791 if (m > l) {
00792 iter = 0;
00793
00794 do {
00795 iter++;
00796
00797
00798
00799 g = d[l];
00800 p = (d[l + 1] - g) / (2.0 * e[l]);
00801 r = sqrt (p * p + 1.);
00802 if (p < 0)
00803 r = -r;
00804
00805 d[l] = e[l] / (p + r);
00806 d[l + 1] = e[l] * (p + r);
00807 dl1 = d[l + 1];
00808 h = g - d[l];
00809 for (i = l + 2; i < n; i++)
00810 d[i] -= h;
00811
00812 f = f + h;
00813
00814
00815
00816 p = d[m];
00817 c = 1.0;
00818 c2 = c;
00819 c3 = c;
00820 el1 = e[l + 1];
00821 s = 0.0;
00822 s2 = 0.0;
00823
00824 for (i = m - 1; i >= l; i--) {
00825 c3 = c2;
00826 c2 = c;
00827 s2 = s;
00828 g = c * e[i];
00829 h = c * p;
00830 r = sqrt (p * p + e[i] * e[i]);
00831 e[i + 1] = s * r;
00832 s = e[i] / r;
00833 c = p / r;
00834 p = c * d[i] - s * g;
00835 d[i + 1] = h + s * (c * g + s * d[i]);
00836
00837
00838
00839 for (k = 0; k < n; k++) {
00840 h = evec[k][i + 1];
00841 evec[k][i + 1] = s * evec[k][i] + c * h;
00842 evec[k][i] = c * evec[k][i] - s * h;
00843 }
00844 }
00845 p = -s * s2 * c3 * el1 * e[l] / dl1;
00846 e[l] = s * p;
00847 d[l] = c * p;
00848
00849
00850
00851 } while (fabs (e[l]) > eps * tst1);
00852 }
00853 d[l] = d[l] + f;
00854 e[l] = 0.0;
00855 }
00856
00857
00858
00859 for (i = 0; i < n - 1; i++) {
00860 k = i;
00861 p = d[i];
00862
00863 for (j = i + 1; j < n; j++)
00864 if (d[j] < p) {
00865 k = j;
00866 p = d[j];
00867 }
00868
00869 if (k != i) {
00870 d[k] = d[i];
00871 d[i] = p;
00872 for (j = 0; j < n; j++) {
00873 p = evec[j][i];
00874 evec[j][i] = evec[j][k];
00875 evec[j][k] = p;
00876 }
00877 }
00878 }
00879
00880 return (d);
00881 }
00882
00883
00884
00885
00886
00887
00888
00889 mat mat_hessenberg (mat a, mat V)
00890 {
00891
00892 int i, j, m, n;
00893 int low = 0, high;
00894 double scale, f, g, h;
00895 mat H;
00896 vec ort;
00897
00898 it_assert (mat_height (a) == mat_width (a), "Matrix must be square");
00899
00900 it_assert (mat_height (V) == mat_width (V),
00901 "Transformation matrix must be square");
00902
00903 it_assert (mat_width (a) == mat_width (V),
00904 "Matrices must have same dimensions");
00905
00906 H = mat_clone (a);
00907
00908 n = mat_height (a);
00909
00910 mat_zeros (V);
00911 ort = vec_new_zeros (n);
00912
00913 high = n - 1;
00914
00915 for (m = low + 1; m <= high - 1; m++) {
00916
00917
00918
00919 scale = 0.0;
00920 for (i = m; i <= high; i++)
00921 scale = scale + fabs (H[i][m - 1]);
00922
00923 if (scale) {
00924
00925
00926 h = 0.0;
00927 for (i = high; i >= m; i--) {
00928 ort[i] = H[i][m - 1] / scale;
00929 h += ort[i] * ort[i];
00930 }
00931 g = sqrt (h);
00932
00933 if (ort[m] > 0)
00934 g = -g;
00935
00936 h = h - ort[m] * g;
00937 ort[m] = ort[m] - g;
00938
00939
00940
00941
00942
00943
00944 for (j = m; j < n; j++) {
00945 f = 0.0;
00946 for (i = high; i >= m; i--)
00947 f += ort[i] * H[i][j];
00948
00949 f /= h;
00950
00951 for (i = m; i <= high; i++)
00952 H[i][j] -= f * ort[i];
00953 }
00954
00955 for (i = 0; i <= high; i++) {
00956 f = 0.0;
00957 for (j = high; j >= m; j--)
00958 f += ort[j] * H[i][j];
00959
00960 f /= h;
00961
00962 for (j = m; j <= high; j++)
00963 H[i][j] -= f * ort[j];
00964
00965 }
00966 ort[m] = scale * ort[m];
00967 H[m][m - 1] = scale * g;
00968
00969 }
00970 }
00971
00972
00973
00974 for (i = 0; i < n; i++)
00975 for (j = 0; j < n; j++)
00976 V[i][j] = (i == j ? 1.0 : 0.0);
00977
00978 for (m = high - 1; m >= low + 1; m--) {
00979 if (H[m][m - 1]) {
00980 for (i = m + 1; i <= high; i++)
00981 ort[i] = H[i][m - 1];
00982
00983 for (j = m; j <= high; j++) {
00984 g = 0.0;
00985 for (i = m; i <= high; i++)
00986 g += ort[i] * V[i][j];
00987
00988
00989 g = (g / ort[m]) / H[m][m - 1];
00990 for (i = m; i <= high; i++)
00991 V[i][j] += g * ort[i];
00992 }
00993 }
00994 }
00995
00996 vec_delete (ort);
00997
00998 return (H);
00999
01000 }
01001
01002 static cvec mat_h2rs (mat H, mat evec)
01003 {
01004
01005 int nn, n, low, high;
01006 int i, j, k, l, m, mmax, mmin, iter, notlast;
01007 double eps;
01008 double exshift = 0.0;
01009 double p = 0, q = 0, r = 0, s = 0, z = 0, t, w, x, y;
01010 double norm = 0.0;
01011 double ra, sa, vr, vi;
01012 double cdivr, cdivi;
01013 cvec eval;
01014 vec e, d;
01015
01016 it_assert (mat_width (H) == mat_height (H), "Matrix must be square");
01017
01018 nn = mat_height (H);
01019 n = nn - 1;
01020 low = 0;
01021 high = nn - 1;
01022 eps = pow (2.0, -52.0);
01023
01024 e = vec_new_zeros (nn);
01025 d = vec_new_zeros (nn);
01026
01027 eval = cvec_new_zeros (nn);
01028
01029
01030
01031
01032
01033 for (i = 0; i < nn; i++) {
01034 if (i < low || i > high) {
01035 d[i] = H[i][i];
01036 e[i] = 0.0;
01037 }
01038
01039 mmax = i - 1 > 0 ? i - 1 : 0;
01040
01041 for (j = mmax; j < nn; j++)
01042 norm += fabs (H[i][j]);
01043
01044 }
01045
01046
01047
01048 iter = 0;
01049
01050 while (n >= low) {
01051
01052
01053
01054 l = n;
01055
01056 while (l > low) {
01057 s = fabs (H[l - 1][l - 1]) + fabs (H[l][l]);
01058
01059 if (!s)
01060 s = norm;
01061
01062 if (fabs (H[l][l - 1]) < eps * s)
01063 break;
01064
01065 l--;
01066 }
01067
01068
01069
01070
01071 if (l == n) {
01072 H[n][n] += exshift;
01073 d[n] = H[n][n];
01074 e[n] = 0.0;
01075 n--;
01076 iter = 0;
01077
01078
01079
01080 }
01081 else if (l == n - 1) {
01082 w = H[n][n - 1] * H[n - 1][n];
01083 p = (H[n - 1][n - 1] - H[n][n]) / 2.;
01084 q = p * p + w;
01085 z = sqrt (fabs (q));
01086 H[n][n] += exshift;
01087 H[n - 1][n - 1] += exshift;
01088 x = H[n][n];
01089
01090
01091
01092 if (q >= 0) {
01093 if (p >= 0)
01094 z = p + z;
01095 else
01096 z = p - z;
01097
01098 d[n - 1] = x + z;
01099 d[n] = d[n - 1];
01100 if (z)
01101 d[n] = x - w / z;
01102
01103 e[n - 1] = 0.0;
01104 e[n] = 0.0;
01105 x = H[n][n - 1];
01106 s = fabs (x) + fabs (z);
01107 p = x / s;
01108 q = z / s;
01109 r = sqrt (p * p + q * q);
01110 p /= r;
01111 q /= r;
01112
01113
01114
01115 for (j = n - 1; j < nn; j++) {
01116 z = H[n - 1][j];
01117 H[n - 1][j] = q * z + p * H[n][j];
01118 H[n][j] = q * H[n][j] - p * z;
01119 }
01120
01121
01122
01123 for (i = 0; i <= n; i++) {
01124 z = H[i][n - 1];
01125 H[i][n - 1] = q * z + p * H[i][n];
01126 H[i][n] = q * H[i][n] - p * z;
01127 }
01128
01129
01130
01131 for (i = low; i <= high; i++) {
01132 z = evec[i][n - 1];
01133 evec[i][n - 1] = q * z + p * evec[i][n];
01134 evec[i][n] = q * evec[i][n] - p * z;
01135 }
01136
01137
01138
01139 }
01140 else {
01141 d[n - 1] = x + p;
01142 d[n] = x + p;
01143 e[n - 1] = z;
01144 e[n] = -z;
01145 }
01146
01147 n -= 2;
01148 iter = 0;
01149
01150
01151
01152 }
01153 else {
01154
01155
01156 x = H[n][n];
01157 y = 0.0;
01158 w = 0.0;
01159 if (l < n) {
01160 y = H[n - 1][n - 1];
01161 w = H[n][n - 1] * H[n - 1][n];
01162 }
01163
01164
01165
01166 if (iter == 10) {
01167 exshift += x;
01168 for (i = low; i <= n; i++)
01169 H[i][i] -= x;
01170
01171 s = fabs (H[n][n - 1]) + fabs (H[n - 1][n - 2]);
01172 x = y = 0.75 * s;
01173 w = -0.4375 * s * s;
01174 }
01175
01176
01177
01178 if (iter == 30) {
01179 s = (y - x) / 2.0;
01180 s = s * s + w;
01181 if (s > 0) {
01182 s = sqrt (s);
01183 if (y < x)
01184 s = -s;
01185 s = x - w / ((y - x) / 2. + s);
01186 for (i = low; i <= n; i++)
01187 H[i][i] -= s;
01188 exshift += s;
01189 x = y = w = 0.964;
01190 }
01191 }
01192
01193 iter++;
01194
01195
01196
01197 m = n - 2;
01198 while (m >= l) {
01199 z = H[m][m];
01200 r = x - z;
01201 s = y - z;
01202 p = (r * s - w) / H[m + 1][m] + H[m][m + 1];
01203 q = H[m + 1][m + 1] - z - r - s;
01204 r = H[m + 2][m + 1];
01205 s = fabs (p) + fabs (q) + fabs (r);
01206 p /= s;
01207 q /= s;
01208 r /= s;
01209 if (m == l)
01210 break;
01211
01212 if (fabs (H[m][m - 1]) * (fabs (q) + fabs (r)) <
01213 eps * (fabs (p) *
01214 (fabs (H[m - 1][m - 1]) + fabs (z) +
01215 fabs (H[m + 1][m + 1]))))
01216 break;
01217
01218 m--;
01219 }
01220
01221 for (i = m + 2; i <= n; i++) {
01222 H[i][i - 2] = 0.;
01223 if (i > m + 2)
01224 H[i][i - 3] = 0.;
01225 }
01226
01227
01228
01229 for (k = m; k <= n - 1; k++) {
01230 notlast = (k != n - 1);
01231 if (k != m) {
01232 p = H[k][k - 1];
01233 q = H[k + 1][k - 1];
01234 r = (notlast ? H[k + 2][k - 1] : 0.);
01235 x = fabs (p) + fabs (q) + fabs (r);
01236 if (x) {
01237 p /= x;
01238 q /= x;
01239 r /= x;
01240 }
01241 }
01242
01243 if (!x)
01244 break;
01245
01246 s = sqrt (p * p + q * q + r * r);
01247 if (p < 0)
01248 s = -s;
01249
01250 if (s) {
01251 if (k != m)
01252 H[k][k - 1] = -s * x;
01253 else if (l != m)
01254 H[k][k - 1] = -H[k][k - 1];
01255
01256 p += s;
01257 x = p / s;
01258 y = q / s;
01259 z = r / s;
01260 q /= p;
01261 r /= p;
01262
01263
01264
01265 for (j = k; j < nn; j++) {
01266 p = H[k][j] + q * H[k + 1][j];
01267 if (notlast) {
01268 p = p + r * H[k + 2][j];
01269 H[k + 2][j] = H[k + 2][j] - p * z;
01270 }
01271 H[k][j] = H[k][j] - p * x;
01272 H[k + 1][j] = H[k + 1][j] - p * y;
01273 }
01274
01275
01276
01277 mmin = n < k + 3 ? n : k + 3;
01278
01279 for (i = 0; i <= mmin; i++) {
01280 p = x * H[i][k] + y * H[i][k + 1];
01281 if (notlast) {
01282 p += z * H[i][k + 2];
01283 H[i][k + 2] -= p * r;
01284 }
01285 H[i][k] -= p;
01286 H[i][k + 1] -= p * q;
01287 }
01288
01289
01290
01291 for (i = low; i <= high; i++) {
01292 p = x * evec[i][k] + y * evec[i][k + 1];
01293 if (notlast) {
01294 p += z * evec[i][k + 2];
01295 evec[i][k + 2] -= p * r;
01296 }
01297 evec[i][k] -= p;
01298 evec[i][k + 1] -= p * q;
01299 }
01300
01301 }
01302 }
01303 }
01304 }
01305
01306
01307
01308
01309 if (!norm)
01310 return (eval);
01311
01312 for (n = nn - 1; n >= 0; n--) {
01313 p = d[n];
01314 q = e[n];
01315
01316
01317
01318 if (!q) {
01319 l = n;
01320 H[n][n] = 1.;
01321 for (i = n - 1; i >= 0; i--) {
01322 w = H[i][i] - p;
01323 r = 0.;
01324 for (j = l; j <= n; j++)
01325 r += H[i][j] * H[j][n];
01326
01327 if (e[i] < 0.0) {
01328 z = w;
01329 s = r;
01330 }
01331 else {
01332 l = i;
01333 if (!e[i]) {
01334 if (w != 0.0)
01335 H[i][n] = -r / w;
01336 else
01337 H[i][n] = -r / (eps * norm);
01338
01339
01340
01341 }
01342 else {
01343 x = H[i][i + 1];
01344 y = H[i + 1][i];
01345 q = (d[i] - p) * (d[i] - p) + e[i] * e[i];
01346 t = (x * s - z * r) / q;
01347 H[i][n] = t;
01348 if (fabs (x) > fabs (z))
01349 H[i + 1][n] = (-r - w * t) / x;
01350 else
01351 H[i + 1][n] = (-s - y * t) / z;
01352 }
01353
01354
01355
01356 t = fabs (H[i][n]);
01357 if ((eps * t) * t > 1)
01358 for (j = i; j <= n; j++)
01359 H[j][n] /= t;
01360 }
01361 }
01362
01363
01364
01365 }
01366 else if (q < 0) {
01367 l = n - 1;
01368
01369
01370
01371 if (fabs (H[n][n - 1]) > fabs (H[n - 1][n])) {
01372 H[n - 1][n - 1] = q / H[n][n - 1];
01373 H[n - 1][n] = -(H[n][n] - p) / H[n][n - 1];
01374 }
01375 else {
01376 ccdiv (0.0, -H[n - 1][n], H[n - 1][n - 1] - p, q, &cdivr, &cdivi);
01377 H[n - 1][n - 1] = cdivr;
01378 H[n - 1][n] = cdivi;
01379 }
01380 H[n][n - 1] = 0.;
01381 H[n][n] = 1.;
01382 for (i = n - 2; i >= 0; i--) {
01383 ra = 0.0;
01384 sa = 0.0;
01385 for (j = l; j <= n; j++) {
01386 ra += H[i][j] * H[j][n - 1];
01387 sa += H[i][j] * H[j][n];
01388 }
01389 w = H[i][i] - p;
01390
01391 if (e[i] < 0.0) {
01392 z = w;
01393 r = ra;
01394 s = sa;
01395 }
01396 else {
01397 l = i;
01398 if (e[i]) {
01399 ccdiv (-ra, -sa, w, q, &cdivr, &cdivi);
01400 H[i][n - 1] = cdivr;
01401 H[i][n] = cdivi;
01402 }
01403 else {
01404
01405
01406
01407 x = H[i][i + 1];
01408 y = H[i + 1][i];
01409 vr = (d[i] - p) * (d[i] - p) + e[i] * e[i] - q * q;
01410 vi = (d[i] - p) * 2.0 * q;
01411 if (!vr && !vi)
01412 vr =
01413 eps * norm * (fabs (w) + fabs (q) + fabs (x) + fabs (y) +
01414 fabs (z));
01415
01416 ccdiv (x * r - z * ra + q * sa, x * s - z * sa - q * ra, vr, vi,
01417 &cdivr, &cdivi);
01418 H[i][n - 1] = cdivr;
01419 H[i][n] = cdivi;
01420 if (fabs (x) > (fabs (z) + fabs (q))) {
01421 H[i + 1][n - 1] = (-ra - w * H[i][n - 1] + q * H[i][n]) / x;
01422 H[i + 1][n] = (-sa - w * H[i][n] - q * H[i][n - 1]) / x;
01423 }
01424 else {
01425 ccdiv (-r - y * H[i][n - 1], -s - y * H[i][n], z, q, &cdivr,
01426 &cdivi);
01427 H[i + 1][n - 1] = cdivr;
01428 H[i + 1][n] = cdivi;
01429 }
01430 }
01431
01432
01433
01434 t =
01435 fabs (H[i][n - 1]) >
01436 fabs (H[i][n]) ? fabs (H[i][n - 1]) : fabs (H[i][n]);
01437
01438 if ((eps * t) * t > 1.)
01439 for (j = i; j <= n; j++) {
01440 H[j][n - 1] /= t;
01441 H[j][n] /= t;
01442 }
01443 }
01444 }
01445 }
01446 }
01447
01448
01449
01450 for (i = 0; i < nn; i++)
01451 if (i < low || i > high)
01452 for (j = i; j < nn; j++)
01453 evec[i][j] = H[i][j];
01454
01455
01456
01457 for (j = nn - 1; j >= low; j--) {
01458 for (i = low; i <= high; i++) {
01459 z = 0.;
01460
01461 mmin = j < high ? j : high;
01462
01463 for (k = low; k <= mmin; k++)
01464 z += evec[i][k] * H[k][j];
01465 evec[i][j] = z;
01466 }
01467 }
01468
01469 for (i = 0; i < vec_length (d); i++) {
01470 creal (eval[i]) = d[i];
01471 cimag (eval[i]) = e[i];
01472 }
01473
01474 vec_delete (e);
01475 vec_delete (d);
01476
01477 return (eval);
01478
01479 }
01480
01481
01482
01483
01484
01485
01486
01487
01488 vec mat_eig_sym (mat a, mat evec)
01489 {
01490
01491 int i, j;
01492 vec e, d;
01493
01494 it_assert (mat_width (a) == mat_height (a), "Matrix must be square");
01495 it_assert (evec != NULL,
01496 "Memory for matrix of eigenvectors must be reserved");
01497 it_assert (mat_width (evec) == mat_height (evec),
01498 "Matrix of eigenvectors must be square");
01499 it_assert (mat_width (evec) == mat_width (a),
01500 "Matrices dimensions must agree");
01501
01502 e = vec_new_zeros (mat_width (a));
01503 d = vec_new_zeros (mat_width (a));
01504
01505 for (i = 0; i < mat_height (a); i++)
01506 for (j = 0; j < mat_width (a); j++)
01507 evec[i][j] = a[i][j];
01508
01509 mat_tridiag (e, d, evec);
01510 mat_tridiag_ql (e, d, evec);
01511
01512 vec_delete (e);
01513
01514 return (d);
01515 }
01516
01517
01518
01519
01520
01521
01522
01523
01524
01525 cvec mat_eig (mat a, cmat evec)
01526 {
01527
01528 int i, j, n;
01529 cvec eval;
01530 mat h, V;
01531 double z;
01532
01533 it_assert (mat_width (a) == mat_height (a), "Matrix must be square");
01534 it_assert (evec != NULL,
01535 "Memory for matrix of eigenvectors must be reserved");
01536 it_assert (cmat_width (evec) == cmat_height (evec),
01537 "Matrix of eigenvectors must be square");
01538 it_assert (cmat_width (evec) == mat_width (a),
01539 "Matrices dimensions must agree");
01540
01541 V = mat_clone (a);
01542
01543 n = mat_width (a);
01544
01545 h = mat_hessenberg (a, V);
01546 eval = mat_h2rs (h, V);
01547 mat_delete (h);
01548
01549
01550
01551 for (j = 0; j < n; j++) {
01552 if (cimag (eval[j])) {
01553
01554 z = 0.;
01555
01556 for (i = 0; i < n; i++) {
01557 creal (evec[i][j]) = creal (evec[i][j + 1]) = V[i][j];
01558 cimag (evec[i][j]) = V[i][j + 1];
01559 cimag (evec[i][j + 1]) = -V[i][j + 1];
01560 z +=
01561 creal (evec[i][j]) * creal (evec[i][j]) +
01562 cimag (evec[i][j]) * cimag (evec[i][j]);
01563 }
01564
01565 z = 1. / sqrt (z);
01566
01567 for (i = 0; i < n; i++) {
01568 creal (evec[i][j]) *= z;
01569 cimag (evec[i][j]) *= z;
01570 creal (evec[i][j + 1]) *= z;
01571 cimag (evec[i][j + 1]) *= z;
01572 }
01573
01574 j++;
01575 }
01576 else {
01577
01578 z = 0.;
01579
01580 for (i = 0; i < n; i++) {
01581 cimag (evec[i][j]) = 0.;
01582 creal (evec[i][j]) = V[i][j];
01583 z += V[i][j] * V[i][j];
01584 }
01585
01586 z = 1. / sqrt (z);
01587
01588
01589 if (V[0][j] < 0.)
01590 z = -z;
01591
01592 for (i = 0; i < n; i++)
01593 creal (evec[i][j]) *= z;
01594
01595 }
01596
01597 }
01598
01599 mat_delete (V);
01600
01601 return (eval);
01602
01603 }
01604
01605
01606
01607
01608
01609 mat mat_real_schur (mat a)
01610 {
01611 mat h, e;
01612 cvec eval;
01613
01614 it_assert (mat_height (a) == mat_width (a), "Matrix must be square");
01615
01616 e = mat_new_zeros (mat_height (a), mat_width (a));
01617
01618 h = mat_hessenberg (a, e);
01619 eval = mat_h2rs (h, e);
01620
01621 cvec_delete (eval);
01622 mat_delete (e);
01623
01624 return (h);
01625 }
01626
01627 double mat_lu( mat a, ivec piv )
01628 {
01629
01630 idx_t i = 0;
01631 idx_t j = 0;
01632 idx_t k = 0;
01633 idx_t pi = 0;
01634 idx_t xp, yp;
01635 idx_t t = 0;
01636
01637 int pivsign = 1;
01638
01639 size_t n, m, p;
01640
01641 double max = 0.0;
01642 double eps = IT_EPSILON*IT_EPSILON;
01643
01644 it_assert( a, "Please use an existing matrix" );
01645 it_assert( pc, "Please use an existing pc vector" );
01646 it_assert( pr, "Please use an existing pr vector" );
01647 it_assert( ivec_length( piv ) == mat_height( a ), "Vector piv must have matrix height size" );
01648
01649 m = mat_height( a );
01650 n = mat_width( a );
01651
01652 for ( i= 0; i< ivec_length( piv ); i++ )
01653 piv[i] = i;
01654
01655 p = (n<=m)?n:m;
01656
01657
01658 for ( k= 0; k< p; k++ )
01659 {
01660
01661 max = a[k][k];
01662 xp = yp = k;
01663
01664 for ( i= k; i< m; i++ )
01665 if ( fabs(max) < fabs( a[i][k] ) )
01666 {
01667 max = a[i][k];
01668 yp = i;
01669 }
01670
01671 if ( fabs(max) > eps )
01672 {
01673
01674 if ( yp!=k )
01675 {
01676 mat_swap_rows( a, yp, k );
01677
01678
01679 t = piv[yp];
01680 piv[yp] = piv[k];
01681 piv[k] = t;
01682
01683 pivsign = -pivsign;
01684
01685 }
01686
01687
01688
01689 for ( j= k; j< n; j++ )
01690 for ( pi= 0; pi< k; pi++ )
01691 a[k][j] -= a[k][pi]*a[pi][j];
01692
01693
01694 for ( i= k+1; i< m; i++ )
01695 {
01696 for ( pi= 0; pi< k; pi++ )
01697 a[i][k] -= a[i][pi]*a[pi][k];
01698 a[i][k] /= a[k][k];
01699 }
01700
01701 }
01702 else
01703 {
01704 it_warning( "Matrix is singular" );
01705 return( 0. );
01706 }
01707
01708 }
01709
01710
01711 max = (double)pivsign;
01712
01713 for ( i= 0; i< n; i++ )
01714 max *= a[i][i];
01715
01716 return( max );
01717
01718 }
01719
01720
01721
01722 double mat_det (mat a)
01723 {
01724 double det = 0.;
01725 ivec piv;
01726 mat lu = mat_clone (a);
01727
01728 piv = ivec_new_zeros (mat_height (a));
01729
01730
01731 det = mat_lu (lu, piv );
01732
01733 ivec_delete (piv);
01734 mat_delete (lu);
01735
01736 return (det);
01737 }
01738
01739
01740
01741 vec mat_solve_vec (mat A, vec b)
01742 {
01743 size_t m, n;
01744 idx_t i, k;
01745 ivec piv;
01746 mat LU;
01747 vec X;
01748
01749 m = mat_height( A );
01750 n = mat_width( A );
01751
01752 it_assert( m==vec_length(b), "Matrices size mismatch" );
01753
01754 piv = ivec_new( m );
01755 LU = mat_clone( A );
01756
01757 if ( !mat_lu( LU, piv ) )
01758 {
01759 it_warning( "Matrix is singular, aborting" );
01760 ivec_delete( piv );
01761 mat_delete( LU );
01762 return( NULL );
01763 }
01764
01765 X = vec_new( ivec_length(piv) );
01766
01767 for ( i= 0; i< ivec_length(piv); i++ )
01768 X[i] = b[piv[i]];
01769
01770 for ( k= 0; k< n; k++ )
01771 for ( i= k+1; i< n; i++ )
01772 X[i] -= X[k]*LU[i][k];
01773
01774 for ( k= n-1; k >= 0; k-- )
01775 {
01776 X[k] /= LU[k][k];
01777
01778 for ( i= 0; i< k; i++ )
01779 X[i] -= X[k]*LU[i][k];
01780 }
01781
01782 ivec_delete( piv );
01783 mat_delete( LU );
01784
01785 return( X );
01786 }
01787
01788
01789
01790
01791
01792
01793 mat mat_solve_mat( mat A, mat B )
01794 {
01795 size_t m, n, nx;
01796 ivec piv;
01797 idx_t i, j, k;
01798 mat LU, X;
01799
01800 m = mat_height( A );
01801 n = mat_width( A );
01802 nx = mat_width( B );
01803
01804 it_assert( m==mat_height(B), "Matrices size mismatch" );
01805
01806 piv = ivec_new( m );
01807 LU = mat_clone( A );
01808
01809 if ( !mat_lu( LU, piv ) )
01810 {
01811 it_warning( "Matrix is singular, aborting" );
01812 ivec_delete( piv );
01813 mat_delete( LU );
01814 return( NULL );
01815 }
01816
01817 X = mat_new( ivec_length(piv), nx );
01818
01819 for ( i= 0; i< ivec_length(piv); i++ )
01820 for ( j= 0; j< nx; j++ )
01821 X[i][j] = B[piv[i]][j];
01822
01823 for ( k= 0; k< n; k++ )
01824 for ( i= k+1; i< n; i++ )
01825 for ( j= 0; j< nx; j++ )
01826 X[i][j] -= X[k][j]*LU[i][k];
01827
01828 for ( k= n-1; k >= 0; k-- )
01829 {
01830 for ( j= 0; j< nx; j++ )
01831 X[k][j] /= LU[k][k];
01832
01833 for ( i= 0; i< k; i++ )
01834 for ( j= 0; j< nx; j++ )
01835 X[i][j] -= X[k][j]*LU[i][k];
01836 }
01837
01838 ivec_delete( piv );
01839 mat_delete( LU );
01840
01841 return( X );
01842 }
01843
01844 static mat mat_inv_direct (mat A)
01845 {
01846 mat I, Id;
01847
01848 it_assert (mat_width (A) == mat_height (A), "Matrix must be square");
01849
01850 Id = mat_new_zeros (mat_height (A), mat_width (A));
01851 mat_eye (Id);
01852
01853 I = mat_solve_mat (A, Id);
01854
01855 mat_delete (Id);
01856 return (I);
01857 }
01858
01859
01860
01861
01862 vec mat_qr( mat A )
01863 {
01864
01865 size_t m, n;
01866 idx_t i, j, k;
01867 vec Rdiag;
01868 double nrm, s;
01869
01870 m = mat_height( A );
01871 n = mat_width( A );
01872
01873 Rdiag = vec_new( n );
01874
01875 for ( k= 0; k< n; k++ )
01876 {
01877 nrm = 0.;
01878 for ( i= k; i< m; i++ )
01879 nrm = hypot( nrm, A[i][k] );
01880
01881 if ( nrm )
01882 {
01883 if ( A[k][k] < 0 )
01884 nrm = -nrm;
01885
01886 for ( i= k; i< m; i++ )
01887 A[i][k] /= nrm;
01888
01889 A[k][k] += 1.;
01890
01891 for ( j= k+1; j< n; j++ )
01892 {
01893 s = 0.;
01894 for ( i= k; i< m; i++ )
01895 s+= A[i][k]*A[i][j];
01896
01897 s = -s / A[k][k];
01898
01899 for ( i= k; i< m; i++ )
01900 A[i][j] += s*A[i][k];
01901 }
01902
01903 }
01904
01905 Rdiag[k] = -nrm;
01906 }
01907
01908 return Rdiag;
01909
01910 }
01911
01912 mat mat_ls( mat A, mat B )
01913 {
01914
01915 size_t m, n, nx;
01916 idx_t i, j, k;
01917 double s;
01918 mat QR, X;
01919 vec Rdiag;
01920
01921 m = mat_height( A );
01922 n = mat_width( A );
01923 nx = mat_width( B );
01924
01925 it_assert( m==mat_height(B), "Matrices size mismatch" );
01926
01927 QR = mat_clone( A );
01928
01929 Rdiag = mat_qr( QR );
01930
01931 for ( j= 0; j< n; j++ )
01932 if ( !Rdiag[j] )
01933 {
01934 it_warning( "Matrix is rank deficient, aborting" );
01935 vec_delete( Rdiag );
01936 mat_delete( QR );
01937 return NULL;
01938 }
01939
01940 X = mat_clone( B );
01941
01942 for ( k= 0; k< n; k++ )
01943 for ( j= 0; j< nx; j++ )
01944 {
01945 s = 0.;
01946 for ( i= k; i< m; i++ )
01947 s+= QR[i][k]*X[i][j];
01948
01949 s = -s / QR[k][k];
01950
01951 for ( i= k; i< m; i++ )
01952 X[i][j] += s*QR[i][k];
01953
01954 }
01955
01956 for ( k= n-1; k >= 0; k-- )
01957 {
01958 for ( j= 0; j< nx; j++ )
01959 X[k][j] /= Rdiag[k];
01960
01961 for ( i= 0; i< k; i++ )
01962 for ( j= 0; j< nx; j++ )
01963 X[i][j] -= X[k][j]*QR[i][k];
01964 }
01965
01966 vec_delete( Rdiag );
01967 mat_delete( QR );
01968
01969 return X;
01970
01971 }
01972
01973
01974
01975
01976 void mat_gs (mat A)
01977 {
01978 int i, j, k;
01979 vec v = vec_new (mat_height (A)), proj;
01980 double innerp;
01981
01982 for (i = 1; i < mat_width (A); i++) {
01983 vec_zeros (v);
01984
01985 for (j = 0; j < i; j++) {
01986 innerp = 0.;
01987 for (k = 0; k < mat_height (A); k++)
01988 innerp += A[k][i] * A[k][j];
01989
01990 proj = mat_get_col (A, j);
01991 vec_mul_by (proj, innerp / pow( vec_norm( proj, 2.), 2.));
01992
01993 vec_add (v, proj);
01994 vec_delete (proj);
01995 }
01996
01997
01998 for (j = 0; j < mat_height (A); j++)
01999 A[j][i] -= v[j];
02000 }
02001
02002
02003
02004
02005 if ( mat_width( A ) < mat_height( A ) )
02006 mat_cols_normalize( A, 2. );
02007
02008 vec_delete (v);
02009 }
02010
02011 void mat_cholesky( mat a )
02012 {
02013
02014 idx_t i = 0;
02015 idx_t j = 0;
02016 idx_t k = 0;
02017 size_t n = 0;
02018
02019 it_assert( a, "Please use an existing matrix" );
02020 it_assert( mat_width( a )==mat_height( a ), "Matrix must be square" );
02021
02022 n = mat_width( a );
02023
02024 for ( k= 0; k< n; k++ )
02025 {
02026 a[k][k] = sqrt( a[k][k] );
02027 for ( i= k+1; i< n; i++ )
02028 a[i][k] /= a[k][k];
02029 for ( j= k+1; j< n; j++ )
02030 for ( i= j; i< n; i++ )
02031 a[i][j] -= a[i][k]*a[j][k];
02032 }
02033
02034 for ( j= 0; j< n; j++ )
02035 for ( i= 0; i< j; i++ )
02036 a[i][j] = 0.0;
02037
02038 return;
02039 }
02040
02041
02042
02043
02044
02045
02046
02047 mat mat_inv (mat m)
02048 {
02049
02050 mat inv;
02051 idx_t i, j;
02052
02053 inv = mat_inv_direct (m);
02054
02055 if (inv) {
02056 for (i = 0; i < mat_height (m); i++)
02057 for (j = 0; j < mat_width (m); j++)
02058 m[i][j] = inv[i][j];
02059
02060 mat_delete (inv);
02061
02062 return (m);
02063
02064 }
02065 else
02066 return (NULL);
02067
02068 }
02069
02070
02071
02072 mat mat_new_inv (mat m)
02073 {
02074 return mat_inv_direct (m);
02075 }
02076
02077
02078
02079 cmat cmat_inv (cmat m)
02080 {
02081 idx_t i, j, k;
02082 cplx coef;
02083 cvec f = cvec_new (cmat_height (m));
02084
02085 it_assert (cmat_height (m) == cmat_width (m), "Matrix must be square");
02086
02087
02088 for (i = 0; i < cmat_height (m); i++) {
02089 if (cnorm (m[i][i]) < IT_EPSILON * 1e-5) {
02090 cmat_delete (m);
02091 cvec_delete (f);
02092 it_warning
02093 ("Matrix is singular or you are unlucky. Try another method for inversion.\n");
02094 m = cmat_new_void ();
02095 return m;
02096 }
02097
02098 f[i] = m[i][i];
02099 cvec_div_by (m[i], f[i]);
02100
02101 for (j = 0; j < cmat_height (m); j++) {
02102 if (i != j) {
02103 coef = m[j][i];
02104 m[j][i] = cplx_0;
02105
02106 for (k = 0; k < cmat_width (m); k++)
02107 m[j][k] = csub (m[j][k], cmul (coef, m[i][k]));
02108 }
02109 }
02110 }
02111
02112
02113 for (i = 0; i < cmat_height (m); i++)
02114 cvec_div_by (m[i], f[i]);
02115
02116 cvec_delete (f);
02117 return m;
02118 }
02119
02120
02121
02122 cmat cmat_new_inv (cmat m)
02123 {
02124 cmat r = cmat_clone (m);
02125 return cmat_inv (r);
02126 }