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_DYNAMICSYMMETRY_H 112b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#define EIGEN_CXX11_TENSORSYMMETRY_DYNAMICSYMMETRY_H 122b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 132b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangnamespace Eigen { 142b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 152b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangclass DynamicSGroup 162b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 172b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang public: 182b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inline explicit DynamicSGroup() : m_numIndices(1), m_elements(), m_generators(), m_globalFlags(0) { m_elements.push_back(ge(Generator(0, 0, 0))); } 192b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inline DynamicSGroup(const DynamicSGroup& o) : m_numIndices(o.m_numIndices), m_elements(o.m_elements), m_generators(o.m_generators), m_globalFlags(o.m_globalFlags) { } 202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inline DynamicSGroup(DynamicSGroup&& o) : m_numIndices(o.m_numIndices), m_elements(), m_generators(o.m_generators), m_globalFlags(o.m_globalFlags) { std::swap(m_elements, o.m_elements); } 212b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inline DynamicSGroup& operator=(const DynamicSGroup& o) { m_numIndices = o.m_numIndices; m_elements = o.m_elements; m_generators = o.m_generators; m_globalFlags = o.m_globalFlags; return *this; } 222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inline DynamicSGroup& operator=(DynamicSGroup&& o) { m_numIndices = o.m_numIndices; std::swap(m_elements, o.m_elements); m_generators = o.m_generators; m_globalFlags = o.m_globalFlags; return *this; } 232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 242b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang void add(int one, int two, int flags = 0); 252b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 262b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang template<typename Gen_> 272b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inline void add(Gen_) { add(Gen_::One, Gen_::Two, Gen_::Flags); } 282b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inline void addSymmetry(int one, int two) { add(one, two, 0); } 292b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inline void addAntiSymmetry(int one, int two) { add(one, two, NegationFlag); } 302b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inline void addHermiticity(int one, int two) { add(one, two, ConjugationFlag); } 312b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inline void addAntiHermiticity(int one, int two) { add(one, two, NegationFlag | ConjugationFlag); } 322b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 332b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang template<typename Op, typename RV, typename Index, std::size_t N, typename... Args> 342b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inline RV apply(const std::array<Index, N>& idx, RV initial, Args&&... args) const 352b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 362b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang eigen_assert(N >= m_numIndices && "Can only apply symmetry group to objects that have at least the required amount of indices."); 372b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang for (std::size_t i = 0; i < size(); i++) 382b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang initial = Op::run(h_permute(i, idx, typename internal::gen_numeric_list<int, N>::type()), m_elements[i].flags, initial, std::forward<Args>(args)...); 392b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return initial; 402b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 412b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 422b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang template<typename Op, typename RV, typename Index, typename... Args> 432b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inline RV apply(const std::vector<Index>& idx, RV initial, Args&&... args) const 442b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 452b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang eigen_assert(idx.size() >= m_numIndices && "Can only apply symmetry group to objects that have at least the required amount of indices."); 462b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang for (std::size_t i = 0; i < size(); i++) 472b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang initial = Op::run(h_permute(i, idx), m_elements[i].flags, initial, std::forward<Args>(args)...); 482b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return initial; 492b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 502b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 512b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inline int globalFlags() const { return m_globalFlags; } 522b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inline std::size_t size() const { return m_elements.size(); } 532b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 542b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang template<typename Tensor_, typename... IndexTypes> 552b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inline internal::tensor_symmetry_value_setter<Tensor_, DynamicSGroup> operator()(Tensor_& tensor, typename Tensor_::Index firstIndex, IndexTypes... otherIndices) const 562b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 572b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao 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."); 582b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return operator()(tensor, std::array<typename Tensor_::Index, Tensor_::NumIndices>{{firstIndex, otherIndices...}}); 592b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 602b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 612b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang template<typename Tensor_> 622b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inline internal::tensor_symmetry_value_setter<Tensor_, DynamicSGroup> operator()(Tensor_& tensor, std::array<typename Tensor_::Index, Tensor_::NumIndices> const& indices) const 632b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 642b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return internal::tensor_symmetry_value_setter<Tensor_, DynamicSGroup>(tensor, *this, indices); 652b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 662b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang private: 672b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang struct GroupElement { 682b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang std::vector<int> representation; 692b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang int flags; 702b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang bool isId() const 712b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 722b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang for (std::size_t i = 0; i < representation.size(); i++) 732b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if (i != (size_t)representation[i]) 742b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return false; 752b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return true; 762b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 772b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang }; 782b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang struct Generator { 792b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang int one; 802b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang int two; 812b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang int flags; 822b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang constexpr inline Generator(int one_, int two_, int flags_) : one(one_), two(two_), flags(flags_) {} 832b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang }; 842b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 852b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang std::size_t m_numIndices; 862b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang std::vector<GroupElement> m_elements; 872b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang std::vector<Generator> m_generators; 882b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang int m_globalFlags; 892b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 902b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang template<typename Index, std::size_t N, int... n> 912b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inline std::array<Index, N> h_permute(std::size_t which, const std::array<Index, N>& idx, internal::numeric_list<int, n...>) const 922b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 932b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return std::array<Index, N>{{ idx[n >= m_numIndices ? n : m_elements[which].representation[n]]... }}; 942b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 952b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 962b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang template<typename Index> 972b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inline std::vector<Index> h_permute(std::size_t which, std::vector<Index> idx) const 982b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 992b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang std::vector<Index> result; 1002b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang result.reserve(idx.size()); 1012b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang for (auto k : m_elements[which].representation) 1022b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang result.push_back(idx[k]); 1032b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang for (std::size_t i = m_numIndices; i < idx.size(); i++) 1042b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang result.push_back(idx[i]); 1052b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return result; 1062b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 1072b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1082b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inline GroupElement ge(Generator const& g) const 1092b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 1102b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang GroupElement result; 1112b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang result.representation.reserve(m_numIndices); 1122b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang result.flags = g.flags; 1132b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang for (std::size_t k = 0; k < m_numIndices; k++) { 1142b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if (k == (std::size_t)g.one) 1152b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang result.representation.push_back(g.two); 1162b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang else if (k == (std::size_t)g.two) 1172b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang result.representation.push_back(g.one); 1182b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang else 1192b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang result.representation.push_back(int(k)); 1202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 1212b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return result; 1222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 1232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1242b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang GroupElement mul(GroupElement, GroupElement) const; 1252b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inline GroupElement mul(Generator g1, GroupElement g2) const 1262b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 1272b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return mul(ge(g1), g2); 1282b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 1292b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1302b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inline GroupElement mul(GroupElement g1, Generator g2) const 1312b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 1322b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return mul(g1, ge(g2)); 1332b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 1342b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1352b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inline GroupElement mul(Generator g1, Generator g2) const 1362b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 1372b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return mul(ge(g1), ge(g2)); 1382b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 1392b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1402b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inline int findElement(GroupElement e) const 1412b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 1422b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang for (auto ee : m_elements) { 1432b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if (ee.representation == e.representation) 1442b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return ee.flags ^ e.flags; 1452b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 1462b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return -1; 1472b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 1482b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1492b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang void updateGlobalFlags(int flagDiffOfSameGenerator); 1502b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}; 1512b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1522b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// dynamic symmetry group that auto-adds the template parameters in the constructor 1532b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename... Gen> 1542b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangclass DynamicSGroupFromTemplateArgs : public DynamicSGroup 1552b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 1562b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang public: 1572b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inline DynamicSGroupFromTemplateArgs() : DynamicSGroup() 1582b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 1592b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang add_all(internal::type_list<Gen...>()); 1602b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 1612b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inline DynamicSGroupFromTemplateArgs(DynamicSGroupFromTemplateArgs const& other) : DynamicSGroup(other) { } 1622b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inline DynamicSGroupFromTemplateArgs(DynamicSGroupFromTemplateArgs&& other) : DynamicSGroup(other) { } 1632b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inline DynamicSGroupFromTemplateArgs<Gen...>& operator=(const DynamicSGroupFromTemplateArgs<Gen...>& o) { DynamicSGroup::operator=(o); return *this; } 1642b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inline DynamicSGroupFromTemplateArgs<Gen...>& operator=(DynamicSGroupFromTemplateArgs<Gen...>&& o) { DynamicSGroup::operator=(o); return *this; } 1652b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1662b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang private: 1672b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang template<typename Gen1, typename... GenNext> 1682b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inline void add_all(internal::type_list<Gen1, GenNext...>) 1692b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 1702b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang add(Gen1()); 1712b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang add_all(internal::type_list<GenNext...>()); 1722b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 1732b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1742b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inline void add_all(internal::type_list<>) 1752b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 1762b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 1772b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}; 1782b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1792b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wanginline DynamicSGroup::GroupElement DynamicSGroup::mul(GroupElement g1, GroupElement g2) const 1802b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 1812b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang eigen_internal_assert(g1.representation.size() == m_numIndices); 1822b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang eigen_internal_assert(g2.representation.size() == m_numIndices); 1832b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1842b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang GroupElement result; 1852b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang result.representation.reserve(m_numIndices); 1862b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang for (std::size_t i = 0; i < m_numIndices; i++) { 1872b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang int v = g2.representation[g1.representation[i]]; 1882b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang eigen_assert(v >= 0); 1892b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang result.representation.push_back(v); 1902b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 1912b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang result.flags = g1.flags ^ g2.flags; 1922b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return result; 1932b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang} 1942b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1952b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wanginline void DynamicSGroup::add(int one, int two, int flags) 1962b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 1972b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang eigen_assert(one >= 0); 1982b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang eigen_assert(two >= 0); 1992b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang eigen_assert(one != two); 2002b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 2012b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if ((std::size_t)one >= m_numIndices || (std::size_t)two >= m_numIndices) { 2022b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang std::size_t newNumIndices = (one > two) ? one : two + 1; 2032b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang for (auto& gelem : m_elements) { 2042b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang gelem.representation.reserve(newNumIndices); 2052b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang for (std::size_t i = m_numIndices; i < newNumIndices; i++) 2062b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang gelem.representation.push_back(i); 2072b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 2082b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang m_numIndices = newNumIndices; 2092b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 2102b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 2112b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Generator g{one, two, flags}; 2122b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang GroupElement e = ge(g); 2132b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 2142b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang /* special case for first generator */ 2152b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if (m_elements.size() == 1) { 2162b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang while (!e.isId()) { 2172b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang m_elements.push_back(e); 2182b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang e = mul(e, g); 2192b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 2202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 2212b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if (e.flags > 0) 2222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang updateGlobalFlags(e.flags); 2232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 2242b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang // only add in case we didn't have identity 2252b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if (m_elements.size() > 1) 2262b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang m_generators.push_back(g); 2272b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return; 2282b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 2292b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 2302b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang int p = findElement(e); 2312b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if (p >= 0) { 2322b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang updateGlobalFlags(p); 2332b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return; 2342b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 2352b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 2362b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang std::size_t coset_order = m_elements.size(); 2372b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang m_elements.push_back(e); 2382b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang for (std::size_t i = 1; i < coset_order; i++) 2392b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang m_elements.push_back(mul(m_elements[i], e)); 2402b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang m_generators.push_back(g); 2412b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 2422b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang std::size_t coset_rep = coset_order; 2432b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang do { 2442b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang for (auto g : m_generators) { 2452b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang e = mul(m_elements[coset_rep], g); 2462b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang p = findElement(e); 2472b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if (p < 0) { 2482b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang // element not yet in group 2492b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang m_elements.push_back(e); 2502b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang for (std::size_t i = 1; i < coset_order; i++) 2512b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang m_elements.push_back(mul(m_elements[i], e)); 2522b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } else if (p > 0) { 2532b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang updateGlobalFlags(p); 2542b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 2552b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 2562b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang coset_rep += coset_order; 2572b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } while (coset_rep < m_elements.size()); 2582b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang} 2592b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 2602b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wanginline void DynamicSGroup::updateGlobalFlags(int flagDiffOfSameGenerator) 2612b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 2622b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang switch (flagDiffOfSameGenerator) { 2632b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang case 0: 2642b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang default: 2652b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang // nothing happened 2662b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang break; 2672b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang case NegationFlag: 2682b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang // every element is it's own negative => whole tensor is zero 2692b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang m_globalFlags |= GlobalZeroFlag; 2702b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang break; 2712b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang case ConjugationFlag: 2722b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang // every element is it's own conjugate => whole tensor is real 2732b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang m_globalFlags |= GlobalRealFlag; 2742b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang break; 2752b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang case (NegationFlag | ConjugationFlag): 2762b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang // every element is it's own negative conjugate => whole tensor is imaginary 2772b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang m_globalFlags |= GlobalImagFlag; 2782b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang break; 2792b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang /* NOTE: 2802b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * since GlobalZeroFlag == GlobalRealFlag | GlobalImagFlag, if one generator 2812b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * causes the tensor to be real and the next one to be imaginary, this will 2822b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * trivially give the correct result 2832b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang */ 2842b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 2852b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang} 2862b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 2872b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang} // end namespace Eigen 2882b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 2892b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#endif // EIGEN_CXX11_TENSORSYMMETRY_DYNAMICSYMMETRY_H 2902b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 2912b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang/* 2922b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * kate: space-indent on; indent-width 2; mixedindent off; indent-mode cstyle; 2932b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang */ 294