diff --git a/nonclass.cc b/nonclass.cc index 532844a..4d7e16f 100644 --- a/nonclass.cc +++ b/nonclass.cc @@ -184,7 +184,7 @@ void linear_solve(NRSMat &a, NRMat *b, double *det) extern "C" void FORNAME(dsyev)(const char *JOBZ, const char *UPLO, const int *N, double *A, const int *LDA, double *W, double *WORK, const int *LWORK, int *INFO); -// a will contain eigenvectors, w eigenvalues +// a will contain eigenvectors (columns if corder==1), w eigenvalues void diagonalize(NRMat &a, NRVec &w, const bool eivec, const bool corder) { @@ -524,3 +524,154 @@ double trace2(const NRSMat &a, const NRSMat &b, return r; } + +//generalized diagonalization, eivecs will be in columns of a +void gendiagonalize(NRMat &a, NRVec &w, NRMat b) +{ +if(a.nrows()!=a.ncols() || a.nrows()!=w.size() || a.nrows()!=b.nrows() || b.nrows()!=b.ncols() ) laerror("incompatible Mats in gendiagonalize"); + +a.copyonwrite(); +w.copyonwrite(); +b.copyonwrite(); +int n=w.size(); +NRVec dl(n); +int i,j; +double x; + +//transform the problem to usual diagonalization +/* +c +c this routine is a translation of the algol procedure reduc1, +c num. math. 11, 99-110(1968) by martin and wilkinson. +c handbook for auto. comp., vol.ii-linear algebra, 303-314(1971). +c +c this routine reduces the generalized symmetric eigenproblem +c ax=(lambda)bx, where b is positive definite, to the standard +c symmetric eigenproblem using the cholesky factorization of b. +c +c on input +c +c nm must be set to the row dimension of two-dimensional +c array parameters as declared in the calling program +c dimension statement. +c +c n is the order of the matrices a and b. if the cholesky +c factor l of b is already available, n should be prefixed +c with a minus sign. +c +c a and b contain the real symmetric input matrices. only the +c full upper triangles of the matrices need be supplied. if +c n is negative, the strict lower triangle of b contains, +c instead, the strict lower triangle of its cholesky factor l. +c +c dl contains, if n is negative, the diagonal elements of l. +c +c on output +c +c a contains in its full lower triangle the full lower triangle +c of the symmetric matrix derived from the reduction to the +c standard form. the strict upper triangle of a is unaltered. +c +c b contains in its strict lower triangle the strict lower +c triangle of its cholesky factor l. the full upper +c triangle of b is unaltered. +c +c dl contains the diagonal elements of l. +c +c ierr is set to +c zero for normal return, +c 7*n+1 if b is not positive definite. +c +c questions and comments should be directed to burton s. garbow, +c mathematics and computer science div, argonne national laboratory +c +c this version dated august 1983. +c +*/ +// .......... form l in the arrays b and dl .......... +for(i=0; i=0; --i)//component loop + { + if(i extern const NRVec lineof(const NRMat &x, const int i); -template extern const NRVec columnof(const NRMat &x, const int i); -template extern const NRVec diagonalof(const NRMat &x); //more efficient commutator for a special case of full matrices template @@ -52,8 +48,7 @@ extern T trace2(const NRMat &a, const NRMat &b, bool trb=0); \ extern T trace2(const NRSMat &a, const NRSMat &b, const bool diagscaled=0);\ extern void linear_solve(NRMat &a, NRMat *b, double *det=0); \ extern void linear_solve(NRSMat &a, NRMat *b, double *det=0); \ -extern void diagonalize(NRMat &a, NRVec &w, const bool eivec=1,\ - const bool corder=1); \ +extern void diagonalize(NRMat &a, NRVec &w, const bool eivec=1, const bool corder=1); \ extern void diagonalize(NRSMat &a, NRVec &w, NRMat *v, const bool corder=1);\ extern void singular_decomposition(NRMat &a, NRMat *u, NRVec &s,\ NRMat *v, const bool corder=1); @@ -62,6 +57,7 @@ declare_la(double) declare_la(complex) // Separate declarations +//general nonsymmetric matrix extern void gdiagonalize(NRMat &a, NRVec &wr, NRVec &wi, NRMat *vl, NRMat *vr, const bool corder=1); extern void gdiagonalize(NRMat &a, NRVec< complex > &w, @@ -69,6 +65,15 @@ extern void gdiagonalize(NRMat &a, NRVec< complex > &w, extern NRMat matrixfunction(NRSMat a, double (*f) (double)); extern NRMat matrixfunction(NRMat a, complex (*f)(const complex &),const bool adjust=0); + +////////////////////////////// +//other than lapack functions/ +////////////////////////////// + + +//generalized diagonalization of symmetric matrix with symmetric positive definite metric matrix b +extern void gendiagonalize(NRMat &a, NRVec &w, NRMat b); + //functions on matrices inline NRMat sqrt(const NRSMat &a) { return matrixfunction(a,&sqrt); } inline NRMat log(const NRSMat &a) { return matrixfunction(a,&log); }