Eigen::DynamicSGroup Class Reference

Dynamic symmetry group. More...

#include <DynamicSymmetry.h>

+ Inheritance diagram for Eigen::DynamicSGroup:

Classes

struct  Generator
 
struct  GroupElement
 

Public Member Functions

 DynamicSGroup ()
 
 DynamicSGroup (const DynamicSGroup &o)
 
 DynamicSGroup (DynamicSGroup &&o)
 
DynamicSGroupoperator= (const DynamicSGroup &o)
 
DynamicSGroupoperator= (DynamicSGroup &&o)
 
void add (int one, int two, int flags=0)
 
template<typename Gen_ >
void add (Gen_)
 
void addSymmetry (int one, int two)
 
void addAntiSymmetry (int one, int two)
 
void addHermiticity (int one, int two)
 
void addAntiHermiticity (int one, int two)
 
template<typename Op , typename RV , typename Index , std::size_t N, typename... Args>
RV apply (const std::array< Index, N > &idx, RV initial, Args &&... args) const
 
template<typename Op , typename RV , typename Index , typename... Args>
RV apply (const std::vector< Index > &idx, RV initial, Args &&... args) const
 
int globalFlags () const
 
std::size_t size () const
 
template<typename Tensor_ , typename... IndexTypes>
internal::tensor_symmetry_value_setter< Tensor_, DynamicSGroupoperator() (Tensor_ &tensor, typename Tensor_::Index firstIndex, IndexTypes... otherIndices) const
 
template<typename Tensor_ >
internal::tensor_symmetry_value_setter< Tensor_, DynamicSGroupoperator() (Tensor_ &tensor, std::array< typename Tensor_::Index, Tensor_::NumIndices > const &indices) const
 

Private Member Functions

template<typename Index , std::size_t N, int... n>
std::array< Index, Nh_permute (std::size_t which, const std::array< Index, N > &idx, internal::numeric_list< int, n... >) const
 
template<typename Index >
std::vector< Indexh_permute (std::size_t which, std::vector< Index > idx) const
 
GroupElement ge (Generator const &g) const
 
GroupElement mul (GroupElement, GroupElement) const
 
GroupElement mul (Generator g1, GroupElement g2) const
 
GroupElement mul (GroupElement g1, Generator g2) const
 
GroupElement mul (Generator g1, Generator g2) const
 
int findElement (GroupElement e) const
 
void updateGlobalFlags (int flagDiffOfSameGenerator)
 

Private Attributes

std::size_t m_numIndices
 
std::vector< GroupElementm_elements
 
std::vector< Generatorm_generators
 
int m_globalFlags
 

Detailed Description

Dynamic symmetry group.

The DynamicSGroup class represents a symmetry group that need not be known at compile time. It is useful if one wants to support arbitrary run-time defineable symmetries for tensors, but it is also instantiated if a symmetry group is defined at compile time that would be either too large for the compiler to reasonably generate (using templates to calculate this at compile time is very inefficient) or that the compiler could generate the group but that it wouldn't make sense to unroll the loop for setting coefficients anymore.

Constructor & Destructor Documentation

◆ DynamicSGroup() [1/3]

Eigen::DynamicSGroup::DynamicSGroup ( )
inlineexplicit
21  m_elements.push_back(ge(Generator(0, 0, 0)));
22  }
std::size_t m_numIndices
Definition: DynamicSymmetry.h:112
std::vector< Generator > m_generators
Definition: DynamicSymmetry.h:114
int m_globalFlags
Definition: DynamicSymmetry.h:115
std::vector< GroupElement > m_elements
Definition: DynamicSymmetry.h:113
GroupElement ge(Generator const &g) const
Definition: DynamicSymmetry.h:132

References ge(), and m_elements.

◆ DynamicSGroup() [2/3]

Eigen::DynamicSGroup::DynamicSGroup ( const DynamicSGroup o)
inline
24  : m_numIndices(o.m_numIndices),
25  m_elements(o.m_elements),
26  m_generators(o.m_generators),
27  m_globalFlags(o.m_globalFlags) {}

