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 #include "../InternalHeaderCheck.h"
14 
15 namespace Eigen {
16 
17 namespace internal {
18 
19 namespace group_theory {
20 
33 
121 template<template<typename, typename> class Equality, typename id, typename L> struct strip_identities;
122 
123 template<
124  template<typename, typename> class Equality,
125  typename id,
126  typename t,
127  typename... ts
128 >
129 struct strip_identities<Equality, id, type_list<t, ts...>>
130 {
131  typedef std::conditional_t<
132  Equality<id, t>::value,
133  typename strip_identities<Equality, id, type_list<ts...>>::type,
134  typename concat<type_list<t>, typename strip_identities<Equality, id, type_list<ts...>>::type>::type
135  > type;
136  constexpr static int global_flags = Equality<id, t>::global_flags | strip_identities<Equality, id, type_list<ts...>>::global_flags;
137 };
138 
139 template<
140  template<typename, typename> class Equality,
141  typename id
142  EIGEN_TPL_PP_SPEC_HACK_DEFC(typename, ts)
143 >
144 struct strip_identities<Equality, id, type_list<EIGEN_TPL_PP_SPEC_HACK_USE(ts)>>
145 {
146  typedef type_list<> type;
147  constexpr static int global_flags = 0;
148 };
149 
163 template<
164  template<typename, typename> class Multiply,
165  template<typename, typename> class Equality,
166  typename id,
167  typename g,
168  typename current_element,
169  typename elements,
170  bool dont_add_current_element // = false
171 >
172 struct dimino_first_step_elements_helper
173 #ifndef EIGEN_PARSED_BY_DOXYGEN
174  : // recursive inheritance is too difficult for Doxygen
175  public dimino_first_step_elements_helper<
176  Multiply,
177  Equality,
178  id,
179  g,
180  typename Multiply<current_element, g>::type,
181  typename concat<elements, type_list<current_element>>::type,
182  Equality<typename Multiply<current_element, g>::type, id>::value
183  > {};
184 
185 template<
186  template<typename, typename> class Multiply,
187  template<typename, typename> class Equality,
188  typename id,
189  typename g,
190  typename current_element,
191  typename elements
192 >
193 struct dimino_first_step_elements_helper<Multiply, Equality, id, g, current_element, elements, true>
194 #endif // EIGEN_PARSED_BY_DOXYGEN
195 {
196  typedef elements type;
197  constexpr static int global_flags = Equality<current_element, id>::global_flags;
198 };
199 
213 template<
214  template<typename, typename> class Multiply,
215  template<typename, typename> class Equality,
216  typename id,
217  typename generators
218 >
219 struct dimino_first_step_elements
220 {
221  typedef typename get<0, generators>::type first_generator;
222  typedef typename skip<1, generators>::type next_generators;
223  typedef type_list<first_generator> generators_done;
224 
225  typedef dimino_first_step_elements_helper<
226  Multiply,
227  Equality,
228  id,
229  first_generator,
230  first_generator,
231  type_list<id>,
232  false
233  > helper;
234  typedef typename helper::type type;
235  constexpr static int global_flags = helper::global_flags;
236 };
237 
258 template<
259  template<typename, typename> class Multiply,
260  typename sub_group_elements,
261  typename new_coset_rep,
262  bool generate_coset // = true
263 >
264 struct dimino_get_coset_elements
265 {
266  typedef typename apply_op_from_right<Multiply, new_coset_rep, sub_group_elements>::type type;
267 };
268 
269 template<
270  template<typename, typename> class Multiply,
271  typename sub_group_elements,
272  typename new_coset_rep
273 >
274 struct dimino_get_coset_elements<Multiply, sub_group_elements, new_coset_rep, false>
275 {
276  typedef type_list<> type;
277 };
278 
293 template<
294  template<typename, typename> class Multiply,
295  template<typename, typename> class Equality,
296  typename id,
297  typename sub_group_elements,
298  typename elements,
299  typename generators,
300  typename rep_element,
301  int sub_group_size
302 >
303 struct dimino_add_cosets_for_rep;
304 
305 template<
306  template<typename, typename> class Multiply,
307  template<typename, typename> class Equality,
308  typename id,
309  typename sub_group_elements,
310  typename elements,
311  typename g,
312  typename... gs,
313  typename rep_element,
314  int sub_group_size
315 >
316 struct dimino_add_cosets_for_rep<Multiply, Equality, id, sub_group_elements, elements, type_list<g, gs...>, rep_element, sub_group_size>
317 {
318  typedef typename Multiply<rep_element, g>::type new_coset_rep;
319  typedef contained_in_list_gf<Equality, new_coset_rep, elements> _cil;
320  constexpr static bool add_coset = !_cil::value;
321 
322  typedef typename dimino_get_coset_elements<
323  Multiply,
324  sub_group_elements,
325  new_coset_rep,
326  add_coset
327  >::type coset_elements;
328 
329  typedef dimino_add_cosets_for_rep<
330  Multiply,
331  Equality,
332  id,
333  sub_group_elements,
334  typename concat<elements, coset_elements>::type,
335  type_list<gs...>,
336  rep_element,
337  sub_group_size
338  > _helper;
339 
340  typedef typename _helper::type type;
341  constexpr static int global_flags = _cil::global_flags | _helper::global_flags;
342 
343  /* Note that we don't have to update global flags here, since
344  * we will only add these elements if they are not part of
345  * the group already. But that only happens if the coset rep
346  * is not already in the group, so the check for the coset rep
347  * will catch this.
348  */
349 };
350 
351 template<
352  template<typename, typename> class Multiply,
353  template<typename, typename> class Equality,
354  typename id,
355  typename sub_group_elements,
356  typename elements
357  EIGEN_TPL_PP_SPEC_HACK_DEFC(typename, empty),
358  typename rep_element,
359  int sub_group_size
360 >
361 struct 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>
362 {
363  typedef elements type;
364  constexpr static int global_flags = 0;
365 };
366 
381 template<
382  template<typename, typename> class Multiply,
383  template<typename, typename> class Equality,
384  typename id,
385  typename sub_group_elements,
386  typename elements,
387  typename generators,
388  int sub_group_size,
389  int rep_pos,
390  bool stop_condition // = false
391 >
392 struct dimino_add_all_coset_spaces
393 {
394  typedef typename get<rep_pos, elements>::type rep_element;
395  typedef dimino_add_cosets_for_rep<
396  Multiply,
397  Equality,
398  id,
399  sub_group_elements,
400  elements,
401  generators,
402  rep_element,
403  sub_group_elements::count
404  > _ac4r;
405  typedef typename _ac4r::type new_elements;
406 
407  constexpr static int new_rep_pos = rep_pos + sub_group_elements::count;
408  constexpr static bool new_stop_condition = new_rep_pos >= new_elements::count;
409 
410  typedef dimino_add_all_coset_spaces<
411  Multiply,
412  Equality,
413  id,
414  sub_group_elements,
415  new_elements,
416  generators,
417  sub_group_size,
418  new_rep_pos,
419  new_stop_condition
420  > _helper;
421 
422  typedef typename _helper::type type;
423  constexpr static int global_flags = _helper::global_flags | _ac4r::global_flags;
424 };
425 
426 template<
427  template<typename, typename> class Multiply,
428  template<typename, typename> class Equality,
429  typename id,
430  typename sub_group_elements,
431  typename elements,
432  typename generators,
433  int sub_group_size,
434  int rep_pos
435 >
436 struct dimino_add_all_coset_spaces<Multiply, Equality, id, sub_group_elements, elements, generators, sub_group_size, rep_pos, true>
437 {
438  typedef elements type;
439  constexpr static int global_flags = 0;
440 };
441 
454 template<
455  template<typename, typename> class Multiply,
456  template<typename, typename> class Equality,
457  typename id,
458  typename elements,
459  typename generators_done,
460  typename current_generator,
461  bool redundant // = false
462 >
463 struct dimino_add_generator
464 {
465  /* this template is only called if the generator is not redundant
466  * => all elements of the group multiplied with the new generator
467  * are going to be new elements of the most trivial coset space
468  */
469  typedef typename apply_op_from_right<Multiply, current_generator, elements>::type multiplied_elements;
470  typedef typename concat<elements, multiplied_elements>::type new_elements;
471 
472  constexpr static int rep_pos = elements::count;
473 
474  typedef dimino_add_all_coset_spaces<
475  Multiply,
476  Equality,
477  id,
478  elements, // elements of previous subgroup
479  new_elements,
480  typename concat<generators_done, type_list<current_generator>>::type,
481  elements::count, // size of previous subgroup
482  rep_pos,
483  false // don't stop (because rep_pos >= new_elements::count is always false at this point)
484  > _helper;
485  typedef typename _helper::type type;
486  constexpr static int global_flags = _helper::global_flags;
487 };
488 
489 template<
490  template<typename, typename> class Multiply,
491  template<typename, typename> class Equality,
492  typename id,
493  typename elements,
494  typename generators_done,
495  typename current_generator
496 >
497 struct dimino_add_generator<Multiply, Equality, id, elements, generators_done, current_generator, true>
498 {
499  // redundant case
500  typedef elements type;
501  constexpr static int global_flags = 0;
502 };
503 
516 template<
517  template<typename, typename> class Multiply,
518  template<typename, typename> class Equality,
519  typename id,
520  typename generators_done,
521  typename remaining_generators,
522  typename elements
523 >
524 struct dimino_add_remaining_generators
525 {
526  typedef typename get<0, remaining_generators>::type first_generator;
527  typedef typename skip<1, remaining_generators>::type next_generators;
528 
529  typedef contained_in_list_gf<Equality, first_generator, elements> _cil;
530 
531  typedef dimino_add_generator<
532  Multiply,
533  Equality,
534  id,
535  elements,
536  generators_done,
537  first_generator,
538  _cil::value
539  > _helper;
540 
541  typedef typename _helper::type new_elements;
542 
543  typedef dimino_add_remaining_generators<
544  Multiply,
545  Equality,
546  id,
547  typename concat<generators_done, type_list<first_generator>>::type,
548  next_generators,
549  new_elements
550  > _next_iter;
551 
552  typedef typename _next_iter::type type;
553  constexpr static int global_flags =
554  _cil::global_flags |
555  _helper::global_flags |
556  _next_iter::global_flags;
557 };
558 
559 template<
560  template<typename, typename> class Multiply,
561  template<typename, typename> class Equality,
562  typename id,
563  typename generators_done,
564  typename elements
565 >
566 struct dimino_add_remaining_generators<Multiply, Equality, id, generators_done, type_list<>, elements>
567 {
568  typedef elements type;
569  constexpr static int global_flags = 0;
570 };
571 
586 template<
587  template<typename, typename> class Multiply,
588  template<typename, typename> class Equality,
589  typename id,
590  typename generators,
591  int initial_global_flags = 0
592 >
593 struct enumerate_group_elements_noid
594 {
595  typedef dimino_first_step_elements<Multiply, Equality, id, generators> first_step;
596  typedef typename first_step::type first_step_elements;
597 
598  typedef dimino_add_remaining_generators<
599  Multiply,
600  Equality,
601  id,
602  typename first_step::generators_done,
603  typename first_step::next_generators, // remaining_generators
604  typename first_step::type // first_step elements
605  > _helper;
606 
607  typedef typename _helper::type type;
608  constexpr static int global_flags =
609  initial_global_flags |
610  first_step::global_flags |
611  _helper::global_flags;
612 };
613 
614 // in case when no generators are specified
615 template<
616  template<typename, typename> class Multiply,
617  template<typename, typename> class Equality,
618  typename id,
619  int initial_global_flags
620 >
621 struct enumerate_group_elements_noid<Multiply, Equality, id, type_list<>, initial_global_flags>
622 {
623  typedef type_list<id> type;
624  constexpr static int global_flags = initial_global_flags;
625 };
626 
644 template<
645  template<typename, typename> class Multiply,
646  template<typename, typename> class Equality,
647  typename id,
648  typename Generators_
649 >
650 struct enumerate_group_elements
651  : public enumerate_group_elements_noid<
652  Multiply,
653  Equality,
654  id,
655  typename strip_identities<Equality, id, Generators_>::type,
656  strip_identities<Equality, id, Generators_>::global_flags
657  >
658 {
659 };
660 
661 } // end namespace group_theory
662 
663 } // end namespace internal
664 
665 } // end namespace Eigen
666 
667 #endif // EIGEN_CXX11_TENSORSYMMETRY_TEMPLATEGROUPTHEORY_H
668 
669 /*
670  * kate: space-indent on; indent-width 2; mixedindent off; indent-mode cstyle;
671  */
#define EIGEN_TPL_PP_SPEC_HACK_USE(n)
#define EIGEN_TPL_PP_SPEC_HACK_DEFC(mt, n)
MatrixXd L
: TensorContractionSycl.h, provides various tensor contraction kernel for SYCL backend