Loading...
Searching...
No Matches
TemplateGroupTheory.h
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
13namespace Eigen {
14
15namespace internal {
16
17namespace group_theory {
18
31/**********************************************************************
32 * "Ok kid, here is where it gets complicated."
33 * - Amelia Pond in the "Doctor Who" episode
34 * "The Big Bang"
35 *
36 * Dimino's algorithm
37 * ==================
38 *
39 * The following is Dimino's algorithm in sequential form:
40 *
41 * Input: identity element, list of generators, equality check,
42 * multiplication operation
43 * Output: list of group elements
44 *
45 * 1. add identity element
46 * 2. remove identities from list of generators
47 * 3. add all powers of first generator that aren't the
48 * identity element
49 * 4. go through all remaining generators:
50 * a. if generator is already in the list of elements
51 * -> do nothing
52 * b. otherwise
53 * i. remember current # of elements
54 * (i.e. the size of the current subgroup)
55 * ii. add all current elements (which includes
56 * the identity) each multiplied from right
57 * with the current generator to the group
58 * iii. add all remaining cosets that are generated
59 * by products of the new generator with itself
60 * and all other generators seen so far
61 *
62 * In functional form, this is implemented as a long set of recursive
63 * templates that have a complicated relationship.
64 *
65 * The main interface for Dimino's algorithm is the template
66 * enumerate_group_elements. All lists are implemented as variadic
67 * type_list<typename...> and numeric_list<typename = int, int...>
68 * templates.
69 *
70 * 'Calling' templates is usually done via typedefs.
71 *
72 * This algorithm is an extended version of the basic version. The
73 * extension consists in the fact that each group element has a set
74 * of flags associated with it. Multiplication of two group elements
75 * with each other results in a group element whose flags are the
76 * XOR of the flags of the previous elements. Each time the algorithm
77 * notices that a group element it just calculated is already in the
78 * list of current elements, the flags of both will be compared and
79 * added to the so-called 'global flags' of the group.
80 *
81 * The rationale behind this extension is that this allows not only
82 * for the description of symmetries between tensor indices, but
83 * also allows for the description of hermiticity, antisymmetry and
84 * antihermiticity. Negation and conjugation each are specific bit
85 * in the flags value and if two different ways to reach a group
86 * element lead to two different flags, this poses a constraint on
87 * the allowed values of the resulting tensor. For example, if a
88 * group element is reach both with and without the conjugation
89 * flags, it is clear that the resulting tensor has to be real.
90 *
91 * Note that this flag mechanism is quite generic and may have other
92 * uses beyond tensor properties.
93 *
94 * IMPORTANT:
95 * This algorithm assumes the group to be finite. If you try to
96 * run it with a group that's infinite, the algorithm will only
97 * terminate once you hit a compiler limit (max template depth).
98 * Also note that trying to use this implementation to create a
99 * very large group will probably either make you hit the same
100 * limit, cause the compiler to segfault or at the very least
101 * take a *really* long time (hours, days, weeks - sic!) to
102 * compile. It is not recommended to plug in more than 4
103 * generators, unless they are independent of each other.
104 */
105
119template<template<typename, typename> class Equality, typename id, typename L> struct strip_identities;
120
121template<
122 template<typename, typename> class Equality,
123 typename id,
124 typename t,
125 typename... ts
126>
127struct strip_identities<Equality, id, type_list<t, ts...>>
128{
129 typedef typename conditional<
130 Equality<id, t>::value,
131 typename strip_identities<Equality, id, type_list<ts...>>::type,
132 typename concat<type_list<t>, typename strip_identities<Equality, id, type_list<ts...>>::type>::type
133 >::type type;
134 constexpr static int global_flags = Equality<id, t>::global_flags | strip_identities<Equality, id, type_list<ts...>>::global_flags;
135};
136
137template<
138 template<typename, typename> class Equality,
139 typename id
140 EIGEN_TPL_PP_SPEC_HACK_DEFC(typename, ts)
141>
142struct strip_identities<Equality, id, type_list<EIGEN_TPL_PP_SPEC_HACK_USE(ts)>>
143{
144 typedef type_list<> type;
145 constexpr static int global_flags = 0;
146};
147
161template<
162 template<typename, typename> class Multiply,
163 template<typename, typename> class Equality,
164 typename id,
165 typename g,
166 typename current_element,
167 typename elements,
168 bool dont_add_current_element // = false
169>
170struct dimino_first_step_elements_helper :
171 public dimino_first_step_elements_helper<
172 Multiply,
173 Equality,
174 id,
175 g,
176 typename Multiply<current_element, g>::type,
177 typename concat<elements, type_list<current_element>>::type,
178 Equality<typename Multiply<current_element, g>::type, id>::value
179 > {};
180
181template<
182 template<typename, typename> class Multiply,
183 template<typename, typename> class Equality,
184 typename id,
185 typename g,
186 typename current_element,
187 typename elements
188>
189struct dimino_first_step_elements_helper<Multiply, Equality, id, g, current_element, elements, true>
190{
191 typedef elements type;
192 constexpr static int global_flags = Equality<current_element, id>::global_flags;
193};
194
208template<
209 template<typename, typename> class Multiply,
210 template<typename, typename> class Equality,
211 typename id,
212 typename generators
213>
214struct dimino_first_step_elements
215{
216 typedef typename get<0, generators>::type first_generator;
217 typedef typename skip<1, generators>::type next_generators;
218 typedef type_list<first_generator> generators_done;
219
220 typedef dimino_first_step_elements_helper<
221 Multiply,
222 Equality,
223 id,
224 first_generator,
225 first_generator,
226 type_list<id>,
227 false
228 > helper;
229 typedef typename helper::type type;
230 constexpr static int global_flags = helper::global_flags;
231};
232
253template<
254 template<typename, typename> class Multiply,
255 typename sub_group_elements,
256 typename new_coset_rep,
257 bool generate_coset // = true
258>
259struct dimino_get_coset_elements
260{
261 typedef typename apply_op_from_right<Multiply, new_coset_rep, sub_group_elements>::type type;
262};
263
264template<
265 template<typename, typename> class Multiply,
266 typename sub_group_elements,
267 typename new_coset_rep
268>
269struct dimino_get_coset_elements<Multiply, sub_group_elements, new_coset_rep, false>
270{
271 typedef type_list<> type;
272};
273
288template<
289 template<typename, typename> class Multiply,
290 template<typename, typename> class Equality,
291 typename id,
292 typename sub_group_elements,
293 typename elements,
294 typename generators,
295 typename rep_element,
296 int sub_group_size
297>
298struct dimino_add_cosets_for_rep;
299
300template<
301 template<typename, typename> class Multiply,
302 template<typename, typename> class Equality,
303 typename id,
304 typename sub_group_elements,
305 typename elements,
306 typename g,
307 typename... gs,
308 typename rep_element,
309 int sub_group_size
310>
311struct dimino_add_cosets_for_rep<Multiply, Equality, id, sub_group_elements, elements, type_list<g, gs...>, rep_element, sub_group_size>
312{
313 typedef typename Multiply<rep_element, g>::type new_coset_rep;
314 typedef contained_in_list_gf<Equality, new_coset_rep, elements> _cil;
315 constexpr static bool add_coset = !_cil::value;
316
317 typedef typename dimino_get_coset_elements<
318 Multiply,
319 sub_group_elements,
320 new_coset_rep,
321 add_coset
322 >::type coset_elements;
323
324 typedef dimino_add_cosets_for_rep<
325 Multiply,
326 Equality,
327 id,
328 sub_group_elements,
329 typename concat<elements, coset_elements>::type,
330 type_list<gs...>,
331 rep_element,
332 sub_group_size
333 > _helper;
334
335 typedef typename _helper::type type;
336 constexpr static int global_flags = _cil::global_flags | _helper::global_flags;
337
338 /* Note that we don't have to update global flags here, since
339 * we will only add these elements if they are not part of
340 * the group already. But that only happens if the coset rep
341 * is not already in the group, so the check for the coset rep
342 * will catch this.
343 */
344};
345
346template<
347 template<typename, typename> class Multiply,
348 template<typename, typename> class Equality,
349 typename id,
350 typename sub_group_elements,
351 typename elements
352 EIGEN_TPL_PP_SPEC_HACK_DEFC(typename, empty),
353 typename rep_element,
354 int sub_group_size
355>
356struct dimino_add_cosets_for_rep<Multiply, Equality, id, sub_group_elements, elements, type_list<EIGEN_TPL_PP_SPEC_HACK_USE(empty)>, rep_element, sub_group_size>
357{
358 typedef elements type;
359 constexpr static int global_flags = 0;
360};
361
376template<
377 template<typename, typename> class Multiply,
378 template<typename, typename> class Equality,
379 typename id,
380 typename sub_group_elements,
381 typename elements,
382 typename generators,
383 int sub_group_size,
384 int rep_pos,
385 bool stop_condition // = false
386>
387struct dimino_add_all_coset_spaces
388{
389 typedef typename get<rep_pos, elements>::type rep_element;
390 typedef dimino_add_cosets_for_rep<
391 Multiply,
392 Equality,
393 id,
394 sub_group_elements,
395 elements,
396 generators,
397 rep_element,
398 sub_group_elements::count
399 > _ac4r;
400 typedef typename _ac4r::type new_elements;
401
402 constexpr static int new_rep_pos = rep_pos + sub_group_elements::count;
403 constexpr static bool new_stop_condition = new_rep_pos >= new_elements::count;
404
405 typedef dimino_add_all_coset_spaces<
406 Multiply,
407 Equality,
408 id,
409 sub_group_elements,
410 new_elements,
411 generators,
412 sub_group_size,
413 new_rep_pos,
414 new_stop_condition
415 > _helper;
416
417 typedef typename _helper::type type;
418 constexpr static int global_flags = _helper::global_flags | _ac4r::global_flags;
419};
420
421template<
422 template<typename, typename> class Multiply,
423 template<typename, typename> class Equality,
424 typename id,
425 typename sub_group_elements,
426 typename elements,
427 typename generators,
428 int sub_group_size,
429 int rep_pos
430>
431struct dimino_add_all_coset_spaces<Multiply, Equality, id, sub_group_elements, elements, generators, sub_group_size, rep_pos, true>
432{
433 typedef elements type;
434 constexpr static int global_flags = 0;
435};
436
449template<
450 template<typename, typename> class Multiply,
451 template<typename, typename> class Equality,
452 typename id,
453 typename elements,
454 typename generators_done,
455 typename current_generator,
456 bool redundant // = false
457>
458struct dimino_add_generator
459{
460 /* this template is only called if the generator is not redundant
461 * => all elements of the group multiplied with the new generator
462 * are going to be new elements of the most trivial coset space
463 */
464 typedef typename apply_op_from_right<Multiply, current_generator, elements>::type multiplied_elements;
465 typedef typename concat<elements, multiplied_elements>::type new_elements;
466
467 constexpr static int rep_pos = elements::count;
468
469 typedef dimino_add_all_coset_spaces<
470 Multiply,
471 Equality,
472 id,
473 elements, // elements of previous subgroup
474 new_elements,
475 typename concat<generators_done, type_list<current_generator>>::type,
476 elements::count, // size of previous subgroup
477 rep_pos,
478 false // don't stop (because rep_pos >= new_elements::count is always false at this point)
479 > _helper;
480 typedef typename _helper::type type;
481 constexpr static int global_flags = _helper::global_flags;
482};
483
484template<
485 template<typename, typename> class Multiply,
486 template<typename, typename> class Equality,
487 typename id,
488 typename elements,
489 typename generators_done,
490 typename current_generator
491>
492struct dimino_add_generator<Multiply, Equality, id, elements, generators_done, current_generator, true>
493{
494 // redundant case
495 typedef elements type;
496 constexpr static int global_flags = 0;
497};
498
511template<
512 template<typename, typename> class Multiply,
513 template<typename, typename> class Equality,
514 typename id,
515 typename generators_done,
516 typename remaining_generators,
517 typename elements
518>
519struct dimino_add_remaining_generators
520{
521 typedef typename get<0, remaining_generators>::type first_generator;
522 typedef typename skip<1, remaining_generators>::type next_generators;
523
524 typedef contained_in_list_gf<Equality, first_generator, elements> _cil;
525
526 typedef dimino_add_generator<
527 Multiply,
528 Equality,
529 id,
530 elements,
531 generators_done,
532 first_generator,
533 _cil::value
534 > _helper;
535
536 typedef typename _helper::type new_elements;
537
538 typedef dimino_add_remaining_generators<
539 Multiply,
540 Equality,
541 id,
542 typename concat<generators_done, type_list<first_generator>>::type,
543 next_generators,
544 new_elements
545 > _next_iter;
546
547 typedef typename _next_iter::type type;
548 constexpr static int global_flags =
549 _cil::global_flags |
550 _helper::global_flags |
551 _next_iter::global_flags;
552};
553
554template<
555 template<typename, typename> class Multiply,
556 template<typename, typename> class Equality,
557 typename id,
558 typename generators_done,
559 typename elements
560>
561struct dimino_add_remaining_generators<Multiply, Equality, id, generators_done, type_list<>, elements>
562{
563 typedef elements type;
564 constexpr static int global_flags = 0;
565};
566
581template<
582 template<typename, typename> class Multiply,
583 template<typename, typename> class Equality,
584 typename id,
585 typename generators,
586 int initial_global_flags = 0
587>
588struct enumerate_group_elements_noid
589{
590 typedef dimino_first_step_elements<Multiply, Equality, id, generators> first_step;
591 typedef typename first_step::type first_step_elements;
592
593 typedef dimino_add_remaining_generators<
594 Multiply,
595 Equality,
596 id,
597 typename first_step::generators_done,
598 typename first_step::next_generators, // remaining_generators
599 typename first_step::type // first_step elements
600 > _helper;
601
602 typedef typename _helper::type type;
603 constexpr static int global_flags =
604 initial_global_flags |
605 first_step::global_flags |
606 _helper::global_flags;
607};
608
609// in case when no generators are specified
610template<
611 template<typename, typename> class Multiply,
612 template<typename, typename> class Equality,
613 typename id,
614 int initial_global_flags
615>
616struct enumerate_group_elements_noid<Multiply, Equality, id, type_list<>, initial_global_flags>
617{
618 typedef type_list<id> type;
619 constexpr static int global_flags = initial_global_flags;
620};
621
639template<
640 template<typename, typename> class Multiply,
641 template<typename, typename> class Equality,
642 typename id,
643 typename _generators
644>
645struct enumerate_group_elements
646 : public enumerate_group_elements_noid<
647 Multiply,
648 Equality,
649 id,
650 typename strip_identities<Equality, id, _generators>::type,
651 strip_identities<Equality, id, _generators>::global_flags
652 >
653{
654};
655
656} // end namespace group_theory
657
658} // end namespace internal
659
660} // end namespace Eigen
661
662#endif // EIGEN_CXX11_TENSORSYMMETRY_TEMPLATEGROUPTHEORY_H
663
664/*
665 * kate: space-indent on; indent-width 2; mixedindent off; indent-mode cstyle;
666 */
Namespace containing all symbols from the Eigen library.
Definition: AdolcForward:45