◆ DynamicSGroup() [3/3]

Eigen::DynamicSGroup::DynamicSGroup ( DynamicSGroup &&  o)
inline
29  : m_numIndices(o.m_numIndices), m_elements(), m_generators(o.m_generators), m_globalFlags(o.m_globalFlags) {
30  std::swap(m_elements, o.m_elements);
31  }
EIGEN_BLAS_FUNC() swap(int *n, RealScalar *px, int *incx, RealScalar *py, int *incy)
Definition: level1_impl.h:117

References m_elements, and swap().

Member Function Documentation

◆ add() [1/2]

template<typename Gen_ >
void Eigen::DynamicSGroup::add ( Gen_  )
inline
50  {
51  add(Gen_::One, Gen_::Two, Gen_::Flags);
52  }
void add(int one, int two, int flags=0)
Definition: DynamicSymmetry.h:205

References add().

◆ add() [2/2]

void Eigen::DynamicSGroup::add ( int  one,
int  two,
int  flags = 0 
)
inline
205  {
206  eigen_assert(one >= 0);
207  eigen_assert(two >= 0);
208  eigen_assert(one != two);
209 
210  if ((std::size_t)one >= m_numIndices || (std::size_t)two >= m_numIndices) {
211  std::size_t newNumIndices = (one > two) ? one : two + 1;
212  for (auto& gelem : m_elements) {
213  gelem.representation.reserve(newNumIndices);
214  for (std::size_t i = m_numIndices; i < newNumIndices; i++) gelem.representation.push_back(i);
215  }
216  m_numIndices = newNumIndices;
217  }
218 
219  Generator g{one, two, flags};
220  GroupElement e = ge(g);
221 
222  /* special case for first generator */
223  if (m_elements.size() == 1) {
224  while (!e.isId()) {
225  m_elements.push_back(e);
226  e = mul(e, g);
227  }
228 
229  if (e.flags > 0) updateGlobalFlags(e.flags);
230 
231  // only add in case we didn't have identity
232  if (m_elements.size() > 1) m_generators.push_back(g);
233  return;
234  }
235 
236  int p = findElement(e);
237  if (p >= 0) {
239  return;
240  }
241 
242  std::size_t coset_order = m_elements.size();
243  m_elements.push_back(e);
244  for (std::size_t i = 1; i < coset_order; i++) m_elements.push_back(mul(m_elements[i], e));
245  m_generators.push_back(g);
246 
247  std::size_t coset_rep = coset_order;
248  do {
249  for (auto g : m_generators) {
250  e = mul(m_elements[coset_rep], g);
251  p = findElement(e);
252  if (p < 0) {
253  // element not yet in group
254  m_elements.push_back(e);
255  for (std::size_t i = 1; i < coset_order; i++) m_elements.push_back(mul(m_elements[i], e));
256  } else if (p > 0) {
258  }
259  }
260  coset_rep += coset_order;
261  } while (coset_rep < m_elements.size());
262 }
int i
Definition: BiCGSTAB_step_by_step.cpp:9
Array< double, 1, 3 > e(1./3., 0.5, 2.)
#define eigen_assert(x)
Definition: Macros.h:910
float * p
Definition: Tutorial_Map_using.cpp:9
void updateGlobalFlags(int flagDiffOfSameGenerator)
Definition: DynamicSymmetry.h:264
GroupElement mul(GroupElement, GroupElement) const
Definition: DynamicSymmetry.h:190
int findElement(GroupElement e) const
Definition: DynamicSymmetry.h:154

References e(), eigen_assert, findElement(), ge(), i, m_elements, m_generators, m_numIndices, mul(), p, and updateGlobalFlags().

Referenced by add(), Eigen::DynamicSGroupFromTemplateArgs< Gen >::add_all(), addAntiHermiticity(), addAntiSymmetry(), addHermiticity(), addSymmetry(), and test_symgroups_dynamic().

