TemplateGroupTheory.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_TEMPLATEGROUPTHEORY_H
11 #define EIGEN_CXX11_TENSORSYMMETRY_TEMPLATEGROUPTHEORY_H
12 
13 // IWYU pragma: private
14 #include "../InternalHeaderCheck.h"
15 
16 namespace Eigen {
17 
18 namespace internal {
19 
20 namespace group_theory {
21 
34 /**********************************************************************
35  * "Ok kid, here is where it gets complicated."
36  * - Amelia Pond in the "Doctor Who" episode
37  * "The Big Bang"
38  *
39  * Dimino's algorithm
40  * ==================
41  *
42  * The following is Dimino's algorithm in sequential form:
43  *
44  * Input: identity element, list of generators, equality check,
45  * multiplication operation
46  * Output: list of group elements
47  *
48  * 1. add identity element
49  * 2. remove identities from list of generators
50  * 3. add all powers of first generator that aren't the
51  * identity element
52  * 4. go through all remaining generators:
53  * a. if generator is already in the list of elements
54  * -> do nothing
55  * b. otherwise
56  * i. remember current # of elements
57  * (i.e. the size of the current subgroup)
58  * ii. add all current elements (which includes
59  * the identity) each multiplied from right
60  * with the current generator to the group
61  * iii. add all remaining cosets that are generated
62  * by products of the new generator with itself
63  * and all other generators seen so far
64  *
65  * In functional form, this is implemented as a long set of recursive
66  * templates that have a complicated relationship.
67  *
68  * The main interface for Dimino's algorithm is the template
69  * enumerate_group_elements. All lists are implemented as variadic
70  * type_list<typename...> and numeric_list<typename = int, int...>
71  * templates.
72  *
73  * 'Calling' templates is usually done via typedefs.
74  *
75  * This algorithm is an extended version of the basic version. The
76  * extension consists in the fact that each group element has a set
77  * of flags associated with it. Multiplication of two group elements
78  * with each other results in a group element whose flags are the
79  * XOR of the flags of the previous elements. Each time the algorithm
80  * notices that a group element it just calculated is already in the
81  * list of current elements, the flags of both will be compared and
82  * added to the so-called 'global flags' of the group.
83  *
84  * The rationale behind this extension is that this allows not only
85  * for the description of symmetries between tensor indices, but
86  * also allows for the description of hermiticity, antisymmetry and
87  * antihermiticity. Negation and conjugation each are specific bit
88  * in the flags value and if two different ways to reach a group
89  * element lead to two different flags, this poses a constraint on
90  * the allowed values of the resulting tensor. For example, if a
91  * group element is reach both with and without the conjugation
92  * flags, it is clear that the resulting tensor has to be real.
93  *
94  * Note that this flag mechanism is quite generic and may have other
95  * uses beyond tensor properties.
96  *
97  * IMPORTANT:
98  * This algorithm assumes the group to be finite. If you try to
99  * run it with a group that's infinite, the algorithm will only
100  * terminate once you hit a compiler limit (max template depth).
101  * Also note that trying to use this implementation to create a
102  * very large group will probably either make you hit the same
103  * limit, cause the compiler to segfault or at the very least
104  * take a *really* long time (hours, days, weeks - sic!) to
105  * compile. It is not recommended to plug in more than 4
106  * generators, unless they are independent of each other.
107  */
108 
122 template <template <typename, typename> class Equality, typename id, typename L>
124 
125 template <template <typename, typename> class Equality, typename id, typename t, typename... ts>
126 struct strip_identities<Equality, id, type_list<t, ts...>> {
127  typedef std::conditional_t<
128  Equality<id, t>::value, typename strip_identities<Equality, id, type_list<ts...>>::type,
129  typename concat<type_list<t>, typename strip_identities<Equality, id, type_list<ts...>>::type>::type>
131  constexpr static int global_flags =
132  Equality<id, t>::global_flags | strip_identities<Equality, id, type_list<ts...>>::global_flags;
133 };
134 
135 template <template <typename, typename> class Equality, typename id EIGEN_TPL_PP_SPEC_HACK_DEFC(typename, ts)>
137  typedef type_list<> type;
138  constexpr static int global_flags = 0;
139 };
140 
154 template <template <typename, typename> class Multiply, template <typename, typename> class Equality, typename id,
155  typename g, typename current_element, typename elements,
156  bool dont_add_current_element // = false
157  >
159 #ifndef EIGEN_PARSED_BY_DOXYGEN
160  : // recursive inheritance is too difficult for Doxygen
161  public dimino_first_step_elements_helper<Multiply, Equality, id, g, typename Multiply<current_element, g>::type,
162  typename concat<elements, type_list<current_element>>::type,
163  Equality<typename Multiply<current_element, g>::type, id>::value> {
164 };
165 
166 template <template <typename, typename> class Multiply, template <typename, typename> class Equality, typename id,
167  typename g, typename current_element, typename elements>
168 struct dimino_first_step_elements_helper<Multiply, Equality, id, g, current_element, elements, true>
169 #endif // EIGEN_PARSED_BY_DOXYGEN
170 {
171  typedef elements type;
172  constexpr static int global_flags = Equality<current_element, id>::global_flags;
173 };
174 
188 template <template <typename, typename> class Multiply, template <typename, typename> class Equality, typename id,
189  typename generators>
194 
196  false>
198  typedef typename helper::type type;
199  constexpr static int global_flags = helper::global_flags;
200 };
201 
222 template <template <typename, typename> class Multiply, typename sub_group_elements, typename new_coset_rep,
223  bool generate_coset // = true
224  >
227 };
228 
229 template <template <typename, typename> class Multiply, typename sub_group_elements, typename new_coset_rep>
230 struct dimino_get_coset_elements<Multiply, sub_group_elements, new_coset_rep, false> {
231  typedef type_list<> type;
232 };
233 
248 template <template <typename, typename> class Multiply, template <typename, typename> class Equality, typename id,
249  typename sub_group_elements, typename elements, typename generators, typename rep_element, int sub_group_size>
251 
252 template <template <typename, typename> class Multiply, template <typename, typename> class Equality, typename id,
253  typename sub_group_elements, typename elements, typename g, typename... gs, typename rep_element,
254  int sub_group_size>
255 struct dimino_add_cosets_for_rep<Multiply, Equality, id, sub_group_elements, elements, type_list<g, gs...>, rep_element,
256  sub_group_size> {
259  constexpr static bool add_coset = !_cil::value;
260 
261  typedef
263 
264  typedef dimino_add_cosets_for_rep<Multiply, Equality, id, sub_group_elements,
265  typename concat<elements, coset_elements>::type, type_list<gs...>, rep_element,
266  sub_group_size>
268 
269  typedef typename _helper::type type;
270  constexpr static int global_flags = _cil::global_flags | _helper::global_flags;
271 
272  /* Note that we don't have to update global flags here, since
273  * we will only add these elements if they are not part of
274  * the group already. But that only happens if the coset rep
275  * is not already in the group, so the check for the coset rep
276  * will catch this.
277  */
278 };
279 
280 template <template <typename, typename> class Multiply, template <typename, typename> class Equality, typename id,
281  typename sub_group_elements, typename elements EIGEN_TPL_PP_SPEC_HACK_DEFC(typename, empty),
282  typename rep_element, int sub_group_size>
283 struct dimino_add_cosets_for_rep<Multiply, Equality, id, sub_group_elements, elements,
284  type_list<EIGEN_TPL_PP_SPEC_HACK_USE(empty)>, rep_element, sub_group_size> {
285  typedef elements type;
286  constexpr static int global_flags = 0;
287 };
288 
303 template <template <typename, typename> class Multiply, template <typename, typename> class Equality, typename id,
304  typename sub_group_elements, typename elements, typename generators, int sub_group_size, int rep_pos,
305  bool stop_condition // = false
306  >
309  typedef dimino_add_cosets_for_rep<Multiply, Equality, id, sub_group_elements, elements, generators, rep_element,
310  sub_group_elements::count>
312  typedef typename _ac4r::type new_elements;
313 
314  constexpr static int new_rep_pos = rep_pos + sub_group_elements::count;
315  constexpr static bool new_stop_condition = new_rep_pos >= new_elements::count;
316 
317  typedef dimino_add_all_coset_spaces<Multiply, Equality, id, sub_group_elements, new_elements, generators,
318  sub_group_size, new_rep_pos, new_stop_condition>
320 
321  typedef typename _helper::type type;
322  constexpr static int global_flags = _helper::global_flags | _ac4r::global_flags;
323 };
324 
325 template <template <typename, typename> class Multiply, template <typename, typename> class Equality, typename id,
326  typename sub_group_elements, typename elements, typename generators, int sub_group_size, int rep_pos>
327 struct dimino_add_all_coset_spaces<Multiply, Equality, id, sub_group_elements, elements, generators, sub_group_size,
328  rep_pos, true> {
329  typedef elements type;
330  constexpr static int global_flags = 0;
331 };
332 
345 template <template <typename, typename> class Multiply, template <typename, typename> class Equality, typename id,
346  typename elements, typename generators_done, typename current_generator,
347  bool redundant // = false
348  >
350  /* this template is only called if the generator is not redundant
351  * => all elements of the group multiplied with the new generator
352  * are going to be new elements of the most trivial coset space
353  */
356 
357  constexpr static int rep_pos = elements::count;
358 
360  Multiply, Equality, id,
361  elements, // elements of previous subgroup
363  elements::count, // size of previous subgroup
364  rep_pos,
365  false // don't stop (because rep_pos >= new_elements::count is always false at this point)
366  >
368  typedef typename _helper::type type;
369  constexpr static int global_flags = _helper::global_flags;
370 };
371 
372 template <template <typename, typename> class Multiply, template <typename, typename> class Equality, typename id,
373  typename elements, typename generators_done, typename current_generator>
374 struct dimino_add_generator<Multiply, Equality, id, elements, generators_done, current_generator, true> {
375  // redundant case
376  typedef elements type;
377  constexpr static int global_flags = 0;
378 };
379 
392 template <template <typename, typename> class Multiply, template <typename, typename> class Equality, typename id,
393  typename generators_done, typename remaining_generators, typename elements>
397 
399 
401 
402  typedef typename _helper::type new_elements;
403 
404  typedef dimino_add_remaining_generators<Multiply, Equality, id,
408 
409  typedef typename _next_iter::type type;
410  constexpr static int global_flags = _cil::global_flags | _helper::global_flags | _next_iter::global_flags;
411 };
412 
413 template <template <typename, typename> class Multiply, template <typename, typename> class Equality, typename id,
414  typename generators_done, typename elements>
415 struct dimino_add_remaining_generators<Multiply, Equality, id, generators_done, type_list<>, elements> {
416  typedef elements type;
417  constexpr static int global_flags = 0;
418 };
419 
434 template <template <typename, typename> class Multiply, template <typename, typename> class Equality, typename id,
435  typename generators, int initial_global_flags = 0>
439 
440  typedef dimino_add_remaining_generators<Multiply, Equality, id, typename first_step::generators_done,
441  typename first_step::next_generators, // remaining_generators
442  typename first_step::type // first_step elements
443  >
445 
446  typedef typename _helper::type type;
447  constexpr static int global_flags = initial_global_flags | first_step::global_flags | _helper::global_flags;
448 };
449 
450 // in case when no generators are specified
451 template <template <typename, typename> class Multiply, template <typename, typename> class Equality, typename id,
452  int initial_global_flags>
453 struct enumerate_group_elements_noid<Multiply, Equality, id, type_list<>, initial_global_flags> {
455  constexpr static int global_flags = initial_global_flags;
456 };
457 
475 template <template <typename, typename> class Multiply, template <typename, typename> class Equality, typename id,
476  typename Generators_>
478  : public enumerate_group_elements_noid<Multiply, Equality, id,
479  typename strip_identities<Equality, id, Generators_>::type,
480  strip_identities<Equality, id, Generators_>::global_flags> {};
481 
482 } // end namespace group_theory
483 
484 } // end namespace internal
485 
486 } // end namespace Eigen
487 
488 #endif // EIGEN_CXX11_TENSORSYMMETRY_TEMPLATEGROUPTHEORY_H
489 
490 /*
491  * kate: space-indent on; indent-width 2; mixedindent off; indent-mode cstyle;
492  */
#define EIGEN_TPL_PP_SPEC_HACK_USE(n)
Definition: CXX11Workarounds.h:73
#define EIGEN_TPL_PP_SPEC_HACK_DEFC(mt, n)
Definition: CXX11Workarounds.h:72
MatrixXd L
Definition: LLT_example.cpp:6
Namespace containing all symbols from the Eigen library.
Definition: bench_norm.cpp:70
squared absolute value
Definition: GlobalFunctions.h:87
type
Definition: compute_granudrum_aor.py:141
Definition: Eigen_Colamd.h:49
t
Definition: plotPSD.py:36
Definition: MoreMeta.h:268
Definition: MoreMeta.h:87
Definition: MoreMeta.h:296
Definition: MoreMeta.h:202
Recursive template for adding all coset spaces for a new generator.
Definition: TemplateGroupTheory.h:307
dimino_add_all_coset_spaces< Multiply, Equality, id, sub_group_elements, new_elements, generators, sub_group_size, new_rep_pos, new_stop_condition > _helper
Definition: TemplateGroupTheory.h:319
constexpr static bool new_stop_condition
Definition: TemplateGroupTheory.h:315
constexpr static int global_flags
Definition: TemplateGroupTheory.h:322
_helper::type type
Definition: TemplateGroupTheory.h:321
get< rep_pos, elements >::type rep_element
Definition: TemplateGroupTheory.h:308
dimino_add_cosets_for_rep< Multiply, Equality, id, sub_group_elements, elements, generators, rep_element, sub_group_elements::count > _ac4r
Definition: TemplateGroupTheory.h:311
constexpr static int new_rep_pos
Definition: TemplateGroupTheory.h:314
_ac4r::type new_elements
Definition: TemplateGroupTheory.h:312
dimino_add_cosets_for_rep< Multiply, Equality, id, sub_group_elements, typename concat< elements, coset_elements >::type, type_list< gs... >, rep_element, sub_group_size > _helper
Definition: TemplateGroupTheory.h:267
dimino_get_coset_elements< Multiply, sub_group_elements, new_coset_rep, add_coset >::type coset_elements
Definition: TemplateGroupTheory.h:262
Recursive template for adding coset spaces.
Definition: TemplateGroupTheory.h:250
Enlarge the group by adding a new generator.
Definition: TemplateGroupTheory.h:349
apply_op_from_right< Multiply, current_generator, elements >::type multiplied_elements
Definition: TemplateGroupTheory.h:354
concat< elements, multiplied_elements >::type new_elements
Definition: TemplateGroupTheory.h:355
_helper::type type
Definition: TemplateGroupTheory.h:368
constexpr static int global_flags
Definition: TemplateGroupTheory.h:369
constexpr static int rep_pos
Definition: TemplateGroupTheory.h:357
dimino_add_all_coset_spaces< Multiply, Equality, id, elements, new_elements, typename concat< generators_done, type_list< current_generator > >::type, elements::count, rep_pos, false > _helper
Definition: TemplateGroupTheory.h:367
Recursive template that adds all remaining generators to a group.
Definition: TemplateGroupTheory.h:394
get< 0, remaining_generators >::type first_generator
Definition: TemplateGroupTheory.h:395
_helper::type new_elements
Definition: TemplateGroupTheory.h:402
skip< 1, remaining_generators >::type next_generators
Definition: TemplateGroupTheory.h:396
dimino_add_generator< Multiply, Equality, id, elements, generators_done, first_generator, _cil::value > _helper
Definition: TemplateGroupTheory.h:400
_next_iter::type type
Definition: TemplateGroupTheory.h:409
constexpr static int global_flags
Definition: TemplateGroupTheory.h:410
contained_in_list_gf< Equality, first_generator, elements > _cil
Definition: TemplateGroupTheory.h:398
dimino_add_remaining_generators< Multiply, Equality, id, typename concat< generators_done, type_list< first_generator > >::type, next_generators, new_elements > _next_iter
Definition: TemplateGroupTheory.h:407
Recursive template that adds powers of the first generator to the list of group elements.
Definition: TemplateGroupTheory.h:163
Add all powers of the first generator to the list of group elements.
Definition: TemplateGroupTheory.h:190
helper::type type
Definition: TemplateGroupTheory.h:198
dimino_first_step_elements_helper< Multiply, Equality, id, first_generator, first_generator, type_list< id >, false > helper
Definition: TemplateGroupTheory.h:197
skip< 1, generators >::type next_generators
Definition: TemplateGroupTheory.h:192
constexpr static int global_flags
Definition: TemplateGroupTheory.h:199
type_list< first_generator > generators_done
Definition: TemplateGroupTheory.h:193
get< 0, generators >::type first_generator
Definition: TemplateGroupTheory.h:191
Generate all elements of a specific coset.
Definition: TemplateGroupTheory.h:225
apply_op_from_right< Multiply, new_coset_rep, sub_group_elements >::type type
Definition: TemplateGroupTheory.h:226
Helper template that implements group element enumeration.
Definition: TemplateGroupTheory.h:436
dimino_first_step_elements< Multiply, Equality, id, generators > first_step
Definition: TemplateGroupTheory.h:437
dimino_add_remaining_generators< Multiply, Equality, id, typename first_step::generators_done, typename first_step::next_generators, typename first_step::type > _helper
Definition: TemplateGroupTheory.h:444
_helper::type type
Definition: TemplateGroupTheory.h:446
constexpr static int global_flags
Definition: TemplateGroupTheory.h:447
first_step::type first_step_elements
Definition: TemplateGroupTheory.h:438
Enumerate all elements in a finite group.
Definition: TemplateGroupTheory.h:480
std::conditional_t< Equality< id, t >::value, typename strip_identities< Equality, id, type_list< ts... > >::type, typename concat< type_list< t >, typename strip_identities< Equality, id, type_list< ts... > >::type >::type > type
Definition: TemplateGroupTheory.h:130
Cleanse a list of group elements of the identity element.
Definition: TemplateGroupTheory.h:123
Definition: MoreMeta.h:192
Definition: MoreMeta.h:22