QMCPACK
ParticleAttribOps.h
Go to the documentation of this file.
1 //////////////////////////////////////////////////////////////////////////////////////
2 // This file is distributed under the University of Illinois/NCSA Open Source License.
3 // See LICENSE file in top directory for details.
4 //
5 // Copyright (c) 2016 Jeongnim Kim and QMCPACK developers.
6 //
7 // File developed by: Miguel Morales, moralessilva2@llnl.gov, Lawrence Livermore National Laboratory
8 // Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
9 // Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
10 // Mark A. Berrill, berrillma@ornl.gov, Oak Ridge National Laboratory
11 // Mark Dewing, markdewing@gmail.com, University of Illinois at Urbana-Champaign
12 //
13 // File created by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
14 //////////////////////////////////////////////////////////////////////////////////////
15 
16 
17 /**@file ParticleAttribOps.h
18  *@brief Declaraton of ParticleAttrib<T>
19  */
20 
21 /*! \class ParticleAttribOps
22  * \brief A one-dimensional vector class based on PETE.
23  *
24  * Closely related to PETE STL vector example and written to substitute
25  * Poomar1::ParticleInteractAttrib.
26  *
27  * Equivalent to blitz::Array<T,1>, pooma::Array<1,T>.
28  *
29  * class C is a container class. Default is std::vector<T>
30  *
31  * \todo Implement openMP compatible container class or evaluate function.
32  * \todo Implement get/put member functions for MPI-like parallelism
33  */
34 #ifndef OHMMS_PARTICLEATTRIB_OPS_H
35 #define OHMMS_PARTICLEATTRIB_OPS_H
36 
37 #include "ParticleUtility.h"
38 
39 namespace qmcplusplus
40 {
41 template<class T1, class T2, unsigned D>
42 struct OTCDot
43 {
45  inline static Type_t apply(const TinyVector<std::complex<T1>, D>& lhs, const TinyVector<std::complex<T2>, D>& rhs)
46  {
47  Type_t res = lhs[0].real() * rhs[0].real() - lhs[0].imag() * rhs[0].imag();
48  for (unsigned d = 1; d < D; ++d)
49  res += lhs[d].real() * rhs[d].real() - lhs[d].imag() * rhs[d].imag();
50  return res;
51  }
52 
53  inline static std::complex<Type_t> cplx_apply(const TinyVector<std::complex<T1>, D>& lhs,
54  const TinyVector<std::complex<T2>, D>& rhs)
55  {
56  std::complex<Type_t> res = lhs[0] * rhs[0];
57  for (unsigned d = 1; d < D; ++d)
58  res += lhs[d] * rhs[d];
59  return res;
60  }
61 };
62 
63 // Use complex conjugate of the second argument
64 template<class T1, class T2, unsigned D>
65 struct OTCDot_CC
66 {
68  inline static Type_t apply(const TinyVector<std::complex<T1>, D>& lhs, const TinyVector<std::complex<T2>, D>& rhs)
69  {
70  Type_t res = lhs[0].real() * rhs[0].real() + lhs[0].imag() * rhs[0].imag();
71  for (unsigned d = 1; d < D; ++d)
72  res += lhs[d].real() * rhs[d].real() + lhs[d].imag() * rhs[d].imag();
73  return res;
74  }
75 };
76 
77 template<class T1, class T2>
78 struct OTCDot<T1, T2, 3>
79 {
81  inline static Type_t apply(const TinyVector<std::complex<T1>, 3>& lhs, const TinyVector<std::complex<T2>, 3>& rhs)
82  {
83  return lhs[0].real() * rhs[0].real() - lhs[0].imag() * rhs[0].imag() + lhs[1].real() * rhs[1].real() -
84  lhs[1].imag() * rhs[1].imag() + lhs[2].real() * rhs[2].real() - lhs[2].imag() * rhs[2].imag();
85  }
86 
87  inline static std::complex<Type_t> cplx_apply(const TinyVector<std::complex<T1>, 3>& lhs,
88  const TinyVector<std::complex<T2>, 3>& rhs)
89  {
90  return lhs[0] * rhs[0] + lhs[1] * rhs[1] + lhs[2] * rhs[2];
91  }
92 };
93 
94 // Use complex conjugate of the second argument
95 template<class T1, class T2>
96 struct OTCDot_CC<T1, T2, 3>
97 {
99  inline static Type_t apply(const TinyVector<std::complex<T1>, 3>& lhs, const TinyVector<std::complex<T2>, 3>& rhs)
100  {
101  return lhs[0].real() * rhs[0].real() + lhs[0].imag() * rhs[0].imag() + lhs[1].real() * rhs[1].real() +
102  lhs[1].imag() * rhs[1].imag() + lhs[2].real() * rhs[2].real() + lhs[2].imag() * rhs[2].imag();
103  }
104 };
105 
106 template<class T, unsigned D>
108 {
109  T factor = Dot(pa, pa);
110  factor = 1.0 / sqrt(factor);
111  pa *= factor;
112 }
113 
114 /////////////////////////////////////////////////////////////////
115 /*\fn template<class T, unsigned D>
116  * T Dot(const ParticleAttrib<TinyVector<T, D> >& pa,
117  * const ParticleAttrib<TinyVector<T, D> >& pb)
118  * \return a dot product of an array
119  */
120 /////////////////////////////////////////////////////////////////
121 template<typename T, unsigned D>
123 {
124  T sum = 0;
125  for (int i = 0; i < pa.size(); i++)
126  {
127  sum += dot(pa[i], pb[i]);
128  }
129  return sum;
130 }
131 
132 template<typename T, unsigned D>
133 inline T Dot(const ParticleAttrib<TinyVector<std::complex<T>, D>>& pa,
134  const ParticleAttrib<TinyVector<std::complex<T>, D>>& pb)
135 {
136  T sum = 0;
137  for (int i = 0; i < pa.size(); i++)
138  {
139  sum += OTCDot<T, T, D>::apply(pa[i], pb[i]);
140  }
141  return sum;
142 }
143 
144 template<typename T, unsigned D>
145 inline std::complex<T> CplxDot(const ParticleAttrib<TinyVector<std::complex<T>, D>>& pa,
146  const ParticleAttrib<TinyVector<std::complex<T>, D>>& pb)
147 {
148  std::complex<T> sum(0.0, 0.0);
149  for (int i = 0; i < pa.size(); i++)
150  {
151  sum += OTCDot<T, T, D>::cplx_apply(pa[i], pb[i]);
152  }
153  return sum;
154 }
155 
156 // Use complex conjugate of the second argument
157 template<unsigned D>
158 inline double Dot_CC(const ParticleAttrib<TinyVector<std::complex<double>, D>>& pa,
159  const ParticleAttrib<TinyVector<std::complex<double>, D>>& pb)
160 {
161  double sum = 0;
162  for (int i = 0; i < pa.size(); i++)
163  {
164  sum += OTCDot_CC<double, double, D>::apply(pa[i], pb[i]);
165  }
166  return sum;
167 }
168 
169 template<typename T>
170 inline T Sum(const ParticleAttrib<T>& pa)
171 {
172  T sum = 0;
173  for (int i = 0; i < pa.size(); i++)
174  {
175  sum += pa[i];
176  }
177  return sum;
178 }
179 
180 template<typename T>
181 inline T Sum(const ParticleAttrib<std::complex<T>>& pa)
182 {
183  T sum = 0;
184  for (int i = 0; i < pa.size(); i++)
185  {
186  sum += pa[i].real();
187  }
188  return sum;
189 }
190 
191 template<typename T>
192 inline std::complex<T> CplxSum(const ParticleAttrib<std::complex<T>>& pa)
193 {
194  std::complex<T> sum(0.0, 0.0);
195  for (int i = 0; i < pa.size(); i++)
196  {
197  sum += pa[i];
198  }
199  return sum;
200 }
201 
202 template<class T, unsigned D>
203 inline void Copy(const ParticleAttrib<TinyVector<std::complex<T>, D>>& c, ParticleAttrib<TinyVector<T, D>>& r)
204 {
205  for (int i = 0; i < c.size(); i++)
206  {
207  //r[i]=real(c[i]);
208  for (int j = 0; j < D; j++)
209  r[i][j] = c[i][j].real();
210  }
211 }
212 
213 template<class T, unsigned D>
215 {
216  r = c;
217 }
218 
219 
220 /** generic PAOps
221  */
222 template<class T, unsigned D, class T1 = T>
223 struct PAOps
224 {};
225 
226 ///specialization for three-dimension
227 template<class T, class T1>
228 struct PAOps<T, 3, T1>
229 {
230  using real_type = T;
231  using complex_type = std::complex<T>;
235 
236  static inline void scale(T a, const ParticleAttrib<cpos_type>& pa, ParticleAttrib<rpos_type>& pb)
237  {
238  for (int i = 0; i < pa.size(); i++)
239  {
240  pb[i][0] = a * pa[i][0].real();
241  pb[i][1] = a * pa[i][1].real();
242  pb[i][2] = a * pa[i][2].real();
243  }
244  }
245 
246  static inline void scale(T a, const ParticleAttrib<ipos_type>& pa, ParticleAttrib<rpos_type>& pb) { pb = a * pa; }
247 
248  static inline void axpy(T a, const ParticleAttrib<cpos_type>& pa, ParticleAttrib<rpos_type>& pb)
249  {
250  for (int i = 0; i < pa.size(); ++i)
251  {
252  pb[i][0] += a * pa[i][0].real();
253  pb[i][1] += a * pa[i][1].real();
254  pb[i][2] += a * pa[i][2].real();
255  }
256  }
257 
258  static inline void axpy(T a, const ParticleAttrib<ipos_type>& pa, ParticleAttrib<rpos_type>& pb)
259  {
260  for (int i = 0; i < pa.size(); ++i)
261  {
262  pb[i][0] += a * pa[i][0];
263  pb[i][1] += a * pa[i][1];
264  pb[i][2] += a * pa[i][2];
265  }
266  }
267 
268  static inline void axpy(T a,
269  const ParticleAttrib<cpos_type>& pa,
270  const ParticleAttrib<ipos_type>& pb,
272  {
273  for (int i = 0; i < pa.size(); ++i)
274  {
275  py[i][0] = a * pa[i][0].real() + pb[i][0];
276  py[i][1] = a * pa[i][1].real() + pb[i][1];
277  py[i][2] = a * pa[i][2].real() + pb[i][2];
278  }
279  }
280 
281  static inline void axpy(T a,
282  const ParticleAttrib<ipos_type>& pa,
283  const ParticleAttrib<ipos_type>& pb,
285  {
286  for (int i = 0; i < pa.size(); ++i)
287  {
288  py[i][0] = a * pa[i][0] + pb[i][0];
289  py[i][1] = a * pa[i][1] + pb[i][1];
290  py[i][2] = a * pa[i][2] + pb[i][2];
291  }
292  }
293 
294  static inline void copy(const ParticleAttrib<ipos_type>& px, ParticleAttrib<rpos_type>& py) { py = px; }
295 
296  static inline void copy(const ParticleAttrib<cpos_type>& px, ParticleAttrib<rpos_type>& py)
297  {
298  for (int i = 0; i < px.size(); ++i)
299  {
300  py[i][0] = px[i][0].real();
301  py[i][1] = px[i][1].real();
302  py[i][2] = px[i][2].real();
303  }
304  }
305 };
306 
307 ///specialization for 2-dimension
308 template<class T, class T1>
309 struct PAOps<T, 2, T1>
310 {
311  using real_type = T;
312  using complex_type = std::complex<T>;
316 
317  static inline void scale(T a, const ParticleAttrib<cpos_type>& pa, ParticleAttrib<rpos_type>& pb)
318  {
319  for (int i = 0; i < pa.size(); i++)
320  {
321  pb[i][0] = a * pa[i][0].real();
322  pb[i][1] = a * pa[i][1].real();
323  }
324  }
325 
326  static inline void scale(T a, const ParticleAttrib<ipos_type>& pa, ParticleAttrib<rpos_type>& pb) { pb = a * pa; }
327 
328 
329  static inline void axpy(T a, const ParticleAttrib<cpos_type>& pa, ParticleAttrib<rpos_type>& pb)
330  {
331  for (int i = 0; i < pa.size(); i++)
332  {
333  pb[i][0] += a * pa[i][0].real();
334  pb[i][1] += a * pa[i][1].real();
335  }
336  }
337 
338  static inline void axpy(T a, const ParticleAttrib<ipos_type>& pa, ParticleAttrib<rpos_type>& pb)
339  {
340  for (int i = 0; i < pa.size(); i++)
341  {
342  pb[i][0] += a * pa[i][0];
343  pb[i][1] += a * pa[i][1];
344  }
345  }
346 
347  static inline void axpy(T a,
348  const ParticleAttrib<cpos_type>& pa,
349  const ParticleAttrib<ipos_type>& pb,
351  {
352  for (int i = 0; i < pa.size(); i++)
353  {
354  py[i][0] = a * pa[i][0].real() + pb[i][0];
355  py[i][1] = a * pa[i][1].real() + pb[i][1];
356  }
357  }
358 
359  static inline void axpy(T a,
360  const ParticleAttrib<ipos_type>& pa,
361  const ParticleAttrib<ipos_type>& pb,
363  {
364  for (int i = 0; i < pa.size(); i++)
365  {
366  py[i][0] = a * pa[i][0] + pb[i][0];
367  py[i][1] = a * pa[i][1] + pb[i][1];
368  }
369  }
370 };
371 } // namespace qmcplusplus
372 #endif // OHMMS_PARTICLEATTRIB_OPS_H
static void axpy(T a, const ParticleAttrib< cpos_type > &pa, ParticleAttrib< rpos_type > &pb)
static void axpy(T a, const ParticleAttrib< cpos_type > &pa, ParticleAttrib< rpos_type > &pb)
void normalize(ParticleAttrib< TinyVector< T, D >> &pa)
typename Promote< T1, T2 >::Type_t Type_t
static void axpy(T a, const ParticleAttrib< ipos_type > &pa, const ParticleAttrib< ipos_type > &pb, ParticleAttrib< rpos_type > &py)
static void scale(T a, const ParticleAttrib< cpos_type > &pa, ParticleAttrib< rpos_type > &pb)
T Sum(const ParticleAttrib< T > &pa)
Fixed-size array.
Definition: OhmmsTinyMeta.h:30
static void scale(T a, const ParticleAttrib< cpos_type > &pa, ParticleAttrib< rpos_type > &pb)
std::complex< T > CplxDot(const ParticleAttrib< TinyVector< std::complex< T >, D >> &pa, const ParticleAttrib< TinyVector< std::complex< T >, D >> &pb)
static std::complex< Type_t > cplx_apply(const TinyVector< std::complex< T1 >, 3 > &lhs, const TinyVector< std::complex< T2 >, 3 > &rhs)
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
static void axpy(T a, const ParticleAttrib< ipos_type > &pa, ParticleAttrib< rpos_type > &pb)
static Type_t apply(const TinyVector< std::complex< T1 >, D > &lhs, const TinyVector< std::complex< T2 >, D > &rhs)
static Type_t apply(const TinyVector< std::complex< T1 >, D > &lhs, const TinyVector< std::complex< T2 >, D > &rhs)
std::complex< T > CplxSum(const ParticleAttrib< std::complex< T >> &pa)
static Type_t apply(const TinyVector< std::complex< T1 >, 3 > &lhs, const TinyVector< std::complex< T2 >, 3 > &rhs)
static void axpy(T a, const ParticleAttrib< ipos_type > &pa, const ParticleAttrib< ipos_type > &pb, ParticleAttrib< rpos_type > &py)
float real(const float &c)
real part of a scalar. Cannot be replaced by std::real due to AFQMC specific needs.
static std::complex< Type_t > cplx_apply(const TinyVector< std::complex< T1 >, D > &lhs, const TinyVector< std::complex< T2 >, D > &rhs)
Attaches a unit to a Vector for IO.
T Dot(const ParticleAttrib< TinyVector< T, D >> &pa, const ParticleAttrib< TinyVector< T, D >> &pb)
static void copy(const ParticleAttrib< cpos_type > &px, ParticleAttrib< rpos_type > &py)
void Copy(const ParticleAttrib< TinyVector< std::complex< T >, D >> &c, ParticleAttrib< TinyVector< T, D >> &r)
typename BinaryReturn< T1, T2, OpMultiply >::Type_t Type_t
static void axpy(T a, const ParticleAttrib< ipos_type > &pa, ParticleAttrib< rpos_type > &pb)
static void axpy(T a, const ParticleAttrib< cpos_type > &pa, const ParticleAttrib< ipos_type > &pb, ParticleAttrib< rpos_type > &py)
typename BinaryReturn< T1, T2, OpMultiply >::Type_t Type_t
size_type size() const
return the current size
Definition: OhmmsVector.h:162
typename BinaryReturn< T1, T2, OpMultiply >::Type_t Type_t
static void scale(T a, const ParticleAttrib< ipos_type > &pa, ParticleAttrib< rpos_type > &pb)
static void axpy(T a, const ParticleAttrib< cpos_type > &pa, const ParticleAttrib< ipos_type > &pb, ParticleAttrib< rpos_type > &py)
static Type_t apply(const TinyVector< std::complex< T1 >, 3 > &lhs, const TinyVector< std::complex< T2 >, 3 > &rhs)
MakeReturn< UnaryNode< FnSqrt, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t sqrt(const Vector< T1, C1 > &l)
double Dot_CC(const ParticleAttrib< TinyVector< std::complex< double >, D >> &pa, const ParticleAttrib< TinyVector< std::complex< double >, D >> &pb)
static void copy(const ParticleAttrib< ipos_type > &px, ParticleAttrib< rpos_type > &py)
Tensor< typename BinaryReturn< T1, T2, OpMultiply >::Type_t, D > dot(const AntiSymTensor< T1, D > &lhs, const AntiSymTensor< T2, D > &rhs)
typename BinaryReturn< T1, T2, OpMultiply >::Type_t Type_t
static void scale(T a, const ParticleAttrib< ipos_type > &pa, ParticleAttrib< rpos_type > &pb)