mirror of
https://github.com/paboyle/Grid.git
synced 2026-07-17 15:43:27 +01:00
Sorting eval/evec according to RitzFilter
This commit is contained in:
@@ -30,6 +30,7 @@ See the full license in the file "LICENSE" in the top level distribution directo
|
||||
#define GRID_BLOCKED_KRYLOV_SCHUR_H
|
||||
|
||||
#include <iomanip>
|
||||
#include <numeric>
|
||||
|
||||
NAMESPACE_BEGIN(Grid);
|
||||
|
||||
@@ -697,8 +698,22 @@ private:
|
||||
{
|
||||
Eigen::ComplexEigenSolver<CMat> es;
|
||||
es.compute(Hk);
|
||||
evals = es.eigenvalues();
|
||||
littleEvecs = es.eigenvectors();
|
||||
|
||||
// Sort to match schurReorder ordering.
|
||||
int n = es.eigenvalues().size();
|
||||
ComplexComparator cComp(ritzFilter);
|
||||
std::vector<int> idx(n);
|
||||
std::iota(idx.begin(), idx.end(), 0);
|
||||
std::sort(idx.begin(), idx.end(), [&](int a, int b){
|
||||
return cComp(toStdCmplx(es.eigenvalues()(a)), toStdCmplx(es.eigenvalues()(b)));
|
||||
});
|
||||
|
||||
evals.resize(n);
|
||||
littleEvecs.resize(n, n);
|
||||
for (int k = 0; k < n; k++) {
|
||||
evals(k) = es.eigenvalues()(idx[k]);
|
||||
littleEvecs.col(k) = es.eigenvectors().col(idx[k]);
|
||||
}
|
||||
|
||||
evecs.clear();
|
||||
for (int k = 0; k < Nkeep; k++) {
|
||||
@@ -735,6 +750,7 @@ private:
|
||||
std::cout << GridLogMessage << "BlockKrylovSchur: Ritz estimate[" << k
|
||||
<< "] = " << res << " eval = " << evals[k] << std::endl;
|
||||
if (res < rtol) Nconv++;
|
||||
else break;
|
||||
}
|
||||
return Nconv;
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ See the full license in the file "LICENSE" in the top level distribution directo
|
||||
#define GRID_HARMONIC_BLOCKED_KRYLOV_SCHUR_H
|
||||
|
||||
#include <iomanip>
|
||||
#include <numeric>
|
||||
|
||||
NAMESPACE_BEGIN(Grid);
|
||||
|
||||
@@ -574,8 +575,22 @@ private:
|
||||
{
|
||||
Eigen::ComplexEigenSolver<CMat> es;
|
||||
es.compute(Hk);
|
||||
evals = es.eigenvalues();
|
||||
littleEvecs = es.eigenvectors();
|
||||
|
||||
// Sort to match schurReorder ordering.
|
||||
int n = es.eigenvalues().size();
|
||||
ComplexComparator cComp(ritzFilter);
|
||||
std::vector<int> idx(n);
|
||||
std::iota(idx.begin(), idx.end(), 0);
|
||||
std::sort(idx.begin(), idx.end(), [&](int a, int b){
|
||||
return cComp(toStdCmplx(es.eigenvalues()(a)), toStdCmplx(es.eigenvalues()(b)));
|
||||
});
|
||||
|
||||
evals.resize(n);
|
||||
littleEvecs.resize(n, n);
|
||||
for (int k = 0; k < n; k++) {
|
||||
evals(k) = es.eigenvalues()(idx[k]);
|
||||
littleEvecs.col(k) = es.eigenvectors().col(idx[k]);
|
||||
}
|
||||
|
||||
evecs.clear();
|
||||
for (int k = 0; k < Nkeep; k++) {
|
||||
@@ -612,6 +627,7 @@ private:
|
||||
<< "HarmonicBlockKrylovSchur: Ritz estimate[" << k
|
||||
<< "] = " << res << " eval = " << evals[k] << std::endl;
|
||||
if (res < rtol) Nconv++;
|
||||
else break;
|
||||
}
|
||||
return Nconv;
|
||||
}
|
||||
|
||||
@@ -105,8 +105,8 @@ struct ComplexComparator
|
||||
bool operator()(std::complex<double> z1, std::complex<double> z2) {
|
||||
RealD tmp1=std::abs(std::imag(z1));
|
||||
RealD tmp2=std::abs(std::imag(z2));
|
||||
if ( std::abs(std::real(z1)) >4.) tmp1 += 100.;
|
||||
if ( std::abs(std::real(z2)) >4.) tmp2 += 100.;
|
||||
if ( std::abs(std::real(z1)) >2.) tmp1 += 100.;
|
||||
if ( std::abs(std::real(z2)) >2.) tmp2 += 100.;
|
||||
switch (RF) {
|
||||
case EvalNormSmall:
|
||||
return std::abs(z1) < std::abs(z2);
|
||||
@@ -738,35 +738,36 @@ if (!shift){
|
||||
{
|
||||
std::cout << GridLogMessage << "Computing eigenvalues." << std::endl;
|
||||
|
||||
// evals = S.diagonal();
|
||||
int n = evals.size(); // should be regular Nm
|
||||
|
||||
evecs.clear();
|
||||
// evecs.assign(n, Field(Grid));
|
||||
|
||||
// TODO: is there a faster way to get the eigenvectors of a triangular matrix?
|
||||
// Rayleigh.triangularView<Eigen::Upper> tri;
|
||||
|
||||
Eigen::ComplexEigenSolver<Eigen::MatrixXcd> es;
|
||||
// es.compute(Rayleigh);
|
||||
es.compute(S);
|
||||
evals = es.eigenvalues();
|
||||
littleEvecs = es.eigenvectors();
|
||||
|
||||
// std::cout << GridLogDebug << "Little evecs: " << littleEvecs << std::endl;
|
||||
// std::cout << "Rayleigh diag: " << S.diagonal() << std::endl;
|
||||
// std::cout << "Rayleigh evals: " << evals << std::endl;
|
||||
// Sort eigenvalues/evecs to match the schurReorder ordering.
|
||||
int n = es.eigenvalues().size();
|
||||
ComplexComparator cComp(ritzFilter);
|
||||
std::vector<int> idx(n);
|
||||
std::iota(idx.begin(), idx.end(), 0);
|
||||
std::sort(idx.begin(), idx.end(), [&](int a, int b){
|
||||
return cComp(toStdCmplx(es.eigenvalues()(a)), toStdCmplx(es.eigenvalues()(b)));
|
||||
});
|
||||
|
||||
evals.resize(n);
|
||||
littleEvecs.resize(n, n);
|
||||
for (int k = 0; k < n; k++) {
|
||||
evals(k) = es.eigenvalues()(idx[k]);
|
||||
littleEvecs.col(k) = es.eigenvectors().col(idx[k]);
|
||||
}
|
||||
|
||||
// Convert evecs to lattice fields
|
||||
for (int k = 0; k < n; k++) {
|
||||
Eigen::VectorXcd vec = littleEvecs.col(k);
|
||||
Field tmp (basis[0].Grid());
|
||||
tmp = Zero();
|
||||
for (int j = 0; j < basis.size(); j++) {
|
||||
for (int j = 0; j < (int)basis.size(); j++) {
|
||||
tmp = tmp + vec[j] * basis[j];
|
||||
}
|
||||
evecs.push_back(tmp);
|
||||
// evecs[k] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -831,12 +832,12 @@ if (!shift){
|
||||
Eigen::VectorXcd evec_k = littleEvecs.col(k);
|
||||
RealD ritzEstimate = std::abs(b.dot(evec_k)); // b^\dagger s
|
||||
ritzEstimates.push_back(ritzEstimate);
|
||||
// ritzEstimates[k] = ritzEstimate;
|
||||
std::cout << GridLogMessage << "Ritz estimate for evec " << k << " = " << ritzEstimate << std::endl;
|
||||
if (ritzEstimate < rtol) {
|
||||
Nconv++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
// Check that Ritz estimate is explicitly || D (Uy) - lambda (Uy) ||
|
||||
// checkRitzEstimate();
|
||||
|
||||
@@ -338,6 +338,7 @@ int main (int argc, char ** argv)
|
||||
#if 0
|
||||
KrylovSchur KrySchur (Dwilson, UGrid, resid,EvalImNormSmall);
|
||||
// KrySchur(src[0], maxIter, Nm, Nk, Nstop);
|
||||
KrySchur.doEvalCheck=true;
|
||||
KrySchur(src[0], maxIter, Nm, Nk, Nstop,&shift);
|
||||
std::cout << GridLogMessage << "KrylovSchur evec.size= " << KrySchur.evecs.size()<< std::endl;
|
||||
#else
|
||||
@@ -345,8 +346,9 @@ int main (int argc, char ** argv)
|
||||
Nblock=LanParams.Nblock;
|
||||
bool if_verify=false;
|
||||
if(LanParams.verify) if_verify=true;
|
||||
// BlockKrylovSchur KrySchur (Dwilson, UGrid, resid,EvalImNormSmall);
|
||||
HarmonicBlockKrylovSchur KrySchur (Dwilson, UGrid, resid,shift,EvalNormSmall);
|
||||
BlockKrylovSchur KrySchur (Dwilson, UGrid, resid,EvalImNormSmall);
|
||||
// HarmonicBlockKrylovSchur KrySchur (Dwilson, UGrid, resid,shift,EvalNormSmall);
|
||||
KrySchur.doEvalCheck=true;
|
||||
KrySchur(src, maxIter, Nm, Nk, Nstop,Nblock,true,if_verify);
|
||||
std::cout << GridLogMessage << "BlockKrylovSchur evec.size= " << KrySchur.evecs.size()<< std::endl;
|
||||
#endif
|
||||
|
||||
@@ -10,8 +10,10 @@
|
||||
<Np>100</Np>
|
||||
<ReadEvec>0</ReadEvec>
|
||||
<maxIter>1000</maxIter>
|
||||
<reorthog>1</reorthog>
|
||||
<Nblock>4</Nblock>
|
||||
<verify>0</verify>
|
||||
<shift>1.5</shift>
|
||||
<resid>1e-10</resid>
|
||||
<ChebyLow>1</ChebyLow>
|
||||
<ChebyHigh>100</ChebyHigh>
|
||||
|
||||
Reference in New Issue
Block a user