◆ addAntiHermiticity()

void Eigen::DynamicSGroup::addAntiHermiticity ( int  one,
int  two 
)
inline
56 { add(one, two, NegationFlag | ConjugationFlag); }
@ NegationFlag
Definition: Symmetry.h:18
@ ConjugationFlag
Definition: Symmetry.h:18

References add(), Eigen::ConjugationFlag, and Eigen::NegationFlag.

◆ addAntiSymmetry()

void Eigen::DynamicSGroup::addAntiSymmetry ( int  one,
int  two 
)
inline
54 { add(one, two, NegationFlag); }

References add(), and Eigen::NegationFlag.

◆ addHermiticity()

void Eigen::DynamicSGroup::addHermiticity ( int  one,
int  two 
)
inline
55 { add(one, two, ConjugationFlag); }

References add(), and Eigen::ConjugationFlag.

◆ addSymmetry()

void Eigen::DynamicSGroup::addSymmetry ( int  one,
int  two 
)
inline
53 { add(one, two, 0); }

References add().

Referenced by test_tensor_dynsym().

◆ apply() [1/2]

template<typename Op , typename RV , typename Index , std::size_t N, typename... Args>
RV Eigen::DynamicSGroup::apply ( const std::array< Index, N > &  idx,
RV  initial,
Args &&...  args 
) const
inline
59  {
61  "Can only apply symmetry group to objects that have at least the required amount of indices.");
62  for (std::size_t i = 0; i < size(); i++)
63  initial = Op::run(h_permute(i, idx, typename internal::gen_numeric_list<int, N>::type()), m_elements[i].flags,
64  initial, std::forward<Args>(args)...);
65  return initial;
66  }
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:118
std::size_t size() const
Definition: DynamicSymmetry.h:78
@ N
Definition: constructor.cpp:22
args
Definition: compute_granudrum_aor.py:143
type
Definition: compute_granudrum_aor.py:141
void run(const string &dir_name, LinearSolver *linear_solver_pt, const unsigned nel_1d, bool mess_up_order)
Definition: two_d_poisson_compare_solvers.cc:317

References compute_granudrum_aor::args, eigen_assert, h_permute(), i, m_elements, m_numIndices, N, run(), and size().

Referenced by test_symgroups_dynamic().

◆ apply() [2/2]

template<typename Op , typename RV , typename Index , typename... Args>
RV Eigen::DynamicSGroup::apply ( const std::vector< Index > &  idx,
RV  initial,
Args &&...  args 
) const
inline
69  {
70  eigen_assert(idx.size() >= m_numIndices &&
71  "Can only apply symmetry group to objects that have at least the required amount of indices.");
72  for (std::size_t i = 0; i < size(); i++)
73  initial = Op::run(h_permute(i, idx), m_elements[i].flags, initial, std::forward<Args>(args)...);
74  return initial;
75  }

References compute_granudrum_aor::args, eigen_assert, h_permute(), i, m_elements, m_numIndices, run(), and size().

◆ findElement()

int Eigen::DynamicSGroup::findElement ( GroupElement  e) const
inlineprivate
154  {
155  for (auto ee : m_elements) {
156  if (ee.representation == e.representation) return ee.flags ^ e.flags;
157  }
158  return -1;
159  }

References e(), and m_elements.

Referenced by add().

◆ ge()

GroupElement Eigen::DynamicSGroup::ge ( Generator const &  g) const
inlineprivate
132  {
133  GroupElement result;
134  result.representation.reserve(m_numIndices);
135  result.flags = g.flags;
136  for (std::size_t k = 0; k < m_numIndices; k++) {
137  if (k == (std::size_t)g.one)
138  result.representation.push_back(g.two);
139  else if (k == (std::size_t)g.two)
140  result.representation.push_back(g.one);
141  else
142  result.representation.push_back(int(k));
143  }
144  return result;
145  }
char char char int int * k
Definition: level2_impl.h:374

