CHROMA
invcg1_array.cc
Go to the documentation of this file.
1 /*! \file
2  * \brief Conjugate-Gradient algorithm for a generic Linear Operator
3  */
4 
5 #include "chromabase.h"
7 
8 using namespace QDP::Hints;
9 
10 namespace Chroma {
11 
12 //! Conjugate-Gradient (CGNE) algorithm for a generic Linear Operator
13 /*! \ingroup invert
14  * This subroutine uses the Conjugate Gradient (CG) algorithm to find
15  * the solution of the set of linear equations
16  *
17  * Chi = A . Psi
18  *
19  * where A is hermitian
20  *
21  * Algorithm:
22 
23  * Psi[0] := initial guess; Linear interpolation (argument)
24  * r[0] := Chi - M^dag . M . Psi[0] ; Initial residual
25  * p[1] := r[0] ; Initial direction
26  * IF |r[0]| <= RsdCG |Chi| THEN RETURN; Converged?
27  * FOR k FROM 1 TO MaxCG DO CG iterations
28  * a[k] := |r[k-1]|**2 / <Mp[k],Mp[k]> ;
29  * Psi[k] += a[k] p[k] ; New solution std::vector
30  * r[k] -= a[k] M^dag . M . p[k] ; New residual
31  * IF |r[k]| <= RsdCG |Chi| THEN RETURN; Converged?
32  * b[k+1] := |r[k]|**2 / |r[k-1]|**2 ;
33  * p[k+1] := r[k] + b[k+1] p[k]; New direction
34  *
35  * Arguments:
36  *
37  * \param M Linear Operator (Read)
38  * \param chi Source (Read)
39  * \param psi Solution (Modify)
40  * \param RsdCG CG residual accuracy (Read)
41  * \param MaxCG Maximum CG iterations (Read)
42  * \param n_count Number of CG iteration (Write)
43  *
44  * Local Variables:
45  *
46  * p Direction std::vector
47  * r Residual std::vector
48  * cp | r[k] |**2
49  * c | r[k-1] |**2
50  * k CG iteration counter
51  * a a[k]
52  * b b[k+1]
53  * d < p[k], A.p[k] >
54  * Mp Temporary for M.p
55  *
56  * Subroutines:
57  * +
58  * A Apply matrix M or M to std::vector
59  *
60  * Operations:
61  *
62  * 2 A + 2 Nc Ns + N_Count ( 2 A + 10 Nc Ns )
63  */
64 
65 #undef PRINT_5D_RESID
66 template<typename T>
68  const multi1d<T> & chi,
69  multi1d<T>& psi,
70  const Real& RsdCG,
71  int MaxCG,
72  int& n_count)
73 {
74  START_CODE();
75 
76  const int N = psi.size();
77  const Subset& s = A.subset();
78 
79  multi1d<T> Ap(N); moveToFastMemoryHint(Ap);
80 
81  moveToFastMemoryHint(psi,true);
82 
83  multi1d<T> r(N); moveToFastMemoryHint(r);
84  multi1d<T> p(N); moveToFastMemoryHint(p);
85  multi1d<T> chi_internal(N); moveToFastMemoryHint(chi_internal);
86 
87  for(int i=0; i < N; i++) {
88  chi_internal[i][s] = chi[i];
89  }
90 
91 
92  Real chi_sq = Real(norm2(chi_internal,s));
93 
94  QDPIO::cout << "chi_norm = " << sqrt(chi_sq) << std::endl;
95  Real rsd_sq = (RsdCG * RsdCG) * chi_sq;
96 
97  //
98  // r[0] := Chi - A . Psi[0] where A is hermitian
99 
100  //
101  // r := [ Chi - A. psi ]
102 
103  A(Ap, psi, PLUS);
104  for(int n=0; n < N; ++n)
105  r[n][s] = chi[n] - Ap[n];
106 
107 #ifdef PRINT_5D_RESID
108  for(int n=0; n < N; n++) {
109  Double norm_r = norm2(r[n],s);
110  if( toBool( norm_r > Double(1.0e-20)) ) {
111  QDPIO::cout << "Iteration 0 r[" << n << "] = " << norm_r << std::endl;
112  }
113  }
114 #endif
115 
116 
117  // p[1] := r[0]
118  for(int n=0; n < N; ++n) {
119  p[n][s] = r[n];
120  }
121 
122  // Cp = |r[0]|^2
123  Double cp = norm2(r, s); /* 2 Nc Ns flops */
124 
125  QDPIO::cout << "InvCG: k = 0 cp = " << cp << " rsd_sq = " << rsd_sq << std::endl;
126 
127  // IF |r[0]| <= RsdCG |Chi| THEN RETURN;
128  if ( toBool(cp <= rsd_sq) )
129  {
130  n_count = 0;
131  revertFromFastMemoryHint(psi,true);
132  END_CODE();
133  return;
134  }
135 
136  //
137  // FOR k FROM 1 TO MaxCG DO
138  //
139  Real a, b;
140  Double c, d;
141 
142  for(int k = 1; k <= MaxCG; ++k)
143  {
144  // c = | r[k-1] |**2
145  c = cp;
146 
147  // a[k] := | r[k-1] |**2 / < p[k], Ap[k] > ;
148  //
149  // First compute d = < p, A.p >
150  // Mp = M(u) * p
151 
152  A(Ap, p, PLUS);
153 
154  // d = | mp | ** 2
155  d = innerProductReal(p, Ap, s); /* 2 Nc Ns flops */
156 
157  a = Real(c)/Real(d);
158 
159  // Psi[k] += a[k] p[k]
160  for(int n=0; n < N; ++n) {
161  psi[n][s] += a * p[n]; /* 2 Nc Ns flops */
162  }
163 
164  // r[k] -= a[k] A . p[k] ;
165  //
166  for(int n=0; n < N; ++n) {
167  r[n][s] -= a * Ap[n];
168  }
169 
170 #ifdef PRINT_5D_RESID
171  for(int n=0; n < N; n++) {
172  Double norm_r = norm2(r[n],s);
173  if( toBool( norm_r > Double(1.0e-20)) )
174  QDPIO::cout << "Iteration " << k << " r[" << n << "] = " << norm_r << std::endl;
175  }
176 #endif
177 
178  // IF |r[k]| <= RsdCG |Chi| THEN RETURN;
179 
180  // cp = | r[k] |**2
181  cp = norm2(r, s); /* 2 Nc Ns flops */
182 
183  QDPIO::cout << "InvCG: k = " << k << " cp = " << cp << std::endl;
184 
185  if ( toBool(cp <= rsd_sq) )
186  {
187  n_count = k;
188  revertFromFastMemoryHint(psi,true);
189  END_CODE();
190  return;
191  }
192 
193  // b[k+1] := |r[k]|**2 / |r[k-1]|**2
194  b = Real(cp) / Real(c);
195 #if 1
196  QDPIO::cout << "InvCGev: k = " << k << " alpha = " << a << " beta = " << b << std::endl;
197 #endif
198 
199  // p[k+1] := r[k] + b[k+1] p[k]
200  for(int n=0; n < N; ++n)
201  p[n][s] = r[n] + b*p[n]; /* Nc Ns flops */
202  }
203  n_count = MaxCG;
204  QDPIO::cerr << "Nonconvergence Warning" << std::endl;
205  revertFromFastMemoryHint(psi,true);
206  END_CODE();
207  return;
208 
209 }
210 
211 
212 
213 
214 // Fix here for now
215 template<>
217  const multi1d<LatticeFermion>& chi,
218  multi1d<LatticeFermion>& psi,
219  const Real& RsdCG,
220  int MaxCG,
221  int& n_count)
222 {
224 }
225 
226 } // end namespace Chroma
Primary include file for CHROMA library code.
#define END_CODE()
Definition: chromabase.h:65
#define START_CODE()
Definition: chromabase.h:64
Linear Operator to arrays.
Definition: linearop.h:61
EXTERN int MaxCG
void InvCG1(const LinearOperatorArray< LatticeFermion > &A, const multi1d< LatticeFermion > &chi, multi1d< LatticeFermion > &psi, const Real &RsdCG, int MaxCG, int &n_count)
Conjugate-Gradient (CGNE) algorithm for a generic Linear Operator.
void InvCG1_a(const LinearOperatorArray< T > &A, const multi1d< T > &chi, multi1d< T > &psi, const Real &RsdCG, int MaxCG, int &n_count)
Conjugate-Gradient (CGNE) algorithm for a generic Linear Operator.
Definition: invcg1_array.cc:67
Conjugate-Gradient algorithm for a generic Linear Operator.
unsigned s
Definition: ldumul_w.cc:37
unsigned i
Definition: ldumul_w.cc:34
unsigned n
Definition: ldumul_w.cc:36
int c
Definition: meslate.cc:61
Asqtad Staggered-Dirac operator.
Definition: klein_gord.cc:10
const WilsonTypeFermAct< multi1d< LatticeFermion > > Handle< const ConnectState > const multi1d< Real > enum InvType invType const multi1d< Real > & RsdCG
Definition: pbg5p_w.cc:30
Real rsd_sq
Definition: invbicg.cc:121
@ PLUS
Definition: chromabase.h:45
Double cp
Definition: invbicg.cc:107
Complex a
Definition: invbicg.cc:95
DComplex d
Definition: invbicg.cc:99
A(A, psi, r, Ncb, PLUS)
Complex b
Definition: invbicg.cc:96
int k
Definition: invbicg.cc:119
FloatingPoint< double > Double
Definition: gtest.h:7351
multi1d< LatticeFermion > r(Ncb)
chi
Definition: pade_trln_w.cc:24
psi
Definition: pade_trln_w.cc:191
int n_count
Definition: pade_trln_w.cc:69