#ifndef BFM_UTSOLVE_H #define BFM_UTSOLVE_H #include #include #include #include #include #include #include #include #include #include "RandomMatrix.h" namespace BFM_Krylov{ /** Find eigenvectors of an upper quasi triangular matrix U (N x N) eg. x x x x x x x x x 0 x x x x x x x x 0 0 x x x x x x x 0 0 0 r r x x x x 0 0 0 r r x x x x 0 0 0 0 0 0 x x x 0 0 0 0 0 0 0 x x 0 0 0 0 0 0 0 0 x It can handle the r r block if you tell it where to look with trows, here trows[3] = 1 rest are zero. r r I am aware that this is stupid. The Eigenvalues are specified in uvals (N). Gives the vector of vectors uvecs (N x N) of corresponding eigenvectors. So many special cases... **/ template void UTSymmEigenvectors(Matrix &U, std::vector trows, std::vector uvals, std::vector > &uvecs){ int N = U.dim; uvecs.resize(N); T a,b,c,d,L1,L2,Norm,lab; for(int eno = 0;eno void UTSymmEigensystem(Matrix &U, std::vector trows, std::vector uvals, std::vector > &uvecs){ int N = U.dim; uvecs.resize(N); uvals.resize(N); T a,b,c,d,L1,L2,apd,amd,bc, Norm, lab; for(int eno = 0;eno void UTeigenvectors(Matrix &U, std::vector trows, std::vector uvals, std::vector > &uvecs){ int N = uvals.size(); uvecs.resize(N); for(int i=0; i abs(L1-d) ){ uvecs[eno-1][eno-1] = b/(L1-a); uvecs[eno-1][eno] = 1; } else{ uvecs[eno-1][eno-1] = 1; uvecs[eno-1][eno] = c/(L1-d); } if( abs(L2-a) > abs(L2-d) ){ uvecs[eno][eno-1] = b/(L2-a); uvecs[eno][eno] = 1; } else{ uvecs[eno][eno-1] = 1; uvecs[eno][eno] = c/(L2-d); } tag = 2; ///precomputed last two components } for(int i=(eno-tag);i>=0;i--){ ///Simple eval. if tag = 2 do two evecs at once if(trows[i] == 0){ for(int j=i+1;j<=eno;j++){ uvecs[eno][i] = uvecs[eno][i] - U(i,j)*uvecs[eno][j]; if(tag==2){uvecs[eno-1][i] = uvecs[eno-1][i] - U(i,j)*uvecs[eno-1][j];} } if(i void UTeigenvalues(Matrix &U, std::vector trows, std::vector &uvals){ int N = U.dim; uvals.resize(N); for(int eno = 0;eno void UTeigensystem(Matrix &U, std::vector trows, std::vector &uvals, std::vector > &uvecs){ UTeigenvalues(U, trows, uvals); UTeigenvectors(U, trows, uvals, uvecs); } /** Determine the structure of the Reduced Matrix U e.g. x x x x x x x x x x 0 0 x x x 0 0 0 x x 0 0 0 x x here trows = {1 , 0 , 0, 1, 0} **/ template void UTrows(Matrix &U, std::vector &trows){ fill(trows,0); T nrm = abs( U.Norm() ); int M = U.dim; for(int i=1;i (T)abs(nrm) ){ trows[i] = 1; } } } } #endif