Symmetry.h
Go to the documentation of this file.
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2013 Christian Seiler <christian@iwakd.de>
5 //
6 // This Source Code Form is subject to the terms of the Mozilla
7 // Public License v. 2.0. If a copy of the MPL was not distributed
8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 
10 #ifndef EIGEN_CXX11_TENSORSYMMETRY_SYMMETRY_H
11 #define EIGEN_CXX11_TENSORSYMMETRY_SYMMETRY_H
12 
13 namespace Eigen {
14 
15 enum {
16  NegationFlag = 0x01,
18 };
19 
20 enum {
24 };
25 
26 namespace internal {
27 
28 template<std::size_t NumIndices, typename... Sym> struct tensor_symmetry_pre_analysis;
29 template<std::size_t NumIndices, typename... Sym> struct tensor_static_symgroup;
30 template<bool instantiate, std::size_t NumIndices, typename... Sym> struct tensor_static_symgroup_if;
31 template<typename Tensor_> struct tensor_symmetry_calculate_flags;
32 template<typename Tensor_> struct tensor_symmetry_assign_value;
33 template<typename... Sym> struct tensor_symmetry_num_indices;
34 
35 } // end namespace internal
36 
37 template<int One_, int Two_>
38 struct Symmetry
39 {
40  static_assert(One_ != Two_, "Symmetries must cover distinct indices.");
41  constexpr static int One = One_;
42  constexpr static int Two = Two_;
43  constexpr static int Flags = 0;
44 };
45 
46 template<int One_, int Two_>
48 {
49  static_assert(One_ != Two_, "Symmetries must cover distinct indices.");
50  constexpr static int One = One_;
51  constexpr static int Two = Two_;
52  constexpr static int Flags = NegationFlag;
53 };
54 
55 template<int One_, int Two_>
57 {
58  static_assert(One_ != Two_, "Symmetries must cover distinct indices.");
59  constexpr static int One = One_;
60  constexpr static int Two = Two_;
61  constexpr static int Flags = ConjugationFlag;
62 };
63 
64 template<int One_, int Two_>
66 {
67  static_assert(One_ != Two_, "Symmetries must cover distinct indices.");
68  constexpr static int One = One_;
69  constexpr static int Two = Two_;
70  constexpr static int Flags = ConjugationFlag | NegationFlag;
71 };
72 
86 class DynamicSGroup;
87 
98 template<typename... Gen>
100 
120 template<typename... Gen>
121 class StaticSGroup;
122 
135 template<typename... Gen>
136 class SGroup : public internal::tensor_symmetry_pre_analysis<internal::tensor_symmetry_num_indices<Gen...>::value, Gen...>::root_type
137 {
138  public:
139  constexpr static std::size_t NumIndices = internal::tensor_symmetry_num_indices<Gen...>::value;
140  typedef typename internal::tensor_symmetry_pre_analysis<NumIndices, Gen...>::root_type Base;
141 
142  // make standard constructors + assignment operators public
143  inline SGroup() : Base() { }
144  inline SGroup(const SGroup<Gen...>& other) : Base(other) { }
145  inline SGroup(SGroup<Gen...>&& other) : Base(other) { }
146  inline SGroup<Gen...>& operator=(const SGroup<Gen...>& other) { Base::operator=(other); return *this; }
147  inline SGroup<Gen...>& operator=(SGroup<Gen...>&& other) { Base::operator=(other); return *this; }
148 
149  // all else is defined in the base class
150 };
151 
152 namespace internal {
153 
154 template<typename... Sym> struct tensor_symmetry_num_indices
155 {
156  constexpr static std::size_t value = 1;
157 };
158 
159 template<int One_, int Two_, typename... Sym> struct tensor_symmetry_num_indices<Symmetry<One_, Two_>, Sym...>
160 {
161 private:
162  constexpr static std::size_t One = static_cast<std::size_t>(One_);
163  constexpr static std::size_t Two = static_cast<std::size_t>(Two_);
164  constexpr static std::size_t Three = tensor_symmetry_num_indices<Sym...>::value;
165 
166  // don't use std::max, since it's not constexpr until C++14...
167  constexpr static std::size_t maxOneTwoPlusOne = ((One > Two) ? One : Two) + 1;
168 public:
169  constexpr static std::size_t value = (maxOneTwoPlusOne > Three) ? maxOneTwoPlusOne : Three;
170 };
171 
172 template<int One_, int Two_, typename... Sym> struct tensor_symmetry_num_indices<AntiSymmetry<One_, Two_>, Sym...>
173  : public tensor_symmetry_num_indices<Symmetry<One_, Two_>, Sym...> {};
174 template<int One_, int Two_, typename... Sym> struct tensor_symmetry_num_indices<Hermiticity<One_, Two_>, Sym...>
175  : public tensor_symmetry_num_indices<Symmetry<One_, Two_>, Sym...> {};
176 template<int One_, int Two_, typename... Sym> struct tensor_symmetry_num_indices<AntiHermiticity<One_, Two_>, Sym...>
177  : public tensor_symmetry_num_indices<Symmetry<One_, Two_>, Sym...> {};
178 
226 template<std::size_t NumIndices>
228 {
230 };
231 
232 template<std::size_t NumIndices, typename Gen_, typename... Gens_>
233 struct tensor_symmetry_pre_analysis<NumIndices, Gen_, Gens_...>
234 {
235  constexpr static std::size_t max_static_generators = 4;
236  constexpr static std::size_t max_static_elements = 16;
237  typedef tensor_static_symgroup_if<(sizeof...(Gens_) + 1 <= max_static_generators), NumIndices, Gen_, Gens_...> helper;
238  constexpr static std::size_t possible_size = helper::size;
239 
240  typedef typename conditional<
241  possible_size == 0 || possible_size >= max_static_elements,
242  DynamicSGroupFromTemplateArgs<Gen_, Gens_...>,
243  typename helper::type
244  >::type root_type;
245 };
246 
247 template<bool instantiate, std::size_t NumIndices, typename... Gens>
249 {
250  constexpr static std::size_t size = 0;
251  typedef void type;
252 };
253 
254 template<std::size_t NumIndices, typename... Gens>
255 struct tensor_static_symgroup_if<true, NumIndices, Gens...> : tensor_static_symgroup<NumIndices, Gens...> {};
256 
257 template<typename Tensor_>
259 {
260  typedef typename Tensor_::Index Index;
261  typedef typename Tensor_::Scalar Scalar;
262  constexpr static std::size_t NumIndices = Tensor_::NumIndices;
263 
264  static inline int run(const std::array<Index, NumIndices>& transformed_indices, int transformation_flags, int dummy, Tensor_& tensor, const Scalar& value_)
265  {
266  Scalar value(value_);
267  if (transformation_flags & ConjugationFlag)
268  value = numext::conj(value);
269  if (transformation_flags & NegationFlag)
270  value = -value;
271  tensor.coeffRef(transformed_indices) = value;
272  return dummy;
273  }
274 };
275 
276 template<typename Tensor_>
278 {
279  typedef typename Tensor_::Index Index;
280  constexpr static std::size_t NumIndices = Tensor_::NumIndices;
281 
282  static inline int run(const std::array<Index, NumIndices>& transformed_indices, int transform_flags, int current_flags, const std::array<Index, NumIndices>& orig_indices)
283  {
284  if (transformed_indices == orig_indices) {
285  if (transform_flags & (ConjugationFlag | NegationFlag))
286  return current_flags | GlobalImagFlag; // anti-hermitian diagonal
287  else if (transform_flags & ConjugationFlag)
288  return current_flags | GlobalRealFlag; // hermitian diagonal
289  else if (transform_flags & NegationFlag)
290  return current_flags | GlobalZeroFlag; // anti-symmetric diagonal
291  }
292  return current_flags;
293  }
294 };
295 
296 template<typename Tensor_, typename Symmetry_, int Flags = 0>
298 {
299  public:
300  typedef typename Tensor_::Index Index;
301  typedef typename Tensor_::Scalar Scalar;
302  constexpr static std::size_t NumIndices = Tensor_::NumIndices;
303 
304  inline tensor_symmetry_value_setter(Tensor_& tensor, Symmetry_ const& symmetry, std::array<Index, NumIndices> const& indices)
305  : m_tensor(tensor), m_symmetry(symmetry), m_indices(indices) { }
306 
308  {
309  doAssign(value);
310  return *this;
311  }
312  private:
313  Tensor_& m_tensor;
314  Symmetry_ m_symmetry;
315  std::array<Index, NumIndices> m_indices;
316 
317  inline void doAssign(Scalar const& value)
318  {
319  #ifdef EIGEN_TENSOR_SYMMETRY_CHECK_VALUES
320  int value_flags = m_symmetry.template apply<internal::tensor_symmetry_calculate_flags<Tensor_>, int>(m_indices, m_symmetry.globalFlags(), m_indices);
321  if (value_flags & GlobalRealFlag)
322  eigen_assert(numext::imag(value) == 0);
323  if (value_flags & GlobalImagFlag)
324  eigen_assert(numext::real(value) == 0);
325  #endif
326  m_symmetry.template apply<internal::tensor_symmetry_assign_value<Tensor_>, int>(m_indices, 0, m_tensor, value);
327  }
328 };
329 
330 } // end namespace internal
331 
332 } // end namespace Eigen
333 
334 #endif // EIGEN_CXX11_TENSORSYMMETRY_SYMMETRY_H
335 
336 /*
337  * kate: space-indent on; indent-width 2; mixedindent off; indent-mode cstyle;
338  */
SCALAR Scalar
Definition: bench_gemm.cpp:46
static int run(const std::array< Index, NumIndices > &transformed_indices, int transformation_flags, int dummy, Tensor_ &tensor, const Scalar &value_)
Definition: Symmetry.h:264
tensor_symmetry_value_setter(Tensor_ &tensor, Symmetry_ const &symmetry, std::array< Index, NumIndices > const &indices)
Definition: Symmetry.h:304
float real
Definition: datatypes.h:10
static int run(const std::array< Index, NumIndices > &transformed_indices, int transform_flags, int current_flags, const std::array< Index, NumIndices > &orig_indices)
Definition: Symmetry.h:282
Symmetry group, initialized from template arguments.
Definition: Symmetry.h:136
Namespace containing all symbols from the Eigen library.
Definition: jet.h:637
internal::tensor_symmetry_pre_analysis< NumIndices, Gen... >::root_type Base
Definition: Symmetry.h:140
AnnoyingScalar conj(const AnnoyingScalar &x)
Scalar Scalar int size
Definition: benchVecAdd.cpp:17
Static symmetry group.
SGroup< Gen... > & operator=(SGroup< Gen... > &&other)
Definition: Symmetry.h:147
SGroup(SGroup< Gen... > &&other)
Definition: Symmetry.h:145
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:74
#define eigen_assert(x)
Definition: Macros.h:1037
SGroup< Gen... > & operator=(const SGroup< Gen... > &other)
Definition: Symmetry.h:146
EIGEN_CONSTEXPR Index size(const T &x)
Definition: Meta.h:479
void doAssign(Scalar const &value)
Definition: Symmetry.h:317
std::array< Index, NumIndices > m_indices
Definition: Symmetry.h:315
tensor_static_symgroup_if<(sizeof...(Gens_)+1<=max_static_generators), NumIndices, Gen_, Gens_... > helper
Definition: Symmetry.h:237
EIGEN_DEVICE_FUNC const ImagReturnType imag() const
Dynamic symmetry group.
SGroup(const SGroup< Gen... > &other)
Definition: Symmetry.h:144
tensor_symmetry_value_setter< Tensor_, Symmetry_, Flags > & operator=(Scalar const &value)
Definition: Symmetry.h:307
Definition: pytypes.h:1370


gtsam
Author(s):
autogenerated on Tue Jul 4 2023 02:36:35