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