DynamicSymmetry.h
Go to the documentation of this file.
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2013 Christian Seiler <christian@iwakd.de>
5 //
6 // This Source Code Form is subject to the terms of the Mozilla
7 // Public License v. 2.0. If a copy of the MPL was not distributed
8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 
10 #ifndef EIGEN_CXX11_TENSORSYMMETRY_DYNAMICSYMMETRY_H
11 #define EIGEN_CXX11_TENSORSYMMETRY_DYNAMICSYMMETRY_H
12 
13 namespace Eigen {
14 
16 {
17  public:
18  inline explicit DynamicSGroup() : m_numIndices(1), m_elements(), m_generators(), m_globalFlags(0) { m_elements.push_back(ge(Generator(0, 0, 0))); }
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; }
23 
24  void add(int one, int two, int flags = 0);
25 
26  template<typename Gen_>
27  inline void add(Gen_) { add(Gen_::One, Gen_::Two, Gen_::Flags); }
28  inline void addSymmetry(int one, int two) { add(one, two, 0); }
29  inline void addAntiSymmetry(int one, int two) { add(one, two, NegationFlag); }
30  inline void addHermiticity(int one, int two) { add(one, two, ConjugationFlag); }
31  inline void addAntiHermiticity(int one, int two) { add(one, two, NegationFlag | ConjugationFlag); }
32 
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
35  {
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++)
38  initial = Op::run(h_permute(i, idx, typename internal::gen_numeric_list<int, N>::type()), m_elements[i].flags, initial, std::forward<Args>(args)...);
39  return initial;
40  }
41 
42  template<typename Op, typename RV, typename Index, typename... Args>
43  inline RV apply(const std::vector<Index>& idx, RV initial, Args&&... args) const
44  {
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)...);
48  return initial;
49  }
50 
51  inline int globalFlags() const { return m_globalFlags; }
52  inline std::size_t size() const { return m_elements.size(); }
53 
54  template<typename Tensor_, typename... IndexTypes>
55  inline internal::tensor_symmetry_value_setter<Tensor_, DynamicSGroup> operator()(Tensor_& tensor, typename Tensor_::Index firstIndex, IndexTypes... otherIndices) const
56  {
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...}});
59  }
60 
61  template<typename Tensor_>
62  inline internal::tensor_symmetry_value_setter<Tensor_, DynamicSGroup> operator()(Tensor_& tensor, std::array<typename Tensor_::Index, Tensor_::NumIndices> const& indices) const
63  {
65  }
66  private:
67  struct GroupElement {
68  std::vector<int> representation;
69  int flags;
70  bool isId() const
71  {
72  for (std::size_t i = 0; i < representation.size(); i++)
73  if (i != (size_t)representation[i])
74  return false;
75  return true;
76  }
77  };
78  struct Generator {
79  int one;
80  int two;
81  int flags;
82  constexpr inline Generator(int one_, int two_, int flags_) : one(one_), two(two_), flags(flags_) {}
83  };
84 
86  std::vector<GroupElement> m_elements;
87  std::vector<Generator> m_generators;
89 
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
92  {
93  return std::array<Index, N>{{ idx[n >= m_numIndices ? n : m_elements[which].representation[n]]... }};
94  }
95 
96  template<typename Index>
97  inline std::vector<Index> h_permute(std::size_t which, std::vector<Index> idx) const
98  {
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]);
105  return result;
106  }
107 
108  inline GroupElement ge(Generator const& g) const
109  {
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);
118  else
119  result.representation.push_back(int(k));
120  }
121  return result;
122  }
123 
124  GroupElement mul(GroupElement, GroupElement) const;
126  {
127  return mul(ge(g1), g2);
128  }
129 
131  {
132  return mul(g1, ge(g2));
133  }
134 
136  {
137  return mul(ge(g1), ge(g2));
138  }
139 
140  inline int findElement(GroupElement e) const
141  {
142  for (auto ee : m_elements) {
143  if (ee.representation == e.representation)
144  return ee.flags ^ e.flags;
145  }
146  return -1;
147  }
148 
149  void updateGlobalFlags(int flagDiffOfSameGenerator);
150 };
151 
152 // dynamic symmetry group that auto-adds the template parameters in the constructor
153 template<typename... Gen>
155 {
156  public:
158  {
160  }
165 
166  private:
167  template<typename Gen1, typename... GenNext>
169  {
170  add(Gen1());
172  }
173 
175  {
176  }
177 };
178 
180 {
181  eigen_internal_assert(g1.representation.size() == m_numIndices);
182  eigen_internal_assert(g2.representation.size() == m_numIndices);
183 
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]];
188  eigen_assert(v >= 0);
189  result.representation.push_back(v);
190  }
191  result.flags = g1.flags ^ g2.flags;
192  return result;
193 }
194 
195 inline void DynamicSGroup::add(int one, int two, int flags)
196 {
197  eigen_assert(one >= 0);
198  eigen_assert(two >= 0);
199  eigen_assert(one != two);
200 
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);
207  }
208  m_numIndices = newNumIndices;
209  }
210 
211  Generator g{one, two, flags};
212  GroupElement e = ge(g);
213 
214  /* special case for first generator */
215  if (m_elements.size() == 1) {
216  while (!e.isId()) {
217  m_elements.push_back(e);
218  e = mul(e, g);
219  }
220 
221  if (e.flags > 0)
222  updateGlobalFlags(e.flags);
223 
224  // only add in case we didn't have identity
225  if (m_elements.size() > 1)
226  m_generators.push_back(g);
227  return;
228  }
229 
230  int p = findElement(e);
231  if (p >= 0) {
233  return;
234  }
235 
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);
241 
242  std::size_t coset_rep = coset_order;
243  do {
244  for (auto g : m_generators) {
245  e = mul(m_elements[coset_rep], g);
246  p = findElement(e);
247  if (p < 0) {
248  // element not yet in group
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));
252  } else if (p > 0) {
254  }
255  }
256  coset_rep += coset_order;
257  } while (coset_rep < m_elements.size());
258 }
259 
260 inline void DynamicSGroup::updateGlobalFlags(int flagDiffOfSameGenerator)
261 {
262  switch (flagDiffOfSameGenerator) {
263  case 0:
264  default:
265  // nothing happened
266  break;
267  case NegationFlag:
268  // every element is it's own negative => whole tensor is zero
270  break;
271  case ConjugationFlag:
272  // every element is it's own conjugate => whole tensor is real
274  break;
275  case (NegationFlag | ConjugationFlag):
276  // every element is it's own negative conjugate => whole tensor is imaginary
278  break;
279  /* NOTE:
280  * since GlobalZeroFlag == GlobalRealFlag | GlobalImagFlag, if one generator
281  * causes the tensor to be real and the next one to be imaginary, this will
282  * trivially give the correct result
283  */
284  }
285 }
286 
287 } // end namespace Eigen
288 
289 #endif // EIGEN_CXX11_TENSORSYMMETRY_DYNAMICSYMMETRY_H
290 
291 /*
292  * kate: space-indent on; indent-width 2; mixedindent off; indent-mode cstyle;
293  */
Eigen::DynamicSGroup::size
std::size_t size() const
Definition: DynamicSymmetry.h:52
Eigen::DynamicSGroup::mul
GroupElement mul(GroupElement g1, Generator g2) const
Definition: DynamicSymmetry.h:130
Eigen
Namespace containing all symbols from the Eigen library.
Definition: jet.h:637
Eigen::GlobalRealFlag
@ GlobalRealFlag
Definition: Symmetry.h:21
Eigen::GlobalZeroFlag
@ GlobalZeroFlag
Definition: Symmetry.h:23
Eigen::DynamicSGroup::m_elements
std::vector< GroupElement > m_elements
Definition: DynamicSymmetry.h:86
e
Array< double, 1, 3 > e(1./3., 0.5, 2.)
Eigen::DynamicSGroup::h_permute
std::array< Index, N > h_permute(std::size_t which, const std::array< Index, N > &idx, internal::numeric_list< int, n... >) const
Definition: DynamicSymmetry.h:91
g1
Pose3 g1(Rot3(), Point3(100.0, 0.0, 300.0))
Eigen::DynamicSGroup::m_globalFlags
int m_globalFlags
Definition: DynamicSymmetry.h:88
Eigen::DynamicSGroupFromTemplateArgs::DynamicSGroupFromTemplateArgs
DynamicSGroupFromTemplateArgs(DynamicSGroupFromTemplateArgs const &other)
Definition: DynamicSymmetry.h:161
eigen_assert
#define eigen_assert(x)
Definition: Macros.h:1037
initial
Values initial
Definition: OdometryOptimize.cpp:2
Eigen::internal::tensor_symmetry_value_setter
Definition: Symmetry.h:297
Eigen::DynamicSGroup::operator=
DynamicSGroup & operator=(const DynamicSGroup &o)
Definition: DynamicSymmetry.h:21
Eigen::DynamicSGroup::add
void add(Gen_)
Definition: DynamicSymmetry.h:27
Eigen::DynamicSGroupFromTemplateArgs::operator=
DynamicSGroupFromTemplateArgs< Gen... > & operator=(const DynamicSGroupFromTemplateArgs< Gen... > &o)
Definition: DynamicSymmetry.h:163
Eigen::DynamicSGroupFromTemplateArgs
Definition: DynamicSymmetry.h:154
Eigen::DynamicSGroup::GroupElement::representation
std::vector< int > representation
Definition: DynamicSymmetry.h:68
Eigen::DynamicSGroup
Dynamic symmetry group.
Definition: DynamicSymmetry.h:15
Eigen::DynamicSGroup::updateGlobalFlags
void updateGlobalFlags(int flagDiffOfSameGenerator)
Definition: DynamicSymmetry.h:260
Eigen::DynamicSGroupFromTemplateArgs::DynamicSGroupFromTemplateArgs
DynamicSGroupFromTemplateArgs()
Definition: DynamicSymmetry.h:157
result
Values result
Definition: OdometryOptimize.cpp:8
eigen_internal_assert
#define eigen_internal_assert(x)
Definition: Macros.h:1043
Eigen::DynamicSGroupFromTemplateArgs::add_all
void add_all(internal::type_list<>)
Definition: DynamicSymmetry.h:174
Eigen::DynamicSGroup::DynamicSGroup
DynamicSGroup(const DynamicSGroup &o)
Definition: DynamicSymmetry.h:19
test_eigen_tensor.indices
indices
Definition: test_eigen_tensor.py:33
Eigen::DynamicSGroup::ge
GroupElement ge(Generator const &g) const
Definition: DynamicSymmetry.h:108
n
int n
Definition: BiCGSTAB_simple.cpp:1
Eigen::DynamicSGroup::Generator::flags
int flags
Definition: DynamicSymmetry.h:81
Eigen::NegationFlag
@ NegationFlag
Definition: Symmetry.h:16
Eigen::DynamicSGroup::DynamicSGroup
DynamicSGroup()
Definition: DynamicSymmetry.h:18
g2
Pose3 g2(g1.expmap(h *V1_g1))
Eigen::DynamicSGroup::operator()
internal::tensor_symmetry_value_setter< Tensor_, DynamicSGroup > operator()(Tensor_ &tensor, typename Tensor_::Index firstIndex, IndexTypes... otherIndices) const
Definition: DynamicSymmetry.h:55
Eigen::DynamicSGroup::add
void add(int one, int two, int flags=0)
Definition: DynamicSymmetry.h:195
Eigen::DynamicSGroupFromTemplateArgs::DynamicSGroupFromTemplateArgs
DynamicSGroupFromTemplateArgs(DynamicSGroupFromTemplateArgs &&other)
Definition: DynamicSymmetry.h:162
Eigen::DynamicSGroup::h_permute
std::vector< Index > h_permute(std::size_t which, std::vector< Index > idx) const
Definition: DynamicSymmetry.h:97
std::swap
void swap(GeographicLib::NearestNeighbor< dist_t, pos_t, distfun_t > &a, GeographicLib::NearestNeighbor< dist_t, pos_t, distfun_t > &b)
Definition: NearestNeighbor.hpp:827
Eigen::DynamicSGroup::addHermiticity
void addHermiticity(int one, int two)
Definition: DynamicSymmetry.h:30
Eigen::DynamicSGroup::findElement
int findElement(GroupElement e) const
Definition: DynamicSymmetry.h:140
Eigen::internal::gen_numeric_list
Definition: CXX11Meta.h:51
Eigen::DynamicSGroup::Generator::one
int one
Definition: DynamicSymmetry.h:79
gtsam.examples.DogLegOptimizerExample.run
def run(args)
Definition: DogLegOptimizerExample.py:21
Eigen::DynamicSGroup::GroupElement::isId
bool isId() const
Definition: DynamicSymmetry.h:70
Eigen::DynamicSGroup::globalFlags
int globalFlags() const
Definition: DynamicSymmetry.h:51
size_t
std::size_t size_t
Definition: wrap/pybind11/include/pybind11/detail/common.h:490
Eigen::DynamicSGroup::addAntiSymmetry
void addAntiSymmetry(int one, int two)
Definition: DynamicSymmetry.h:29
Eigen::DynamicSGroup::mul
GroupElement mul(Generator g1, Generator g2) const
Definition: DynamicSymmetry.h:135
Eigen::internal::type_list
Definition: CXX11Meta.h:29
g
void g(const string &key, int i)
Definition: testBTree.cpp:41
Eigen::DynamicSGroup::operator=
DynamicSGroup & operator=(DynamicSGroup &&o)
Definition: DynamicSymmetry.h:22
Eigen::DynamicSGroup::apply
RV apply(const std::vector< Index > &idx, RV initial, Args &&... args) const
Definition: DynamicSymmetry.h:43
Eigen::DynamicSGroup::Generator::Generator
constexpr Generator(int one_, int two_, int flags_)
Definition: DynamicSymmetry.h:82
Eigen::internal::numeric_list
Definition: CXX11Meta.h:35
Eigen::DynamicSGroup::Generator::two
int two
Definition: DynamicSymmetry.h:80
Eigen::DynamicSGroup::mul
GroupElement mul(GroupElement, GroupElement) const
Definition: DynamicSymmetry.h:179
Eigen::DynamicSGroup::operator()
internal::tensor_symmetry_value_setter< Tensor_, DynamicSGroup > operator()(Tensor_ &tensor, std::array< typename Tensor_::Index, Tensor_::NumIndices > const &indices) const
Definition: DynamicSymmetry.h:62
Eigen::DynamicSGroup::GroupElement
Definition: DynamicSymmetry.h:67
Eigen::DynamicSGroup::DynamicSGroup
DynamicSGroup(DynamicSGroup &&o)
Definition: DynamicSymmetry.h:20
Eigen::DynamicSGroup::apply
RV apply(const std::array< Index, N > &idx, RV initial, Args &&... args) const
Definition: DynamicSymmetry.h:34
Eigen::DynamicSGroup::m_numIndices
std::size_t m_numIndices
Definition: DynamicSymmetry.h:85
Eigen::DynamicSGroup::mul
GroupElement mul(Generator g1, GroupElement g2) const
Definition: DynamicSymmetry.h:125
args
Definition: pytypes.h:2210
p
float * p
Definition: Tutorial_Map_using.cpp:9
Eigen::DynamicSGroupFromTemplateArgs::add_all
void add_all(internal::type_list< Gen1, GenNext... >)
Definition: DynamicSymmetry.h:168
v
Array< int, Dynamic, 1 > v
Definition: Array_initializer_list_vector_cxx11.cpp:1
Eigen::DynamicSGroup::Generator
Definition: DynamicSymmetry.h:78
Eigen::DynamicSGroupFromTemplateArgs::operator=
DynamicSGroupFromTemplateArgs< Gen... > & operator=(DynamicSGroupFromTemplateArgs< Gen... > &&o)
Definition: DynamicSymmetry.h:164
Eigen::DynamicSGroup::m_generators
std::vector< Generator > m_generators
Definition: DynamicSymmetry.h:87
initial
Definition: testScenarioRunner.cpp:148
N
#define N
Definition: igam.h:9
Eigen::DynamicSGroup::addSymmetry
void addSymmetry(int one, int two)
Definition: DynamicSymmetry.h:28
two
Definition: testHybridBayesTree.cpp:59
Eigen::DynamicSGroup::GroupElement::flags
int flags
Definition: DynamicSymmetry.h:69
Eigen::GlobalImagFlag
@ GlobalImagFlag
Definition: Symmetry.h:22
i
int i
Definition: BiCGSTAB_step_by_step.cpp:9
pybind_wrapper_test_script.other
other
Definition: pybind_wrapper_test_script.py:42
Eigen::ConjugationFlag
@ ConjugationFlag
Definition: Symmetry.h:17
Eigen::DynamicSGroup::addAntiHermiticity
void addAntiHermiticity(int one, int two)
Definition: DynamicSymmetry.h:31
Eigen::Index
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:74


gtsam
Author(s):
autogenerated on Sun Dec 22 2024 04:11:29