12b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// This file is part of Eigen, a lightweight C++ template library
22b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// for linear algebra.
32b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang//
42b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// Copyright (C) 2013 Christian Seiler <christian@iwakd.de>
52b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang//
62b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// This Source Code Form is subject to the terms of the Mozilla
72b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// Public License v. 2.0. If a copy of the MPL was not distributed
82b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
92b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
102b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#ifndef EIGEN_CXX11_TENSORSYMMETRY_STATICSYMMETRY_H
112b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#define EIGEN_CXX11_TENSORSYMMETRY_STATICSYMMETRY_H
122b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
132b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangnamespace Eigen {
142b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
152b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangnamespace internal {
162b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
172b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename list> struct tensor_static_symgroup_permutate;
182b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
192b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<int... nn>
202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct tensor_static_symgroup_permutate<numeric_list<int, nn...>>
212b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  constexpr static std::size_t N = sizeof...(nn);
232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
242b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  template<typename T>
252b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  constexpr static inline std::array<T, N> run(const std::array<T, N>& indices)
262b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  {
272b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    return {{indices[nn]...}};
282b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  }
292b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
302b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
312b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename indices_, int flags_>
322b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct tensor_static_symgroup_element
332b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
342b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef indices_ indices;
352b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  constexpr static int flags = flags_;
362b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
372b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
382b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Gen, int N>
392b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct tensor_static_symgroup_element_ctor
402b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
412b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef tensor_static_symgroup_element<
422b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typename gen_numeric_list_swapped_pair<int, N, Gen::One, Gen::Two>::type,
432b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    Gen::Flags
442b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  > type;
452b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
462b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
472b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<int N>
482b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct tensor_static_symgroup_identity_ctor
492b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
502b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef tensor_static_symgroup_element<
512b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typename gen_numeric_list<int, N>::type,
522b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    0
532b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  > type;
542b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
552b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
562b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename iib>
572b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct tensor_static_symgroup_multiply_helper
582b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
592b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  template<int... iia>
602b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  constexpr static inline numeric_list<int, get<iia, iib>::value...> helper(numeric_list<int, iia...>) {
612b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    return numeric_list<int, get<iia, iib>::value...>();
622b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  }
632b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
642b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
652b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename A, typename B>
662b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct tensor_static_symgroup_multiply
672b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
682b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  private:
692b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typedef typename A::indices iia;
702b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typedef typename B::indices iib;
712b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    constexpr static int ffa = A::flags;
722b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    constexpr static int ffb = B::flags;
732b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
742b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  public:
752b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    static_assert(iia::count == iib::count, "Cannot multiply symmetry elements with different number of indices.");
762b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
772b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typedef tensor_static_symgroup_element<
782b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      decltype(tensor_static_symgroup_multiply_helper<iib>::helper(iia())),
792b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      ffa ^ ffb
802b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    > type;
812b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
822b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
832b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename A, typename B>
842b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct tensor_static_symgroup_equality
852b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
862b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typedef typename A::indices iia;
872b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typedef typename B::indices iib;
882b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    constexpr static int ffa = A::flags;
892b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    constexpr static int ffb = B::flags;
902b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    static_assert(iia::count == iib::count, "Cannot compare symmetry elements with different number of indices.");
912b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
922b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    constexpr static bool value = is_same<iia, iib>::value;
932b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
942b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  private:
952b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    /* this should be zero if they are identical, or else the tensor
962b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang     * will be forced to be pure real, pure imaginary or even pure zero
972b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang     */
982b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    constexpr static int flags_cmp_ = ffa ^ ffb;
992b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1002b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    /* either they are not equal, then we don't care whether the flags
1012b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang     * match, or they are equal, and then we have to check
1022b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang     */
1032b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    constexpr static bool is_zero      = value && flags_cmp_ == NegationFlag;
1042b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    constexpr static bool is_real      = value && flags_cmp_ == ConjugationFlag;
1052b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    constexpr static bool is_imag      = value && flags_cmp_ == (NegationFlag | ConjugationFlag);
1062b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1072b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  public:
1082b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    constexpr static int global_flags =
1092b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      (is_real ? GlobalRealFlag : 0) |
1102b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      (is_imag ? GlobalImagFlag : 0) |
1112b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      (is_zero ? GlobalZeroFlag : 0);
1122b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
1132b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1142b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<std::size_t NumIndices, typename... Gen>
1152b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct tensor_static_symgroup
1162b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
1172b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef StaticSGroup<Gen...> type;
1182b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  constexpr static std::size_t size = type::static_size;
1192b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
1202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1212b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Index, std::size_t N, int... ii, int... jj>
1222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangconstexpr 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...>)
1232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
1242b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  return {{ idx[ii]..., idx[jj]... }};
1252b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}
1262b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1272b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Index, int... ii>
1282b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstatic inline std::vector<Index> tensor_static_symgroup_index_permute(std::vector<Index> idx, internal::numeric_list<int, ii...>)
1292b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
1302b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  std::vector<Index> result{{ idx[ii]... }};
1312b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  std::size_t target_size = idx.size();
1322b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  for (std::size_t i = result.size(); i < target_size; i++)
1332b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    result.push_back(idx[i]);
1342b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  return result;
1352b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}
1362b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1372b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename T> struct tensor_static_symgroup_do_apply;
1382b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1392b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename first, typename... next>
1402b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct tensor_static_symgroup_do_apply<internal::type_list<first, next...>>
1412b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
1422b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  template<typename Op, typename RV, std::size_t SGNumIndices, typename Index, std::size_t NumIndices, typename... Args>
1432b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  static inline RV run(const std::array<Index, NumIndices>& idx, RV initial, Args&&... args)
1442b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  {
1452b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    static_assert(NumIndices >= SGNumIndices, "Can only apply symmetry group to objects that have at least the required amount of indices.");
1462b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typedef typename internal::gen_numeric_list<int, NumIndices - SGNumIndices, SGNumIndices>::type remaining_indices;
1472b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    initial = Op::run(tensor_static_symgroup_index_permute(idx, typename first::indices(), remaining_indices()), first::flags, initial, std::forward<Args>(args)...);
1482b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    return tensor_static_symgroup_do_apply<internal::type_list<next...>>::template run<Op, RV, SGNumIndices>(idx, initial, args...);
1492b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  }
1502b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1512b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  template<typename Op, typename RV, std::size_t SGNumIndices, typename Index, typename... Args>
1522b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  static inline RV run(const std::vector<Index>& idx, RV initial, Args&&... args)
1532b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  {
1542b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    eigen_assert(idx.size() >= SGNumIndices && "Can only apply symmetry group to objects that have at least the required amount of indices.");
1552b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    initial = Op::run(tensor_static_symgroup_index_permute(idx, typename first::indices()), first::flags, initial, std::forward<Args>(args)...);
1562b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    return tensor_static_symgroup_do_apply<internal::type_list<next...>>::template run<Op, RV, SGNumIndices>(idx, initial, args...);
1572b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  }
1582b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
1592b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1602b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<EIGEN_TPL_PP_SPEC_HACK_DEF(typename, empty)>
1612b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct tensor_static_symgroup_do_apply<internal::type_list<EIGEN_TPL_PP_SPEC_HACK_USE(empty)>>
1622b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
1632b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  template<typename Op, typename RV, std::size_t SGNumIndices, typename Index, std::size_t NumIndices, typename... Args>
1642b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  static inline RV run(const std::array<Index, NumIndices>&, RV initial, Args&&...)
1652b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  {
1662b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    // do nothing
1672b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    return initial;
1682b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  }
1692b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1702b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  template<typename Op, typename RV, std::size_t SGNumIndices, typename Index, typename... Args>
1712b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  static inline RV run(const std::vector<Index>&, RV initial, Args&&...)
1722b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  {
1732b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    // do nothing
1742b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    return initial;
1752b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  }
1762b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
1772b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1782b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang} // end namespace internal
1792b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1802b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename... Gen>
1812b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangclass StaticSGroup
1822b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
1832b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    constexpr static std::size_t NumIndices = internal::tensor_symmetry_num_indices<Gen...>::value;
1842b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typedef internal::group_theory::enumerate_group_elements<
1852b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      internal::tensor_static_symgroup_multiply,
1862b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      internal::tensor_static_symgroup_equality,
1872b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      typename internal::tensor_static_symgroup_identity_ctor<NumIndices>::type,
1882b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      internal::type_list<typename internal::tensor_static_symgroup_element_ctor<Gen, NumIndices>::type...>
1892b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    > group_elements;
1902b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typedef typename group_elements::type ge;
1912b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  public:
1922b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    constexpr inline StaticSGroup() {}
1932b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    constexpr inline StaticSGroup(const StaticSGroup<Gen...>&) {}
1942b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    constexpr inline StaticSGroup(StaticSGroup<Gen...>&&) {}
1952b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1962b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    template<typename Op, typename RV, typename Index, std::size_t N, typename... Args>
1972b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    static inline RV apply(const std::array<Index, N>& idx, RV initial, Args&&... args)
1982b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    {
1992b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      return internal::tensor_static_symgroup_do_apply<ge>::template run<Op, RV, NumIndices>(idx, initial, args...);
2002b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    }
2012b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
2022b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    template<typename Op, typename RV, typename Index, typename... Args>
2032b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    static inline RV apply(const std::vector<Index>& idx, RV initial, Args&&... args)
2042b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    {
2052b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      eigen_assert(idx.size() == NumIndices);
2062b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      return internal::tensor_static_symgroup_do_apply<ge>::template run<Op, RV, NumIndices>(idx, initial, args...);
2072b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    }
2082b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
2092b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    constexpr static std::size_t static_size = ge::count;
2102b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
2112b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    constexpr static inline std::size_t size() {
2122b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      return ge::count;
2132b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    }
2142b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    constexpr static inline int globalFlags() { return group_elements::global_flags; }
2152b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
2162b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    template<typename Tensor_, typename... IndexTypes>
2172b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    inline internal::tensor_symmetry_value_setter<Tensor_, StaticSGroup<Gen...>> operator()(Tensor_& tensor, typename Tensor_::Index firstIndex, IndexTypes... otherIndices) const
2182b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    {
2192b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      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.");
2202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      return operator()(tensor, std::array<typename Tensor_::Index, Tensor_::NumIndices>{{firstIndex, otherIndices...}});
2212b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    }
2222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
2232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    template<typename Tensor_>
2242b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    inline internal::tensor_symmetry_value_setter<Tensor_, StaticSGroup<Gen...>> operator()(Tensor_& tensor, std::array<typename Tensor_::Index, Tensor_::NumIndices> const& indices) const
2252b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    {
2262b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      return internal::tensor_symmetry_value_setter<Tensor_, StaticSGroup<Gen...>>(tensor, *this, indices);
2272b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    }
2282b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
2292b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
2302b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang} // end namespace Eigen
2312b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
2322b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#endif // EIGEN_CXX11_TENSORSYMMETRY_STATICSYMMETRY_H
2332b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
2342b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang/*
2352b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * kate: space-indent on; indent-width 2; mixedindent off; indent-mode cstyle;
2362b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang */
237