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]