CHROMA
mre_extrap_predictor.cc
Go to the documentation of this file.
1 #include "chromabase.h"
3 #include "meas/eig/gramschm.h"
6 
7 
8 namespace Chroma
9 {
10 
11  namespace MinimalResidualExtrapolation4DChronoPredictorEnv
12  {
13  namespace
14  {
15  // Create a new 4D Zero Guess Predictor
16  // No params to read -- but preserve form
17  AbsChronologicalPredictor4D<LatticeFermion>* createPredictor(XMLReader& xml,
18  const std::string& path)
19  {
20  unsigned int max_chrono = 1;
21 
22  try
23  {
24  XMLReader paramtop(xml, path);
25  read( paramtop, "./MaxChrono", max_chrono);
26  }
27  catch( const std::string& e ) {
28  QDPIO::cerr << "Caught exception reading XML: " << e << std::endl;
29  QDP_abort(1);
30  }
31 
33  }
34 
35  //! Local registration flag
36  bool registered = false;
37  }
38 
39  const std::string name = "MINIMAL_RESIDUAL_EXTRAPOLATION_4D_PREDICTOR";
40 
41  //! Register all the factories
42  bool registerAll()
43  {
44  bool success = true;
45  if (! registered)
46  {
47  success &= The4DChronologicalPredictorFactory::Instance().registerObject(name, createPredictor);
48  registered = true;
49  }
50  return success;
51  }
52  }
53 
54 
55 
56 
57 
58 
59  namespace MinimalResidualExtrapolation5DChronoPredictorEnv
60  {
61  namespace
62  {
63  // Create a new 5D Zero Guess Predictor
64  // No params to read
65  AbsChronologicalPredictor5D<LatticeFermion>* createPredictor(const int N5,
66  XMLReader& xml,
67  const std::string& path)
68  {
69  unsigned int max_chrono = 1;
70 
71  try
72  {
73  XMLReader paramtop(xml, path);
74  read( paramtop, "./MaxChrono", max_chrono);
75  }
76  catch( const std::string& e ) {
77  QDPIO::cerr << "Caught exception reading XML: " << e << std::endl;
78  QDP_abort(1);
79  }
80 
82  }
83 
84  //! Local registration flag
85  bool registered = false;
86  }
87 
88  const std::string name = "MINIMAL_RESIDUAL_EXTRAPOLATION_5D_PREDICTOR";
89 
90  //! Register all the factories
91  bool registerAll()
92  {
93  bool success = true;
94  if (! registered)
95  {
96  success &= The5DChronologicalPredictorFactory::Instance().registerObject(name, createPredictor);
97  registered = true;
98  }
99  return success;
100  }
101  }
102 
103 
104 
106  multi1d<LatticeFermion>& psi,
108  const multi1d<LatticeFermion>& chi)
109  {
110  START_CODE();
111 
112  int Nvec = chrono_buf->size();
113  switch(Nvec) {
114  case 0:
115  {
116  QDPIO::cout << "MRE Predictor: Zero vectors stored. Giving you zero guess" << std::endl;
117  psi = zero;
118  }
119  break;
120  case 1:
121  {
122  QDPIO::cout << "MRE Predictor: Only 1 std::vector stored. Giving you last solution " << std::endl;
123  chrono_buf->get(0,psi);
124  }
125  break;
126  default:
127  {
128  QDPIO::cout << "MRE Predictor: Finding extrapolation with "<< Nvec << " vectors" << std::endl;
130  }
131  break;
132  }
133 
134  END_CODE();
135  }
136 
137 
138  void
140  multi1d<LatticeFermion>& psi,
142  const multi1d<LatticeFermion>& chi)
143  {
144  START_CODE();
145 
146  const Subset& s= A.subset();
147 
148  int Nvec = chrono_buf->size();
149 
150 
151  // Construct an orthonormal basis from the
152  // vectors in the buffer. Stick to notation of paper and call these
153  // v
154  multi2d<LatticeFermion> v(Nvec, N5);
155 
156  for(int i=0; i < Nvec; i++) {
157  // Zero out the non subsetted part
158  for(int d5=0; d5 < N5; d5++) {
159  v[i][d5] = zero;
160  }
161 
162  // Grab the relevant std::vector from the chronobuf
163  multi1d<LatticeFermion> tmpvec(N5);
164  chrono_buf->get(i, tmpvec);
165 
166  if( i == 0 ) {
167  // First std::vector we just take
168  // Loop over 5th dim
169  for(int d5=0; d5 < N5; d5++) {
170  v[i][d5][s] = tmpvec[d5];
171  }
172  }
173  else {
174  // i-th std::vector. Orthogonalise against i-1 previous
175  // std::vector, but i is an index running from 0. So I need
176  // to pass i+1-1=i as the number of vectors to orthog against
177  //
178  // This is a very dumb GramSchmidt process and possibly
179  // unstable, however apparently (according to the paper)
180  // this is OK.
181  GramSchmArray(tmpvec, v, i, s);
182 
183  // Loop over 5th dim
184  for(int d5=0; d5 < N5; d5++) {
185  v[i][d5][s] = tmpvec[d5];
186  }
187  }
188 
189  // Normalise v[i]
190  Double norm = norm2(v[i][0], s);
191 
192  // Loop over 5th dim and accumulate
193  for(int d5=1; d5 < N5; d5++) {
194  norm += norm2(v[i][d5], s);
195  }
196 
197  // Square root
198  Double root_norm = sqrt(norm);
199 
200  // Normalise -- Loop over 5th dim
201  for(int d5=0; d5 < N5; d5++) {
202  v[i][d5][s] /= root_norm;
203  }
204 
205 
206  }
207 
208  // Now I need to form G_n m = v_[n]^{dag} A v[m]
209  multi2d<DComplex> G(Nvec,Nvec);
210 
211  for(int m = 0 ; m < Nvec; m++) {
212  multi1d<LatticeFermion> tmpvec(N5);
213 
214  // 5D Matrix application
215  A(tmpvec, v[m], PLUS);
216 
217 
218  for(int n = 0; n < Nvec; n++) {
219 
220  // Compute 5D ioner product
221  G(n,m) = innerProduct(v[n][0], tmpvec[0], s);
222  for(int d5=1; d5 < N5; d5++) {
223  G(n,m) += innerProduct(v[n][d5], tmpvec[d5], s);
224  }
225 
226  }
227  }
228 
229  // Now I need to form b_n = v[n]^{dag} chi
230  multi1d<DComplex> b(Nvec);
231 
232  for(int n = 0; n < Nvec; n++) {
233 
234  // Loop over 5th Dim
235  b[n] = innerProduct(v[n][0], chi[0], s);
236  for(int d5=1; d5 < N5; d5++) {
237  b[n] += innerProduct(v[n][d5], chi[d5], s);
238  }
239  }
240 
241  // Solve G_nm a_m = b_n:
242 
243  // First LU decompose G in place
244  multi1d<DComplex> a(Nvec);
245 
246  LUSolve(a, G, b);
247 
248 #if 0
249  // Check solution
250  multi1d<DComplex> Ga(Nvec);
251 
252 
253  for(int i=0; i < Nvec; i++) {
254  Ga[i] = G(i,0)*a[0];
255  for(int j=1; j < Nvec; j++) {
256  Ga[i] += G(i,j)*a[j];
257  }
258  }
259 
260  multi1d<DComplex> r(Nvec);
261  for(int i=0; i < Nvec; i++) {
262  r[i] = b[i]-Ga[i];
263  }
264 
265  QDPIO::cout << "Constraint Eq Solution Check" << std::endl;
266  for(int i=0; i < Nvec; i++) {
267  QDPIO::cout << " r[ " << i << "] = " << r[i] << std::endl;
268  }
269 #endif
270 
271  // Create the lnear combination
272 
273  // First piece
274  for(int d5=0; d5 < N5; d5++) {
275  psi[d5][s] = Complex(a[0])*v[0][d5];
276 
277 
278  for(int n=1; n < Nvec; n++) {
279  psi[d5][s] += Complex(a[n])*v[n][d5];
280  }
281 
282  }
283 
284  END_CODE();
285  }
286 
287 }
Primary include file for CHROMA library code.
Linear Operator to arrays.
Definition: linearop.h:61
void operator()(multi1d< LatticeFermion > &psi, const LinearOperatorArray< LatticeFermion > &A, const multi1d< LatticeFermion > &chi)
void find_extrap_solution(multi1d< LatticeFermion > &psi, const LinearOperatorArray< LatticeFermion > &A, const multi1d< LatticeFermion > &chi)
Handle< CircularBufferArray< LatticeFermion > > chrono_buf
static T & Instance()
Definition: singleton.h:432
Gramm-Schmidt orthogonolization.
Gramm-Schmidt orthogonolization.
void GramSchmArray(multi2d< LatticeFermion > &psi, const int Npsi, const multi2d< LatticeFermion > &vec, const int Nvec, const Subset &sub)
Gramm-Schmidt orthogonolization.
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.
static bool registered
Local registration flag.
BinaryReturn< C1, C2, FnInnerProduct >::Type_t innerProduct(const QDPSubType< T1, C1 > &s1, const QDPType< T2, C2 > &s2)
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