10#ifndef EIGEN_CXX11_TENSORSYMMETRY_DYNAMICSYMMETRY_H
11#define EIGEN_CXX11_TENSORSYMMETRY_DYNAMICSYMMETRY_H
18 inline explicit DynamicSGroup() : m_numIndices(1), m_elements(), m_generators(), m_globalFlags(0) { m_elements.push_back(ge(Generator(0, 0, 0))); }
19 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) { }
20 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); }
21 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; }
22 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; }
24 void add(
int one,
int two,
int flags = 0);
26 template<
typename Gen_>
27 inline void add(Gen_) {
add(Gen_::One, Gen_::Two, Gen_::Flags); }
33 template<
typename Op,
typename RV,
typename Index, std::size_t
N,
typename... Args>
34 inline RV
apply(
const std::array<Index, N>& idx, RV initial, Args&&... args)
const
36 eigen_assert(
N >= m_numIndices &&
"Can only apply symmetry group to objects that have at least the required amount of indices.");
37 for (std::size_t
i = 0;
i <
size();
i++)
42 template<
typename Op,
typename RV,
typename Index,
typename... Args>
43 inline RV
apply(
const std::vector<Index>& idx, RV initial, Args&&... args)
const
45 eigen_assert(idx.size() >= m_numIndices &&
"Can only apply symmetry group to objects that have at least the required amount of indices.");
46 for (std::size_t
i = 0;
i <
size();
i++)
47 initial = Op::run(h_permute(
i, idx), m_elements[
i].flags, initial, std::forward<Args>(args)...);
52 inline std::size_t
size()
const {
return m_elements.size(); }
54 template<
typename Tensor_,
typename... IndexTypes>
57 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.");
58 return operator()(tensor, std::array<typename Tensor_::Index, Tensor_::NumIndices>{{firstIndex, otherIndices...}});
61 template<
typename Tensor_>
68 std::vector<int> representation;
72 for (std::size_t
i = 0;
i < representation.size();
i++)
73 if (
i != (
size_t)representation[
i])
82 constexpr inline Generator(
int one_,
int two_,
int flags_) : one(one_), two(two_), flags(flags_) {}
85 std::size_t m_numIndices;
86 std::vector<GroupElement> m_elements;
87 std::vector<Generator> m_generators;
90 template<
typename Index, std::size_t
N,
int...
n>
91 inline std::array<Index, N> h_permute(std::size_t which,
const std::array<Index, N>& idx, internal::numeric_list<int, n...>)
const
93 return std::array<Index, N>{{ idx[
n >= m_numIndices ?
n : m_elements[which].representation[
n]]... }};
96 template<
typename Index>
97 inline std::vector<Index> h_permute(std::size_t which, std::vector<Index> idx)
const
99 std::vector<Index> result;
100 result.reserve(idx.size());
101 for (
auto k : m_elements[which].representation)
102 result.push_back(idx[k]);
103 for (std::size_t
i = m_numIndices;
i < idx.size();
i++)
104 result.push_back(idx[
i]);
108 inline GroupElement ge(Generator
const& g)
const
111 result.representation.reserve(m_numIndices);
112 result.flags = g.flags;
113 for (std::size_t k = 0; k < m_numIndices; k++) {
114 if (k == (std::size_t)g.one)
115 result.representation.push_back(g.two);
116 else if (k == (std::size_t)g.two)
117 result.representation.push_back(g.one);
119 result.representation.push_back(
int(k));
124 GroupElement mul(GroupElement, GroupElement)
const;
125 inline GroupElement mul(Generator g1, GroupElement g2)
const
127 return mul(ge(g1), g2);
130 inline GroupElement mul(GroupElement g1, Generator g2)
const
132 return mul(g1, ge(g2));
135 inline GroupElement mul(Generator g1, Generator g2)
const
137 return mul(ge(g1), ge(g2));
140 inline int findElement(GroupElement
e)
const
142 for (
auto ee : m_elements) {
143 if (ee.representation ==
e.representation)
144 return ee.flags ^
e.flags;
149 void updateGlobalFlags(
int flagDiffOfSameGenerator);
153template<
typename... Gen>
167 template<
typename Gen1,
typename... GenNext>
174 inline void add_all(internal::type_list<>)
179inline DynamicSGroup::GroupElement DynamicSGroup::mul(GroupElement g1, GroupElement g2)
const
185 result.representation.reserve(m_numIndices);
186 for (std::size_t
i = 0;
i < m_numIndices;
i++) {
187 int v = g2.representation[g1.representation[
i]];
189 result.representation.push_back(
v);
191 result.flags = g1.flags ^ g2.flags;
201 if ((std::size_t)one >= m_numIndices || (std::size_t)two >= m_numIndices) {
202 std::size_t newNumIndices = (one > two) ? one : two + 1;
203 for (
auto& gelem : m_elements) {
204 gelem.representation.reserve(newNumIndices);
205 for (std::size_t
i = m_numIndices;
i < newNumIndices;
i++)
206 gelem.representation.push_back(
i);
208 m_numIndices = newNumIndices;
211 Generator g{one, two, flags};
212 GroupElement
e = ge(g);
215 if (m_elements.size() == 1) {
217 m_elements.push_back(
e);
222 updateGlobalFlags(
e.flags);
225 if (m_elements.size() > 1)
226 m_generators.push_back(g);
230 int p = findElement(
e);
232 updateGlobalFlags(
p);
236 std::size_t coset_order = m_elements.size();
237 m_elements.push_back(
e);
238 for (std::size_t
i = 1;
i < coset_order;
i++)
239 m_elements.push_back(mul(m_elements[
i],
e));
240 m_generators.push_back(g);
242 std::size_t coset_rep = coset_order;
244 for (
auto g : m_generators) {
245 e = mul(m_elements[coset_rep], g);
249 m_elements.push_back(
e);
250 for (std::size_t
i = 1;
i < coset_order;
i++)
251 m_elements.push_back(mul(m_elements[
i],
e));
253 updateGlobalFlags(
p);
256 coset_rep += coset_order;
257 }
while (coset_rep < m_elements.size());
260inline void DynamicSGroup::updateGlobalFlags(
int flagDiffOfSameGenerator)
262 switch (flagDiffOfSameGenerator) {
Array< int, Dynamic, 1 > v
Definition Array_initializer_list_vector_cxx11.cpp:1
int n
Definition BiCGSTAB_simple.cpp:1
int i
Definition BiCGSTAB_step_by_step.cpp:9
Array< double, 1, 3 > e(1./3., 0.5, 2.)
#define eigen_internal_assert(x)
Definition Macros.h:1043
#define eigen_assert(x)
Definition Macros.h:1037
float * p
Definition Tutorial_Map_using.cpp:9
Definition DynamicSymmetry.h:155
DynamicSGroupFromTemplateArgs< Gen... > & operator=(const DynamicSGroupFromTemplateArgs< Gen... > &o)
Definition DynamicSymmetry.h:163
DynamicSGroupFromTemplateArgs(DynamicSGroupFromTemplateArgs const &other)
Definition DynamicSymmetry.h:161
DynamicSGroupFromTemplateArgs()
Definition DynamicSymmetry.h:157
DynamicSGroupFromTemplateArgs< Gen... > & operator=(DynamicSGroupFromTemplateArgs< Gen... > &&o)
Definition DynamicSymmetry.h:164
DynamicSGroupFromTemplateArgs(DynamicSGroupFromTemplateArgs &&other)
Definition DynamicSymmetry.h:162
Dynamic symmetry group.
Definition DynamicSymmetry.h:16
internal::tensor_symmetry_value_setter< Tensor_, DynamicSGroup > operator()(Tensor_ &tensor, typename Tensor_::Index firstIndex, IndexTypes... otherIndices) const
Definition DynamicSymmetry.h:55
void add(Gen_)
Definition DynamicSymmetry.h:27
void addSymmetry(int one, int two)
Definition DynamicSymmetry.h:28
void addHermiticity(int one, int two)
Definition DynamicSymmetry.h:30
DynamicSGroup & operator=(DynamicSGroup &&o)
Definition DynamicSymmetry.h:22
void addAntiHermiticity(int one, int two)
Definition DynamicSymmetry.h:31
DynamicSGroup()
Definition DynamicSymmetry.h:18
internal::tensor_symmetry_value_setter< Tensor_, DynamicSGroup > operator()(Tensor_ &tensor, std::array< typename Tensor_::Index, Tensor_::NumIndices > const &indices) const
Definition DynamicSymmetry.h:62
DynamicSGroup & operator=(const DynamicSGroup &o)
Definition DynamicSymmetry.h:21
DynamicSGroup(const DynamicSGroup &o)
Definition DynamicSymmetry.h:19
int globalFlags() const
Definition DynamicSymmetry.h:51
DynamicSGroup(DynamicSGroup &&o)
Definition DynamicSymmetry.h:20
void add(int one, int two, int flags=0)
Definition DynamicSymmetry.h:195
void addAntiSymmetry(int one, int two)
Definition DynamicSymmetry.h:29
std::size_t size() const
Definition DynamicSymmetry.h:52
RV apply(const std::array< Index, N > &idx, RV initial, Args &&... args) const
Definition DynamicSymmetry.h:34
RV apply(const std::vector< Index > &idx, RV initial, Args &&... args) const
Definition DynamicSymmetry.h:43
@ N
Definition constructor.cpp:23
Namespace containing all symbols from the Eigen library.
Definition bench_norm.cpp:85
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition Meta.h:74
@ NegationFlag
Definition Symmetry.h:16
@ ConjugationFlag
Definition Symmetry.h:17
@ GlobalZeroFlag
Definition Symmetry.h:23
@ GlobalRealFlag
Definition Symmetry.h:21
@ GlobalImagFlag
Definition Symmetry.h:22
Definition CXX11Meta.h:51
Definition ForwardDeclarations.h:17