References Eigen::DynamicSGroup::GroupElement::flags, Eigen::DynamicSGroup::Generator::flags, k, m_numIndices, Eigen::DynamicSGroup::Generator::one, Eigen::DynamicSGroup::GroupElement::representation, and Eigen::DynamicSGroup::Generator::two.

Referenced by add(), DynamicSGroup(), and mul().

◆ globalFlags()

int Eigen::DynamicSGroup::globalFlags ( ) const
inline
77 { return m_globalFlags; }

References m_globalFlags.

Referenced by test_symgroups_dynamic().

◆ h_permute() [1/2]

template<typename Index , std::size_t N, int... n>
std::array<Index, N> Eigen::DynamicSGroup::h_permute ( std::size_t  which,
const std::array< Index, N > &  idx,
internal::numeric_list< int, n... >   
) const
inlineprivate
119  {
120  return std::array<Index, N>{{idx[n >= m_numIndices ? n : m_elements[which].representation[n]]...}};
121  }
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11

References m_elements, m_numIndices, and n.

Referenced by apply().

◆ h_permute() [2/2]

template<typename Index >
std::vector<Index> Eigen::DynamicSGroup::h_permute ( std::size_t  which,
std::vector< Index idx 
) const
inlineprivate
124  {
125  std::vector<Index> result;
126  result.reserve(idx.size());
127  for (auto k : m_elements[which].representation) result.push_back(idx[k]);
128  for (std::size_t i = m_numIndices; i < idx.size(); i++) result.push_back(idx[i]);
129  return result;
130  }

References i, k, m_elements, and m_numIndices.

◆ mul() [1/4]

GroupElement Eigen::DynamicSGroup::mul ( Generator  g1,
Generator  g2 
) const
inlineprivate
152 { return mul(ge(g1), ge(g2)); }

References ge(), and mul().

Referenced by mul().

◆ mul() [2/4]

GroupElement Eigen::DynamicSGroup::mul ( Generator  g1,
GroupElement  g2 
) const
inlineprivate
148 { return mul(ge(g1), g2); }

References ge(), and mul().

Referenced by mul().

◆ mul() [3/4]

GroupElement Eigen::DynamicSGroup::mul ( GroupElement  g1,
Generator  g2 
) const
inlineprivate
150 { return mul(g1, ge(g2)); }

References ge(), and mul().

Referenced by mul().

◆ mul() [4/4]

DynamicSGroup::GroupElement Eigen::DynamicSGroup::mul ( GroupElement  g1,
GroupElement  g2 
) const
inlineprivate
190  {
191  eigen_internal_assert(g1.representation.size() == m_numIndices);
192  eigen_internal_assert(g2.representation.size() == m_numIndices);
193 
194  GroupElement result;
195  result.representation.reserve(m_numIndices);
196  for (std::size_t i = 0; i < m_numIndices; i++) {
197  int v = g2.representation[g1.representation[i]];
198  eigen_assert(v >= 0);
199  result.representation.push_back(v);
200  }
201  result.flags = g1.flags ^ g2.flags;
202  return result;
203 }
Array< int, Dynamic, 1 > v
Definition: Array_initializer_list_vector_cxx11.cpp:1
#define eigen_internal_assert(x)
Definition: Macros.h:916

References eigen_assert, eigen_internal_assert, Eigen::DynamicSGroup::GroupElement::flags, i, m_numIndices, Eigen::DynamicSGroup::GroupElement::representation, and v.

Referenced by add().

◆ operator()() [1/2]

template<typename Tensor_ >
internal::tensor_symmetry_value_setter<Tensor_, DynamicSGroup> Eigen::DynamicSGroup::operator() ( Tensor_ &  tensor,
std::array< typename Tensor_::Index, Tensor_::NumIndices > const &  indices 
) const
inline
91  {
92  return internal::tensor_symmetry_value_setter<Tensor_, DynamicSGroup>(tensor, *this, indices);
93  }

