#ifndef EIGCGCONTROLLER_H #define EIGCGCONTROLLER_H //by Qi Liu 2012 #include #include #include #include template class EigCGController { private: const int nev; //typical nev=8; const int m; //typical m=24; should be bigger than 2*nev const int max_def_len;//the size of the deflation space that we try to accumulate const double max_eig_cut; //throw away those fake low modes const bool always_restart; //it is better not to usually Float* V; //the space for eigen vectors std::vector U; //at some point, we want to use float for U no matter what. //To save the usage of memory, //it is fine to use float since the low modes are not //accurately any way and it has not effect on the final result const int vec_len; //for convenient use between cps and bfm, this is as an input parameter. //better be infered from bfm_qdp class, it is the length of Fermion_t public: int def_len; //keep the record of the number of low modes we achieved std::complex *H; std::vector restart; private: static EigCGController* _instance; EigCGController(EigCGController &){}; EigCGController & operator=(EigCGController const &){}; EigCGController(int _nev, int _m, int _max_def_len, double _max_eig_cut, std::vector &_restart, bool _ar, int cg_vec_len): nev(_nev),m(_m),max_def_len(_max_def_len),max_eig_cut(_max_eig_cut),restart(_restart),vec_len(cg_vec_len),always_restart(_ar) { if(m<=2*nev) { printf("m should be larger than 2*nev !\n"); exit(-1); } def_len = 0; V = new Float[vec_len*m]; if(V==NULL){ printf("fail to malloc space for pointer V in eigcgcontroller\n"); exit(-1); } U.resize(max_def_len,NULL); for(int i=0;i[max_def_len*max_def_len]; //The max length. In the first few uses, only def_len*def_len is used. if(H==NULL) { printf("fail to malloc space for pointer H\n"); exit(-1); } if(restart.size()>2) { //check if it is decreasing order! for(unsigned int i=1;i=restart[i-1]) { printf("restart should in decreasing order!\n"); exit(-1); } } } } public: static void free() { delete _instance; _instance = NULL; } static EigCGController* getInstance() { if(NULL == _instance) { printf("Need to setup/initialize the instance first!\n"); exit(-1); //_instance = new EigCGController(); } return _instance; } static EigCGController* setInstance(int nev, int m, int max_def_len, double max_eig_cut, std::vector &restart, bool always_restart, int vec_len) { if(NULL == _instance) { _instance = new EigCGController(nev, m, max_def_len, max_eig_cut, restart, always_restart, vec_len); } else { printf("Should be initialized once only! or should be deleted before another use for a different case!\n"); exit(-1); } } ~EigCGController() { if(H!=NULL) delete [] H; H=NULL; if(V!=NULL) delete [] V; V=NULL; for(int i=0;i EigCGController* EigCGController::_instance = NULL; #endif