mirror of
https://github.com/paboyle/Grid.git
synced 2025-04-24 12:45:56 +01:00
print Ritz values before and after the shift; rollback to simple last lanczos vector rebuild; print formatting is changed
This commit is contained in:
parent
bc5ba39278
commit
3caf0e8b09
@ -118,23 +118,6 @@ public:
|
|||||||
normalize(w);
|
normalize(w);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Rudy Arthur's thesis pp.137
|
|
||||||
------------------------
|
|
||||||
Require: M > K P = M − K †
|
|
||||||
Compute the factorization AVM = VM HM + fM eM
|
|
||||||
repeat
|
|
||||||
Q=I
|
|
||||||
for i = 1,...,P do
|
|
||||||
QiRi =HM −θiI Q = QQi
|
|
||||||
H M = Q †i H M Q i
|
|
||||||
end for
|
|
||||||
βK =HM(K+1,K) σK =Q(M,K)
|
|
||||||
r=vK+1βK +rσK
|
|
||||||
VK =VM(1:M)Q(1:M,1:K)
|
|
||||||
HK =HM(1:K,1:K)
|
|
||||||
→AVK =VKHK +fKe†K † Extend to an M = K + P step factorization AVM = VMHM + fMeM
|
|
||||||
until convergence
|
|
||||||
*/
|
|
||||||
void calc(std::vector<RealD>& eval,
|
void calc(std::vector<RealD>& eval,
|
||||||
std::vector<Field>& evec,
|
std::vector<Field>& evec,
|
||||||
const std::vector<Field>& src, int& Nconv)
|
const std::vector<Field>& src, int& Nconv)
|
||||||
@ -197,10 +180,7 @@ until convergence
|
|||||||
int iter;
|
int iter;
|
||||||
for(iter = 0; iter<MaxIter; ++iter){
|
for(iter = 0; iter<MaxIter; ++iter){
|
||||||
|
|
||||||
clog <<" **********************"<< std::endl;
|
clog <<"#Restart iteration = "<< iter << std::endl;
|
||||||
clog <<" Restart iteration = "<< iter << std::endl;
|
|
||||||
clog <<" **********************"<< std::endl;
|
|
||||||
|
|
||||||
// additional (Nblock_m - Nblock_k) steps
|
// additional (Nblock_m - Nblock_k) steps
|
||||||
for(int b=Nblock_k; b<Nblock_m; ++b) blockwiseStep(lmd,lme,evec,f,f_copy,b);
|
for(int b=Nblock_k; b<Nblock_m; ++b) blockwiseStep(lmd,lme,evec,f,f_copy,b);
|
||||||
|
|
||||||
@ -213,11 +193,20 @@ until convergence
|
|||||||
}
|
}
|
||||||
Qt = Eigen::MatrixXcd::Identity(Nm,Nm);
|
Qt = Eigen::MatrixXcd::Identity(Nm,Nm);
|
||||||
diagonalize(eval2,lmd2,lme2,Nu,Nm,Nm,Qt,grid);
|
diagonalize(eval2,lmd2,lme2,Nu,Nm,Nm,Qt,grid);
|
||||||
|
|
||||||
// sorting
|
|
||||||
_sort.push(eval2,Nm);
|
_sort.push(eval2,Nm);
|
||||||
|
clog << "#Ritz value before shift: "<< std::endl;
|
||||||
|
for(int i=0; i<Nm; ++i){
|
||||||
|
std::cout.precision(13);
|
||||||
|
std::cout << "[" << std::setw(4)<< std::setiosflags(std::ios_base::right) <<i<<"] ";
|
||||||
|
std::cout << "Rval = "<<std::setw(20)<< std::setiosflags(std::ios_base::left)<< eval2[i] << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
if ( Nm>Nk ) {
|
||||||
|
clog <<" #Apply shifted QR transformations "<<std::endl;
|
||||||
|
//int k2 = Nk+Nu;
|
||||||
|
int k2 = Nk;
|
||||||
|
|
||||||
// Implicitly shifted QR transformations
|
|
||||||
Eigen::MatrixXcd BTDM = Eigen::MatrixXcd::Identity(Nm,Nm);
|
Eigen::MatrixXcd BTDM = Eigen::MatrixXcd::Identity(Nm,Nm);
|
||||||
Q = Eigen::MatrixXcd::Identity(Nm,Nm);
|
Q = Eigen::MatrixXcd::Identity(Nm,Nm);
|
||||||
|
|
||||||
@ -229,8 +218,6 @@ until convergence
|
|||||||
|
|
||||||
packHermitBlockTriDiagMatfromEigen(lmd,lme,Nu,Nblock_m,Nm,Nm,BTDM);
|
packHermitBlockTriDiagMatfromEigen(lmd,lme,Nu,Nblock_m,Nm,Nm,BTDM);
|
||||||
|
|
||||||
//int k2 = Nk+Nu;
|
|
||||||
int k2 = Nk;
|
|
||||||
for(int i=0; i<k2; ++i) B[i] = 0.0;
|
for(int i=0; i<k2; ++i) B[i] = 0.0;
|
||||||
for(int j=0; j<k2; ++j){
|
for(int j=0; j<k2; ++j){
|
||||||
for(int k=0; k<Nm; ++k){
|
for(int k=0; k<Nm; ++k){
|
||||||
@ -240,7 +227,10 @@ until convergence
|
|||||||
}
|
}
|
||||||
for(int i=0; i<k2; ++i) evec[i] = B[i];
|
for(int i=0; i<k2; ++i) evec[i] = B[i];
|
||||||
|
|
||||||
// Convergence test
|
// reconstruct initial vector for additional pole space
|
||||||
|
blockwiseStep(lmd,lme,evec,f,f_copy,Nblock_k-1);
|
||||||
|
|
||||||
|
// getting eigenvalues
|
||||||
for(int u=0; u<Nu; ++u){
|
for(int u=0; u<Nu; ++u){
|
||||||
for(int k=0; k<Nm; ++k){
|
for(int k=0; k<Nm; ++k){
|
||||||
lmd2[u][k] = lmd[u][k];
|
lmd2[u][k] = lmd[u][k];
|
||||||
@ -249,7 +239,18 @@ until convergence
|
|||||||
}
|
}
|
||||||
Qt = Eigen::MatrixXcd::Identity(Nm,Nm);
|
Qt = Eigen::MatrixXcd::Identity(Nm,Nm);
|
||||||
diagonalize(eval2,lmd2,lme2,Nu,Nk,Nm,Qt,grid);
|
diagonalize(eval2,lmd2,lme2,Nu,Nk,Nm,Qt,grid);
|
||||||
|
_sort.push(eval2,Nk);
|
||||||
|
clog << "#Ritz value after shift: "<< std::endl;
|
||||||
|
for(int i=0; i<Nk; ++i){
|
||||||
|
std::cout.precision(13);
|
||||||
|
std::cout << "[" << std::setw(4)<< std::setiosflags(std::ios_base::right) <<i<<"] ";
|
||||||
|
std::cout << "Rval = "<<std::setw(20)<< std::setiosflags(std::ios_base::left)<< eval2[i] << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Convergence test
|
||||||
|
clog <<" #Convergence test: "<<std::endl;
|
||||||
for(int k = 0; k<Nk; ++k) B[k]=0.0;
|
for(int k = 0; k<Nk; ++k) B[k]=0.0;
|
||||||
for(int j = 0; j<Nk; ++j){
|
for(int j = 0; j<Nk; ++j){
|
||||||
for(int k = 0; k<Nk; ++k){
|
for(int k = 0; k<Nk; ++k){
|
||||||
@ -262,7 +263,6 @@ until convergence
|
|||||||
for(int i=0; i<Nk; ++i){
|
for(int i=0; i<Nk; ++i){
|
||||||
|
|
||||||
_Linop.HermOp(B[i],v);
|
_Linop.HermOp(B[i],v);
|
||||||
|
|
||||||
RealD vnum = real(innerProduct(B[i],v)); // HermOp.
|
RealD vnum = real(innerProduct(B[i],v)); // HermOp.
|
||||||
RealD vden = norm2(B[i]);
|
RealD vden = norm2(B[i]);
|
||||||
eval2[i] = vnum/vden;
|
eval2[i] = vnum/vden;
|
||||||
@ -271,9 +271,9 @@ until convergence
|
|||||||
resid[i] = vv;
|
resid[i] = vv;
|
||||||
|
|
||||||
std::cout.precision(13);
|
std::cout.precision(13);
|
||||||
clog << "[" << std::setw(3)<< std::setiosflags(std::ios_base::right) <<i<<"] ";
|
std::cout << "[" << std::setw(4)<< std::setiosflags(std::ios_base::right) <<i<<"] ";
|
||||||
std::cout << "eval = "<<std::setw(25)<< std::setiosflags(std::ios_base::left)<< eval2[i];
|
std::cout << "eval = "<<std::setw(20)<< std::setiosflags(std::ios_base::left)<< eval2[i];
|
||||||
std::cout << " |H B[i] - eval[i]B[i]|^2 "<< std::setw(25)<< std::setiosflags(std::ios_base::right)<< vv<< std::endl;
|
std::cout << " resid^2 = "<< std::setw(20)<< std::setiosflags(std::ios_base::right)<< vv<< std::endl;
|
||||||
|
|
||||||
// change the criteria as evals are supposed to be sorted, all evals smaller(larger) than Nstop should have converged
|
// change the criteria as evals are supposed to be sorted, all evals smaller(larger) than Nstop should have converged
|
||||||
//if( (vv<eresid*eresid) && (i == Nconv) ){
|
//if( (vv<eresid*eresid) && (i == Nconv) ){
|
||||||
@ -285,43 +285,23 @@ until convergence
|
|||||||
} // i-loop end
|
} // i-loop end
|
||||||
|
|
||||||
clog <<" #modes converged: "<<Nconv<<std::endl;
|
clog <<" #modes converged: "<<Nconv<<std::endl;
|
||||||
|
|
||||||
for(int i=0; i<Nconv; ++i){
|
for(int i=0; i<Nconv; ++i){
|
||||||
std::cout.precision(13);
|
std::cout.precision(13);
|
||||||
clog << "[" << std::setw(3)<< std::setiosflags(std::ios_base::right) <<Iconv[i]<<"] ";
|
std::cout << "[" << std::setw(4)<< std::setiosflags(std::ios_base::right) <<Iconv[i]<<"] ";
|
||||||
std::cout << "eval_conv = "<<std::setw(25)<< std::setiosflags(std::ios_base::left)<< eval2[Iconv[i]];
|
std::cout << "eval_conv = "<<std::setw(20)<< std::setiosflags(std::ios_base::left)<< eval2[Iconv[i]];
|
||||||
std::cout << " |H B[i] - eval_conv[i]B[i]|^2 "<< std::setw(25)<< std::setiosflags(std::ios_base::right)<< resid[Iconv[i]]<< std::endl;
|
std::cout << " resid^2 = "<< std::setw(20)<< std::setiosflags(std::ios_base::right)<< resid[Iconv[i]]<< std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( Nconv>=Nstop ){
|
if ( Nconv>=Nstop ) break;
|
||||||
goto converged;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( iter < MaxIter-1 ) {
|
|
||||||
if ( Nu == 1 ) {
|
|
||||||
// reconstruct initial vector for additional pole space
|
|
||||||
blockwiseStep(lmd,lme,evec,f,f_copy,Nblock_k-1);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// update the first block
|
|
||||||
for (int i=0; i<Nu; ++i) {
|
|
||||||
//evec[i] = B[i];
|
|
||||||
orthogonalize(evec[i],evec,i);
|
|
||||||
}
|
|
||||||
// restart Nblock_k steps from the first block
|
|
||||||
for(int b=0; b<Nblock_k; ++b) blockwiseStep(lmd,lme,evec,f,f_copy,b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // end of iter loop
|
} // end of iter loop
|
||||||
|
|
||||||
clog <<"**************************************************************************"<< std::endl;
|
clog << std::string(74,'*') << std::endl;
|
||||||
std::cout<< GridLogError << fname + " NOT converged.";
|
if ( Nconv<Nstop ) {
|
||||||
clog <<"**************************************************************************"<< std::endl;
|
clog << fname + " NOT converged ; Summary :\n";
|
||||||
abort();
|
} else {
|
||||||
|
clog << fname + " CONVERGED ; Summary :\n";
|
||||||
converged:
|
// Sort convered eigenpairs.
|
||||||
// Sorting
|
|
||||||
eval.resize(Nconv);
|
eval.resize(Nconv);
|
||||||
evec.resize(Nconv,grid);
|
evec.resize(Nconv,grid);
|
||||||
for(int i=0; i<Nconv; ++i){
|
for(int i=0; i<Nconv; ++i){
|
||||||
@ -329,27 +309,16 @@ until convergence
|
|||||||
evec[i] = B[Iconv[i]];
|
evec[i] = B[Iconv[i]];
|
||||||
}
|
}
|
||||||
_sort.push(eval,evec,Nconv);
|
_sort.push(eval,evec,Nconv);
|
||||||
|
}
|
||||||
clog <<"**************************************************************************"<< std::endl;
|
clog << std::string(74,'*') << std::endl;
|
||||||
clog << fname + " CONVERGED ; Summary :\n";
|
|
||||||
clog <<"**************************************************************************"<< std::endl;
|
|
||||||
clog << " -- Iterations = "<< iter << "\n";
|
clog << " -- Iterations = "<< iter << "\n";
|
||||||
//clog << " -- beta(k) = "<< beta_k << "\n";
|
//clog << " -- beta(k) = "<< beta_k << "\n";
|
||||||
clog << " -- Nconv = "<< Nconv << "\n";
|
clog << " -- Nconv = "<< Nconv << "\n";
|
||||||
clog <<"**************************************************************************"<< std::endl;
|
clog << std::string(74,'*') << std::endl;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/* Saad PP. 195
|
|
||||||
1. Choose an initial vector v1 of 2-norm unity. Set β1 ≡ 0, v0 ≡ 0
|
|
||||||
2. For k = 1,2,...,m Do:
|
|
||||||
3. wk:=Avk−βkv_{k−1}
|
|
||||||
4. αk:=(wk,vk) //
|
|
||||||
5. wk:=wk−αkvk // wk orthog vk
|
|
||||||
6. βk+1 := ∥wk∥2. If βk+1 = 0 then Stop
|
|
||||||
7. vk+1 := wk/βk+1
|
|
||||||
8. EndDo
|
|
||||||
*/
|
|
||||||
void blockwiseStep(std::vector<std::vector<ComplexD>>& lmd,
|
void blockwiseStep(std::vector<std::vector<ComplexD>>& lmd,
|
||||||
std::vector<std::vector<ComplexD>>& lme,
|
std::vector<std::vector<ComplexD>>& lme,
|
||||||
std::vector<Field>& evec,
|
std::vector<Field>& evec,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user