◆ operator()() [2/2]

template<typename Tensor_ , typename... IndexTypes>
internal::tensor_symmetry_value_setter<Tensor_, DynamicSGroup> Eigen::DynamicSGroup::operator() ( Tensor_ &  tensor,
typename Tensor_::Index  firstIndex,
IndexTypes...  otherIndices 
) const
inline
83  {
84  static_assert(sizeof...(otherIndices) + 1 == Tensor_::NumIndices,
85  "Number of indices used to access a tensor coefficient must be equal to the rank of the tensor.");
86  return operator()(tensor, std::array<typename Tensor_::Index, Tensor_::NumIndices>{{firstIndex, otherIndices...}});
87  }
internal::tensor_symmetry_value_setter< Tensor_, DynamicSGroup > operator()(Tensor_ &tensor, typename Tensor_::Index firstIndex, IndexTypes... otherIndices) const
Definition: DynamicSymmetry.h:81

◆ operator=() [1/2]

DynamicSGroup& Eigen::DynamicSGroup::operator= ( const DynamicSGroup o)
inline
32  {
33  m_numIndices = o.m_numIndices;
34  m_elements = o.m_elements;
35  m_generators = o.m_generators;
36  m_globalFlags = o.m_globalFlags;
37  return *this;
38  }

References m_elements, m_generators, m_globalFlags, and m_numIndices.

Referenced by Eigen::DynamicSGroupFromTemplateArgs< Gen >::operator=().

◆ operator=() [2/2]

DynamicSGroup& Eigen::DynamicSGroup::operator= ( DynamicSGroup &&  o)
inline
39  {
40  m_numIndices = o.m_numIndices;
41  std::swap(m_elements, o.m_elements);
42  m_generators = o.m_generators;
43  m_globalFlags = o.m_globalFlags;
44  return *this;
45  }

References m_elements, m_generators, m_globalFlags, m_numIndices, and swap().

◆ size()

std::size_t Eigen::DynamicSGroup::size ( ) const
inline
78 { return m_elements.size(); }

References m_elements.

Referenced by apply(), and test_symgroups_dynamic().

◆ updateGlobalFlags()

void Eigen::DynamicSGroup::updateGlobalFlags ( int  flagDiffOfSameGenerator)
inlineprivate
264  {
265  switch (flagDiffOfSameGenerator) {
266  case 0:
267  default:
268  // nothing happened
269  break;
270  case NegationFlag:
271  // every element is it's own negative => whole tensor is zero
273  break;
274  case ConjugationFlag:
275  // every element is it's own conjugate => whole tensor is real
277  break;
278  case (NegationFlag | ConjugationFlag):
279  // every element is it's own negative conjugate => whole tensor is imaginary
281  break;
282  /* NOTE:
283  * since GlobalZeroFlag == GlobalRealFlag | GlobalImagFlag, if one generator
284  * causes the tensor to be real and the next one to be imaginary, this will
285  * trivially give the correct result
286  */
287  }
288 }
@ GlobalZeroFlag
Definition: Symmetry.h:20
@ GlobalRealFlag
Definition: Symmetry.h:20
@ GlobalImagFlag
Definition: Symmetry.h:20

References Eigen::ConjugationFlag, Eigen::GlobalImagFlag, Eigen::GlobalRealFlag, Eigen::GlobalZeroFlag, m_globalFlags, and Eigen::NegationFlag.

Referenced by add().

Member Data Documentation

◆ m_elements

std::vector<GroupElement> Eigen::DynamicSGroup::m_elements
private

◆ m_generators

std::vector<Generator> Eigen::DynamicSGroup::m_generators
private

Referenced by add(), and operator=().

◆ m_globalFlags

int Eigen::DynamicSGroup::m_globalFlags
private

◆ m_numIndices

std::size_t Eigen::DynamicSGroup::m_numIndices
private

Referenced by add(), apply(), ge(), h_permute(), mul(), and operator=().


The documentation for this class was generated from the following file: