CHROMA
mre_initcg_extrap_predictor.cc
Go to the documentation of this file.
1 #include "chromabase.h"
4 #include "meas/eig/gramschm.h"
8 #include "meas/eig/sn_jacob.h"
9 
10 namespace Chroma
11 {
12 
13  namespace MREInitCG4DChronoPredictorEnv
14  {
15  namespace
16  {
17  // Create a new 4D Zero Guess Predictor
18  // No params to read -- but preserve form
19  AbsChronologicalPredictor4D<LatticeFermion>* createPredictor(XMLReader& xml,
20  const std::string& path)
21  {
22  unsigned int max_chrono = 1;
23  std::string opt_eigen_id;
24  int nevec;
25  int max_evec;
26  try
27  {
28  XMLReader paramtop(xml, path);
29  read( paramtop, "./MaxChrono", max_chrono);
30  read( paramtop, "./MaxEvec", max_evec);
31  read( paramtop, "./opt_eigen_id", opt_eigen_id);
32  }
33  catch( const std::string& e ) {
34  QDPIO::cerr << "Caught exception reading XML: " << e << std::endl;
35  QDP_abort(1);
36  }
37 
38  return new MREInitCG4DChronoPredictor(max_chrono, opt_eigen_id, max_evec);
39  }
40 
41  //! Local registration flag
42  bool registered = false;
43  }
44 
45  const std::string name = "MRE_INITCG_4D_PREDICTOR";
46 
47  //! Register all the factories
48  bool registerAll()
49  {
50  bool success = true;
51  if (! registered)
52  {
53  success &= The4DChronologicalPredictorFactory::Instance().registerObject(name, createPredictor);
54  registered = true;
55  }
56  return success;
57  }
58  }
59 
60 
62  LatticeFermion& psi,
64  const LatticeFermion& chi)
65  {
66  START_CODE();
67 
68  // Always do this...
70 
71 
72  END_CODE();
73  }
74 
75 
76  void
78  LatticeFermion& psi,
80  const LatticeFermion& chi)
81  {
82  START_CODE();
83 
84  const Subset& s= A.subset();
85 
86 
87 
88 
89  int Nchrono = chrono_buf->size();
90 
91  QDPIO::cout << "MREInitCG Predictor: Got " << Nchrono << " chrono vecs" << std::endl;
92 
93 
94  psi = zero;
95 
96  if (Nchrono > 0 ) {
97 
98  if( Nchrono == 1 ) {
99 
100  // If only one chrono std::vector exists, give that.
101  LatticeFermion tmpvec;
102  chrono_buf->get(0, tmpvec);
103  psi[s] = tmpvec;
104 
105  }
106 
107  else {
108 
109  // Otherwise do minimum norm extrapolation
110  multi1d<LatticeFermion> v(Nchrono);
111  QDPIO::cout << "MREInitCG Predictor: Orthonormalizing the " << Nchrono << " chrono vecs" << std::endl;
112 
113  // Orthogonalize current against the last N....
114  for(int i=0; i < Nchrono; i++) {
115 
116  // Zero out the non subsetted part
117  v[i] = zero;
118 
119  // Grab the relevant std::vector from the chronobuf
120  // The way the circular buffer works is that i=0 is the
121  // most recent... as i increases vectors become less recent.
122  LatticeFermion tmpvec;
123  chrono_buf->get(i, tmpvec);
124 
125  if( i == 0 ) {
126  // First std::vector we just take
127  v[i][s] = tmpvec;
128  }
129  else {
130  // i-th std::vector. Orthogonalise against i-1 previous
131  // std::vector, but i is an index running from 0. So I need
132  // to pass i+1-1=i as the number of vectors to orthog against
133  //
134  // This is a very dumb GramSchmidt process and possibly
135  // unstable, however apparently (according to the paper)
136  // this is OK.
137  GramSchm(tmpvec, v, i, s);
138  GramSchm(tmpvec, v, i, s);
139  v[i][s] = tmpvec;
140  }
141  // QDPIO::cout << "Norm v[i] = " << norm2(v[i],s) << std::endl;
142  // Normalise v[i]
143  Double norm = sqrt(norm2(v[i], s));
144  v[i][s] /= norm;
145  }
146 
147  // Now I need to form G_n m = v_[n]^{dag} A v[m]
148  multi2d<DComplex> G(Nchrono,Nchrono);
149 
150  for(int m = 0 ; m < Nchrono; m++) {
151  LatticeFermion tmpvec;
152  A(tmpvec, v[m], PLUS);
153 
154  for(int n = 0; n < Nchrono; n++) {
155  G(n,m) = innerProduct(v[n], tmpvec, s);
156  }
157  }
158 
159  // Now I need to form b_n = v[n]^{dag} chi
160  multi1d<DComplex> b(Nchrono);
161 
162  for(int n = 0; n < Nchrono; n++) {
163  b[n] = innerProduct(v[n], chi, s);
164  }
165 
166  // Solve G_nm a_m = b_n:
167 
168  // First LU decompose G in place
169  multi1d<DComplex> a(Nchrono);
170 
171  LUSolve(a, G, b);
172 
173  // Create teh lnear combination
174  psi[s] = Complex(a[0])*v[0];
175  for(int n=1; n < Nchrono; n++) {
176  psi[s] += Complex(a[n])*v[n];
177  }
178  }
179  }
180 
181  QDPIO::cout << "MRE InitCG predictor: psi prepared " << std::endl;
182 
183  // Strategy: Rayleigh Ritz all the EVs, put back Neig of them.
185 
186  int Nevec = eiginfo.ncurEvals;
187  QDPIO::cout << "There are " << Nevec << " current EVs" << std::endl;
188 
189  if( Nevec > 0 ) {
190  LatticeFermion tmpvec;
191  multi1d<LatticeFermion> ev(Nevec);
192  for(int i=0; i < Nevec; i++) {
193 
194  // The EigCG rather conveniently Orthonormalizes
195  // evs for me, so I don't need to. Just copy them into ev
196  ev[i] = zero;
197  eiginfo.CvToLatFerm(ev[i],s,i);
198 
199  }
200 
201  QDPIO::cout << "MREInitCG: Making up little matrix" << std::endl;
202 
203  multi1d<Real> lambda(Nevec);
204  for(int i=0; i < Nevec;i++) {
205  A(tmpvec, ev[i], PLUS);
206  lambda[i] = innerProductReal(ev[i], tmpvec, s);
207  }
208 
209 
210  multi1d<Complex> offd(Nevec*(Nevec-1)/2);
211  int ij=0;
212  for(int i=0; i < Nevec; i++) {
213  A(tmpvec, ev[i], PLUS);
214  for(int j=0; j < i; j++) {
215  offd[ij] = innerProduct(ev[j], tmpvec);
216  ij++;
217  }
218  }
219 
220  QDPIO::cout << "MREInitCG: Calling Jacobi Diagonalizer " << std::endl;
221  Real rsda=Real(1.0e-5);
222  int n_jacob = SN_Jacob(ev, Nevec, lambda, offd,
223  rsda, 50, s);
224 
225 
226  int vecs_to_copy=Nevec; // Copy back all Nevec
227  if( Nevec > Neig ) {
228  vecs_to_copy = Neig; // If we have more vecs than max, only copy Max back
229  }
230 
231  QDPIO::cout << "MREInitCG: Copying " << vecs_to_copy << " vecs into EigInfo " << std::endl;
232  // EigCG Will Recompute necessary vectors & Matrices...
233  // Copy the Nvec chrono vectors into the buffer
234  for(int i=0; i < vecs_to_copy; i++) {
235  eiginfo.CvToEigCGvec(ev[i],s,i);
236  }
237 
238  QDPIO::cout << "MREInitCG: Resetting nCurVal" << std::endl;
239  eiginfo.ncurEvals = vecs_to_copy;
240 
241  }
242 
243 
244  END_CODE();
245  }
246 
247 
248 
249 
250 
251 }
Primary include file for CHROMA library code.
void CvToLatFerm(LatticeFermion &lf, const Subset &s, int v) const
Definition: containers.h:100
void CvToEigCGvec(const LatticeFermion &lf, const Subset &s, int v)
Definition: containers.h:112
Handle< CircularBuffer< LatticeFermion > > chrono_buf
void operator()(LatticeFermion &psi, const LinearOperator< LatticeFermion > &A, const LatticeFermion &chi)
void find_extrap_solution(LatticeFermion &psi, const LinearOperator< LatticeFermion > &A, const LatticeFermion &chi)
static T & Instance()
Definition: singleton.h:432
Gramm-Schmidt orthogonolization.
Gramm-Schmidt orthogonolization.
void GramSchm(multi1d< LatticeFermion > &psi, const int Npsi, const multi1d< LatticeFermion > &vec, const int Nvec, const Subset &sub)
Gramm-Schmidt orthogonolization.
Definition: gramschm.cc:127
int SN_Jacob(multi1d< LatticeFermion > &psi, const int N_eig, multi1d< Real > &lambda, multi1d< Complex > &off_diag, Real tolerance, int N_max, const Subset &sub)
Single-node Jacobi rotation.
Definition: sn_jacob.cc:226
void read(XMLReader &xml, const std::string &path, AsqtadFermActParams &param)
Read parameters.
void LUSolve(multi1d< DComplex > &a, const multi2d< DComplex > &M, const multi1d< DComplex > &b)
Solve M a = b by LU decomposition with partial pivoting.
Definition: lu_solve.cc:8
unsigned j
Definition: ldumul_w.cc:35
unsigned n
Definition: ldumul_w.cc:36
LU solver.
static int m[4]
Definition: make_seeds.cc:16
Minimal residual predictor - which takes also information from an EIG CG e-vec basis....
Named object function std::map.
static bool registered
Local registration flag.
BinaryReturn< C1, C2, FnInnerProduct >::Type_t innerProduct(const QDPSubType< T1, C1 > &s1, const QDPType< T2, C2 > &s2)
bool registerAll()
Register all the factories.
multi1d< LatticeColorMatrix > G
Asqtad Staggered-Dirac operator.
Definition: klein_gord.cc:10
int i
Definition: pbg5p_w.cc:55
@ PLUS
Definition: chromabase.h:45
multi1d< LatticeFermion > chi(Ncb)
Complex a
Definition: invbicg.cc:95
LatticeFermion psi
Definition: mespbg5p_w.cc:35
START_CODE()
A(A, psi, r, Ncb, PLUS)
Complex b
Definition: invbicg.cc:96
Double zero
Definition: invbicg.cc:106
multi1d< LatticeFermion > s(Ncb)
FloatingPoint< double > Double
Definition: gtest.h:7351
::std::string string
Definition: gtest.h:1979
int norm
Definition: qtopcor.cc:35