// This file is part of Eigen, a lightweight C++ template library // for linear algebra. // // Copyright (C) 2013 Christian Seiler // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_CXX11_TENSORSYMMETRY_TEMPLATEGROUPTHEORY_H #define EIGEN_CXX11_TENSORSYMMETRY_TEMPLATEGROUPTHEORY_H // IWYU pragma: private #include "../InternalHeaderCheck.h" namespace Eigen { namespace internal { namespace group_theory { /** \internal * \file CXX11/src/TensorSymmetry/util/TemplateGroupTheory.h * This file contains C++ templates that implement group theory algorithms. * * The algorithms allow for a compile-time analysis of finite groups. * * Currently only Dimino's algorithm is implemented, which returns a list * of all elements in a group given a set of (possibly redundant) generators. * (One could also do that with the so-called orbital algorithm, but that * is much more expensive and usually has no advantages.) */ /********************************************************************** * "Ok kid, here is where it gets complicated." * - Amelia Pond in the "Doctor Who" episode * "The Big Bang" * * Dimino's algorithm * ================== * * The following is Dimino's algorithm in sequential form: * * Input: identity element, list of generators, equality check, * multiplication operation * Output: list of group elements * * 1. add identity element * 2. remove identities from list of generators * 3. add all powers of first generator that aren't the * identity element * 4. go through all remaining generators: * a. if generator is already in the list of elements * -> do nothing * b. otherwise * i. remember current # of elements * (i.e. the size of the current subgroup) * ii. add all current elements (which includes * the identity) each multiplied from right * with the current generator to the group * iii. add all remaining cosets that are generated * by products of the new generator with itself * and all other generators seen so far * * In functional form, this is implemented as a long set of recursive * templates that have a complicated relationship. * * The main interface for Dimino's algorithm is the template * enumerate_group_elements. All lists are implemented as variadic * type_list and numeric_list * templates. * * 'Calling' templates is usually done via typedefs. * * This algorithm is an extended version of the basic version. The * extension consists in the fact that each group element has a set * of flags associated with it. Multiplication of two group elements * with each other results in a group element whose flags are the * XOR of the flags of the previous elements. Each time the algorithm * notices that a group element it just calculated is already in the * list of current elements, the flags of both will be compared and * added to the so-called 'global flags' of the group. * * The rationale behind this extension is that this allows not only * for the description of symmetries between tensor indices, but * also allows for the description of hermiticity, antisymmetry and * antihermiticity. Negation and conjugation each are specific bit * in the flags value and if two different ways to reach a group * element lead to two different flags, this poses a constraint on * the allowed values of the resulting tensor. For example, if a * group element is reach both with and without the conjugation * flags, it is clear that the resulting tensor has to be real. * * Note that this flag mechanism is quite generic and may have other * uses beyond tensor properties. * * IMPORTANT: * This algorithm assumes the group to be finite. If you try to * run it with a group that's infinite, the algorithm will only * terminate once you hit a compiler limit (max template depth). * Also note that trying to use this implementation to create a * very large group will probably either make you hit the same * limit, cause the compiler to segfault or at the very least * take a *really* long time (hours, days, weeks - sic!) to * compile. It is not recommended to plug in more than 4 * generators, unless they are independent of each other. */ /** \internal * * \class strip_identities * \ingroup CXX11_TensorSymmetry_Module * * \brief Cleanse a list of group elements of the identity element * * This template is used to make a first pass through all initial * generators of Dimino's algorithm and remove the identity * elements. * * \sa enumerate_group_elements */ template