Mercurial > hg > x
comparison matrix.cpp @ 5:5f3c32dc6e17
* Adjust comment syntax to permit Doxygen to generate HTML documentation; add Doxyfile
author | Chris Cannam |
---|---|
date | Wed, 06 Oct 2010 15:19:49 +0100 |
parents | fc19d45615d1 |
children | c6528c38b23c |
comparison
equal
deleted
inserted
replaced
4:92ee28024c05 | 5:5f3c32dc6e17 |
---|---|
1 //--------------------------------------------------------------------------- | 1 //--------------------------------------------------------------------------- |
2 #include <math.h> | 2 #include <math.h> |
3 #include <memory.h> | 3 #include <memory.h> |
4 #include "matrix.h" | 4 #include "matrix.h" |
5 //--------------------------------------------------------------------------- | 5 |
6 /* | 6 /** \file matrix.h */ |
7 | |
8 //--------------------------------------------------------------------------- | |
9 | |
10 /** | |
7 function BalanceSim: applies a similarity transformation to matrix a so that a is "balanced". This is | 11 function BalanceSim: applies a similarity transformation to matrix a so that a is "balanced". This is |
8 used by various eigenvalue evaluation routines. | 12 used by various eigenvalue evaluation routines. |
9 | 13 |
10 In: matrix A[n][n] | 14 In: matrix A[n][n] |
11 Out: balanced matrix a | 15 Out: balanced matrix a |
58 } | 62 } |
59 } | 63 } |
60 }//BalanceSim | 64 }//BalanceSim |
61 | 65 |
62 //--------------------------------------------------------------------------- | 66 //--------------------------------------------------------------------------- |
63 /* | 67 /** |
64 function Choleski: Choleski factorization A=LL', where L is lower triangular. The symmetric matrix | 68 function Choleski: Choleski factorization A=LL', where L is lower triangular. The symmetric matrix |
65 A[N][N] is positive definite iff A can be factored as LL', where L is lower triangular with nonzero | 69 A[N][N] is positive definite iff A can be factored as LL', where L is lower triangular with nonzero |
66 diagonl entries. | 70 diagonl entries. |
67 | 71 |
68 In: matrix A[N][N] | 72 In: matrix A[N][N] |
91 }//Choleski | 95 }//Choleski |
92 | 96 |
93 //--------------------------------------------------------------------------- | 97 //--------------------------------------------------------------------------- |
94 //matrix duplication routines | 98 //matrix duplication routines |
95 | 99 |
96 /* | 100 /** |
97 function Copy: duplicate the matrix A as matrix Z. | 101 function Copy: duplicate the matrix A as matrix Z. |
98 | 102 |
99 In: matrix A[M][N] | 103 In: matrix A[M][N] |
100 Out: matrix Z[M][N] | 104 Out: matrix Z[M][N] |
101 | 105 |
126 cdouble** Copy(int N, cdouble** A, MList* List){return Copy(N, N, 0, A, List);} | 130 cdouble** Copy(int N, cdouble** A, MList* List){return Copy(N, N, 0, A, List);} |
127 | 131 |
128 //--------------------------------------------------------------------------- | 132 //--------------------------------------------------------------------------- |
129 //vector duplication routines | 133 //vector duplication routines |
130 | 134 |
131 /* | 135 /** |
132 function Copy: duplicating vector a as vector z | 136 function Copy: duplicating vector a as vector z |
133 | 137 |
134 In: vector a[N] | 138 In: vector a[N] |
135 Out: vector z[N] | 139 Out: vector z[N] |
136 | 140 |
151 //version without specifying pre-allocated z | 155 //version without specifying pre-allocated z |
152 double* Copy(int N, double* a, MList* List){return Copy(N, 0, a, List);} | 156 double* Copy(int N, double* a, MList* List){return Copy(N, 0, a, List);} |
153 cdouble* Copy(int N, cdouble* a, MList* List){return Copy(N, 0, a, List);} | 157 cdouble* Copy(int N, cdouble* a, MList* List){return Copy(N, 0, a, List);} |
154 | 158 |
155 //--------------------------------------------------------------------------- | 159 //--------------------------------------------------------------------------- |
156 /* | 160 /** |
157 function det: computes determinant by Gaussian elimination method with column pivoting | 161 function det: computes determinant by Gaussian elimination method with column pivoting |
158 | 162 |
159 In: matrix A[N][N] | 163 In: matrix A[N][N] |
160 | 164 |
161 Returns det(A). On return content of matrix A is unchanged if mode=0. | 165 Returns det(A). On return content of matrix A is unchanged if mode=0. |
233 delete[] rp; | 237 delete[] rp; |
234 return result; | 238 return result; |
235 }//det | 239 }//det |
236 | 240 |
237 //--------------------------------------------------------------------------- | 241 //--------------------------------------------------------------------------- |
238 /* | 242 /** |
239 function EigPower: power method for solving dominant eigenvalue and eigenvector | 243 function EigPower: power method for solving dominant eigenvalue and eigenvector |
240 | 244 |
241 In: matrix A[N][N], initial arbitrary vector x[N]. | 245 In: matrix A[N][N], initial arbitrary vector x[N]. |
242 Out: eigenvalue l, eigenvector x[N]. | 246 Out: eigenvalue l, eigenvector x[N]. |
243 | 247 |
266 } | 270 } |
267 delete[] y; return 1; | 271 delete[] y; return 1; |
268 }//EigPower | 272 }//EigPower |
269 | 273 |
270 //--------------------------------------------------------------------------- | 274 //--------------------------------------------------------------------------- |
271 /* | 275 /** |
272 function EigPowerA: EigPower with Aitken acceleration | 276 function EigPowerA: EigPower with Aitken acceleration |
273 | 277 |
274 In: matrix A[N][N], initial arbitrary vector x[N]. | 278 In: matrix A[N][N], initial arbitrary vector x[N]. |
275 Out: eigenvalue l, eigenvector x[N]. | 279 Out: eigenvalue l, eigenvector x[N]. |
276 | 280 |
299 } | 303 } |
300 delete[] y; return 1; | 304 delete[] y; return 1; |
301 }//EigPowerA | 305 }//EigPowerA |
302 | 306 |
303 //--------------------------------------------------------------------------- | 307 //--------------------------------------------------------------------------- |
304 /* | 308 /** |
305 function EigPowerI: Inverse power method for solving the eigenvalue given an approximate non-zero | 309 function EigPowerI: Inverse power method for solving the eigenvalue given an approximate non-zero |
306 eigenvector. | 310 eigenvector. |
307 | 311 |
308 In: matrix A[N][N], approximate eigenvector x[N]. | 312 In: matrix A[N][N], approximate eigenvector x[N]. |
309 Out: eigenvalue l, eigenvector x[N]. | 313 Out: eigenvalue l, eigenvector x[N]. |
340 delete[] aa[0]; delete[] aa; | 344 delete[] aa[0]; delete[] aa; |
341 delete[] y; return 1; | 345 delete[] y; return 1; |
342 }//EigPowerI | 346 }//EigPowerI |
343 | 347 |
344 //--------------------------------------------------------------------------- | 348 //--------------------------------------------------------------------------- |
345 /* | 349 /** |
346 function EigPowerS: symmetric power method for solving the dominant eigenvalue with its eigenvector | 350 function EigPowerS: symmetric power method for solving the dominant eigenvalue with its eigenvector |
347 | 351 |
348 In: matrix A[N][N], initial arbitrary vector x[N]. | 352 In: matrix A[N][N], initial arbitrary vector x[N]. |
349 Out: eigenvalue l, eigenvector x[N]. | 353 Out: eigenvalue l, eigenvector x[N]. |
350 | 354 |
373 delete[] y; | 377 delete[] y; |
374 return 1; | 378 return 1; |
375 }//EigPowerS | 379 }//EigPowerS |
376 | 380 |
377 //--------------------------------------------------------------------------- | 381 //--------------------------------------------------------------------------- |
378 /* | 382 /** |
379 function EigPowerWielandt: Wielandt's deflation algorithm for solving a second dominant eigenvalue and | 383 function EigPowerWielandt: Wielandt's deflation algorithm for solving a second dominant eigenvalue and |
380 eigenvector (m,u) given the dominant eigenvalue and eigenvector (l,v). | 384 eigenvector (m,u) given the dominant eigenvalue and eigenvector (l,v). |
381 | 385 |
382 In: matrix A[N][N], first eigenvalue l with eigenvector v[N] | 386 In: matrix A[N][N], first eigenvalue l with eigenvector v[N] |
383 Out: second eigenvalue m with eigenvector u | 387 Out: second eigenvalue m with eigenvector u |
413 }//EigPowerWielandt | 417 }//EigPowerWielandt |
414 | 418 |
415 //--------------------------------------------------------------------------- | 419 //--------------------------------------------------------------------------- |
416 //NR versions of eigensystem | 420 //NR versions of eigensystem |
417 | 421 |
418 /* | 422 /** |
419 function EigenValues: solves for eigenvalues of general system | 423 function EigenValues: solves for eigenvalues of general system |
420 | 424 |
421 In: matrix A[N][N] | 425 In: matrix A[N][N] |
422 Out: eigenvalues ev[N] | 426 Out: eigenvalues ev[N] |
423 | 427 |
428 BalanceSim(N, A); | 432 BalanceSim(N, A); |
429 Hessenb(N, A); | 433 Hessenb(N, A); |
430 return QR(N, A, ev); | 434 return QR(N, A, ev); |
431 }//EigenValues | 435 }//EigenValues |
432 | 436 |
433 /* | 437 /** |
434 function EigSym: Solves real symmetric eigensystem A | 438 function EigSym: Solves real symmetric eigensystem A |
435 | 439 |
436 In: matrix A[N][N] | 440 In: matrix A[N][N] |
437 Out: eigenvalues d[N], transform matrix Q[N][N], so that diag(d)=Q'AQ, A=Q diag(d) Q', AQ=Q diag(d) | 441 Out: eigenvalues d[N], transform matrix Q[N][N], so that diag(d)=Q'AQ, A=Q diag(d) Q', AQ=Q diag(d) |
438 | 442 |
447 delete[] t; | 451 delete[] t; |
448 return result; | 452 return result; |
449 }//EigSym | 453 }//EigSym |
450 | 454 |
451 //--------------------------------------------------------------------------- | 455 //--------------------------------------------------------------------------- |
452 /* | 456 /** |
453 function GEB: Gaussian elimination with backward substitution for solving linear system Ax=b. | 457 function GEB: Gaussian elimination with backward substitution for solving linear system Ax=b. |
454 | 458 |
455 In: coefficient matrix A[N][N], vector b[N] | 459 In: coefficient matrix A[N][N], vector b[N] |
456 Out: vector x[N] | 460 Out: vector x[N] |
457 | 461 |
489 delete[] rp; | 493 delete[] rp; |
490 return 0; | 494 return 0; |
491 }//GEB | 495 }//GEB |
492 | 496 |
493 //--------------------------------------------------------------------------- | 497 //--------------------------------------------------------------------------- |
494 /* | 498 /** |
495 function GESCP: Gaussian elimination with scaled column pivoting for solving linear system Ax=b | 499 function GESCP: Gaussian elimination with scaled column pivoting for solving linear system Ax=b |
496 | 500 |
497 In: matrix A[N][N], vector b[N] | 501 In: matrix A[N][N], vector b[N] |
498 Out: vector x[N] | 502 Out: vector x[N] |
499 | 503 |
535 delete[] s; delete[] rp; | 539 delete[] s; delete[] rp; |
536 return 0; | 540 return 0; |
537 }//GESCP | 541 }//GESCP |
538 | 542 |
539 //--------------------------------------------------------------------------- | 543 //--------------------------------------------------------------------------- |
540 /* | 544 /** |
541 function GExL: solves linear system xL=a, L being lower-triangular. This is used in LU factorization | 545 function GExL: solves linear system xL=a, L being lower-triangular. This is used in LU factorization |
542 for solving linear systems. | 546 for solving linear systems. |
543 | 547 |
544 In: lower-triangular matrix L[N][N], vector a[N] | 548 In: lower-triangular matrix L[N][N], vector a[N] |
545 Out: vector x[N] | 549 Out: vector x[N] |
554 for (int m=n+1; m<N; m++) xn-=x[m]*L[m][n]; | 558 for (int m=n+1; m<N; m++) xn-=x[m]*L[m][n]; |
555 x[n]=xn/L[n][n]; | 559 x[n]=xn/L[n][n]; |
556 } | 560 } |
557 }//GExL | 561 }//GExL |
558 | 562 |
559 /* | 563 /** |
560 function GExLAdd: solves linear system *L=a, L being lower-triangular, and add the solution * to x[]. | 564 function GExLAdd: solves linear system *L=a, L being lower-triangular, and add the solution * to x[]. |
561 | 565 |
562 In: lower-triangular matrix L[N][N], vector a[N] | 566 In: lower-triangular matrix L[N][N], vector a[N] |
563 Out: updated vector x[N] | 567 Out: updated vector x[N] |
564 | 568 |
570 GExL(N, lx, L, a); | 574 GExL(N, lx, L, a); |
571 for (int i=0; i<N; i++) x[i]+=lx[i]; | 575 for (int i=0; i<N; i++) x[i]+=lx[i]; |
572 delete[] lx; | 576 delete[] lx; |
573 }//GExLAdd | 577 }//GExLAdd |
574 | 578 |
575 /* | 579 /** |
576 function GExL1: solves linear system xL=(0, 0, ..., 0, a)', L being lower-triangular. | 580 function GExL1: solves linear system xL=(0, 0, ..., 0, a)', L being lower-triangular. |
577 | 581 |
578 In: lower-triangular matrix L[N][N], a | 582 In: lower-triangular matrix L[N][N], a |
579 Out: vector x[N] | 583 Out: vector x[N] |
580 | 584 |
589 x[n]=xn/L[n][n]; | 593 x[n]=xn/L[n][n]; |
590 xn=0; | 594 xn=0; |
591 } | 595 } |
592 }//GExL1 | 596 }//GExL1 |
593 | 597 |
594 /* | 598 /** |
595 function GExL1Add: solves linear system *L=(0, 0, ..., 0, a)', L being lower-triangular, and add the | 599 function GExL1Add: solves linear system *L=(0, 0, ..., 0, a)', L being lower-triangular, and add the |
596 solution * to x[]. | 600 solution * to x[]. |
597 | 601 |
598 In: lower-triangular matrix L[N][N], vector a | 602 In: lower-triangular matrix L[N][N], vector a |
599 Out: updated vector x[N] | 603 Out: updated vector x[N] |
607 for (int i=0; i<N; i++) x[i]+=lx[i]; | 611 for (int i=0; i<N; i++) x[i]+=lx[i]; |
608 delete[] lx; | 612 delete[] lx; |
609 }//GExL1Add | 613 }//GExL1Add |
610 | 614 |
611 //--------------------------------------------------------------------------- | 615 //--------------------------------------------------------------------------- |
612 /* | 616 /** |
613 function GICP: matrix inverse using Gaussian elimination with column pivoting: inv(A)->A. | 617 function GICP: matrix inverse using Gaussian elimination with column pivoting: inv(A)->A. |
614 | 618 |
615 In: matrix A[N][N] | 619 In: matrix A[N][N] |
616 Out: matrix A[N][N] | 620 Out: matrix A[N][N] |
617 | 621 |
699 | 703 |
700 delete[] tm; delete[] rp; | 704 delete[] tm; delete[] rp; |
701 return result; | 705 return result; |
702 }//GICP | 706 }//GICP |
703 | 707 |
704 /* | 708 /** |
705 function GICP: wrapper function that does not overwrite the input matrix: inv(A)->X. | 709 function GICP: wrapper function that does not overwrite the input matrix: inv(A)->X. |
706 | 710 |
707 In: matrix A[N][N] | 711 In: matrix A[N][N] |
708 Out: matrix X[N][N] | 712 Out: matrix X[N][N] |
709 | 713 |
714 Copy(N, X, A); | 718 Copy(N, X, A); |
715 return GICP(N, X); | 719 return GICP(N, X); |
716 }//GICP | 720 }//GICP |
717 | 721 |
718 //--------------------------------------------------------------------------- | 722 //--------------------------------------------------------------------------- |
719 /* | 723 /** |
720 function GILT: inv(lower trangular of A)->lower trangular of A | 724 function GILT: inv(lower trangular of A)->lower trangular of A |
721 | 725 |
722 In: matrix A[N][N] | 726 In: matrix A[N][N] |
723 Out: matrix A[N][N] | 727 Out: matrix A[N][N] |
724 | 728 |
740 } | 744 } |
741 } | 745 } |
742 return result; | 746 return result; |
743 }//GILT | 747 }//GILT |
744 | 748 |
745 /* | 749 /** |
746 function GIUT: inv(upper trangular of A)->upper trangular of A | 750 function GIUT: inv(upper trangular of A)->upper trangular of A |
747 | 751 |
748 In: matrix A[N][N] | 752 In: matrix A[N][N] |
749 Out: matrix A[N][N] | 753 Out: matrix A[N][N] |
750 | 754 |
767 } | 771 } |
768 return result; | 772 return result; |
769 }//GIUT | 773 }//GIUT |
770 | 774 |
771 //--------------------------------------------------------------------------- | 775 //--------------------------------------------------------------------------- |
772 /* | 776 /** |
773 function GISCP: matrix inverse using Gaussian elimination w. scaled column pivoting: inv(A)->A. | 777 function GISCP: matrix inverse using Gaussian elimination w. scaled column pivoting: inv(A)->A. |
774 | 778 |
775 In: matrix A[N][N] | 779 In: matrix A[N][N] |
776 Out: matrix A[N][N] | 780 Out: matrix A[N][N] |
777 | 781 |
825 | 829 |
826 delete[] tm; delete[] s; delete[] rp; | 830 delete[] tm; delete[] s; delete[] rp; |
827 return result; | 831 return result; |
828 }//GISCP | 832 }//GISCP |
829 | 833 |
830 /* | 834 /** |
831 function GISCP: wrapper function that does not overwrite input matrix A: inv(A)->X. | 835 function GISCP: wrapper function that does not overwrite input matrix A: inv(A)->X. |
832 | 836 |
833 In: matrix A[N][N] | 837 In: matrix A[N][N] |
834 Out: matrix X[N][N] | 838 Out: matrix X[N][N] |
835 | 839 |
840 Copy(N, X, A); | 844 Copy(N, X, A); |
841 return GISCP(N, X); | 845 return GISCP(N, X); |
842 }//GISCP | 846 }//GISCP |
843 | 847 |
844 //--------------------------------------------------------------------------- | 848 //--------------------------------------------------------------------------- |
845 /* | 849 /** |
846 function GSI: Gaussian-Seidel iterative algorithm for solving linear system Ax=b. Breaks down if any | 850 function GSI: Gaussian-Seidel iterative algorithm for solving linear system Ax=b. Breaks down if any |
847 Aii=0, like the Jocobi method JI(...). | 851 Aii=0, like the Jocobi method JI(...). |
848 | 852 |
849 Gaussian-Seidel iteration is x(k)=(D-L)^(-1)(Ux(k-1)+b), where D is diagonal, L is lower triangular, | 853 Gaussian-Seidel iteration is x(k)=(D-L)^(-1)(Ux(k-1)+b), where D is diagonal, L is lower triangular, |
850 U is upper triangular and A=L+D+U. | 854 U is upper triangular and A=L+D+U. |
876 if (k>=maxiter) return 1; | 880 if (k>=maxiter) return 1; |
877 return 0; | 881 return 0; |
878 }//GSI | 882 }//GSI |
879 | 883 |
880 //--------------------------------------------------------------------------- | 884 //--------------------------------------------------------------------------- |
881 /* | 885 /** |
882 function Hessenb: reducing a square matrix A to upper Hessenberg form | 886 function Hessenb: reducing a square matrix A to upper Hessenberg form |
883 | 887 |
884 In: matrix A[N][N] | 888 In: matrix A[N][N] |
885 Out: matrix A[N][N], in upper Hessenberg form | 889 Out: matrix A[N][N], in upper Hessenberg form |
886 | 890 |
931 } | 935 } |
932 } | 936 } |
933 }//Hessenb | 937 }//Hessenb |
934 | 938 |
935 //--------------------------------------------------------------------------- | 939 //--------------------------------------------------------------------------- |
936 /* | 940 /** |
937 function HouseHolder: house holder method converting a symmetric matrix into a tridiagonal symmetric | 941 function HouseHolder: house holder method converting a symmetric matrix into a tridiagonal symmetric |
938 matrix, or a non-symmetric matrix into an upper-Hessenberg matrix, using similarity transformation. | 942 matrix, or a non-symmetric matrix into an upper-Hessenberg matrix, using similarity transformation. |
939 | 943 |
940 In: matrix A[N][N] | 944 In: matrix A[N][N] |
941 Out: matrix A[N][N] after transformation | 945 Out: matrix A[N][N] after transformation |
976 A[k][k+1]=A[k+1][k]=A[k+1][k]-v[k+1]*z[k]; | 980 A[k][k+1]=A[k+1][k]=A[k+1][k]-v[k+1]*z[k]; |
977 } | 981 } |
978 delete[] u; delete[] v; delete[] z; | 982 delete[] u; delete[] v; delete[] z; |
979 }//HouseHolder | 983 }//HouseHolder |
980 | 984 |
981 /* | 985 /** |
982 function HouseHolder: house holder transformation T=Q'AQ or A=QTQ', where T is tridiagonal and Q is | 986 function HouseHolder: house holder transformation T=Q'AQ or A=QTQ', where T is tridiagonal and Q is |
983 unitary i.e. QQ'=I. | 987 unitary i.e. QQ'=I. |
984 | 988 |
985 In: matrix A[N][N] | 989 In: matrix A[N][N] |
986 Out: matrix tridiagonal matrix T[N][N] and unitary matrix Q[N][N] | 990 Out: matrix tridiagonal matrix T[N][N] and unitary matrix Q[N][N] |
1027 MultiAdd(N-k, &Q[i][k], &Q[i][k], &v[k], -Inner(N-k, &Q[i][k], &v[k])/r2); | 1031 MultiAdd(N-k, &Q[i][k], &Q[i][k], &v[k], -Inner(N-k, &Q[i][k], &v[k])/r2); |
1028 } | 1032 } |
1029 delete[] u; delete[] v; delete[] z; | 1033 delete[] u; delete[] v; delete[] z; |
1030 }//HouseHolder | 1034 }//HouseHolder |
1031 | 1035 |
1032 /* | 1036 /** |
1033 function HouseHolder: nr version of householder method for transforming symmetric matrix A to QTQ', | 1037 function HouseHolder: nr version of householder method for transforming symmetric matrix A to QTQ', |
1034 where T is tridiagonal and Q is orthonormal. | 1038 where T is tridiagonal and Q is orthonormal. |
1035 | 1039 |
1036 In: matrix A[N][N] | 1040 In: matrix A[N][N] |
1037 Out: A[N][N]: now containing Q | 1041 Out: A[N][N]: now containing Q |
1105 for (int j=0; j<=l; j++) A[j][i]=A[i][j]=0.0; | 1109 for (int j=0; j<=l; j++) A[j][i]=A[i][j]=0.0; |
1106 } | 1110 } |
1107 }//HouseHolder | 1111 }//HouseHolder |
1108 | 1112 |
1109 //--------------------------------------------------------------------------- | 1113 //--------------------------------------------------------------------------- |
1110 /* | 1114 /** |
1111 function Inner: inner product z=y'x | 1115 function Inner: inner product z=y'x |
1112 | 1116 |
1113 In: vectors x[N], y[N] | 1117 In: vectors x[N], y[N] |
1114 | 1118 |
1115 Returns inner product of x and y. | 1119 Returns inner product of x and y. |
1144 cfloat result=0; | 1148 cfloat result=0; |
1145 for (int i=0; i<N; i++) result+=x[i]^y[i]; | 1149 for (int i=0; i<N; i++) result+=x[i]^y[i]; |
1146 return result; | 1150 return result; |
1147 }//Inner | 1151 }//Inner |
1148 | 1152 |
1149 /* | 1153 /** |
1150 function Inner: inner product z=tr(Y'X) | 1154 function Inner: inner product z=tr(Y'X) |
1151 | 1155 |
1152 In: matrices X[M][N], Y[M][N] | 1156 In: matrices X[M][N], Y[M][N] |
1153 | 1157 |
1154 Returns inner product of X and Y. | 1158 Returns inner product of X and Y. |
1159 for (int m=0; m<M; m++) for (int n=0; n<N; n++) result+=X[m][n]*Y[m][n]; | 1163 for (int m=0; m<M; m++) for (int n=0; n<N; n++) result+=X[m][n]*Y[m][n]; |
1160 return result; | 1164 return result; |
1161 }//Inner | 1165 }//Inner |
1162 | 1166 |
1163 //--------------------------------------------------------------------------- | 1167 //--------------------------------------------------------------------------- |
1164 /* | 1168 /** |
1165 function JI: Jacobi interative algorithm for solving linear system Ax=b Breaks down if A[i][i]=0 for | 1169 function JI: Jacobi interative algorithm for solving linear system Ax=b Breaks down if A[i][i]=0 for |
1166 any i. Reorder A so that this does not happen. | 1170 any i. Reorder A so that this does not happen. |
1167 | 1171 |
1168 Jacobi iteration is x(k)=D^(-1)((L+U)x(k-1)+b), D is diagonal, L is lower triangular, U is upper | 1172 Jacobi iteration is x(k)=D^(-1)((L+U)x(k-1)+b), D is diagonal, L is lower triangular, U is upper |
1169 triangular and A=L+D+U. | 1173 triangular and A=L+D+U. |
1192 if (k>=maxiter) return 1; | 1196 if (k>=maxiter) return 1; |
1193 else return 0; | 1197 else return 0; |
1194 }//JI | 1198 }//JI |
1195 | 1199 |
1196 //--------------------------------------------------------------------------- | 1200 //--------------------------------------------------------------------------- |
1197 /* | 1201 /** |
1198 function LDL: LDL' decomposition A=LDL', where L is lower triangular and D is diagonal identical l and | 1202 function LDL: LDL' decomposition A=LDL', where L is lower triangular and D is diagonal identical l and |
1199 a allowed. | 1203 a allowed. |
1200 | 1204 |
1201 The symmetric matrix A is positive definite iff A can be factorized as LDL', where L is lower | 1205 The symmetric matrix A is positive definite iff A can be factorized as LDL', where L is lower |
1202 triangular with ones on its diagonal and D is diagonal with positive diagonal entries. | 1206 triangular with ones on its diagonal and D is diagonal with positive diagonal entries. |
1231 for (int i=0; i<N; i++) {L[i][i]=1; memset(&L[i][i+1], 0, sizeof(double)*(N-1-i));} | 1235 for (int i=0; i<N; i++) {L[i][i]=1; memset(&L[i][i+1], 0, sizeof(double)*(N-1-i));} |
1232 return 0; | 1236 return 0; |
1233 }//LDL | 1237 }//LDL |
1234 | 1238 |
1235 //--------------------------------------------------------------------------- | 1239 //--------------------------------------------------------------------------- |
1236 /* | 1240 /** |
1237 function LQ_GS: LQ decomposition using Gram-Schmidt method | 1241 function LQ_GS: LQ decomposition using Gram-Schmidt method |
1238 | 1242 |
1239 In: matrix A[M][N], M<=N | 1243 In: matrix A[M][N], M<=N |
1240 Out: matrices L[M][M], Q[M][N] | 1244 Out: matrices L[M][M], Q[M][N] |
1241 | 1245 |
1260 } | 1264 } |
1261 delete[] u; | 1265 delete[] u; |
1262 }//LQ_GS | 1266 }//LQ_GS |
1263 | 1267 |
1264 //--------------------------------------------------------------------------- | 1268 //--------------------------------------------------------------------------- |
1265 /* | 1269 /** |
1266 function LSLinear2: 2-dtage LS solution of A[M][N]x[N][1]=y[M][1], M>=N. Use of this function requires | 1270 function LSLinear2: 2-dtage LS solution of A[M][N]x[N][1]=y[M][1], M>=N. Use of this function requires |
1267 the submatrix A[N][N] be invertible. | 1271 the submatrix A[N][N] be invertible. |
1268 | 1272 |
1269 In: matrix A[M][N], vector y[M], M>=N. | 1273 In: matrix A[M][N], vector y[M], M>=N. |
1270 Out: vector x[N]. | 1274 Out: vector x[N]. |
1294 } | 1298 } |
1295 DeAlloc2(A1); | 1299 DeAlloc2(A1); |
1296 }//LSLinear2 | 1300 }//LSLinear2 |
1297 | 1301 |
1298 //--------------------------------------------------------------------------- | 1302 //--------------------------------------------------------------------------- |
1299 /* | 1303 /** |
1300 function LU: LU decomposition A=LU, where L is lower triangular with diagonal entries 1 and U is upper | 1304 function LU: LU decomposition A=LU, where L is lower triangular with diagonal entries 1 and U is upper |
1301 triangular. | 1305 triangular. |
1302 | 1306 |
1303 LU is possible if A can be reduced by Gaussian elimination without row interchanges. | 1307 LU is possible if A can be reduced by Gaussian elimination without row interchanges. |
1304 | 1308 |
1331 } | 1335 } |
1332 delete[] diagl; | 1336 delete[] diagl; |
1333 return result; | 1337 return result; |
1334 }//LU | 1338 }//LU |
1335 | 1339 |
1336 /* | 1340 /** |
1337 function LU: Solving linear system Ax=y by LU factorization | 1341 function LU: Solving linear system Ax=y by LU factorization |
1338 | 1342 |
1339 In: matrix A[N][N], vector y[N] | 1343 In: matrix A[N][N], vector y[N] |
1340 Out: x[N] | 1344 Out: x[N] |
1341 | 1345 |
1386 u[N-1][N-1]=a[N-1][N-1]; for (int k=0; k<N-1; k++) u[N-1][N-1]-=l[N-1][k]*u[k][N-1]; u[N-1][N-1]/=l[N-1][N-1]; | 1390 u[N-1][N-1]=a[N-1][N-1]; for (int k=0; k<N-1; k++) u[N-1][N-1]-=l[N-1][k]*u[k][N-1]; u[N-1][N-1]/=l[N-1][N-1]; |
1387 memset(u[N-1], 0, sizeof(double)*(N-1)); | 1391 memset(u[N-1], 0, sizeof(double)*(N-1)); |
1388 } //LU_DiagL*/ | 1392 } //LU_DiagL*/ |
1389 | 1393 |
1390 //--------------------------------------------------------------------------- | 1394 //--------------------------------------------------------------------------- |
1391 /* | 1395 /** |
1392 function LU_Direct: LU factorization A=LU. | 1396 function LU_Direct: LU factorization A=LU. |
1393 | 1397 |
1394 In: matrix A[N][N], vector diag[N] specifying main diagonal of L or U, according to mode (0=LDiag, | 1398 In: matrix A[N][N], vector diag[N] specifying main diagonal of L or U, according to mode (0=LDiag, |
1395 1=UDiag). | 1399 1=UDiag). |
1396 Out: matrix A[N][N] now containing L and U. | 1400 Out: matrix A[N][N] now containing L and U. |
1435 } | 1439 } |
1436 return 0; | 1440 return 0; |
1437 }//LU_Direct | 1441 }//LU_Direct |
1438 | 1442 |
1439 //--------------------------------------------------------------------------- | 1443 //--------------------------------------------------------------------------- |
1440 /* | 1444 /** |
1441 function LU_PD: LU factorization for pentadiagonal A=LU | 1445 function LU_PD: LU factorization for pentadiagonal A=LU |
1442 | 1446 |
1443 In: pentadiagonal matrix A[N][N] stored in a compact format, i.e. A[i][j]->b[i-j, j] | 1447 In: pentadiagonal matrix A[N][N] stored in a compact format, i.e. A[i][j]->b[i-j, j] |
1444 the main diagonal is b[0][0]~b[0][N-1] | 1448 the main diagonal is b[0][0]~b[0][N-1] |
1445 the 1st upper subdiagonal is b[-1][1]~b[-1][N-1] | 1449 the 1st upper subdiagonal is b[-1][1]~b[-1][N-1] |
1508 } | 1512 } |
1509 for (int k=N-3; k<N-1; k++) b[0][N-1]-=b[N-1-k][k]*b[k-N+1][N-1]; | 1513 for (int k=N-3; k<N-1; k++) b[0][N-1]-=b[N-1-k][k]*b[k-N+1][N-1]; |
1510 return 0; | 1514 return 0; |
1511 }//LU_PD*/ | 1515 }//LU_PD*/ |
1512 | 1516 |
1513 /* | 1517 /** |
1514 function LU_PD: solve pentadiagonal system Ax=c | 1518 function LU_PD: solve pentadiagonal system Ax=c |
1515 | 1519 |
1516 In: pentadiagonal matrix A[N][N] stored in a compact format in b[-2:2][N], vector c[N] | 1520 In: pentadiagonal matrix A[N][N] stored in a compact format in b[-2:2][N], vector c[N] |
1517 Out: vector c now containing x. | 1521 Out: vector c now containing x. |
1518 | 1522 |
1535 } | 1539 } |
1536 return result; | 1540 return result; |
1537 }//LU_PD | 1541 }//LU_PD |
1538 | 1542 |
1539 //--------------------------------------------------------------------------- | 1543 //--------------------------------------------------------------------------- |
1540 /* | 1544 /** |
1541 function LUCP: LU decomposition A=LU with column pivoting | 1545 function LUCP: LU decomposition A=LU with column pivoting |
1542 | 1546 |
1543 In: matrix A[N][N] | 1547 In: matrix A[N][N] |
1544 Out: matrix A[N][N] now holding L and U by L_U[i][j]=A[ind[i]][j], where L_U | 1548 Out: matrix A[N][N] now holding L and U by L_U[i][j]=A[ind[i]][j], where L_U |
1545 hosts L and U according to mode: | 1549 hosts L and U according to mode: |
1624 delete[] norm; | 1628 delete[] norm; |
1625 return det*parity; | 1629 return det*parity; |
1626 }//LUCP | 1630 }//LUCP |
1627 | 1631 |
1628 //--------------------------------------------------------------------------- | 1632 //--------------------------------------------------------------------------- |
1629 /* | 1633 /** |
1630 function maxind: returns the index of the maximal value of data[from:(to-1)]. | 1634 function maxind: returns the index of the maximal value of data[from:(to-1)]. |
1631 | 1635 |
1632 In: vector data containing at least $to entries. | 1636 In: vector data containing at least $to entries. |
1633 Out: the index to the maximal entry of data[from:(to-1)] | 1637 Out: the index to the maximal entry of data[from:(to-1)] |
1634 | 1638 |
1684 //function MultiplyXcy: z[M]=(x*)[M][N]y[N] | 1688 //function MultiplyXcy: z[M]=(x*)[M][N]y[N] |
1685 Multiply_vect(MultiplyXcy, cdouble, cdouble*, cdouble, *x[m][n], y[n]) | 1689 Multiply_vect(MultiplyXcy, cdouble, cdouble*, cdouble, *x[m][n], y[n]) |
1686 Multiply_vect(MultiplyXcy, cdouble, cdouble*, cfloat, *x[m][n], y[n]) | 1690 Multiply_vect(MultiplyXcy, cdouble, cdouble*, cfloat, *x[m][n], y[n]) |
1687 | 1691 |
1688 //--------------------------------------------------------------------------- | 1692 //--------------------------------------------------------------------------- |
1689 /* | 1693 /** |
1690 function Norm1: L-1 norm of a square matrix A | 1694 function Norm1: L-1 norm of a square matrix A |
1691 | 1695 |
1692 In: matrix A[N][N] | 1696 In: matrix A[N][N] |
1693 Out: its L-1 norm | 1697 Out: its L-1 norm |
1694 | 1698 |
1704 } | 1708 } |
1705 return result; | 1709 return result; |
1706 }//Norm1 | 1710 }//Norm1 |
1707 | 1711 |
1708 //--------------------------------------------------------------------------- | 1712 //--------------------------------------------------------------------------- |
1709 /* | 1713 /** |
1710 function QL: QL method for solving tridiagonal symmetric matrix eigenvalue problem. | 1714 function QL: QL method for solving tridiagonal symmetric matrix eigenvalue problem. |
1711 | 1715 |
1712 In: A[N][N]: tridiagonal symmetric matrix stored in d[N] and sd[] arranged so that d[0:n-1] contains | 1716 In: A[N][N]: tridiagonal symmetric matrix stored in d[N] and sd[] arranged so that d[0:n-1] contains |
1713 the diagonal elements of A, sd[0]=0, sd[1:n-1] contains the subdiagonal elements of A. | 1717 the diagonal elements of A, sd[0]=0, sd[1:n-1] contains the subdiagonal elements of A. |
1714 z[N][N]: pre-transform matrix z[N][N] compatible with HouseHolder() routine. | 1718 z[N][N]: pre-transform matrix z[N][N] compatible with HouseHolder() routine. |
1774 } | 1778 } |
1775 return 0; | 1779 return 0; |
1776 }//QL | 1780 }//QL |
1777 | 1781 |
1778 //--------------------------------------------------------------------------- | 1782 //--------------------------------------------------------------------------- |
1779 /* | 1783 /** |
1780 function QR: nr version of QR method for solving upper Hessenberg system A. This is compatible with | 1784 function QR: nr version of QR method for solving upper Hessenberg system A. This is compatible with |
1781 Hessenb method. | 1785 Hessenb method. |
1782 | 1786 |
1783 In: matrix A[N][N] | 1787 In: matrix A[N][N] |
1784 Out: vector ev[N] of eigenvalues | 1788 Out: vector ev[N] of eigenvalues |
1906 } while (n>l+1); | 1910 } while (n>l+1); |
1907 } | 1911 } |
1908 return 0; | 1912 return 0; |
1909 }//QR | 1913 }//QR |
1910 | 1914 |
1911 /* | 1915 /** |
1912 function QR_GS: QR decomposition A=QR using Gram-Schmidt method | 1916 function QR_GS: QR decomposition A=QR using Gram-Schmidt method |
1913 | 1917 |
1914 In: matrix A[M][N], M>=N | 1918 In: matrix A[M][N], M>=N |
1915 Out: Q[M][N], R[N][N] | 1919 Out: Q[M][N], R[N][N] |
1916 | 1920 |
1934 iu=1.0/iu; for (int m=0; m<M; m++) Q[m][n]=u[m]*iu; | 1938 iu=1.0/iu; for (int m=0; m<M; m++) Q[m][n]=u[m]*iu; |
1935 } | 1939 } |
1936 delete[] u; | 1940 delete[] u; |
1937 }//QR_GS | 1941 }//QR_GS |
1938 | 1942 |
1939 /* | 1943 /** |
1940 function QR_householder: QR decomposition using householder transform | 1944 function QR_householder: QR decomposition using householder transform |
1941 | 1945 |
1942 In: A[M][N], M>=N | 1946 In: A[M][N], M>=N |
1943 Out: Q[M][M], R[M][N] | 1947 Out: Q[M][M], R[M][N] |
1944 | 1948 |
1972 } | 1976 } |
1973 delete[] u; | 1977 delete[] u; |
1974 }//QR_householder | 1978 }//QR_householder |
1975 | 1979 |
1976 //--------------------------------------------------------------------------- | 1980 //--------------------------------------------------------------------------- |
1977 /* | 1981 /** |
1978 function QU: Unitary decomposition A=QU, where Q is unitary and U is upper triangular | 1982 function QU: Unitary decomposition A=QU, where Q is unitary and U is upper triangular |
1979 | 1983 |
1980 In: matrix A[N][N] | 1984 In: matrix A[N][N] |
1981 Out: matrices Q[N][N], A[n][n] now containing U | 1985 Out: matrices Q[N][N], A[n][n] now containing U |
1982 | 1986 |
2002 delete[] tmpi; delete[] tmpj; | 2006 delete[] tmpi; delete[] tmpj; |
2003 transpose(N, Q); | 2007 transpose(N, Q); |
2004 }//QU | 2008 }//QU |
2005 | 2009 |
2006 //--------------------------------------------------------------------------- | 2010 //--------------------------------------------------------------------------- |
2007 /* | 2011 /** |
2008 function Real: extracts the real part of matrix X | 2012 function Real: extracts the real part of matrix X |
2009 | 2013 |
2010 In: matrix x[M][N]; | 2014 In: matrix x[M][N]; |
2011 Out: matrix z[M][N] | 2015 Out: matrix z[M][N] |
2012 | 2016 |
2019 return z; | 2023 return z; |
2020 }//Real | 2024 }//Real |
2021 double** Real(int M, int N, cdouble** x, MList* List){return Real(M, N, 0, x, List);} | 2025 double** Real(int M, int N, cdouble** x, MList* List){return Real(M, N, 0, x, List);} |
2022 | 2026 |
2023 //--------------------------------------------------------------------------- | 2027 //--------------------------------------------------------------------------- |
2024 /* | 2028 /** |
2025 function Roots: finds the roots of a polynomial. x^N+p[N-1]x^(N-1)+p[N-2]x^(N-2)...+p[0] | 2029 function Roots: finds the roots of a polynomial. x^N+p[N-1]x^(N-1)+p[N-2]x^(N-2)...+p[0] |
2026 | 2030 |
2027 In: vector p[N] of polynomial coefficients. | 2031 In: vector p[N] of polynomial coefficients. |
2028 Out: vector r[N] of roots. | 2032 Out: vector r[N] of roots. |
2029 | 2033 |
2049 delete[] r; | 2053 delete[] r; |
2050 return result; | 2054 return result; |
2051 }//Roots | 2055 }//Roots |
2052 | 2056 |
2053 //--------------------------------------------------------------------------- | 2057 //--------------------------------------------------------------------------- |
2054 /* | 2058 /** |
2055 function SorI: Sor iteration algorithm for solving linear system Ax=b. | 2059 function SorI: Sor iteration algorithm for solving linear system Ax=b. |
2056 | 2060 |
2057 Sor method is an extension of the Gaussian-Siedel method, with the latter equivalent to the former | 2061 Sor method is an extension of the Gaussian-Siedel method, with the latter equivalent to the former |
2058 with w set to 1. The Sor iteration is given by x(k)=(D-wL)^(-1)(((1-w)D+wU)x(k-1)+wb), where 0<w<2, D | 2062 with w set to 1. The Sor iteration is given by x(k)=(D-wL)^(-1)(((1-w)D+wU)x(k-1)+wb), where 0<w<2, D |
2059 is diagonal, L is lower triangular, U is upper triangular and A=L+D+U. Sor method converges if A is | 2063 is diagonal, L is lower triangular, U is upper triangular and A=L+D+U. Sor method converges if A is |
2088 }//SorI | 2092 }//SorI |
2089 | 2093 |
2090 //--------------------------------------------------------------------------- | 2094 //--------------------------------------------------------------------------- |
2091 //Submatrix routines | 2095 //Submatrix routines |
2092 | 2096 |
2093 /* | 2097 /** |
2094 function SetSubMatrix: copy matrix x[Y][X] into matrix z at (Y1, X1). | 2098 function SetSubMatrix: copy matrix x[Y][X] into matrix z at (Y1, X1). |
2095 | 2099 |
2096 In: matrix x[Y][X], matrix z with dimensions no less than [Y+Y1][X+X1] | 2100 In: matrix x[Y][X], matrix z with dimensions no less than [Y+Y1][X+X1] |
2097 Out: matrix z, updated. | 2101 Out: matrix z, updated. |
2098 | 2102 |
2106 void SetSubMatrix(cdouble** z, cdouble** x, int Y1, int Y, int X1, int X) | 2110 void SetSubMatrix(cdouble** z, cdouble** x, int Y1, int Y, int X1, int X) |
2107 { | 2111 { |
2108 for (int y=0; y<Y; y++) memcpy(&z[Y1+y][X1], x[y], sizeof(cdouble)*X); | 2112 for (int y=0; y<Y; y++) memcpy(&z[Y1+y][X1], x[y], sizeof(cdouble)*X); |
2109 }//SetSubMatrix | 2113 }//SetSubMatrix |
2110 | 2114 |
2111 /* | 2115 /** |
2112 function SubMatrix: extract a submatrix of x at (Y1, X1) to z[Y][X]. | 2116 function SubMatrix: extract a submatrix of x at (Y1, X1) to z[Y][X]. |
2113 | 2117 |
2114 In: matrix x of dimensions no less than [Y+Y1][X+X1] | 2118 In: matrix x of dimensions no less than [Y+Y1][X+X1] |
2115 Out: matrix z[Y][X]. | 2119 Out: matrix z[Y][X]. |
2116 | 2120 |
2126 cdouble** SubMatrix(cdouble** x, int Y1, int Y, int X1, int X, MList* List) | 2130 cdouble** SubMatrix(cdouble** x, int Y1, int Y, int X1, int X, MList* List) |
2127 { | 2131 { |
2128 return SubMatrix(0, x, Y1, Y, X1, X, List); | 2132 return SubMatrix(0, x, Y1, Y, X1, X, List); |
2129 }//SetSubMatrix | 2133 }//SetSubMatrix |
2130 | 2134 |
2131 /* | 2135 /** |
2132 function SubVector: extract a subvector of x at X1 to z[X]. | 2136 function SubVector: extract a subvector of x at X1 to z[X]. |
2133 | 2137 |
2134 In: vector x no shorter than X+X1. | 2138 In: vector x no shorter than X+X1. |
2135 Out: vector z[X]. | 2139 Out: vector z[X]. |
2136 | 2140 |
2147 { | 2151 { |
2148 return SubVector(0, x, X1, X, List); | 2152 return SubVector(0, x, X1, X, List); |
2149 }//SubVector | 2153 }//SubVector |
2150 | 2154 |
2151 //--------------------------------------------------------------------------- | 2155 //--------------------------------------------------------------------------- |
2152 /* | 2156 /** |
2153 function transpose: matrix transpose: A'->A | 2157 function transpose: matrix transpose: A'->A |
2154 | 2158 |
2155 In: matrix a[N][N] | 2159 In: matrix a[N][N] |
2156 Out: matrix a[N][N] after transpose | 2160 Out: matrix a[N][N] after transpose |
2157 | 2161 |
2167 { | 2171 { |
2168 cdouble tmp; | 2172 cdouble tmp; |
2169 for (int i=1; i<N; i++) for (int j=0; j<i; j++) {tmp=a[i][j]; a[i][j]=a[j][i]; a[j][i]=tmp;} | 2173 for (int i=1; i<N; i++) for (int j=0; j<i; j++) {tmp=a[i][j]; a[i][j]=a[j][i]; a[j][i]=tmp;} |
2170 }//transpose | 2174 }//transpose |
2171 | 2175 |
2172 /* | 2176 /** |
2173 function transpose: matrix transpose: A'->Z | 2177 function transpose: matrix transpose: A'->Z |
2174 | 2178 |
2175 In: matrix a[M][N] | 2179 In: matrix a[M][N] |
2176 Out: matrix z[N][M] | 2180 Out: matrix z[N][M] |
2177 | 2181 |
2188 { | 2192 { |
2189 return transpose(N, M, 0, a, List); | 2193 return transpose(N, M, 0, a, List); |
2190 }//transpose | 2194 }//transpose |
2191 | 2195 |
2192 //--------------------------------------------------------------------------- | 2196 //--------------------------------------------------------------------------- |
2193 /* | 2197 /** |
2194 function Unitary: given x & y s.t. |x|=|y|, find unitary matrix P s.t. Px=y. P is given in closed form | 2198 function Unitary: given x & y s.t. |x|=|y|, find unitary matrix P s.t. Px=y. P is given in closed form |
2195 as I-(x-y)(x-y)'/(x-y)'x | 2199 as I-(x-y)(x-y)'/(x-y)'x |
2196 | 2200 |
2197 In: vectors x[N] and y[N] | 2201 In: vectors x[N] and y[N] |
2198 Out: matrix P[N][N] | 2202 Out: matrix P[N][N] |