Hammer  1.0.0
Helicity Amplitude Module for Matrix Element Reweighting
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Divide.cc
Go to the documentation of this file.
1 ///
2 /// @file Divide.cc
3 /// @brief Tensor element-wise division algorithm
4 ///
5 
6 //**** This file is a part of the HAMMER library
7 //**** Copyright (C) 2016 - 2020 The HAMMER Collaboration
8 //**** HAMMER is licensed under version 3 of the GPL; see COPYING for details
9 //**** Please note the MCnet academic guidelines; see GUIDELINES for details
10 
11 // -*- C++ -*-
17 #include "Hammer/Exceptions.hh"
18 #include "Hammer/Tools/Utils.hh"
19 #include "Hammer/Math/Utils.hh"
20 
21 using namespace std;
22 
23 namespace Hammer {
24 
25  namespace MultiDimensional {
26 
27  using VTensor = VectorContainer;
28  using STensor = SparseContainer;
29  using OTensor = OuterContainer;
30  using Base = IContainer;
31 
32  namespace Ops {
33 
34  IContainer* Divide::operator()(VTensor& a, const VTensor& b) {
35  VTensor::iterator ita = a.begin();
37  for(; ita != a.end(); ++itb, ++ita) {
38  *ita /= *itb;
39  }
40  return static_cast<IContainer*>(&a);
41  }
42 
43  IContainer* Divide::operator()(STensor& a, const STensor& b) {
44  auto first1 = a.begin();
45  auto first2 = b.begin();
46  while (first1 != a.end()) {
47  if (first2 == b.end())
48  a.erase(first1, a.end());
49  if (first1->first < first2->first) {
50  first1->second = isZero(first1->second) ? 0.: numeric_limits<double>::infinity();
51  ++first1;
52  } else {
53  if (!(first2->first < first1->first)) {
54  first1->second /= first2->second;
55  ++first1;
56  }
57  ++first2;
58  }
59  }
60  return static_cast<IContainer*>(&a);
61  }
62 
63  IContainer* Divide::operator()(VTensor& a, const STensor& b) {
64  size_t n = 0;
65  auto oldsize = a.numValues();
66  auto first2 = b.begin();
67  while (n < oldsize) {
68  if (first2 == b.end()) {
69  for (size_t m = n; m < oldsize; ++m) {
70  a[m] = isZero(a[m]) ? 0. : numeric_limits<double>::infinity();
71  }
72  break;
73  }
74  if (n < b.getIndexing().alignedPosToPos(first2->first)) {
75  a[n] = isZero(a[n]) ? 0. : numeric_limits<double>::infinity();
76  ++n;
77  } else {
78  if (!(b.getIndexing().alignedPosToPos(first2->first) < n)) {
79  a[n] /= first2->second;
80  ++n;
81  }
82  ++first2;
83  }
84  }
85  return static_cast<IContainer*>(&a);
86  }
87 
88  IContainer* Divide::operator()(STensor& a, const VTensor& b) {
89  for (auto& elem : a) {
90  elem.second /= b[a.getIndexing().alignedPosToPos(elem.first)];
91  }
92  return static_cast<IContainer*>(&a);
93  }
94 
95  IContainer* Divide::operator()(OTensor& a, const Base& b) {
96  return error(a, b);
97  }
98 
99  IContainer* Divide::operator()(Base& a, const Base& b) {
100  BruteForceIterator bf{a.dims()};
101  for(auto elem: bf) {
102  a.element(elem) /= b.element(elem);
103  }
104  return &a;
105  }
106 
107  IContainer* Divide::error(Base&, const Base&) {
108  throw Error("Invalid data types for tensor Divide");
109  }
110 
111  } // namespace Ops
112 
113 
114  } // namespace MultiDimensional
115 
116 } // namespace Hammer
const LabeledIndexing< AlignedIndexing > & getIndexing() const
Non-sparse tensor data container.
(Sum of) Outer product tensor data container
Hammer exception definitions.
Sparse tensor data container.
virtual IndexList dims() const =0
Generic error class.
Definition: Exceptions.hh:23
bool isZero(const std::complex< double > val)
Definition: Math/Utils.hh:25
SparseContainer STensor
Definition: AddAt.cc:28
iterator erase(const_iterator first, const_iterator last)
Tensor element-wise division algorithm.
VectorContainer VTensor
Definition: AddAt.cc:27
OuterContainer OTensor
Definition: AddAt.cc:29
Generic tensor indexing iterator.
virtual reference element(const IndexList &coords={})=0