CHROMA
containers.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 
3 #ifndef _INV_CONTAINERS__H
4 #define _INV_CONTAINERS__H
5 
6 #include "chromabase.h"
7 
8 namespace Chroma
9 {
10  namespace LinAlg
11  {
12 
13 
14  //! copies an EigCG std::vector to a LatticeFermion (Works only in single prec.
15  // Robert et.al. we might want to generalizes this to work for everything
16  // We will make a double prec eigCG at some point
17  template <typename T, typename R> inline
18  void CopyToLatFerm(T& lf, RComplex<R> *px, const Subset& s)
19  {
20  if(s.hasOrderedRep()){
21  int count=0 ;
22  //can be done with ccopy for speed...
23  for(int i=s.start(); i <= s.end(); i++)
24  for(int ss(0);ss<Ns;ss++)
25  for(int c(0);c<Nc;c++){
26  lf.elem(i).elem(ss).elem(c) = *(px+count);
27  count++;
28  }
29  }//if
30  else{
31  int i ;
32  const int *tab = s.siteTable().slice();
33  int count=0;
34  for(int x=0; x < s.numSiteTable(); ++x){
35  i = tab[x] ;
36  for(int ss(0);ss<Ns;ss++)
37  for(int c(0);c<Nc;c++){
38  lf.elem(i).elem(ss).elem(c) = *(px+count);
39  count++;
40  }
41  }
42  }//else
43  }
44 
45  //! copies a LatticeFermion into an EigCG std::vector
46  //! (Works only in single prec.
47  // Robert et.al. we might want to generalizes this to work for everything
48  template<typename T, typename R> inline
49  void CopyFromLatFerm(RComplex<R> *px, const T& lf, const Subset& s)
50  {
51 #ifndef QDP_IS_QDPJIT
52  if(s.hasOrderedRep()){
53  int count=0 ;
54  //can be done with ccopy for speed...
55  for(int i=s.start(); i <= s.end(); i++)
56  for(int ss(0);ss<Ns;ss++)
57  for(int c(0);c<Nc;c++){
58  *(px+count) = lf.elem(i).elem(ss).elem(c) ;
59  count++;
60  }
61  }//if
62  else{
63  int i ;
64  const int *tab = s.siteTable().slice();
65  int count=0;
66  for(int x=0; x < s.numSiteTable(); ++x){
67  i = tab[x] ;
68  for(int ss(0);ss<Ns;ss++)
69  for(int c(0);c<Nc;c++){
70  *(px+count) = lf.elem(i).elem(ss).elem(c) ;
71  count++;
72  }
73  }
74  }//else
75 #endif
76  }
77 
78  //--- OPT eigcg space ---//
79  class OptEigInfo{
80  public:
81  int N ; // std::vector dimension (large)
82  int ncurEvals ;
83  int lde ;
84  float restartTol ;
85  multi1d<Real> evals ;
86  multi1d<Complex> evecs ;
87  multi1d<Complex> H ;
88  multi1d<Complex> HU ;
89  void init(int ldh,int lde_, int nn){
90  restartTol =0 ;
91  ncurEvals = 0 ;
92  N=nn;
93  lde = lde_ ;
94  evals.resize(ldh);
95  evecs.resize(lde*ldh);
96  H.resize(ldh*ldh);
97  HU.resize(ldh*ldh);
98  }
99 
100  void CvToLatFerm(LatticeFermion& lf, const Subset& s, int v) const
101  {// returnts the std::vector v as a lattice fermion
102 #ifndef QDP_IS_QDPJIT
103  if(v>=evals.size()){
104  QDPIO::cerr<<"CvToLatFerm: index out of range"<<std::endl ;
105  QDP_abort(100);
106  }
107  RComplex<float> *px = (RComplex<float> *)&evecs[v*lde];
108  CopyToLatFerm<LatticeFermion, float>(lf,px,s);
109 #endif
110  }
111 
112  void CvToEigCGvec(const LatticeFermion& lf, const Subset& s, int v)
113  {// returnts the std::vector v as a lattice fermion
114 #ifndef QDP_IS_QDPJIT
115  if(v>=evals.size()){
116  QDPIO::cerr<<"CopyFromLatFerm: index out of range"<<std::endl ;
117  QDP_abort(101);
118  }
119  RComplex<float> *px = (RComplex<float> *)&evecs[v*lde];
120  CopyFromLatFerm<LatticeFermion, float>(px,lf,s);
121 #endif
122  }
123  } ;
124 
125  class EigInfo{
126  public:
127  int ncurEvals ;
128  int lde ;
129  float restartTol ;
130  multi1d<Real> evals ;
131  multi1d<LatticeFermion> evecs ;
132  multi1d<Complex> H ;
133  multi1d<Complex> HU ;
134  void init(int ldh,int lde_){
135  restartTol =0 ;
136  ncurEvals = 0 ;
137  lde = lde_ ;
138  evals.resize(ldh);
139  evecs.resize(ldh);
140  H.resize(ldh*ldh);
141  HU.resize(ldh*ldh);
142  }
143  EigInfo(const OptEigInfo& o, const Subset& s){
144  ncurEvals = o.ncurEvals ;
145  lde = o.lde ;
146  restartTol = o.restartTol ;
147  evals = o.evals ;
148  H = o.H ;
149  HU = o.HU ;
150  evecs.resize(o.evals.size()) ;
151  for(int v(0);v<ncurEvals;v++)
152  o.CvToLatFerm(evecs[v],s,v);
153  }
154  } ;
155 
156  //-------------------------------------------------------------------------
157  //! Hold vectors
158  /*! \ingroup invert */
159  template<class T> class Vectors
160  {
161  public:
162  multi1d<T> vec;
163  int N; // number of active vectors size of vec must be larger or equal to N
164 
165  Vectors():N(0){}
166  Vectors(const multi1d<T>& v):vec(v),N(v.size()){}
168 
170 
171  void AddVector(const T& v,const Subset& s){
172  if(N<vec.size()){
173  vec[N][s] = v;
174  N++;
175  }
176  }
177 
178  void AddVector(const T& v){
179  if(N<vec.size()){
180  vec[N] = v;
181  N++;
182  }
183  }
184 
185  void NormalizeAndAddVector(const T& v,const Double& inorm,
186  const Subset& s){
187  if(N<vec.size()){// inorm is the inverse of the norm
188  vec[N][s] = v;
189  vec[N][s] *= inorm;
190  N++;
191  }
192  }
193  void AddOrReplaceVector(const T& v,const Subset& s){
194  if(N<vec.size()){
195  vec[N][s] = v;
196  N++;
197  }
198  else{// replace the last std::vector
199  vec[N-1] = v;
200  }
201  }
202 
203  // This will only add as many vectors as they fit
204  void AddVectors(multi1d<T>& v,const Subset& s){
205  for(int i(0);i<v.size();i++)
206  AddVector(v[i],s);
207  }
208 
209  void AddVectors(multi1d<T>& v){
210  for(int i(0);i<v.size();i++)
211  AddVector(v[i]);
212  }
213 
214 
215  void resize(int n) {N=0;vec.resize(n);}
216  int size() const { return vec.size();}
217  int Nvecs() const { return N; }
218  T& operator[](int i){ return vec[i];}
219  };
220 
221 
222  //--- OPT eigbicg space ---//
223  template<typename R>
225  public:
226  int N ; // std::vector dimension (large)
227  int ncurEvals ;
228  int lde ;
229  float restartTol ;
230  multi1d<RComplex<R> > evals ;
231  multi1d<RComplex<R> > evecsL ;
232  multi1d<RComplex<R> > evecsR ;
233  multi1d<RComplex<R> > H ;
234  void init(int ldh,int lde_, int nn){
235  restartTol =0 ;
236  ncurEvals = 0 ;
237  N=nn;
238  lde = lde_ ;
239  evals.resize(ldh);
240  evecsL.resize(lde*ldh);
241  evecsR.resize(lde*ldh);
242  H.resize(ldh*ldh);
243  }
244 
245  void CvToLatFerm(LatticeFermion& lf, const Subset& s, int v, const std::string& LR) const
246  {// returnts the std::vector v as a lattice fermion
247  if(v>=evals.size()){
248  QDPIO::cerr<<"CvToLatFerm: index out of range"<<std::endl ;
249  QDP_abort(100);
250  }
251  RComplex<R> *px ;
252  if(LR=="L")
253  px = (RComplex<R> *)&evecsL[v*lde];
254  else
255  px = (RComplex<R> *)&evecsR[v*lde];
256 
257  CopyToLatFerm<LatticeFermion, R>(lf,px,s);
258  }
259 
260  void CvToEigCGvec(const LatticeFermion& lf, const Subset& s, int v, const std::string& LR)
261  {// returnts the std::vector v as a lattice fermion
262  if(v>=evals.size()){
263  QDPIO::cerr<<"CopyFromLatFerm: index out of range"<<std::endl ;
264  QDP_abort(101);
265  }
266 
267  RComplex<R> *px ;
268  if(LR=="L")
269  px = (RComplex<R> *)&evecsL[v*lde];
270  else
271  px = (RComplex<R> *)&evecsR[v*lde];
272 
273  CopyFromLatFerm<LatticeFermion, R>(px,lf,s);
274  }
275 
276  } ;
277 
278  //------------------------------------------------------------------------------
279  //! Holds eigenvalues and eigenvectors
280  /*! \ingroup invert */
281  template<class T> class RitzPairs
282  {
283  public:
286  int Neig;
287 
288  RitzPairs() {init(0);}
289  RitzPairs(int N) {init(N);}
290 
291  void init(int N) {
292  eval.resize(N);
293  evec.resize(N);
294  Neig = 0;
295  }
296 
297  void AddVector(const Double& e, const T& v,const Subset& s){
298  eval.AddVector(e);
299  evec.AddVector(v,s);
300  if (eval.N != evec.N)
301  {
302  QDPIO::cerr << __func__ << ": length of value and std::vector arrays are not the same" << std::endl;
303  QDP_abort(1);
304  }
305  Neig = evec.N;
306  }
307 
308  // This will only add as many vectors as they fit
309  void AddVectors(const multi1d<Double>& e,const multi1d<T>& v,const Subset& s){
310  for(int i(0);i<e.size();i++)
311  eval.AddVector(e[i]);
312  for(int i(0);i<v.size();i++)
313  evec.AddVector(v[i],s);
314  if (eval.N != evec.N)
315  {
316  QDPIO::cerr << __func__ << ": length of value and std::vector arrays are not the same" << std::endl;
317  QDP_abort(1);
318  }
319  Neig = evec.N;
320  }
321  };
322 
323 
324  //------------------------------------------------------------------------------
325  //! This is a square matrix
326  /*! \ingroup invert */
327  template<class T> class Matrix
328  {
329  public:
330  multi2d<T> mat;
331  int N; // active size
332 
333  Matrix():N(0){}
334  Matrix(const multi2d<T>& v):mat(v),N(v.size1())
335  {
336  if(v.size1() != v.size2())
337  QDPIO::cerr<<"WARNING!!! Matrix should be square!! CHECK YOUR CODE!\n";
338  }
339 
341 
343 
344  void resize(int size) {N=0; mat.resize(size,size);}
345  int size() const { return mat.size1();}
346  int ld() const { return mat.size1();}
347  int Nmat() const { return N; }
348  T& operator()(int i,int j){ return mat(i,j);}
349  };
350 
351 
352  //------------------------------------------------------------------------------
353  //! Hold vectors
354  /*! \ingroup invert */
355  template<class T> class VectorArrays
356  {
357  public:
358  multi2d<T> vec;
359  int N; // number of active vectors size of vec must be larger or equal to N
360  int Ls; // size of 5D arrays
361 
362  VectorArrays() : N(0) {}
363  VectorArrays(const multi2d<T>& v) : vec(v),N(v.size2()),Ls(v.size1()) {}
364  VectorArrays(int size2,int size1){resize(size2,size1);}
365 
367 
368  void AddVector(const multi1d<T>& v,const Subset& s){
369  if(N<vec.size2())
370  {
371  if (v.size() != Ls)
372  {
373  QDPIO::cerr << "VectorArrays:" << __func__ << ": size of 5D array inconsistent with stored value: Ls=" << Ls
374  << " v.size=" << v.size() << std::endl;
375  QDP_abort(1);
376  }
377  for(int k=0; k < Ls; ++k)
378  vec[N][k][s] = v[k];
379  N++;
380  }
381  }
382 
383  void NormalizeAndAddVector(const multi1d<T>& v,const Double& inorm,
384  const Subset& s){
385  if(N<vec.size2())
386  {
387  // inorm is the inverse of the norm
388  if (v.size() != Ls)
389  {
390  QDPIO::cerr << "VectorArrays:" << __func__ << ": size of 5D array inconsistent with stored value: Ls=" << Ls
391  << " v.size=" << v.size() << std::endl;
392  QDP_abort(1);
393  }
394  for(int k=0; k < Ls; ++k)
395  {
396  vec[N][k][s] = v[k];
397  vec[N][k][s] *= inorm;
398  }
399  N++;
400  }
401  }
402  void AddOrReplaceVector(const multi1d<T>& v,const Subset& s){
403  if(N<vec.size2())
404  {
405  if (v.size() != Ls)
406  {
407  QDPIO::cerr << "VectorArrays:" << __func__ << ": size of 5D array inconsistent with stored value: Ls=" << Ls
408  << " v.size=" << v.size() << std::endl;
409  QDP_abort(1);
410  }
411  for(int k=0; k < Ls; ++k)
412  vec[N][k][s] = v[k];
413  N++;
414  }
415  else{// replace the last std::vector
416  for(int k=0; k < Ls; ++k)
417  vec[N-1][k][s] = v[k];
418  }
419  }
420 
421  // This will only add as many vectors as they fit
422  void AddVectors(multi2d<T>& v,const Subset& s){
423  if (v.size() != Ls)
424  {
425  QDPIO::cerr << "VectorArrays:" << __func__ << ": size of 5D array inconsistent with stored value: Ls=" << Ls
426  << " v.size=" << v.size() << std::endl;
427  QDP_abort(1);
428  }
429  for(int i(0);i<v.size2();i++)
430  AddVector(v[i],s);
431  }
432 
433 
434  void resize(int n2, int n1) {N=Ls=0;vec.resize(n2,n1);}
435  int size() const { return vec.size2();}
436  int Nvecs() const { return N; }
437  int N5d() const { return Ls; }
438  multi1d<T> operator[](int i){ return vec[i];}
439  };
440 
441 
442  //------------------------------------------------------------------------------
443  //! Holds eigenvalues and arrays of eigenvectors for use in 5D work
444  /*! \ingroup invert */
445  template<class T> class RitzPairsArray
446  {
447  public:
450  int Neig;
451 
453  RitzPairsArray(int N, int Ls) {init(N,Ls);}
454 
455  void init(int N, int Ls) {
456  eval.resize(N);
457  evec.resize(N,Ls);
458  Neig = 0;
459  }
460 
461  void AddVector(const Double& e, const multi1d<T>& v,const Subset& s){
462  eval.AddVector(e,s);
463  evec.AddVector(v,s);
464  if (eval.N != evec.N)
465  {
466  QDPIO::cerr << __func__ << ": length of value and std::vector arrays are not the same" << std::endl;
467  QDP_abort(1);
468  }
469  Neig = evec.N;
470  }
471 
472  // This will only add as many vectors as they fit
473  void AddVectors(const multi1d<Double>& e,const multi2d<T>& v,const Subset& s){
474  for(int i(0);i<e.size();i++)
475  eval.AddVector(e[i],s);
476  for(int i(0);i<v.size2();i++)
477  evec.AddVector(v[i],s);
478  if (eval.N != evec.N)
479  {
480  QDPIO::cerr << __func__ << ": length of value and std::vector arrays are not the same" << std::endl;
481  QDP_abort(1);
482  }
483  Neig = evec.N;
484  }
485  };
486 
487  } // namespace LinAlg
488 
489 } // namespace Chroma
490 
491 #endif
Primary include file for CHROMA library code.
multi1d< Complex > HU
Definition: containers.h:133
multi1d< Complex > H
Definition: containers.h:132
EigInfo(const OptEigInfo &o, const Subset &s)
Definition: containers.h:143
multi1d< Real > evals
Definition: containers.h:130
void init(int ldh, int lde_)
Definition: containers.h:134
multi1d< LatticeFermion > evecs
Definition: containers.h:131
This is a square matrix.
Definition: containers.h:328
T & operator()(int i, int j)
Definition: containers.h:348
void resize(int size)
Definition: containers.h:344
Matrix(const multi2d< T > &v)
Definition: containers.h:334
void CvToEigCGvec(const LatticeFermion &lf, const Subset &s, int v, const std::string &LR)
Definition: containers.h:260
multi1d< RComplex< R > > evecsL
Definition: containers.h:231
void CvToLatFerm(LatticeFermion &lf, const Subset &s, int v, const std::string &LR) const
Definition: containers.h:245
multi1d< RComplex< R > > evecsR
Definition: containers.h:232
void init(int ldh, int lde_, int nn)
Definition: containers.h:234
multi1d< RComplex< R > > H
Definition: containers.h:233
multi1d< RComplex< R > > evals
Definition: containers.h:230
void CvToLatFerm(LatticeFermion &lf, const Subset &s, int v) const
Definition: containers.h:100
multi1d< Complex > HU
Definition: containers.h:88
void CvToEigCGvec(const LatticeFermion &lf, const Subset &s, int v)
Definition: containers.h:112
multi1d< Complex > evecs
Definition: containers.h:86
void init(int ldh, int lde_, int nn)
Definition: containers.h:89
multi1d< Complex > H
Definition: containers.h:87
multi1d< Real > evals
Definition: containers.h:85
Holds eigenvalues and arrays of eigenvectors for use in 5D work.
Definition: containers.h:446
void AddVector(const Double &e, const multi1d< T > &v, const Subset &s)
Definition: containers.h:461
void AddVectors(const multi1d< Double > &e, const multi2d< T > &v, const Subset &s)
Definition: containers.h:473
void init(int N, int Ls)
Definition: containers.h:455
Holds eigenvalues and eigenvectors.
Definition: containers.h:282
void AddVector(const Double &e, const T &v, const Subset &s)
Definition: containers.h:297
void AddVectors(const multi1d< Double > &e, const multi1d< T > &v, const Subset &s)
Definition: containers.h:309
Vectors< Double > eval
Definition: containers.h:284
multi1d< T > operator[](int i)
Definition: containers.h:438
void NormalizeAndAddVector(const multi1d< T > &v, const Double &inorm, const Subset &s)
Definition: containers.h:383
void AddVector(const multi1d< T > &v, const Subset &s)
Definition: containers.h:368
VectorArrays(int size2, int size1)
Definition: containers.h:364
void AddOrReplaceVector(const multi1d< T > &v, const Subset &s)
Definition: containers.h:402
void resize(int n2, int n1)
Definition: containers.h:434
void AddVectors(multi2d< T > &v, const Subset &s)
Definition: containers.h:422
VectorArrays(const multi2d< T > &v)
Definition: containers.h:363
void AddVectors(multi1d< T > &v, const Subset &s)
Definition: containers.h:204
void AddOrReplaceVector(const T &v, const Subset &s)
Definition: containers.h:193
Vectors(const multi1d< T > &v)
Definition: containers.h:166
void NormalizeAndAddVector(const T &v, const Double &inorm, const Subset &s)
Definition: containers.h:185
void AddVector(const T &v, const Subset &s)
Definition: containers.h:171
void AddVector(const T &v)
Definition: containers.h:178
void AddVectors(multi1d< T > &v)
Definition: containers.h:209
unsigned j
Definition: ldumul_w.cc:35
unsigned n
Definition: ldumul_w.cc:36
int x
Definition: meslate.cc:34
void CopyToLatFerm(T &lf, RComplex< R > *px, const Subset &s)
copies an EigCG std::vector to a LatticeFermion (Works only in single prec.
Definition: containers.h:18
void CopyFromLatFerm(RComplex< R > *px, const T &lf, const Subset &s)
Definition: containers.h:49
Asqtad Staggered-Dirac operator.
Definition: klein_gord.cc:10
Double c
Definition: invbicg.cc:108
LinOpSysSolverMGProtoClover::T T
int i
Definition: pbg5p_w.cc:55
int k
Definition: invbicg.cc:119
multi1d< LatticeFermion > s(Ncb)
int count
Definition: octave.h:14
FloatingPoint< double > Double
Definition: gtest.h:7351
::std::string string
Definition: gtest.h:1979