Hammer  1.0.0
Helicity Amplitude Module for Matrix Element Reweighting
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Multiply.cc
Go to the documentation of this file.
1 ///
2 /// @file Multiply.cc
3 /// @brief Tensor element-wise multiplication 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* Multiply::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* Multiply::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 = 0.0;
51  ++first1;
52  }
53  else {
54  if (!(first2->first < first1->first)) {
55  first1->second *= first2->second;
56  ++first1;
57  }
58  ++first2;
59  }
60  }
61  return static_cast<IContainer*>(&a);
62  }
63 
64  IContainer* Multiply::operator()(VTensor& a, const STensor& b) {
65  size_t n = 0;
66  auto oldsize = a.numValues();
67  auto first2 = b.begin();
68  while (n < oldsize) {
69  if (first2 == b.end()) {
70  for(size_t m = n; m<oldsize; ++m) {
71  a[m] = 0.;
72  }
73  break;
74  }
75  if (n < b.getIndexing().alignedPosToPos(first2->first)) {
76  a[n] = 0.0;
77  ++n;
78  } else {
79  if (!(b.getIndexing().alignedPosToPos(first2->first) < n)) {
80  a[n] *= first2->second;
81  ++n;
82  }
83  ++first2;
84  }
85  }
86  return static_cast<IContainer*>(&a);
87  }
88 
89  IContainer* Multiply::operator()(STensor& a, const VTensor& b) {
90  for (auto& elem : a) {
91  elem.second *= b[a.getIndexing().alignedPosToPos(elem.first)];
92  }
93  return static_cast<IContainer*>(&a);
94  }
95 
96  IContainer* Multiply::operator()(OTensor& a, const STensor& b) {
97  auto tmp = new STensor{b};
98  auto result = this->operator()(*tmp, a);
99  return result;
100  }
101 
102  IContainer* Multiply::operator()(OTensor& a, const VTensor& b) {
103  auto tmp = new VTensor{b};
104  auto result = this->operator()(*tmp, a);
105  return result;
106  }
107 
108  IContainer* Multiply::operator()(OTensor& a, const OTensor& b) {
109  return error(a,b);
110  }
111 
112  IContainer* Multiply::operator()(Base& a, const Base& b) {
113  BruteForceIterator bf{a.dims()};
114  for (auto elem : bf) {
115  a.element(elem) *= b.element(elem);
116  }
117  return &a;
118  }
119 
120  IContainer* Multiply::error(Base&, const Base&) {
121  throw Error("Invalid data types for tensor Multiply");
122  }
123 
124  } // namespace Ops
125 
126 
127  } // namespace MultiDimensional
128 
129 } // 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
SparseContainer STensor
Definition: AddAt.cc:28
iterator erase(const_iterator first, const_iterator last)
VectorContainer VTensor
Definition: AddAt.cc:27
Tensor element-wise multiplication algorithm.
OuterContainer OTensor
Definition: AddAt.cc:29
Generic tensor indexing iterator.
virtual reference element(const IndexList &coords={})=0