diff --git a/davidson.h b/davidson.h index 5b843a6..a37cd2b 100644 --- a/davidson.h +++ b/davidson.h @@ -27,7 +27,7 @@ namespace LA { //Davidson diagonalization of real symmetric matrix (modified Lanczos), works also for right eigenvectors on non-symmetric matrix - +//should work for complex hermitian-only too, but was not tested yet (maybe somwhere complex conjugation will have to be added) //matrix can be any class which has nrows(), ncols(), diagonalof(), issymmetric(), and gemv() available //does not even have to be explicitly stored - direct CI //therefore the whole implementation must be a template in a header @@ -57,7 +57,7 @@ if(eivals.size() vec1(n),vec2(n); NRMat smallH(maxkrylov,maxkrylov),smallS(maxkrylov,maxkrylov),smallV; -NRVec r(maxkrylov); +NRVec::normtype> r(maxkrylov); NRVec *v0,*v1; AuxStorage *s0,*s1; @@ -87,9 +87,9 @@ if(initguess) initguess(vec1); else { const T *diagonal = bigmat.diagonalof(vec2,false,true); - T t=1e100; int i,j; + typename LA_traits::normtype t=1e100; int i,j; vec1=0; - for(i=0, j= -1; i::realpart(diagonal[i])::realpart(diagonal[i]); j=i;} vec1[j]=1; } @@ -145,14 +145,17 @@ if(bigmat.issymmetric()) } else { - NRVec ri(krylovsize+1),beta(krylovsize+1); + NRVec::normtype> ri(krylovsize+1); + NRVec beta(krylovsize+1); NRMat scratch; scratch=smallV; gdiagonalize(scratch, r, ri,NULL, &smallV, 1, krylovsize+1, 2, 0, &smallSwork, &beta); - for(int i=0; i<=krylovsize; ++i) {r[i]/=beta[i]; ri[i]/=beta[i];} + //the following is definitely NOT OK for non-hermitian complex matrices, but we do not support these + //it is just to make the code compilable for T both real and complex + for(int i=0; i<=krylovsize; ++i) {r[i]/=LA_traits::realpart(beta[i]); ri[i]/=LA_traits::realpart(beta[i]);} } -T eival_n=r[nroot]; +typename LA_traits::normtype eival_n=r[nroot]; oldnroot=nroot; typename LA_traits::normtype test=std::abs(smallV(krylovsize,nroot)); if(test::normtype denom = LA_traits::realpart(diagonal[i]) - eival_n; denom = denom<0?-std::max(0.1,std::abs(denom)):std::max(0.1,std::abs(denom)); vec1[i] /= denom; } diff --git a/nonclass.cc b/nonclass.cc index 1ec68dc..6db71bb 100644 --- a/nonclass.cc +++ b/nonclass.cc @@ -1301,6 +1301,24 @@ void gdiagonalize(NRMat &a, NRVec< std::complex > &w, } +//for compatibility in davidson +void gdiagonalize(NRMat > &a, NRVec &wr, NRVec &wi, + NRMat > *vl, NRMat > *vr, const bool corder, int n, const int sorttype, const int biorthonormalize, + NRMat > *b, NRVec > *beta) +{ +if(wr.size()!=wi.size()) laerror("length mismatch in gdiagonalize"); +NRVec > w(wr.size()); +gdiagonalize(a,w,vl,vr,corder,n,sorttype,biorthonormalize,b,beta); +wr.copyonwrite(); +wi.copyonwrite(); +for(int i=0; i const NRMat realpart > >(const NRMat< std::complex > &a) { diff --git a/nonclass.h b/nonclass.h index c103b7c..494da68 100644 --- a/nonclass.h +++ b/nonclass.h @@ -115,6 +115,11 @@ extern void gdiagonalize(NRMat &a, NRVec< std::complex > &w, const bool corder=1, int n=0, const int sorttype=0, const int biorthonormalize=0, NRMat *b=NULL, NRVec *beta=NULL); //eigenvectors are stored in complex matrices for T both double and complex +//for compatibility in davidson +extern void gdiagonalize(NRMat > &a, NRVec &wr, NRVec &wi, + NRMat > *vl, NRMat > *vr, const bool corder=1, int n=0, const int sorttype=0, const int biorthonormalize=0, + NRMat > *b=NULL, NRVec > *beta=NULL); + //complex,real,imaginary parts of various entities template extern const typename LA_traits::realtype realpart(const T&);