diff --git a/lib/algorithms/Algorithms.h b/lib/algorithms/Algorithms.h index e6a3f530..28bdfe24 100644 --- a/lib/algorithms/Algorithms.h +++ b/lib/algorithms/Algorithms.h @@ -53,6 +53,7 @@ Author: Peter Boyle #include #include #include +#include #include #include #include diff --git a/lib/algorithms/iterative/ImplicitlyRestartedBlockLanczos.h b/lib/algorithms/iterative/ImplicitlyRestartedBlockLanczos.h new file mode 100644 index 00000000..92acb67e --- /dev/null +++ b/lib/algorithms/iterative/ImplicitlyRestartedBlockLanczos.h @@ -0,0 +1,700 @@ + /************************************************************************************* + + Grid physics library, www.github.com/paboyle/Grid + + Source file: ./lib/algorithms/iterative/ImplicitlyRestartedBlockLanczos.h + + Copyright (C) 2015 + +Author: Peter Boyle +Author: Chulwoo Jung +Author: Yong-Chull Jang +Author: Guido Cossu + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + See the full license in the file "LICENSE" in the top level distribution directory + *************************************************************************************/ + /* END LEGAL */ +#ifndef GRID_IRBL_H +#define GRID_IRBL_H + +#include //memset + +#define clog std::cout << GridLogMessage + +namespace Grid { + +///////////////////////////////////////////////////////////// +// Implicitly restarted block lanczos +///////////////////////////////////////////////////////////// +template +class ImplicitlyRestartedBlockLanczos { + +private: + + std::string cname = std::string("ImplicitlyRestartedBlockLanczos"); + int MaxIter; // Max iterations + int Nstop; // Number of evecs checked for convergence + int Nu; // Numbeer of vecs in the unit block + int Nk; // Number of converged sought + int Nm; // total number of vectors + int Nblock_k; // Nk/Nu + int Nblock_m; // Nm/Nu + RealD eresid; + IRLdiagonalisation diagonalisation; + //////////////////////////////////// + // Embedded objects + //////////////////////////////////// + SortEigen _sort; + LinearOperatorBase &_Linop; + OperatorFunction &_poly; + + ///////////////////////// + // Constructor + ///////////////////////// +public: + ImplicitlyRestartedBlockLanczos(LinearOperatorBase &Linop, // op + OperatorFunction & poly, // polynomial + int _Nstop, // really sought vecs + int _Nu, // vecs in the unit block + int _Nk, // sought vecs + int _Nm, // total vecs + RealD _eresid, // resid in lmd deficit + int _MaxIter, // Max iterations + IRLdiagonalisation _diagonalisation = IRLdiagonaliseWithEigen) + : _Linop(Linop), _poly(poly), + Nstop(_Nstop), Nu(_Nu), Nk(_Nk), Nm(_Nm), + Nblock_m(_Nm/_Nu), Nblock_k(_Nk/_Nu), + eresid(_eresid), MaxIter(_MaxIter), + diagonalisation(_diagonalisation) + { assert( (Nk%Nu==0) && (Nm%Nu==0) ); }; + + //////////////////////////////// + // Helpers + //////////////////////////////// + static RealD normalize(Field& v) + { + RealD nn = norm2(v); + nn = sqrt(nn); + v = v * (1.0/nn); + return nn; + } + + void orthogonalize(Field& w, std::vector& evec, int k) + { + typedef typename Field::scalar_type MyComplex; + MyComplex ip; + + for(int j=0; j 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& eval, + std::vector& evec, + const std::vector& src, int& Nconv) + { + std::string fname = std::string(cname+"::calc()"); + GridBase *grid = evec[0]._grid; + assert(grid == src[0]._grid); + assert( Nu = src.size() ); + + clog << std::string(74,'*') << std::endl; + clog << fname + " starting iteration 0 / "<< MaxIter<< std::endl; + clog << std::string(74,'*') << std::endl; + clog <<" -- seek Nk = "<< Nk <<" vectors"<< std::endl; + clog <<" -- accept Nstop = "<< Nstop <<" vectors"<< std::endl; + clog <<" -- total Nm = "<< Nm <<" vectors"<< std::endl; + clog <<" -- size of eval = "<< eval.size() << std::endl; + clog <<" -- size of evec = "<< evec.size() << std::endl; + if ( diagonalisation == IRLdiagonaliseWithDSTEGR ) { + clog << "Diagonalisation is DSTEGR "<< std::endl; + } else if ( diagonalisation == IRLdiagonaliseWithQR ) { + clog << "Diagonalisation is QR "<< std::endl; + } else if ( diagonalisation == IRLdiagonaliseWithEigen ) { + clog << "Diagonalisation is Eigen "<< std::endl; + } + clog << std::string(74,'*') << std::endl; + + assert(Nm == evec.size() && Nm == eval.size()); + + std::vector> lmd(Nu,std::vector(Nm,0.0)); + std::vector> lme(Nu,std::vector(Nm,0.0)); + std::vector> lmd2(Nu,std::vector(Nm,0.0)); + std::vector> lme2(Nu,std::vector(Nm,0.0)); + std::vector eval2(Nm); + + Eigen::MatrixXcd Qt = Eigen::MatrixXcd::Zero(Nm,Nm); + + std::vector Iconv(Nm); + std::vector B(Nm,grid); // waste of space replicating + + std::vector f(Nu,grid); + std::vector f_copy(Nu,grid); + Field v(grid); + + int k1 = 1; + int k2 = Nk; + + Nconv = 0; + + RealD beta_k; + + // Set initial vector + for (int i=0; i=Nstop ){ + goto converged; + } + } // end of iter loop + + clog <<"**************************************************************************"<< std::endl; + std::cout<< GridLogError << fname + " NOT converged."; + clog <<"**************************************************************************"<< std::endl; + abort(); + + converged: + // Sorting + eval.resize(Nconv); + evec.resize(Nconv,grid); + for(int i=0; i>& lmd, + std::vector>& lme, + std::vector& evec, + std::vector& w, + std::vector& w_copy, + int b) + { + const RealD tiny = 1.0e-20; + + int Nu = w.size(); + int Nm = evec.size(); + assert( b < Nm/Nu ); + + // converts block index to full indicies for an interval [L,R) + int L = Nu*b; + int R = Nu*(b+1); + + Real beta; + + clog << "A: b = " << b << std::endl; + // 3. wk:=Avk−βkv_{k−1} + for (int k=L, u=0; k0) { + clog << "B: b = " << b << std::endl; + for (int u=0; u HermOp(Ddwf); const int Nstop = 30; + const int Nu = 4; const int Nk = 60; const int Np = 60; const int Nm = Nk+Np; @@ -92,19 +93,21 @@ int main (int argc, char ** argv) // ChebyshevLanczos Cheb(9.,1.,0.,20); // Cheb.csv(std::cout); // exit(-24); - ImplicitlyRestartedLanczos IRL(HermOp,Cheb,Nstop,Nk,Nm,resid,MaxIt); + ImplicitlyRestartedBlockLanczos IRBL(HermOp,Cheb,Nstop,Nu,Nk,Nm,resid,MaxIt); std::vector eval(Nm); - FermionField src(FrbGrid); - gaussian(RNG5rb,src); + + std::vector src(Nu,FrbGrid); + for ( int i=0; i evec(Nm,FrbGrid); - for(int i=0;i<1;i++){ - std::cout << GridLogMessage <