QMCPACK
AntiSymTensor.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: Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
8 //
9 // File created by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
10 //////////////////////////////////////////////////////////////////////////////////////
11 
12 
13 #ifndef ANTI_SYM_TENZOR_H
14 #define ANTI_SYM_TENZOR_H
15 
16 /***************************************************************************
17  *
18  * The POOMA Framework
19  *
20  * This program was prepared by the Regents of the University of
21  * California at Los Alamos National Laboratory (the University) under
22  * Contract No. W-7405-ENG-36 with the U.S. Department of Energy (DOE).
23  * The University has certain rights in the program pursuant to the
24  * contract and the program should not be copied or distributed outside
25  * your organization. All rights in the program are reserved by the DOE
26  * and the University. Neither the U.S. Government nor the University
27  * makes any warranty, express or implied, or assumes any liability or
28  * responsibility for the use of this software
29  *
30  * Visit http://www.acl.lanl.gov/POOMA for more details
31  *
32  ***************************************************************************/
33 
34 
35 // include files
36 #include "PETE/PETE.h"
38 #include "OhmmsPETE/Tensor.h"
39 
40 #include <iostream>
41 
42 namespace qmcplusplus
43 {
44 //////////////////////////////////////////////////////////////////////
45 //
46 // Definition of class AntiSymTensor.
47 //
48 //////////////////////////////////////////////////////////////////////
49 
50 //
51 // | O -x10 -x20 |
52 // | x10 0 -x21 |
53 // | x20 x21 0 |
54 //
55 
56 template<class T, unsigned D>
58 {
59 public:
60  using Type_t = T;
61  enum
62  {
63  ElemDim = 2
64  };
65  enum
66  {
67  Size = D * (D - 1) / 2
68  };
69 
70  // Default Constructor
71  AntiSymTensor() { OTAssign<AntiSymTensor<T, D>, T, OpAssign>::apply(*this, T(0), OpAssign()); }
72 
73  // A noninitializing ctor.
75  {};
77 
78  // Construct an AntiSymTensor from a single T.
79  // This doubles as the 2D AntiSymTensor initializer.
80  AntiSymTensor(const T& x00) { OTAssign<AntiSymTensor<T, D>, T, OpAssign>::apply(*this, x00, OpAssign()); }
81  // construct a 3D AntiSymTensor
82  AntiSymTensor(const T& x10, const T& x20, const T& x21)
83  {
84  X[0] = x10;
85  X[1] = x20;
86  X[2] = x21;
87  }
88 
89  // Copy Constructor
91  {
93  }
94 
95  // Construct from a Tensor.
96  // Extract the antisymmetric part.
98  {
99  for (int i = 1; i < D; ++i)
100  {
101  for (int j = 0; j < i; ++j)
102  (*this)[((i - 1) * i / 2) + j] = (t(i, j) - t(j, i)) * 0.5;
103  }
104  }
105 
107 
108  // assignment operators
110  {
112  return *this;
113  }
114  template<class T1>
116  {
118  return *this;
119  }
121  {
122  OTAssign<AntiSymTensor<T, D>, T, OpAssign>::apply(*this, rhs, OpAssign());
123  return *this;
124  }
125 
126  // accumulation operators
127  template<class T1>
129  {
131  return *this;
132  }
133 
134  template<class T1>
136  {
138  return *this;
139  }
140 
141  template<class T1>
143  {
145  return *this;
146  }
148  {
150  return *this;
151  }
152 
153  template<class T1>
155  {
157  return *this;
158  }
160  {
162  return *this;
163  }
164 
165  // Methods
166 
167  int len(void) const { return Size; }
168  int size(void) const { return sizeof(*this); }
169  int get_Size(void) const { return Size; }
170 
172  {
173  public:
174  AssignProxy(Type_t& elem, int where) : elem_m(elem), where_m(where) {}
175  AssignProxy(const AssignProxy& model) : elem_m(model.elem_m), where_m(where_m) {}
177  {
178  PAssert(where_m != 0 || a.elem_m == -a.elem_m);
179  elem_m = where_m < 0 ? -a.elem_m : a.elem_m;
180  return *this;
181  }
183  {
184  PAssert(where_m != 0 || e == -e);
185  elem_m = where_m < 0 ? -e : e;
186  return *this;
187  }
188 
189  operator Type_t() const { return (where_m < 0 ? -elem_m : elem_m); }
190 
191  private:
192  //mutable Type_t &elem_m;
193  //mutable int where_m;
195  int where_m;
196  };
197 
198  // Operators
199 
200  Type_t operator()(unsigned int i, unsigned int j) const
201  {
202  if (i == j)
203  return T(0.0);
204  else if (i < j)
205  return -X[((j - 1) * j / 2) + i];
206  else
207  return X[((i - 1) * i / 2) + j];
208  }
209 
210  // Type_t operator()( std::pair<int,int> a) const {
211  // int i = a.first;
212  // int j = a.second;
213  // return (*this)(i, j);
214  // }
215 
216  AssignProxy operator()(unsigned int i, unsigned int j)
217  {
218  if (i == j)
220  else
221  {
222  int lo = i < j ? i : j;
223  int hi = i > j ? i : j;
224  return AssignProxy(X[((hi - 1) * hi / 2) + lo], i - j);
225  }
226  }
227 
228  // AssignProxy operator()(std::pair<int,int> a) {
229  // int i = a.first;
230  // int j = a.second;
231  // return (*this)(i, j);
232  // }
233 
234  Type_t& operator[](unsigned int i)
235  {
236  PAssert(i < Size);
237  return X[i];
238  }
239 
240  Type_t operator[](unsigned int i) const
241  {
242  PAssert(i < Size);
243  return X[i];
244  }
245 
246  // These are the same as operator[] but with () instead:
247 
248  Type_t& operator()(unsigned int i)
249  {
250  PAssert(i < Size);
251  return X[i];
252  }
253 
254  Type_t operator()(unsigned int i) const
255  {
256  PAssert(i < Size);
257  return X[i];
258  }
259 
260  // //----------------------------------------------------------------------
261  // // Comparison operators.
262  // bool operator==(const AntiSymTensor<T,D>& that) const {
263  // return TSV_MetaCompareArrays<T,T,D*(D-1)/2>::apply(X,that.X);
264  // }
265  // bool operator!=(const AntiSymTensor<T,D>& that) const {
266  // return !(*this == that);
267  // }
268 
269  // //----------------------------------------------------------------------
270  // // parallel communication
271  // Message& putMessage(Message& m) const {
272  // m.setCopy(true);
273  // ::putMessage(m, X, X + Size);
274  // return m;
275  // }
276 
277  // Message& getMessage(Message& m) {
278  // ::getMessage(m, X, X + Size);
279  // return m;
280  // }
281 
282 private:
283  friend class AssignProxy;
284 
285  // The elements themselves.
286  T X[Size];
287 
288  // A place to store a zero element.
289  // We need to return a reference to this
290  // for the diagonal element.
291  static T Zero;
292 };
293 
294 
295 ///////////////////////////////////////////////////////////////////////////
296 // Specialization for 1D -- this is basically just the zero tensor
297 ///////////////////////////////////////////////////////////////////////////
298 
299 template<class T>
300 class AntiSymTensor<T, 1>
301 {
302 public:
303  using Type_t = T;
304  enum
305  {
307  };
308 
309  // Default Constructor
311 
312  // Copy Constructor
314 
316 
317  // assignment operators
319  template<class T1>
321  {
322  return *this;
323  }
324  AntiSymTensor<T, 1>& operator=(const T& rhs) { return *this; }
325 
326  // accumulation operators
327  template<class T1>
329  {
330  return *this;
331  }
332 
333  template<class T1>
335  {
336  return *this;
337  }
338 
339  template<class T1>
341  {
342  return *this;
343  }
344  AntiSymTensor<T, 1>& operator*=(const T&) { return *this; }
345 
346  template<class T1>
348  {
349  return *this;
350  }
351  AntiSymTensor<T, 1>& operator/=(const T&) { return *this; }
352 
353  // Methods
354 
355  int len(void) const { return Size; }
356  int size(void) const { return sizeof(*this); }
357  int get_Size(void) const { return Size; }
358 
360  {
361  public:
362  AssignProxy(Type_t& elem, int where) : elem_m(elem), where_m(where) {}
363  AssignProxy(const AssignProxy& model) : elem_m(model.elem_m), where_m(where_m) {}
365  {
366  PAssert(where_m != 0 || a.elem_m == -a.elem_m);
367  elem_m = where_m < 0 ? -a.elem_m : a.elem_m;
368  return *this;
369  }
371  {
372  PAssert(where_m != 0 || e == -e);
373  elem_m = where_m < 0 ? -e : e;
374  return *this;
375  }
376 
377  operator Type_t() const { return (where_m < 0 ? -elem_m : elem_m); }
378 
379  private:
380  //mutable Type_t &elem_m;
381  //mutable int where_m;
383  int where_m;
384  };
385 
386  // Operators
387 
388  Type_t operator()(unsigned int i, unsigned int j) const
389  {
390  PAssert(i == j);
391  return T(0.0);
392  }
393 
394  // Type_t operator()( std::pair<int,int> a) const {
395  // int i = a.first;
396  // int j = a.second;
397  // return (*this)(i, j);
398  // }
399 
400  AssignProxy operator()(unsigned int i, unsigned int j)
401  {
402  PAssert(i == j);
404  }
405 
406  // AssignProxy operator()(std::pair<int,int> a) {
407  // int i = a.first;
408  // int j = a.second;
409  // return (*this)(i, j);
410  // }
411 
412  Type_t operator[](unsigned int i) const
413  {
414  PAssert(i == 0);
416  }
417 
418  // These are the same as operator[] but with () instead:
419 
420  Type_t operator()(unsigned int i) const
421  {
422  PAssert(i == 0);
424  }
425 
426  //----------------------------------------------------------------------
427  // Comparison operators.
428  bool operator==(const AntiSymTensor<T, 1>& that) const { return true; }
429  bool operator!=(const AntiSymTensor<T, 1>& that) const { return !(*this == that); }
430 
431  //----------------------------------------------------------------------
432  // parallel communication
433  // Message& putMessage(Message& m) const {
434  // m.setCopy(true);
435  // m.put(AntiSymTensor<T,1>::Zero);
436  // return m;
437  // }
438 
439  // Message& getMessage(Message& m) {
440  // T zero;
441  // m.get(zero);
442  // return m;
443  // }
444 
445 private:
446  friend class AssignProxy;
447 
448  // The number of elements.
449  enum
450  {
451  Size = 0
452  };
453 
454  // A place to store a zero element.
455  // We need to return a reference to this
456  // for the diagonal element.
457  static T Zero;
458 };
459 
460 
461 //////////////////////////////////////////////////////////////////////
462 //
463 // Free functions
464 //
465 //////////////////////////////////////////////////////////////////////
466 
467 template<class T, unsigned D>
469 {
470  return T(0.0);
471 }
472 
473 template<class T, unsigned D>
475 {
476  return -rhs;
477 }
478 //////////////////////////////////////////////////////////////////////
479 //
480 // Unary Operators
481 //
482 //////////////////////////////////////////////////////////////////////
483 
484 //----------------------------------------------------------------------
485 // unary operator-
486 // template<class T, unsigned D>
487 // inline AntiSymTensor<T,D> operator-(const AntiSymTensor<T,D> &op)
488 // {
489 // return MetaUnary< AntiSymTensor<T,D> , OpUnaryMinus > :: apply(op,OpUnaryMinus());
490 // }
491 
492 //----------------------------------------------------------------------
493 // unary operator+
494 template<class T, unsigned D>
496 {
497  return op;
498 }
499 
500 //////////////////////////////////////////////////////////////////////
501 //
502 // Binary Operators
503 //
504 //////////////////////////////////////////////////////////////////////
505 
506 //
507 // Elementwise operators.
508 //
509 
510 OHMMS_META_BINARY_OPERATORS(AntiSymTensor, operator+, OpAdd)
511 OHMMS_META_BINARY_OPERATORS(AntiSymTensor, operator-, OpSubtract)
512 OHMMS_META_BINARY_OPERATORS(AntiSymTensor, operator*, OpMultiply)
513 OHMMS_META_BINARY_OPERATORS(AntiSymTensor, operator/, OpDivide)
514 
515 //----------------------------------------------------------------------
516 // dot products.
517 //----------------------------------------------------------------------
518 
519 template<class T1, class T2, unsigned D>
521  const AntiSymTensor<T2, D>& rhs)
522 {
523  return OTDot<AntiSymTensor<T1, D>, AntiSymTensor<T2, D>>::apply(lhs, rhs);
524 }
525 
526 template<class T1, class T2, unsigned D>
528  const Tensor<T2, D>& rhs)
529 {
530  return OTDot<Tensor<T1, D>, Tensor<T2, D>>::apply(Tensor<T1, D>(lhs), rhs);
531 }
532 
533 template<class T1, class T2, unsigned D>
535  const AntiSymTensor<T2, D>& rhs)
536 {
537  return OTDot<Tensor<T1, D>, Tensor<T2, D>>::apply(lhs, Tensor<T2, D>(rhs));
538 }
539 
540 template<class T1, class T2, unsigned D>
542  const SymTensor<T2, D>& rhs)
543 {
544  return OTDot<Tensor<T1, D>, Tensor<T2, D>>::apply(Tensor<T1, D>(lhs), Tensor<T2, D>(rhs));
545 }
546 
547 template<class T1, class T2, unsigned D>
549  const AntiSymTensor<T2, D>& rhs)
550 {
551  return OTDot<Tensor<T1, D>, Tensor<T2, D>>::apply(Tensor<T1, D>(lhs), Tensor<T2, D>(rhs));
552 }
553 
554 template<class T1, class T2, unsigned D>
556  const AntiSymTensor<T2, D>& rhs)
557 {
558  return OTDot<TinyVector<T1, D>, AntiSymTensor<T2, D>>::apply(lhs, rhs);
559 }
560 
561 template<class T1, class T2, unsigned D>
563  const TinyVector<T2, D>& rhs)
564 {
565  return OTDot<AntiSymTensor<T1, D>, TinyVector<T2, D>>::apply(lhs, rhs);
566 }
567 
568 //----------------------------------------------------------------------
569 // double dot products.
570 //----------------------------------------------------------------------
571 
572 //template < class T1, class T2, unsigned D >
573 //inline typename BinaryReturn<T1,T2,OpMultiply>::Type_t
574 //dotdot(const AntiSymTensor<T1,D> &lhs, const AntiSymTensor<T2,D> &rhs)
575 //{
576 // return MetaDotDot< AntiSymTensor<T1,D> , AntiSymTensor<T2,D> > ::
577 // apply(lhs,rhs);
578 //}
579 
580 //template < class T1, class T2, unsigned D >
581 //inline typename BinaryReturn<T1,T2,OpMultiply>::Type_t
582 //dotdot(const AntiSymTensor<T1,D> &lhs, const Tensor<T2,D> &rhs)
583 //{
584 // return MetaDotDot< Tensor<T1,D> , Tensor<T2,D> > ::
585 // apply(Tensor<T1,D>(lhs),rhs);
586 //}
587 
588 //template < class T1, class T2, unsigned D >
589 //inline typename BinaryReturn<T1,T2,OpMultiply>::Type_t
590 //dotdot(const Tensor<T1,D> &lhs, const AntiSymTensor<T2,D> &rhs)
591 //{
592 // return MetaDotDot< Tensor<T1,D> , Tensor<T2,D> > ::
593 // apply(lhs,Tensor<T2,D>(rhs));
594 //}
595 
596 //template < class T1, class T2, unsigned D >
597 //inline typename BinaryReturn<T1,T2,OpMultiply>::Type_t
598 //dotdot(const AntiSymTensor<T1,D> &lhs, const SymTensor<T2,D> &rhs)
599 //{
600 // return MetaDotDot< Tensor<T1,D> , Tensor<T2,D> > ::
601 // apply(Tensor<T1,D>(lhs),Tensor<T2,D>(rhs));
602 //}
603 
604 //template < class T1, class T2, unsigned D >
605 //inline typename BinaryReturn<T1,T2,OpMultiply>::Type_t
606 //dotdot(const SymTensor<T1,D> &lhs, const AntiSymTensor<T2,D> &rhs)
607 //{
608 // return MetaDotDot< Tensor<T1,D> , Tensor<T2,D> > ::
609 // apply(Tensor<T1,D>(lhs),Tensor<T2,D>(rhs));
610 //}
611 
612 //----------------------------------------------------------------------
613 // I/O
614 template<class T, unsigned D>
615 std::ostream& operator<<(std::ostream& out, const AntiSymTensor<T, D>& rhs)
616 {
617  if (D >= 1)
618  {
619  for (int i = 0; i < D; i++)
620  {
621  for (int j = 0; j < D - 1; j++)
622  {
623  out << rhs(i, j) << " ";
624  }
625  out << rhs(i, D - 1) << " ";
626  if (i < D - 1)
627  out << std::endl;
628  }
629  }
630  else
631  {
632  out << " " << rhs(0, 0) << " ";
633  }
634  return out;
635 }
636 
637 //////////////////////////////////////////////////////////////////////
638 
639 template<class T, unsigned int D>
641 
642 } // namespace qmcplusplus
643 #endif // ANTI_SYM_TENZOR_H
#define PAssert(condition)
Definition: OhmmsTinyMeta.h:61
Type_t operator()(unsigned int i, unsigned int j) const
AntiSymTensor(const T &x10, const T &x20, const T &x21)
Definition: AntiSymTensor.h:82
Fixed-size array.
Definition: OhmmsTinyMeta.h:30
AntiSymTensor< T, 1 > & operator=(const AntiSymTensor< T1, 1 > &)
AntiSymTensor< T, D > & operator=(const T &rhs)
AntiSymTensor< T, D > & operator=(const AntiSymTensor< T, D > &rhs)
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
AntiSymTensor< T, D > & operator*=(const T &rhs)
Type_t & operator()(unsigned int i)
AntiSymTensor< T, D > & operator-=(const AntiSymTensor< T1, D > &rhs)
AntiSymTensor< T, D > & operator/=(const AntiSymTensor< T1, D > &rhs)
Type_t operator[](unsigned int i) const
AssignProxy(Type_t &elem, int where)
AntiSymTensor(const AntiSymTensor< T, D > &rhs)
Definition: AntiSymTensor.h:90
AntiSymTensor< T, D > & operator*=(const AntiSymTensor< T1, D > &rhs)
AntiSymTensor< T, 1 > & operator+=(const AntiSymTensor< T1, 1 > &)
MakeReturn< TrinaryNode< FnWhere, typename CreateLeaf< Matrix< T1, C1 > >::Leaf_t, typename CreateLeaf< T2 >::Leaf_t, typename CreateLeaf< T3 >::Leaf_t > >::Expression_t where(const Matrix< T1, C1 > &c, const T2 &t, const T3 &f)
AntiSymTensor< T, D > & operator=(const AntiSymTensor< T1, D > &rhs)
const AntiSymTensor< T, D > & operator+(const AntiSymTensor< T, D > &op)
Type_t operator()(unsigned int i) const
AntiSymTensor< T, 1 > & operator=(const T &rhs)
bool operator==(const AntiSymTensor< T, 1 > &that) const
AntiSymTensor< T, D > & operator+=(const AntiSymTensor< T1, D > &rhs)
Tensor<T,D> class for D by D tensor.
Definition: OhmmsTinyMeta.h:32
AssignProxy operator()(unsigned int i, unsigned int j)
Type_t operator()(unsigned int i) const
AntiSymTensor(const AntiSymTensor< T, 1 > &)
AntiSymTensor(DontInitialize)
Definition: AntiSymTensor.h:76
#define OHMMS_META_BINARY_OPERATORS(TENT, FUNC, TAG)
Definition: OhmmsTinyMeta.h:75
AntiSymTensor< T, D > transpose(const AntiSymTensor< T, D > &rhs)
AntiSymTensor< T, D > & operator/=(const T &rhs)
AntiSymTensor< T, 1 > & operator/=(const AntiSymTensor< T1, 1 > &)
Type_t & operator[](unsigned int i)
AntiSymTensor(const Tensor< T, D > &t)
Definition: AntiSymTensor.h:97
AntiSymTensor< T, 1 > & operator/=(const T &)
AntiSymTensor< T, 1 > & operator=(const AntiSymTensor< T, 1 > &)
AssignProxy(const AssignProxy &model)
bool operator!=(const AntiSymTensor< T, 1 > &that) const
Type_t operator()(unsigned int i, unsigned int j) const
AssignProxy & operator=(const Type_t &e)
Tensor< typename BinaryReturn< T1, T2, OpMultiply >::Type_t, D > dot(const AntiSymTensor< T1, D > &lhs, const AntiSymTensor< T2, D > &rhs)
AntiSymTensor< T, 1 > & operator-=(const AntiSymTensor< T1, 1 > &)
AntiSymTensor< T, 1 > & operator*=(const T &)
AssignProxy & operator=(const AssignProxy &a)
AssignProxy operator()(unsigned int i, unsigned int j)
T trace(const AntiSymTensor< T, D > &)
AntiSymTensor< T, 1 > & operator*=(const AntiSymTensor< T1, 1 > &)
AssignProxy & operator=(const Type_t &e)
Type_t operator[](unsigned int i) const
AssignProxy & operator=(const AssignProxy &a)