10#ifndef EIGEN_CXX11_TENSORSYMMETRY_SYMMETRY_H
11#define EIGEN_CXX11_TENSORSYMMETRY_SYMMETRY_H
17 ConjugationFlag = 0x02
21 GlobalRealFlag = 0x01,
22 GlobalImagFlag = 0x02,
28template<std::size_t NumIndices,
typename... Sym>
struct tensor_symmetry_pre_analysis;
29template<std::size_t NumIndices,
typename... Sym>
struct tensor_static_symgroup;
30template<
bool instantiate, std::size_t NumIndices,
typename... Sym>
struct tensor_static_symgroup_if;
31template<
typename Tensor_>
struct tensor_symmetry_calculate_flags;
32template<
typename Tensor_>
struct tensor_symmetry_assign_value;
33template<
typename... Sym>
struct tensor_symmetry_num_indices;
37template<
int One_,
int Two_>
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;
46template<
int One_,
int Two_>
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;
55template<
int One_,
int Two_>
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;
64template<
int One_,
int Two_>
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;
98template<
typename... Gen>
99class DynamicSGroupFromTemplateArgs;
120template<
typename... Gen>
135template<
typename... Gen>
136class SGroup :
public internal::tensor_symmetry_pre_analysis<internal::tensor_symmetry_num_indices<Gen...>::value, Gen...>::root_type
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;
143 inline SGroup() : Base() { }
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; }
154template<
typename... Sym>
struct tensor_symmetry_num_indices
156 constexpr static std::size_t value = 1;
159template<
int One_,
int Two_,
typename... Sym>
struct tensor_symmetry_num_indices<Symmetry<One_, Two_>, Sym...>
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;
167 constexpr static std::size_t maxOneTwoPlusOne = ((One > Two) ? One : Two) + 1;
169 constexpr static std::size_t value = (maxOneTwoPlusOne > Three) ? maxOneTwoPlusOne : Three;
172template<
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...> {};
174template<
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...> {};
176template<
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...> {};
226template<std::
size_t NumIndices>
227struct tensor_symmetry_pre_analysis<NumIndices>
229 typedef StaticSGroup<> root_type;
232template<std::size_t NumIndices,
typename Gen_,
typename... Gens_>
233struct tensor_symmetry_pre_analysis<NumIndices, Gen_, Gens_...>
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;
240 typedef typename conditional<
241 possible_size == 0 || possible_size >= max_static_elements,
242 DynamicSGroupFromTemplateArgs<Gen_, Gens_...>,
243 typename helper::type
247template<
bool instantiate, std::size_t NumIndices,
typename... Gens>
248struct tensor_static_symgroup_if
250 constexpr static std::size_t size = 0;
254template<std::size_t NumIndices,
typename... Gens>
255struct tensor_static_symgroup_if<true, NumIndices, Gens...> : tensor_static_symgroup<NumIndices, Gens...> {};
257template<
typename Tensor_>
258struct tensor_symmetry_assign_value
260 typedef typename Tensor_::Index
Index;
261 typedef typename Tensor_::Scalar Scalar;
262 constexpr static std::size_t NumIndices = Tensor_::NumIndices;
264 static inline int run(
const std::array<Index, NumIndices>& transformed_indices,
int transformation_flags,
int dummy, Tensor_& tensor,
const Scalar& value_)
266 Scalar value(value_);
267 if (transformation_flags & ConjugationFlag)
268 value = numext::conj(value);
269 if (transformation_flags & NegationFlag)
271 tensor.coeffRef(transformed_indices) = value;
276template<
typename Tensor_>
277struct tensor_symmetry_calculate_flags
279 typedef typename Tensor_::Index
Index;
280 constexpr static std::size_t NumIndices = Tensor_::NumIndices;
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)
284 if (transformed_indices == orig_indices) {
285 if (transform_flags & (ConjugationFlag | NegationFlag))
286 return current_flags | GlobalImagFlag;
287 else if (transform_flags & ConjugationFlag)
288 return current_flags | GlobalRealFlag;
289 else if (transform_flags & NegationFlag)
290 return current_flags | GlobalZeroFlag;
292 return current_flags;
296template<
typename Tensor_,
typename Symmetry_,
int Flags = 0>
297class tensor_symmetry_value_setter
300 typedef typename Tensor_::Index
Index;
301 typedef typename Tensor_::Scalar Scalar;
302 constexpr static std::size_t NumIndices = Tensor_::NumIndices;
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) { }
307 inline tensor_symmetry_value_setter<Tensor_, Symmetry_, Flags>& operator=(Scalar
const& value)
314 Symmetry_ m_symmetry;
315 std::array<Index, NumIndices> m_indices;
317 inline void doAssign(Scalar
const& value)
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);
326 m_symmetry.template apply<internal::tensor_symmetry_assign_value<Tensor_>,
int>(m_indices, 0, m_tensor, value);
Symmetry group, initialized from template arguments.
Definition: Symmetry.h:137
Namespace containing all symbols from the Eigen library.
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index