Eigen::DynamicSGroup Class Reference

Dynamic symmetry group. More...

+ Inheritance diagram for Eigen::DynamicSGroup:

Classes

struct  Generator
 
struct  GroupElement
 

Public Member Functions

template<typename Gen_ >
void add (Gen_)
 
void add (int one, int two, int flags=0)
 
void addAntiHermiticity (int one, int two)
 
void addAntiSymmetry (int one, int two)
 
void addHermiticity (int one, int two)
 
void addSymmetry (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
 
 DynamicSGroup ()
 
 DynamicSGroup (const DynamicSGroup &o)
 
 DynamicSGroup (DynamicSGroup &&o)
 
int globalFlags () const
 
template<typename Tensor_ >
internal::tensor_symmetry_value_setter< Tensor_, DynamicSGroupoperator() (Tensor_ &tensor, std::array< typename Tensor_::Index, Tensor_::NumIndices > const &indices) const
 
template<typename Tensor_ , typename... IndexTypes>
internal::tensor_symmetry_value_setter< Tensor_, DynamicSGroupoperator() (Tensor_ &tensor, typename Tensor_::Index firstIndex, IndexTypes... otherIndices) const
 
DynamicSGroupoperator= (const DynamicSGroup &o)
 
DynamicSGroupoperator= (DynamicSGroup &&o)
 
std::size_t size () const
 

Private Member Functions

int findElement (GroupElement e) const
 
GroupElement ge (Generator const &g) const
 
template<typename Index , std::size_t N, int... n>
std::array< Index, N > h_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 mul (Generator g1, Generator g2) const
 
GroupElement mul (Generator g1, GroupElement g2) const
 
GroupElement mul (GroupElement g1, Generator g2) const
 
GroupElement mul (GroupElement, GroupElement) const
 
void updateGlobalFlags (int flagDiffOfSameGenerator)
 

Private Attributes

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

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.

Definition at line 17 of file DynamicSymmetry.h.

Constructor & Destructor Documentation

◆ DynamicSGroup() [1/3]

Eigen::DynamicSGroup::DynamicSGroup ( )
inlineexplicit

Definition at line 20 of file DynamicSymmetry.h.

20 : m_numIndices(1), m_elements(), m_generators(), m_globalFlags(0) { m_elements.push_back(ge(Generator(0, 0, 0))); }
std::size_t m_numIndices
std::vector< Generator > m_generators
std::vector< GroupElement > m_elements
GroupElement ge(Generator const &g) const

◆ DynamicSGroup() [2/3]

Eigen::DynamicSGroup::DynamicSGroup ( const DynamicSGroup o)
inline

Definition at line 21 of file DynamicSymmetry.h.

21 : m_numIndices(o.m_numIndices), m_elements(o.m_elements), m_generators(o.m_generators), m_globalFlags(o.m_globalFlags) { }

◆ DynamicSGroup() [3/3]

Eigen::DynamicSGroup::DynamicSGroup ( DynamicSGroup &&  o)
inline

Definition at line 22 of file DynamicSymmetry.h.

22 : m_numIndices(o.m_numIndices), m_elements(), m_generators(o.m_generators), m_globalFlags(o.m_globalFlags) { std::swap(m_elements, o.m_elements); }

Member Function Documentation

◆ add() [1/2]

template<typename Gen_ >
void Eigen::DynamicSGroup::add ( Gen_  )
inline

Definition at line 29 of file DynamicSymmetry.h.

29 { add(Gen_::One, Gen_::Two, Gen_::Flags); }
void add(int one, int two, int flags=0)

◆ add() [2/2]

void Eigen::DynamicSGroup::add ( int  one,
int  two,
int  flags = 0 
)
inline

Definition at line 197 of file DynamicSymmetry.h.

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

◆ addAntiHermiticity()

void Eigen::DynamicSGroup::addAntiHermiticity ( int  one,
int  two 
)
inline

Definition at line 33 of file DynamicSymmetry.h.

33 { add(one, two, NegationFlag | ConjugationFlag); }
@ NegationFlag
Definition: Symmetry.h:18
@ ConjugationFlag
Definition: Symmetry.h:19

◆ addAntiSymmetry()

void Eigen::DynamicSGroup::addAntiSymmetry ( int  one,
int  two 
)
inline

Definition at line 31 of file DynamicSymmetry.h.

31 { add(one, two, NegationFlag); }

◆ addHermiticity()

void Eigen::DynamicSGroup::addHermiticity ( int  one,
int  two 
)
inline

Definition at line 32 of file DynamicSymmetry.h.

32 { add(one, two, ConjugationFlag); }

◆ addSymmetry()

void Eigen::DynamicSGroup::addSymmetry ( int  one,
int  two 
)
inline

Definition at line 30 of file DynamicSymmetry.h.

30 { add(one, two, 0); }

◆ 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

Definition at line 36 of file DynamicSymmetry.h.

37  {
38  eigen_assert(N >= m_numIndices && "Can only apply symmetry group to objects that have at least the required amount of indices.");
39  for (std::size_t i = 0; i < size(); i++)
40  initial = Op::run(h_permute(i, idx, typename internal::gen_numeric_list<int, N>::type()), m_elements[i].flags, initial, std::forward<Args>(args)...);
41  return initial;
42  }
std::array< Index, N > h_permute(std::size_t which, const std::array< Index, N > &idx, internal::numeric_list< int, n... >) const
std::size_t size() const

◆ 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

Definition at line 45 of file DynamicSymmetry.h.

46  {
47  eigen_assert(idx.size() >= m_numIndices && "Can only apply symmetry group to objects that have at least the required amount of indices.");
48  for (std::size_t i = 0; i < size(); i++)
49  initial = Op::run(h_permute(i, idx), m_elements[i].flags, initial, std::forward<Args>(args)...);
50  return initial;
51  }

◆ findElement()

int Eigen::DynamicSGroup::findElement ( GroupElement  e) const
inlineprivate

Definition at line 142 of file DynamicSymmetry.h.

143  {
144  for (auto ee : m_elements) {
145  if (ee.representation == e.representation)
146  return ee.flags ^ e.flags;
147  }
148  return -1;
149  }

◆ ge()

GroupElement Eigen::DynamicSGroup::ge ( Generator const &  g) const
inlineprivate

Definition at line 110 of file DynamicSymmetry.h.

111  {
112  GroupElement result;
113  result.representation.reserve(m_numIndices);
114  result.flags = g.flags;
115  for (std::size_t k = 0; k < m_numIndices; k++) {
116  if (k == (std::size_t)g.one)
117  result.representation.push_back(g.two);
118  else if (k == (std::size_t)g.two)
119  result.representation.push_back(g.one);
120  else
121  result.representation.push_back(int(k));
122  }
123  return result;
124  }

◆ globalFlags()

int Eigen::DynamicSGroup::globalFlags ( ) const
inline

Definition at line 53 of file DynamicSymmetry.h.

53 { return m_globalFlags; }

◆ 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

Definition at line 93 of file DynamicSymmetry.h.

94  {
95  return std::array<Index, N>{{ idx[n >= m_numIndices ? n : m_elements[which].representation[n]]... }};
96  }
int n

◆ h_permute() [2/2]

template<typename Index >
std::vector<Index> Eigen::DynamicSGroup::h_permute ( std::size_t  which,
std::vector< Index idx 
) const
inlineprivate

Definition at line 99 of file DynamicSymmetry.h.

100  {
101  std::vector<Index> result;
102  result.reserve(idx.size());
103  for (auto k : m_elements[which].representation)
104  result.push_back(idx[k]);
105  for (std::size_t i = m_numIndices; i < idx.size(); i++)
106  result.push_back(idx[i]);
107  return result;
108  }

◆ mul() [1/4]

GroupElement Eigen::DynamicSGroup::mul ( Generator  g1,
Generator  g2 
) const
inlineprivate

Definition at line 137 of file DynamicSymmetry.h.

138  {
139  return mul(ge(g1), ge(g2));
140  }

◆ mul() [2/4]

GroupElement Eigen::DynamicSGroup::mul ( Generator  g1,
GroupElement  g2 
) const
inlineprivate

Definition at line 127 of file DynamicSymmetry.h.

128  {
129  return mul(ge(g1), g2);
130  }

◆ mul() [3/4]

GroupElement Eigen::DynamicSGroup::mul ( GroupElement  g1,
Generator  g2 
) const
inlineprivate

Definition at line 132 of file DynamicSymmetry.h.

133  {
134  return mul(g1, ge(g2));
135  }

◆ mul() [4/4]

DynamicSGroup::GroupElement Eigen::DynamicSGroup::mul ( GroupElement  g1,
GroupElement  g2 
) const
inlineprivate

Definition at line 181 of file DynamicSymmetry.h.

182 {
183  eigen_internal_assert(g1.representation.size() == m_numIndices);
184  eigen_internal_assert(g2.representation.size() == m_numIndices);
185 
186  GroupElement result;
187  result.representation.reserve(m_numIndices);
188  for (std::size_t i = 0; i < m_numIndices; i++) {
189  int v = g2.representation[g1.representation[i]];
190  eigen_assert(v >= 0);
191  result.representation.push_back(v);
192  }
193  result.flags = g1.flags ^ g2.flags;
194  return result;
195 }
Array< int, Dynamic, 1 > v
#define eigen_internal_assert(x)

◆ 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

Definition at line 64 of file DynamicSymmetry.h.

65  {
66  return internal::tensor_symmetry_value_setter<Tensor_, DynamicSGroup>(tensor, *this, indices);
67  }

◆ 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

Definition at line 57 of file DynamicSymmetry.h.

58  {
59  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.");
60  return operator()(tensor, std::array<typename Tensor_::Index, Tensor_::NumIndices>{{firstIndex, otherIndices...}});
61  }
internal::tensor_symmetry_value_setter< Tensor_, DynamicSGroup > operator()(Tensor_ &tensor, typename Tensor_::Index firstIndex, IndexTypes... otherIndices) const

◆ operator=() [1/2]

DynamicSGroup& Eigen::DynamicSGroup::operator= ( const DynamicSGroup o)
inline

Definition at line 23 of file DynamicSymmetry.h.

23 { m_numIndices = o.m_numIndices; m_elements = o.m_elements; m_generators = o.m_generators; m_globalFlags = o.m_globalFlags; return *this; }

◆ operator=() [2/2]

DynamicSGroup& Eigen::DynamicSGroup::operator= ( DynamicSGroup &&  o)
inline

Definition at line 24 of file DynamicSymmetry.h.

24 { m_numIndices = o.m_numIndices; std::swap(m_elements, o.m_elements); m_generators = o.m_generators; m_globalFlags = o.m_globalFlags; return *this; }

◆ size()

std::size_t Eigen::DynamicSGroup::size ( ) const
inline

Definition at line 54 of file DynamicSymmetry.h.

54 { return m_elements.size(); }

◆ updateGlobalFlags()

void Eigen::DynamicSGroup::updateGlobalFlags ( int  flagDiffOfSameGenerator)
inlineprivate

Definition at line 262 of file DynamicSymmetry.h.

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

Member Data Documentation

◆ m_elements

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

Definition at line 88 of file DynamicSymmetry.h.

◆ m_generators

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

Definition at line 89 of file DynamicSymmetry.h.

◆ m_globalFlags

int Eigen::DynamicSGroup::m_globalFlags
private

Definition at line 90 of file DynamicSymmetry.h.

◆ m_numIndices

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

Definition at line 87 of file DynamicSymmetry.h.


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