1
0
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:
Yong-Chull Jang 2018-02-02 18:43:37 -05:00
parent bc5ba39278
commit 3caf0e8b09

View File

@ -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 +fKeK 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,43 +193,64 @@ 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;
// Implicitly shifted QR transformations for(int i=0; i<Nm; ++i){
Eigen::MatrixXcd BTDM = Eigen::MatrixXcd::Identity(Nm,Nm); std::cout.precision(13);
Q = Eigen::MatrixXcd::Identity(Nm,Nm); 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;
unpackHermitBlockTriDiagMatToEigen(lmd,lme,Nu,Nblock_m,Nm,Nm,BTDM);
for(int ip=Nk; ip<Nm; ++ip){
shiftedQRDecompEigen(BTDM,Nu,Nm,eval2[ip],Q);
} }
packHermitBlockTriDiagMatfromEigen(lmd,lme,Nu,Nblock_m,Nm,Nm,BTDM); //----------------------------------------------------------------------
if ( Nm>Nk ) {
clog <<" #Apply shifted QR transformations "<<std::endl;
//int k2 = Nk+Nu;
int k2 = Nk;
//int k2 = Nk+Nu; Eigen::MatrixXcd BTDM = Eigen::MatrixXcd::Identity(Nm,Nm);
int k2 = Nk; Q = Eigen::MatrixXcd::Identity(Nm,Nm);
for(int i=0; i<k2; ++i) B[i] = 0.0;
for(int j=0; j<k2; ++j){ unpackHermitBlockTriDiagMatToEigen(lmd,lme,Nu,Nblock_m,Nm,Nm,BTDM);
for(int k=0; k<Nm; ++k){
B[j].checkerboard = evec[k].checkerboard;
B[j] += evec[k]*Q(k,j);
}
}
for(int i=0; i<k2; ++i) evec[i] = B[i];
// Convergence test for(int ip=Nk; ip<Nm; ++ip){
for(int u=0; u<Nu; ++u){ shiftedQRDecompEigen(BTDM,Nu,Nm,eval2[ip],Q);
for(int k=0; k<Nm; ++k){ }
lmd2[u][k] = lmd[u][k];
lme2[u][k] = lme[u][k]; packHermitBlockTriDiagMatfromEigen(lmd,lme,Nu,Nblock_m,Nm,Nm,BTDM);
for(int i=0; i<k2; ++i) B[i] = 0.0;
for(int j=0; j<k2; ++j){
for(int k=0; k<Nm; ++k){
B[j].checkerboard = evec[k].checkerboard;
B[j] += evec[k]*Q(k,j);
}
}
for(int i=0; i<k2; ++i) evec[i] = B[i];
// 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 k=0; k<Nm; ++k){
lmd2[u][k] = lmd[u][k];
lme2[u][k] = lme[u][k];
}
}
Qt = Eigen::MatrixXcd::Identity(Nm,Nm);
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;
} }
} }
Qt = Eigen::MatrixXcd::Identity(Nm,Nm); //----------------------------------------------------------------------
diagonalize(eval2,lmd2,lme2,Nu,Nk,Nm,Qt,grid);
// 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){
@ -261,8 +262,7 @@ until convergence
Nconv = 0; Nconv = 0;
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,71 +285,40 @@ 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){ eval[i] = eval2[Iconv[i]];
eval[i] = eval2[Iconv[i]]; evec[i] = B[Iconv[i]];
evec[i] = B[Iconv[i]]; }
_sort.push(eval,evec,Nconv);
} }
_sort.push(eval,evec,Nconv); clog << std::string(74,'*') << std::endl;
clog <<"**************************************************************************"<< 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_{k1}
4. αk:=(wk,vk) //
5. wk:=wkαkvk // wk orthog vk
6. βk+1 := wk2. 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,