// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2013 Christian Seiler <christian@iwakd.de>
//
// 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/.
// SPDX-License-Identifier: MPL-2.0

#ifndef EIGEN_TENSORSYMMETRY_SYMMETRY_H
#define EIGEN_TENSORSYMMETRY_SYMMETRY_H

// IWYU pragma: private
#include "./InternalHeaderCheck.h"

namespace Eigen {

enum { NegationFlag = 0x01, ConjugationFlag = 0x02 };

enum { GlobalRealFlag = 0x01, GlobalImagFlag = 0x02, GlobalZeroFlag = 0x03 };

namespace internal {

template <std::size_t NumIndices, typename... Sym>
struct tensor_symmetry_pre_analysis;
template <std::size_t NumIndices, typename... Sym>
struct tensor_static_symgroup;
template <bool instantiate, std::size_t NumIndices, typename... Sym>
struct tensor_static_symgroup_if;
template <typename Tensor_>
struct tensor_symmetry_calculate_flags;
template <typename Tensor_>
struct tensor_symmetry_assign_value;
template <typename... Sym>
struct tensor_symmetry_num_indices;

}  // end namespace internal

template <int One_, int Two_>
struct Symmetry {
  static_assert(One_ != Two_, "Symmetries must cover distinct indices.");
  constexpr static int One = One_;
  constexpr static int Two = Two_;
  constexpr static int Flags = 0;
};

template <int One_, int Two_>
struct AntiSymmetry {
  static_assert(One_ != Two_, "Symmetries must cover distinct indices.");
  constexpr static int One = One_;
  constexpr static int Two = Two_;
  constexpr static int Flags = NegationFlag;
};

template <int One_, int Two_>
struct Hermiticity {
  static_assert(One_ != Two_, "Symmetries must cover distinct indices.");
  constexpr static int One = One_;
  constexpr static int Two = Two_;
  constexpr static int Flags = ConjugationFlag;
};

template <int One_, int Two_>
struct AntiHermiticity {
  static_assert(One_ != Two_, "Symmetries must cover distinct indices.");
  constexpr static int One = One_;
  constexpr static int Two = Two_;
  constexpr static int Flags = ConjugationFlag | NegationFlag;
};

/** \class DynamicSGroup
 * \ingroup TensorSymmetry_Module
 *
 * \brief 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 definable
 * 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.
 */
class DynamicSGroup;

/** \internal
 *
 * \class DynamicSGroupFromTemplateArgs
 * \ingroup TensorSymmetry_Module
 *
 * \brief Dynamic symmetry group, initialized from template arguments
 *
 * This class is a child class of DynamicSGroup. It uses the template arguments
 * specified to initialize itself.
 */
template <typename... Gen>
class DynamicSGroupFromTemplateArgs;

/** \class StaticSGroup
 * \ingroup TensorSymmetry_Module
 *
 * \brief Static symmetry group
 *
 * This class represents a symmetry group that is known and resolved completely
 * at compile time. Ideally, no run-time penalty is incurred compared to the
 * manual unrolling of the symmetry.
 *
 * <b><i>CAUTION:</i></b>
 *
 * Do not use this class directly for large symmetry groups. The compiler
 * may run into a limit, or segfault or in the very least will take a very,
 * very, very long time to compile the code. Use the SGroup class instead
 * if you want a static group. That class contains logic that will
 * automatically select the DynamicSGroup class instead if the symmetry
 * group becomes too large. (In that case, unrolling may not even be
 * beneficial.)
 */
template <typename... Gen>
class StaticSGroup;

/** \class SGroup
 * \ingroup TensorSymmetry_Module
 *
 * \brief Symmetry group, initialized from template arguments
 *
 * This class represents a symmetry group whose generators are already
 * known at compile time. It may or may not be resolved at compile time,
 * depending on the estimated size of the group.
 *
 * \sa StaticSGroup
 * \sa DynamicSGroup
 */
template <typename... Gen>
class SGroup : public internal::tensor_symmetry_pre_analysis<internal::tensor_symmetry_num_indices<Gen...>::value,
                                                             Gen...>::root_type {
 public:
  constexpr static std::size_t NumIndices = internal::tensor_symmetry_num_indices<Gen...>::value;
  typedef typename internal::tensor_symmetry_pre_analysis<NumIndices, Gen...>::root_type Base;

  // make standard constructors + assignment operators public
  inline SGroup() = default;
  inline SGroup(const SGroup<Gen...>& other) = default;
  inline SGroup(SGroup<Gen...>&& other) : Base(other) {}
  inline SGroup<Gen...>& operator=(const SGroup<Gen...>& other) {
    Base::operator=(other);
    return *this;
  }
  inline SGroup<Gen...>& operator=(SGroup<Gen...>&& other) {
    Base::operator=(other);
    return *this;
  }

  // all else is defined in the base class
};

namespace internal {

template <typename... Sym>
struct tensor_symmetry_num_indices {
  constexpr static std::size_t value = 1;
};

template <int One_, int Two_, typename... Sym>
struct tensor_symmetry_num_indices<Symmetry<One_, Two_>, Sym...> {
 private:
  constexpr static std::size_t One = static_cast<std::size_t>(One_);
  constexpr static std::size_t Two = static_cast<std::size_t>(Two_);
  constexpr static std::size_t Three = tensor_symmetry_num_indices<Sym...>::value;

