davidson for complex hermitean
This commit is contained in:
14
davidson.h
14
davidson.h
@@ -33,7 +33,7 @@ namespace LA {
|
|||||||
//Note that for efficiency in a direct CI case the diagonalof() should cache its result
|
//Note that for efficiency in a direct CI case the diagonalof() should cache its result
|
||||||
|
|
||||||
|
|
||||||
//@@@should work for complex hermitian-only too, but was not tested yet (maybe somwhere complex conjugation will have to be added)
|
//works for complex hermitian-only too, but does not converge sowell for more than 1 root
|
||||||
//@@@ for large krylov spaces >200 it can occur 'convergence problem in sygv/syev in diagonalize()'
|
//@@@ for large krylov spaces >200 it can occur 'convergence problem in sygv/syev in diagonalize()'
|
||||||
//@@@options: left eigenvectors by matrix transpose, overridesymmetric (for nrmat)
|
//@@@options: left eigenvectors by matrix transpose, overridesymmetric (for nrmat)
|
||||||
//@@@small matrix gdiagonalize - shift complex roots up (option to gdiagonalize?)
|
//@@@small matrix gdiagonalize - shift complex roots up (option to gdiagonalize?)
|
||||||
@@ -158,12 +158,19 @@ else
|
|||||||
typename LA_traits<T>::normtype eival_n=r[nroot];
|
typename LA_traits<T>::normtype eival_n=r[nroot];
|
||||||
oldnroot=nroot;
|
oldnroot=nroot;
|
||||||
typename LA_traits<T>::normtype test=std::abs(smallV(krylovsize,nroot));
|
typename LA_traits<T>::normtype test=std::abs(smallV(krylovsize,nroot));
|
||||||
|
//std::cout <<"NROOT = "<<nroot<<" TEST = "<<test<<std::endl;
|
||||||
|
if(test>100.)
|
||||||
|
{
|
||||||
|
std::cout <<"Divergence in Davidson\n";
|
||||||
|
flag=1;
|
||||||
|
goto finished;
|
||||||
|
}
|
||||||
if(test<eps) nroot++;
|
if(test<eps) nroot++;
|
||||||
if(it==0) nroot = 0;
|
if(it==0) nroot = 0;
|
||||||
for(int iroot=0; iroot<=std::min(krylovsize,nroots-1); ++iroot)
|
for(int iroot=0; iroot<=std::min(krylovsize,nroots-1); ++iroot)
|
||||||
{
|
{
|
||||||
test = std::abs(smallV(krylovsize,iroot));
|
test = std::abs(smallV(krylovsize,iroot));
|
||||||
if(test>eps) nroot=std::min(nroot,iroot);
|
if(test>eps) nroot=std::min(nroot,iroot); //return to previous root
|
||||||
if(verbose && iroot<=std::max(oldnroot,nroot))
|
if(verbose && iroot<=std::max(oldnroot,nroot))
|
||||||
{
|
{
|
||||||
std::cout <<"Davidson: iter="<<it <<" dim="<<krylovsize<<" root="<<iroot<<" eigenvalue="<<r[iroot]<<"\n";
|
std::cout <<"Davidson: iter="<<it <<" dim="<<krylovsize<<" root="<<iroot<<" eigenvalue="<<r[iroot]<<"\n";
|
||||||
@@ -229,7 +236,8 @@ for(j=0; j<=krylovsize; ++j)
|
|||||||
typename LA_traits<T>::normtype vnorm2;
|
typename LA_traits<T>::normtype vnorm2;
|
||||||
if(!incore) s0->get(vec2,j);
|
if(!incore) s0->get(vec2,j);
|
||||||
do {
|
do {
|
||||||
T ab = vec1*(incore?v0[j]:vec2) /smallS(j,j);
|
// For COMPLEX the order matters, the first one gets conjuagted, changed vec1 to the right!
|
||||||
|
T ab = (incore?v0[j]:vec2)*vec1 /smallS(j,j);
|
||||||
vec1.axpy(-ab,incore?v0[j]:vec2);
|
vec1.axpy(-ab,incore?v0[j]:vec2);
|
||||||
vnorm2 = vec1.norm();
|
vnorm2 = vec1.norm();
|
||||||
if(vnorm2==0)
|
if(vnorm2==0)
|
||||||
|
|||||||
41
t.cc
41
t.cc
@@ -1137,7 +1137,7 @@ if(0)
|
|||||||
{
|
{
|
||||||
int n,m;
|
int n,m;
|
||||||
cin>>n >>m;
|
cin>>n >>m;
|
||||||
NRSMat<double> a(n,n);
|
NRSMat<double> a(n);
|
||||||
NRVec<double> rr(n);
|
NRVec<double> rr(n);
|
||||||
|
|
||||||
for(int i=0;i<n;++i) for(int j=0;j<=i;++j)
|
for(int i=0;i<n;++i) for(int j=0;j<=i;++j)
|
||||||
@@ -4460,7 +4460,7 @@ if(inv==false)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if(1)
|
if(0)
|
||||||
{
|
{
|
||||||
//test linear transform
|
//test linear transform
|
||||||
int r=3;
|
int r=3;
|
||||||
@@ -4500,4 +4500,41 @@ cout <<"Error = "<<(xt-y).norm()<<endl;
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(1)
|
||||||
|
{
|
||||||
|
//n must not be too small
|
||||||
|
int n,m;
|
||||||
|
cin>>n >>m;
|
||||||
|
NRSMat<complex<double> > a(n);
|
||||||
|
a.randomize(.5);
|
||||||
|
|
||||||
|
for(int i=0;i<n;++i)
|
||||||
|
{
|
||||||
|
a(i,i)= RANDDOUBLE() + .2*(i-n);
|
||||||
|
}
|
||||||
|
//cout <<"test matrix = "<<a;
|
||||||
|
|
||||||
|
NRVec<double> rr(n);
|
||||||
|
NRSMat<complex<double> > aa;
|
||||||
|
NRMat<complex<double> > vv(n,n);
|
||||||
|
aa=a; diagonalize(aa,rr,&vv);
|
||||||
|
cout <<"Exact energies "<<rr;
|
||||||
|
|
||||||
|
NRVec<complex<double> > r(m);
|
||||||
|
NRVec<complex<double> > *eivecs = new NRVec<complex<double> >[m];
|
||||||
|
davidson(a,r,eivecs,NULL,m,true,1e-6,true,10*n,n*10);
|
||||||
|
|
||||||
|
cout <<"Davidson energies " <<r;
|
||||||
|
cout <<"Exact energies "<<rr;
|
||||||
|
|
||||||
|
cout <<"Eigenvectors compare:\n";
|
||||||
|
for(int i=0; i<m; ++i)
|
||||||
|
{
|
||||||
|
cout <<eivecs[i];
|
||||||
|
for(int j=0; j<n;++j) cout <<vv[j][i]<<" ";
|
||||||
|
cout <<endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}//main
|
}//main
|
||||||
|
|||||||
30
vec.h
30
vec.h
@@ -311,10 +311,10 @@ public:
|
|||||||
|
|
||||||
//! compute the Euclidean inner product (with conjugation in complex case)
|
//! compute the Euclidean inner product (with conjugation in complex case)
|
||||||
inline const T operator*(const NRVec &rhs) const;
|
inline const T operator*(const NRVec &rhs) const;
|
||||||
inline const T dot(const NRVec &rhs) const {return *this * rhs;};
|
|
||||||
|
|
||||||
//! compute the Euclidean inner product (with conjugation in complex case) with a stride-vector
|
//! compute the Euclidean inner product (with conjugation in complex case) with a stride-vector
|
||||||
inline const T dot(const T *a, const int stride = 1) const;
|
inline const T dot(const T *a, const int stride = 1, bool conjugate=true) const;
|
||||||
|
inline const T dot(const NRVec &rhs, bool conjugate=true) const {return dot(&((*this)[0]),1,conjugate);};
|
||||||
|
|
||||||
void gemv(const T beta, const NRMat<T> &a, const char trans, const T alpha, const NRVec &x);
|
void gemv(const T beta, const NRMat<T> &a, const char trans, const T alpha, const NRVec &x);
|
||||||
void gemv(const T beta, const NRSMat<T> &a, const char trans /**< just for compatibility reasons */, const T alpha, const NRVec &x);
|
void gemv(const T beta, const NRSMat<T> &a, const char trans /**< just for compatibility reasons */, const T alpha, const NRVec &x);
|
||||||
@@ -1073,10 +1073,25 @@ inline const T NRVec<T>::operator*(const NRVec<T> &rhs) const {
|
|||||||
NOT_GPU(rhs);
|
NOT_GPU(rhs);
|
||||||
|
|
||||||
T dot(0);
|
T dot(0);
|
||||||
for(register int i=0; i<nn; ++i) dot += v[i]*rhs.v[i];
|
if(LA_traits<T>::is_complex()) for(register int i=0; i<nn; ++i) dot += LA_traits<T>::conjugate(v[i])*rhs.v[i];
|
||||||
|
else for(register int i=0; i<nn; ++i) dot += v[i]*rhs.v[i];
|
||||||
return dot;
|
return dot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
* compute dot product with optional conjugation
|
||||||
|
*/
|
||||||
|
template<typename T>
|
||||||
|
inline const T NRVec<T>::dot(const T *a, const int stride , bool conjugate) const
|
||||||
|
{
|
||||||
|
NOT_GPU(*this);
|
||||||
|
T dot(0);
|
||||||
|
if(LA_traits<T>::is_complex() && conjugate) for(register int i=0; i<nn; ++i) dot += LA_traits<T>::conjugate(v[i])*a[i*stride];
|
||||||
|
else for(register int i=0; i<nn; ++i) dot += v[i]*a[i*stride];
|
||||||
|
return dot;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************//**
|
/***************************************************************************//**
|
||||||
* indexing operator giving the element at given position with range checking in
|
* indexing operator giving the element at given position with range checking in
|
||||||
* the DEBUG mode
|
* the DEBUG mode
|
||||||
@@ -1801,9 +1816,9 @@ inline const std::complex<double> NRVec<std::complex<double> >::operator*(const
|
|||||||
* @return \f$\sum_{i=1}^N\vec{x}_{i}\cdot y_{\mathrm{stride}\cdot(i-1) + 1}\f$
|
* @return \f$\sum_{i=1}^N\vec{x}_{i}\cdot y_{\mathrm{stride}\cdot(i-1) + 1}\f$
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
template<>
|
template<>
|
||||||
inline const double NRVec<double>::dot(const double *y, const int stride) const {
|
inline const double NRVec<double>::dot(const double *y, const int stride, bool conjugate) const {
|
||||||
NOT_GPU(*this);
|
NOT_GPU(*this);
|
||||||
return cblas_ddot(nn, y, stride, v, 1);
|
return cblas_ddot(nn,v, 1,y,stride);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************//**
|
/***************************************************************************//**
|
||||||
@@ -1813,10 +1828,11 @@ inline const double NRVec<double>::dot(const double *y, const int stride) const
|
|||||||
* @return \f$\sum_{i=1}^N\vec{x}_{i}\cdot \overbar{y_{\mathrm{stride}\cdot(i-1) + 1}}\f$
|
* @return \f$\sum_{i=1}^N\vec{x}_{i}\cdot \overbar{y_{\mathrm{stride}\cdot(i-1) + 1}}\f$
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
template<>
|
template<>
|
||||||
inline const std::complex<double> NRVec<std::complex<double> >::dot(const std::complex<double> *y, const int stride) const {
|
inline const std::complex<double> NRVec<std::complex<double> >::dot(const std::complex<double> *y, const int stride, bool conjugate) const {
|
||||||
std::complex<double> dot;
|
std::complex<double> dot;
|
||||||
NOT_GPU(*this);
|
NOT_GPU(*this);
|
||||||
cblas_zdotc_sub(nn, y, stride, v, 1, &dot);
|
if(conjugate) cblas_zdotc_sub(nn, v,1,y, stride, &dot);
|
||||||
|
else cblas_zdotc_sub(nn, v,1,y, stride, &dot);
|
||||||
return dot;
|
return dot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user