10 #ifndef EIGEN_CXX11_TENSORSYMMETRY_STATICSYMMETRY_H 11 #define EIGEN_CXX11_TENSORSYMMETRY_STATICSYMMETRY_H 17 template<
typename list>
struct tensor_static_symgroup_permutate;
20 struct tensor_static_symgroup_permutate<numeric_list<int, nn...>>
22 constexpr
static std::size_t N =
sizeof...(nn);
25 constexpr
static inline std::array<T, N> run(
const std::array<T, N>& indices)
27 return {{indices[nn]...}};
31 template<
typename indices_,
int flags_>
32 struct tensor_static_symgroup_element
34 typedef indices_ indices;
35 constexpr
static int flags = flags_;
38 template<
typename Gen,
int N>
39 struct tensor_static_symgroup_element_ctor
41 typedef tensor_static_symgroup_element<
42 typename gen_numeric_list_swapped_pair<int, N, Gen::One, Gen::Two>::type,
48 struct tensor_static_symgroup_identity_ctor
50 typedef tensor_static_symgroup_element<
51 typename gen_numeric_list<int, N>::type,
56 template<
typename iib>
57 struct tensor_static_symgroup_multiply_helper
60 constexpr
static inline numeric_list<int, get<iia, iib>::value...> helper(numeric_list<int, iia...>) {
61 return numeric_list<int, get<iia, iib>::value...>();
65 template<
typename A,
typename B>
66 struct tensor_static_symgroup_multiply
69 typedef typename A::indices iia;
70 typedef typename B::indices iib;
71 constexpr
static int ffa = A::flags;
72 constexpr
static int ffb = B::flags;
75 static_assert(iia::count == iib::count,
"Cannot multiply symmetry elements with different number of indices.");
77 typedef tensor_static_symgroup_element<
78 decltype(tensor_static_symgroup_multiply_helper<iib>::helper(iia())),
83 template<
typename A,
typename B>
84 struct tensor_static_symgroup_equality
86 typedef typename A::indices iia;
87 typedef typename B::indices iib;
88 constexpr
static int ffa = A::flags;
89 constexpr
static int ffb = B::flags;
90 static_assert(iia::count == iib::count,
"Cannot compare symmetry elements with different number of indices.");
92 constexpr
static bool value = is_same<iia, iib>::value;
98 constexpr
static int flags_cmp_ = ffa ^ ffb;
103 constexpr
static bool is_zero = value && flags_cmp_ == NegationFlag;
104 constexpr
static bool is_real = value && flags_cmp_ == ConjugationFlag;
105 constexpr
static bool is_imag = value && flags_cmp_ == (NegationFlag | ConjugationFlag);
108 constexpr
static int global_flags =
109 (is_real ? GlobalRealFlag : 0) |
110 (is_imag ? GlobalImagFlag : 0) |
111 (is_zero ? GlobalZeroFlag : 0);
114 template<std::size_t NumIndices,
typename... Gen>
115 struct tensor_static_symgroup
117 typedef StaticSGroup<Gen...> type;
118 constexpr
static std::size_t size = type::static_size;
121 template<
typename Index, std::size_t N,
int... ii,
int... jj>
122 constexpr
static inline std::array<Index, N> tensor_static_symgroup_index_permute(std::array<Index, N> idx, internal::numeric_list<int, ii...>, internal::numeric_list<int, jj...>)
124 return {{ idx[ii]..., idx[jj]... }};
127 template<
typename Index,
int... ii>
128 static inline std::vector<Index> tensor_static_symgroup_index_permute(std::vector<Index> idx, internal::numeric_list<int, ii...>)
130 std::vector<Index> result{{ idx[ii]... }};
131 std::size_t target_size = idx.size();
132 for (std::size_t i = result.size(); i < target_size; i++)
133 result.push_back(idx[i]);
137 template<
typename T>
struct tensor_static_symgroup_do_apply;
139 template<
typename first,
typename... next>
140 struct tensor_static_symgroup_do_apply<internal::type_list<first, next...>>
142 template<
typename Op,
typename RV, std::size_t SGNumIndices,
typename Index, std::size_t NumIndices,
typename... Args>
143 static inline RV run(
const std::array<Index, NumIndices>& idx, RV initial, Args&&... args)
145 static_assert(NumIndices >= SGNumIndices,
"Can only apply symmetry group to objects that have at least the required amount of indices.");
146 typedef typename internal::gen_numeric_list<int, NumIndices - SGNumIndices, SGNumIndices>::type remaining_indices;
147 initial = Op::run(tensor_static_symgroup_index_permute(idx,
typename first::indices(), remaining_indices()), first::flags, initial, std::forward<Args>(args)...);
148 return tensor_static_symgroup_do_apply<internal::type_list<next...>>::template run<Op, RV, SGNumIndices>(idx, initial, args...);
151 template<
typename Op,
typename RV, std::size_t SGNumIndices,
typename Index,
typename... Args>
152 static inline RV run(
const std::vector<Index>& idx, RV initial, Args&&... args)
154 eigen_assert(idx.size() >= SGNumIndices &&
"Can only apply symmetry group to objects that have at least the required amount of indices.");
155 initial = Op::run(tensor_static_symgroup_index_permute(idx,
typename first::indices()), first::flags, initial, std::forward<Args>(args)...);
156 return tensor_static_symgroup_do_apply<internal::type_list<next...>>::template run<Op, RV, SGNumIndices>(idx, initial, args...);
160 template<EIGEN_TPL_PP_SPEC_HACK_DEF(
typename, empty)>
161 struct tensor_static_symgroup_do_apply<internal::type_list<EIGEN_TPL_PP_SPEC_HACK_USE(empty)>>
163 template<
typename Op,
typename RV, std::size_t SGNumIndices,
typename Index, std::size_t NumIndices,
typename... Args>
164 static inline RV run(
const std::array<Index, NumIndices>&, RV initial, Args&&...)
170 template<
typename Op,
typename RV, std::size_t SGNumIndices,
typename Index,
typename... Args>
171 static inline RV run(
const std::vector<Index>&, RV initial, Args&&...)
180 template<
typename... Gen>
183 constexpr
static std::size_t NumIndices = internal::tensor_symmetry_num_indices<Gen...>::value;
184 typedef internal::group_theory::enumerate_group_elements<
185 internal::tensor_static_symgroup_multiply,
186 internal::tensor_static_symgroup_equality,
187 typename internal::tensor_static_symgroup_identity_ctor<NumIndices>::type,
188 internal::type_list<typename internal::tensor_static_symgroup_element_ctor<Gen, NumIndices>::type...>
190 typedef typename group_elements::type ge;
196 template<
typename Op,
typename RV,
typename Index, std::size_t N,
typename... Args>
197 static inline RV apply(
const std::array<Index, N>& idx, RV initial, Args&&... args)
199 return internal::tensor_static_symgroup_do_apply<ge>::template run<Op, RV, NumIndices>(idx, initial, args...);
202 template<
typename Op,
typename RV,
typename Index,
typename... Args>
203 static inline RV apply(
const std::vector<Index>& idx, RV initial, Args&&... args)
205 eigen_assert(idx.size() == NumIndices);
206 return internal::tensor_static_symgroup_do_apply<ge>::template run<Op, RV, NumIndices>(idx, initial, args...);
209 constexpr
static std::size_t static_size = ge::count;
211 constexpr
static inline std::size_t size() {
214 constexpr
static inline int globalFlags() {
return group_elements::global_flags; }
216 template<
typename Tensor_,
typename... IndexTypes>
217 inline internal::tensor_symmetry_value_setter<Tensor_,
StaticSGroup<Gen...>> operator()(Tensor_& tensor,
typename Tensor_::Index firstIndex, IndexTypes... otherIndices)
const 219 static_assert(
sizeof...(otherIndices) + 1 == Tensor_::NumIndices,
"Number of indices used to access a tensor coefficient must be equal to the rank of the tensor.");
220 return operator()(tensor, std::array<typename Tensor_::Index, Tensor_::NumIndices>{{firstIndex, otherIndices...}});
223 template<
typename Tensor_>
224 inline internal::tensor_symmetry_value_setter<Tensor_,
StaticSGroup<Gen...>> operator()(Tensor_& tensor, std::array<typename Tensor_::Index, Tensor_::NumIndices>
const& indices)
const 226 return internal::tensor_symmetry_value_setter<Tensor_,
StaticSGroup<Gen...>>(tensor, *
this, indices);
232 #endif // EIGEN_CXX11_TENSORSYMMETRY_STATICSYMMETRY_H Namespace containing all symbols from the Eigen library.
Definition: AdolcForward:45
Static symmetry group.
Definition: StaticSymmetry.h:181