  constexpr static std::size_t maxOneTwoPlusOne = ((One > Two) ? One : Two) + 1;

 public:
  constexpr static std::size_t value = (maxOneTwoPlusOne > Three) ? maxOneTwoPlusOne : Three;
};

template <int One_, int Two_, typename... Sym>
struct tensor_symmetry_num_indices<AntiSymmetry<One_, Two_>, Sym...>
    : public tensor_symmetry_num_indices<Symmetry<One_, Two_>, Sym...> {};
template <int One_, int Two_, typename... Sym>
struct tensor_symmetry_num_indices<Hermiticity<One_, Two_>, Sym...>
    : public tensor_symmetry_num_indices<Symmetry<One_, Two_>, Sym...> {};
template <int One_, int Two_, typename... Sym>
struct tensor_symmetry_num_indices<AntiHermiticity<One_, Two_>, Sym...>
    : public tensor_symmetry_num_indices<Symmetry<One_, Two_>, Sym...> {};

/** \internal
 *
 * \class tensor_symmetry_pre_analysis
 * \ingroup TensorSymmetry_Module
 *
 * \brief Pre-select whether to use a static or dynamic symmetry group
 *
 * When a symmetry group could in principle be determined at compile time,
 * this template implements the logic whether to actually do that or whether
 * to rather defer that to runtime.
 *
 * The logic is as follows:
 * <dl>
 * <dt><b>No generators (trivial symmetry):</b></dt>
 * <dd>Use a trivial static group. Ideally, this has no performance impact
 *     compared to not using symmetry at all. In practice, this might not
 *     be the case.</dd>
 * <dt><b>More than 4 generators:</b></dt>
 * <dd>Calculate the group at run time, it is likely far too large for the
 *     compiler to be able to properly generate it in a realistic time.</dd>
 * <dt><b>Up to and including 4 generators:</b></dt>
 * <dd>Actually enumerate all group elements, but then check how many there
 *     are. If there are more than 16, it is unlikely that unrolling the
 *     loop (as is done in the static compile-time case) is sensible, so
 *     use a dynamic group instead. If there are at most 16 elements, actually
 *     use that static group. Note that the largest group with 4 generators
 *     still compiles with reasonable resources.</dd>
 * </dl>
 *
 * Note: Example compile time performance with g++-4.6 on an Intel Core i5-3470
 *       with 16 GiB RAM (all generators non-redundant and the subgroups don't
 *       factorize):
 *
 *          # Generators          -O0 -ggdb               -O2
 *          -------------------------------------------------------------------
 *          1                 0.5 s  /   250 MiB     0.45s /   230 MiB
 *          2                 0.5 s  /   260 MiB     0.5 s /   250 MiB
 *          3                 0.65s  /   310 MiB     0.62s /   310 MiB
 *          4                 2.2 s  /   860 MiB     1.7 s /   770 MiB
 *          5               130   s  / 13000 MiB   120   s / 11000 MiB
 *
 * It is clear that everything is still very efficient up to 4 generators, then
 * the memory and CPU requirements become unreasonable. Thus we only instantiate
 * the template group theory logic if the number of generators supplied is 4 or
 * lower, otherwise this will be forced to be done during runtime, where the
 * algorithm is reasonably fast.
 */
template <std::size_t NumIndices>
struct tensor_symmetry_pre_analysis<NumIndices> {
  typedef StaticSGroup<> root_type;
};

template <std::size_t NumIndices, typename Gen_, typename... Gens_>
struct tensor_symmetry_pre_analysis<NumIndices, Gen_, Gens_...> {
  constexpr static std::size_t max_static_generators = 4;
  constexpr static std::size_t max_static_elements = 16;
  typedef tensor_static_symgroup_if<(sizeof...(Gens_) + 1 <= max_static_generators), NumIndices, Gen_, Gens_...> helper;
  constexpr static std::size_t possible_size = helper::size;

