Hammer  1.0.0
Helicity Amplitude Module for Matrix Element Reweighting
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Tensor.hh
Go to the documentation of this file.
1 ///
2 /// @file Tensor.hh
3 /// @brief Hammer tensor class
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++ -*-
12 #ifndef HAMMER_MATH_TENSOR
13 #define HAMMER_MATH_TENSOR
14 
15 #include <complex>
16 #include <set>
17 #include <string>
18 #include <vector>
19 #include <memory>
20 
23 
24 namespace Hammer {
25 
26  class Log;
27 
28  /// @brief Multidimensional tensor class with complex numbers as elements
29  ///
30  /// Contains a complex tensor flattened to a vector as raw-major
31  ///
32  /// @ingroup Math
33  class Tensor {
34 
35  public:
36  Tensor();
37 
38  Tensor(const std::string& name);
39 
40  Tensor(const std::string& name, MultiDimensional::TensorData container);
41 
42  Tensor(const std::string& name, std::vector<std::pair<MultiDimensional::SharedTensorData, bool>>&& data);
43 
44  Tensor(const Tensor& other);
45  Tensor& operator=(const Tensor& other);
46  Tensor(Tensor&& other);
47  Tensor& operator=(Tensor&& other);
48  ~Tensor();
49 
50  public:
51  /// @brief set the value of a specific tensor element
52  /// @param[in] value the value
53  /// @param[in] rest the rest of the indices (0-based)
54  template <typename... Args>
55  void setValue(std::complex<double> value, Args... rest);
56 
57  /// @brief returns the value of a specific tensor element
58  /// @param[in] rest the rest of the indices (0-based)
59  /// @return the element value
60  template <typename... Args>
61  std::complex<double> value(Args... rest) const;
62 
63  /// @brief access an element given its indices
64  /// @param[in] indices the list of indices, 0-based
65  /// @return a reference to the element
66  std::complex<double>& element(const IndexList& indices = {});
67 
68  /// @brief access an element given its indices (const version)
69  /// @param[in] indices the list of indices, 0-based
70  /// @return a reference to the element
71  std::complex<double> element(const IndexList& indices = {}) const;
72 
73  public:
74 
75  /// @brief rank of the tensor
76  /// @return the number of components
77  size_t rank() const;
78 
79  /// @brief get the dimensions of all the indices at once
80  /// @return the list of dimensions
81  IndexList dims() const;
82 
83  /// @brief get the labels of all the indices at once
84  /// @return the list of labels
85  LabelsList labels() const;
86 
87  /// @brief checks if Tensor has indices in the WC range
88  /// @return bool
89  bool hasWCLabels() const;
90 
91  /// @brief checks if Tensor has indices in the FF range
92  /// @return bool
93  bool hasFFLabels() const;
94 
95  /// @brief checks if Tensor has indices in the FF Var range
96  /// @return bool
97  bool hasFFVarLabels() const;
98 
99  /// @brief get the tensor name
100  /// @return the name
101  const std::string& name() const;
102 
103  // protected:
104 
105  // /// @brief fills specific tensor elements at once
106  // /// @param[in] values a list of (indices, value) for the elements to set
107  // /// @return a reference to itself
108  // void fillTensorElements(const std::vector<std::pair<std::vector<size_t>, std::complex<double>>>& values);
109 
110  public:
111 
112  bool isEqualTo(const Tensor& other) const;
113 
114  /// @brief contract this tensor with another and stores the result in this tensor
115  /// @param[in] other the othe tensor
116  /// @param[in] indices restrict the indices to be contracted, identified by labels.
117  /// If no labels are passed all the contractable indices are contracted.
118  /// If a set of labels is passed, the indices to be contracted will be the
119  /// intersection between the provided set and the set of contractable labels
120  /// @return a reference to itself
121  Tensor& dot(const Tensor& other, const UniqueLabelsList& indices = {});
122 
123  /// @brief trace some of the indices of this tensor
124  /// @return a reference to itself
125  Tensor& spinSum();
126 
127  /// @brief trace over the traceable spin indices and divide by the product of the
128  /// dimensions of the traced indices (equal to \f$ 2s_i + 1 \f$)
129  /// @return a reference to itself
130  Tensor& spinAverage();
131 
132  /// @brief creates a tensor with twice the rank
133  /// by multiplying the tensor with its hermitean conjugate
134  /// @return a reference to itself
135  Tensor& outerSquare();
136 
137  /// @brief forces conversion of a tensor to vector type
138  /// @return a reference to itself
139  Tensor& toVector();
140 
141  /// @brief multiply all the elements of the tensor by a real number
142  /// @param[in] val the value
143  /// @return a reference to itself
144  Tensor& operator*=(double val);
145 
146  /// @brief multiply all the elements of the tensor by a complex number
147  /// @param[in] val the value
148  /// @return a reference to itself
149  Tensor& operator*=(std::complex<double> val);
150 
151  /// @brief sums another tensor to itself
152  /// @param[in] other the other tensor
153  /// @return a reference to itself. Throws if tensors have different shapes
154  Tensor& operator+=(const Tensor& other);
155 
156  /// @brief multiply two tensors element by element and stores the result in this tensor
157  /// @param[in] other the other tensor
158  /// @return a reference to itself. Throws if tensors have different shapes
159  Tensor& elementMultiplyBy(const Tensor& other);
160 
161  /// @brief divide two tensors element by element and stores the result in this tensor
162  /// @param[in] other the other tensor
163  /// @return a reference to itself. Throws if tensors have different shapes or if
164  /// a division by zero is encountered
165  Tensor& elementDivideBy(const Tensor& other);
166 
167  /// @brief add a tensor of rank N-1 to a specific position in a specific coordinate
168  /// the dimension of the tensor should match those of this tensor in all the other dimensions
169  /// @param[in] t the other tensor
170  /// @param[in] coord the cooridnate, identified by its label. If multiple dimensions have the
171  /// same label, the first one is considered.
172  /// @param[in] position the position along the dimension
173  /// @return a reference to itself. Throws if the dimensions of the two tensors are incompatible
174  Tensor& addAt(const Tensor& t, IndexLabel coord, IndexType position);
175 
176  /// @brief sets all the elements to 0
177  void clearData();
178 
179  public:
180  /// @brief write the contents of the tensor for serialization
181  /// @param[in] msgwriter the writer object
182  /// @param[in] msg the location where to write
183  void write(flatbuffers::FlatBufferBuilder* msgwriter, flatbuffers::Offset<Serial::FBTensor>* msg) const;
184 
185  /// @brief read the contents of the tensor for serialization
186  /// @param[in] msgreader the reader object
187  void read(const Serial::FBTensor* msgreader);
188 
189  protected:
190  /// @brief logging facility
191  /// @return stream to be used for logging
192  Log& getLog() const;
193 
194  private:
195  std::string _name; ///< the tensor name
197  };
198 
199  /// @brief tensor dot product
200  /// \overload dot
201  /// @param[in] first the first tensor
202  /// @param[in] second the second tensor
203  /// @param[in] indices restrict the indices to be contracted, identified by labels.
204  /// If no labels are passed all the contractable indices are contracted.
205  /// If a set of labels is passed, the indices to be contracted will be the
206  /// intersection between the provided set and the set of contractable labels
207  /// @return the result of the dot product
208  Tensor dot(const Tensor& first, const Tensor& second, const std::set<IndexLabel>& indices = {});
209 
210  /// @brief trace a tensor
211  /// @param[in] first the tensor to be traced
212  /// @return the result of the trace
213  Tensor spinSum(const Tensor& first);
214 
215  /// @brief trace a tensor over the traceable spin indices and divide by the product of the
216  /// dimensions of the traced indices (equal to \f$ 2s_i + 1 \f$)
217  /// @param[in] first the tensor to be spin averaged
218  /// @return the result of the spin average
219  Tensor spinAverage(const Tensor& first);
220 
221  /// @brief left multiplies a tensor by a real constant
222  /// @param[in] first the tensor
223  /// @param[in] val the real number
224  /// @return the result of the multiplication
225  Tensor operator*(const Tensor& first, double val);
226 
227  /// @brief right multiplies a tensor by a real constant
228  /// @param[in] val the real number
229  /// @param[in] first the tensor
230  /// @return the result of the multiplication
231  Tensor operator*(double val, const Tensor& first);
232 
233  /// @brief left multiplies a tensor by a complex constant
234  /// @param[in] first the tensor
235  /// @param[in] val the complex number
236  /// @return the result of the multiplication
237  Tensor operator*(const Tensor& first, std::complex<double> val);
238 
239  /// @brief right multiplies a tensor by a complex constant
240  /// @param[in] val the complex number
241  /// @param[in] first the tensor
242  /// @return the result of the multiplication
243  Tensor operator*(std::complex<double> val, const Tensor& first);
244 
245  /// @brief adds two tensors of the same rank and same dimensions
246  /// @param[in] first the first tensor
247  /// @param[in] second the second tensor
248  /// @return the result of the sum.
249  /// Throws an exception if the tensors don't have the same dimensions
250  Tensor operator+(const Tensor& first, const Tensor& second);
251 
252  /// @brief creates a tensor with twice the rank
253  /// by multiplying the tensor with it's hermitean conjugate
254  /// @param[in] first the tensor
255  /// @return the result
256  Tensor outerSquare(const Tensor& first);
257 
258  /// @brief multiplies two tensors of the same rank and same dimensions element by element
259  /// @param[in] first the first tensor
260  /// @param[in] second the second tensor
261  /// @return the result of the multiplications
262  /// Throws an exception if the tensors don't have the same dimensions
263  Tensor elementMultiply(const Tensor& first, const Tensor& second);
264 
265  /// @brief divides two tensors of the same rank and same dimensions element by element
266  /// @param[in] first the numerator tensor
267  /// @param[in] second the denominator tensor
268  /// @return the result of the divisions
269  /// Throws an exception if the tensors don't have the same dimensions or if a
270  /// division by zero is encountered
271  Tensor elementDivide(const Tensor& first, const Tensor& second);
272 
273 } // namespace Hammer
274 
275 #include "Hammer/Math/TensorDefs.hh"
276 
277 #endif
Tensor elementDivide(const Tensor &first, const Tensor &second)
divides two tensors of the same rank and same dimensions element by element
Definition: Tensor.cc:328
Tensor & outerSquare()
creates a tensor with twice the rank by multiplying the tensor with its hermitean conjugate ...
Definition: Tensor.cc:162
Tensor & spinSum()
trace some of the indices of this tensor
Definition: Tensor.cc:144
Log & getLog() const
logging facility
Definition: Tensor.cc:110
std::complex< double > & element(const IndexList &indices={})
access an element given its indices
Definition: Tensor.cc:67
Forward declaration of serialization related typedefs and includes.
Tensor & spinAverage()
trace over the traceable spin indices and divide by the product of the dimensions of the traced indic...
Definition: Tensor.cc:155
Tensor & toVector()
forces conversion of a tensor to vector type
Definition: Tensor.cc:171
Tensor & addAt(const Tensor &t, IndexLabel coord, IndexType position)
add a tensor of rank N-1 to a specific position in a specific coordinate the dimension of the tensor ...
Definition: Tensor.cc:259
Tensor & operator+=(const Tensor &other)
sums another tensor to itself
Definition: Tensor.cc:187
LabelsList labels() const
get the labels of all the indices at once
Definition: Tensor.cc:83
const std::string & name() const
get the tensor name
Definition: Tensor.cc:102
Tensor outerSquare(const Tensor &first)
creates a tensor with twice the rank by multiplying the tensor with it&#39;s hermitean conjugate ...
Definition: Tensor.cc:316
void write(flatbuffers::FlatBufferBuilder *msgwriter, flatbuffers::Offset< Serial::FBTensor > *msg) const
write the contents of the tensor for serialization
Definition: Tensor.cc:233
Tensor elementMultiply(const Tensor &first, const Tensor &second)
multiplies two tensors of the same rank and same dimensions element by element
Definition: Tensor.cc:322
bool hasFFLabels() const
checks if Tensor has indices in the FF range
Definition: Tensor.cc:92
uint16_t IndexType
std::unique_ptr< IContainer > TensorData
std::complex< double > value(Args...rest) const
returns the value of a specific tensor element
Definition: TensorDefs.hh:31
Forward declarations of types used in the tensor classes.
size_t rank() const
rank of the tensor
Definition: Tensor.cc:75
Tensor spinSum(const Tensor &first)
trace a tensor
Definition: Tensor.cc:274
Tensor & operator*=(double val)
multiply all the elements of the tensor by a real number
Definition: Tensor.cc:176
MultiDimensional::TensorData _data
Definition: Tensor.hh:196
std::vector< IndexType > IndexList
void setValue(std::complex< double > value, Args...rest)
set the value of a specific tensor element
Definition: TensorDefs.hh:22
Logging class.
Definition: Logging.hh:33
IndexLabel
label identifiers of tensor indices they are used to determine which indices can be contracted togeth...
Definition: IndexLabels.hh:27
Multidimensional tensor class with complex numbers as elements.
Definition: Tensor.hh:33
bool isEqualTo(const Tensor &other) const
Definition: Tensor.cc:106
Tensor operator*(const Tensor &first, double val)
left multiplies a tensor by a real constant
Definition: Tensor.cc:286
void clearData()
sets all the elements to 0
Definition: Tensor.cc:229
std::string _name
the tensor name
Definition: Tensor.hh:195
Hammer tensor class template methods definitions.
std::vector< IndexLabel > LabelsList
std::set< IndexLabel > UniqueLabelsList
Tensor & elementDivideBy(const Tensor &other)
divide two tensors element by element and stores the result in this tensor
Definition: Tensor.cc:215
Tensor spinAverage(const Tensor &first)
trace a tensor over the traceable spin indices and divide by the product of the dimensions of the tra...
Definition: Tensor.cc:280
Tensor & dot(const Tensor &other, const UniqueLabelsList &indices={})
contract this tensor with another and stores the result in this tensor
Definition: Tensor.cc:114
IndexList dims() const
get the dimensions of all the indices at once
Definition: Tensor.cc:79
Tensor & elementMultiplyBy(const Tensor &other)
multiply two tensors element by element and stores the result in this tensor
Definition: Tensor.cc:201
void read(const Serial::FBTensor *msgreader)
read the contents of the tensor for serialization
Definition: Tensor.cc:245
Histogram operator+(const Histogram &first, const Histogram &second)
Definition: Histogram.cc:412
bool hasFFVarLabels() const
checks if Tensor has indices in the FF Var range
Definition: Tensor.cc:97
Tensor & operator=(const Tensor &other)
Definition: Tensor.cc:47
bool hasWCLabels() const
checks if Tensor has indices in the WC range
Definition: Tensor.cc:87
Tensor dot(const Tensor &first, const Tensor &second, const set< IndexLabel > &indices)
Definition: Tensor.cc:268