  typedef std::conditional_t<possible_size == 0 || possible_size >= max_static_elements,
                             DynamicSGroupFromTemplateArgs<Gen_, Gens_...>, typename helper::type>
      root_type;
};

template <bool instantiate, std::size_t NumIndices, typename... Gens>
struct tensor_static_symgroup_if {
  constexpr static std::size_t size = 0;
  typedef void type;
};

template <std::size_t NumIndices, typename... Gens>
struct tensor_static_symgroup_if<true, NumIndices, Gens...> : tensor_static_symgroup<NumIndices, Gens...> {};

template <typename Tensor_>
struct tensor_symmetry_assign_value {
  typedef typename Tensor_::Index Index;
  typedef typename Tensor_::Scalar Scalar;
  constexpr static std::size_t NumIndices = Tensor_::NumIndices;

  static inline int run(const std::array<Index, NumIndices>& transformed_indices, int transformation_flags, int dummy,
                        Tensor_& tensor, const Scalar& value_) {
    Scalar value(value_);
    if (transformation_flags & ConjugationFlag) value = numext::conj(value);
    if (transformation_flags & NegationFlag) value = -value;
    tensor.coeffRef(transformed_indices) = value;
    return dummy;
  }
};

template <typename Tensor_>
struct tensor_symmetry_calculate_flags {
  typedef typename Tensor_::Index Index;
  constexpr static std::size_t NumIndices = Tensor_::NumIndices;

  static inline int run(const std::array<Index, NumIndices>& transformed_indices, int transform_flags,
                        int current_flags, const std::array<Index, NumIndices>& orig_indices) {
    if (transformed_indices == orig_indices) {
      if (transform_flags & (ConjugationFlag | NegationFlag))
        return current_flags | GlobalImagFlag;  // anti-hermitian diagonal
      else if (transform_flags & ConjugationFlag)
        return current_flags | GlobalRealFlag;  // hermitian diagonal
      else if (transform_flags & NegationFlag)
        return current_flags | GlobalZeroFlag;  // anti-symmetric diagonal
    }
    return current_flags;
  }
};

template <typename Tensor_, typename Symmetry_, int Flags = 0>
class tensor_symmetry_value_setter {
 public:
  typedef typename Tensor_::Index Index;
  typedef typename Tensor_::Scalar Scalar;
  constexpr static std::size_t NumIndices = Tensor_::NumIndices;

  inline tensor_symmetry_value_setter(Tensor_& tensor, Symmetry_ const& symmetry,
                                      std::array<Index, NumIndices> const& indices)
      : m_tensor(tensor), m_symmetry(symmetry), m_indices(indices) {}

  inline tensor_symmetry_value_setter<Tensor_, Symmetry_, Flags>& operator=(Scalar const& value) {
    doAssign(value);
    return *this;
  }

 private:
  Tensor_& m_tensor;
  Symmetry_ m_symmetry;
  std::array<Index, NumIndices> m_indices;

  inline void doAssign(Scalar const& value) {
#ifdef EIGEN_TENSOR_SYMMETRY_CHECK_VALUES
    int value_flags = m_symmetry.template apply<internal::tensor_symmetry_calculate_flags<Tensor_>, int>(
        m_indices, m_symmetry.globalFlags(), m_indices);
    if (value_flags & GlobalRealFlag) eigen_assert(numext::imag(value) == 0);
    if (value_flags & GlobalImagFlag) eigen_assert(numext::real(value) == 0);
#endif
    m_symmetry.template apply<internal::tensor_symmetry_assign_value<Tensor_>, int>(m_indices, 0, m_tensor, value);
  }
};

}  // end namespace internal

}  // end namespace Eigen

#endif  // EIGEN_TENSORSYMMETRY_SYMMETRY_H

/*
 * kate: space-indent on; indent-width 2; mixedindent off; indent-mode cstyle;
 */
