// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2012, 2013 Chen-Pang He <jdh8@ms63.hinet.net>
//
// 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_MATRIX_POWER
#define EIGEN_MATRIX_POWER

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

namespace Eigen {

template <typename MatrixType>
class MatrixPower;

/**
 * \ingroup MatrixFunctions_Module
 *
 * \brief Proxy for the matrix power of some matrix.
 *
 * \tparam MatrixType  type of the base, a matrix.
 *
 * This class holds the arguments to the matrix power until it is
 * assigned or evaluated for some other reason (so the argument
 * should not be changed in the meantime). It is the return type of
 * MatrixPower::operator() and related functions and most of the
 * time this is the only way it is used.
 */
/* TODO This class is only used by MatrixPower, so it should be nested
 * into MatrixPower, like MatrixPower::ReturnValue. However, my
 * compiler complained about unused template parameter in the
 * following declaration in namespace internal.
 *
 * template<typename MatrixType>
 * struct traits<MatrixPower<MatrixType>::ReturnValue>;
 */
template <typename MatrixType>
class MatrixPowerParenthesesReturnValue : public ReturnByValue<MatrixPowerParenthesesReturnValue<MatrixType> > {
 public:
  typedef typename MatrixType::RealScalar RealScalar;

  /**
   * \brief Constructor.
   *
   * \param[in] pow  %MatrixPower storing the base.
   * \param[in] p    scalar, the exponent of the matrix power.
   */
  MatrixPowerParenthesesReturnValue(MatrixPower<MatrixType>& pow, RealScalar p) : m_pow(pow), m_p(p) {}

  /**
   * \brief Compute the matrix power.
   *
   * \param[out] result
   */
  template <typename ResultType>
  inline void evalTo(ResultType& result) const {
    m_pow.compute(result, m_p);
  }

  Index rows() const { return m_pow.rows(); }
  Index cols() const { return m_pow.cols(); }

 private:
  MatrixPower<MatrixType>& m_pow;
  const RealScalar m_p;
};

/**
 * \ingroup MatrixFunctions_Module
 *
 * \brief Class for computing matrix powers.
 *
 * \tparam MatrixType  type of the base, expected to be an instantiation
 * of the Matrix class template.
 *
 * This class is capable of computing triangular real/complex matrices
 * raised to a power in the interval \f$ (-1, 1) \f$.
 *
 * \note Currently this class is only used by MatrixPower. One may
 * insist that this be nested into MatrixPower. This class is here to
 * facilitate future development of triangular matrix functions.
 */
template <typename MatrixType>
class MatrixPowerAtomic : internal::noncopyable {
 private:
  enum { RowsAtCompileTime = MatrixType::RowsAtCompileTime, MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime };
  typedef typename MatrixType::Scalar Scalar;
  typedef typename MatrixType::RealScalar RealScalar;
  typedef internal::make_complex_t<Scalar> ComplexScalar;
  typedef Block<MatrixType, Dynamic, Dynamic> ResultType;

  const MatrixType& m_A;
  RealScalar m_p;

  void computePade(int degree, const MatrixType& IminusT, ResultType& res) const;
  void compute2x2(ResultType& res, RealScalar p) const;
  void computeBig(ResultType& res) const;
  static int getPadeDegree(float normIminusT);
  static int getPadeDegree(double normIminusT);
  static int getPadeDegree(long double normIminusT);
  static ComplexScalar computeSuperDiag(const ComplexScalar&, const ComplexScalar&, RealScalar p);
  static RealScalar computeSuperDiag(RealScalar, RealScalar, RealScalar p);

 public:
  /**
   * \brief Constructor.
   *
   * \param[in] T  the base of the matrix power.
   * \param[in] p  the exponent of the matrix power, should be in
   * \f$ (-1, 1) \f$.
   *
   * The class stores a reference to T, so it should not be changed
   * (or destroyed) before evaluation. Only the upper triangular
   * part of T is read.
   */
  MatrixPowerAtomic(const MatrixType& T, RealScalar p);

  /**
   * \brief Compute the matrix power.
   *
   * \param[out] res  \f$ A^p \f$ where A and p are specified in the
   * constructor.
   */
  void compute(ResultType& res) const;
};

template <typename MatrixType>
MatrixPowerAtomic<MatrixType>::MatrixPowerAtomic(const MatrixType& T, RealScalar p) : m_A(T), m_p(p) {
  eigen_assert(T.rows() == T.cols());
  eigen_assert(p > -1 && p < 1);
}

template <typename MatrixType>
void MatrixPowerAtomic<MatrixType>::compute(ResultType& res) const {
  using std::pow;
  switch (m_A.rows()) {
    case 0:
      break;
    case 1:
      res(0, 0) = pow(m_A(0, 0), m_p);
      break;
    case 2:
      compute2x2(res, m_p);
      break;
    default:
      computeBig(res);
  }
}

template <typename MatrixType>
void MatrixPowerAtomic<MatrixType>::computePade(int degree, const MatrixType& IminusT, ResultType& res) const {
  int i = 2 * degree;
  res = (m_p - RealScalar(degree)) / RealScalar(2 * i - 2) * IminusT;

  for (--i; i; --i) {
    res = (MatrixType::Identity(IminusT.rows(), IminusT.cols()) + res)
              .template triangularView<Upper>()
              .solve((i == 1  ? -m_p
                      : i & 1 ? (-m_p - RealScalar(i / 2)) / RealScalar(2 * i)
                              : (m_p - RealScalar(i / 2)) / RealScalar(2 * i - 2)) *
                     IminusT)
              .eval();
  }
  res += MatrixType::Identity(IminusT.rows(), IminusT.cols());
}

// This function assumes that res has the correct size (see bug 614)
template <typename MatrixType>
void MatrixPowerAtomic<MatrixType>::compute2x2(ResultType& res, RealScalar p) const {
  using std::abs;
  using std::pow;
  res.coeffRef(0, 0) = pow(m_A.coeff(0, 0), p);

  for (Index i = 1; i < m_A.cols(); ++i) {
    res.coeffRef(i, i) = pow(m_A.coeff(i, i), p);
    if (m_A.coeff(i - 1, i - 1) == m_A.coeff(i, i))
      res.coeffRef(i - 1, i) = p * pow(m_A.coeff(i, i), p - 1);
    else if (2 * abs(m_A.coeff(i - 1, i - 1)) < abs(m_A.coeff(i, i)) ||
             2 * abs(m_A.coeff(i, i)) < abs(m_A.coeff(i - 1, i - 1)))
      res.coeffRef(i - 1, i) =
          (res.coeff(i, i) - res.coeff(i - 1, i - 1)) / (m_A.coeff(i, i) - m_A.coeff(i - 1, i - 1));
    else
      res.coeffRef(i - 1, i) = computeSuperDiag(m_A.coeff(i, i), m_A.coeff(i - 1, i - 1), p);
    res.coeffRef(i - 1, i) *= m_A.coeff(i - 1, i);
  }
}

template <typename MatrixType>
void MatrixPowerAtomic<MatrixType>::computeBig(ResultType& res) const {
  using std::ldexp;
  const int digits = std::numeric_limits<RealScalar>::digits;
  const RealScalar maxNormForPade =
      RealScalar(digits <= 24    ? 4.3386528e-1L                              // single precision
                 : digits <= 53  ? 2.789358995219730e-1L                      // double precision
                 : digits <= 64  ? 2.4471944416607995472e-1L                  // extended precision
                 : digits <= 106 ? 1.1016843812851143391275867258512e-1L      // double-double
                                 : 9.134603732914548552537150753385375e-2L);  // quadruple precision
  MatrixType IminusT, sqrtT, T = m_A.template triangularView<Upper>();
  RealScalar normIminusT;
  int degree, degree2, numberOfSquareRoots = 0;
  bool hasExtraSquareRoot = false;

  for (Index i = 0; i < m_A.cols(); ++i) eigen_assert(m_A(i, i) != RealScalar(0));

  while (true) {
    IminusT = MatrixType::Identity(m_A.rows(), m_A.cols()) - T;
    normIminusT = IminusT.cwiseAbs().colwise().sum().maxCoeff();
    if (normIminusT < maxNormForPade) {
      degree = getPadeDegree(normIminusT);
      degree2 = getPadeDegree(normIminusT / 2);
      if (degree - degree2 <= 1 || hasExtraSquareRoot) break;
      hasExtraSquareRoot = true;
    }
    matrix_sqrt_triangular(T, sqrtT);
    T = sqrtT.template triangularView<Upper>();
    ++numberOfSquareRoots;
  }
  computePade(degree, IminusT, res);

  for (; numberOfSquareRoots; --numberOfSquareRoots) {
    compute2x2(res, ldexp(m_p, -numberOfSquareRoots));
    res = res.template triangularView<Upper>() * res;
  }
  compute2x2(res, m_p);
}

template <typename MatrixType>
inline int MatrixPowerAtomic<MatrixType>::getPadeDegree(float normIminusT) {
  const float maxNormForPade[] = {2.8064004e-1f /* degree = 3 */, 4.3386528e-1f};
  int degree = 3;
  for (; degree <= 4; ++degree)
    if (normIminusT <= maxNormForPade[degree - 3]) break;
  return degree;
}

template <typename MatrixType>
inline int MatrixPowerAtomic<MatrixType>::getPadeDegree(double normIminusT) {
  const double maxNormForPade[] = {1.884160592658218e-2 /* degree = 3 */, 6.038881904059573e-2, 1.239917516308172e-1,
                                   1.999045567181744e-1, 2.789358995219730e-1};
  int degree = 3;
  for (; degree <= 7; ++degree)
    if (normIminusT <= maxNormForPade[degree - 3]) break;
  return degree;
}

template <typename MatrixType>
inline int MatrixPowerAtomic<MatrixType>::getPadeDegree(long double normIminusT) {
#if LDBL_MANT_DIG == 53
  const int maxPadeDegree = 7;
  const double maxNormForPade[] = {1.884160592658218e-2L /* degree = 3 */, 6.038881904059573e-2L, 1.239917516308172e-1L,
                                   1.999045567181744e-1L, 2.789358995219730e-1L};
#elif LDBL_MANT_DIG <= 64
  const int maxPadeDegree = 8;
  const long double maxNormForPade[] = {6.3854693117491799460e-3L /* degree = 3 */,
                                        2.6394893435456973676e-2L,
                                        6.4216043030404063729e-2L,
                                        1.1701165502926694307e-1L,
                                        1.7904284231268670284e-1L,
                                        2.4471944416607995472e-1L};
#elif LDBL_MANT_DIG <= 106
  const int maxPadeDegree = 10;
  const double maxNormForPade[] = {1.0007161601787493236741409687186e-4L /* degree = 3 */,
                                   1.0007161601787493236741409687186e-3L,
                                   4.7069769360887572939882574746264e-3L,
                                   1.3220386624169159689406653101695e-2L,
                                   2.8063482381631737920612944054906e-2L,
                                   4.9625993951953473052385361085058e-2L,
                                   7.7367040706027886224557538328171e-2L,
                                   1.1016843812851143391275867258512e-1L};
#else
  const int maxPadeDegree = 10;
  const double maxNormForPade[] = {5.524506147036624377378713555116378e-5L /* degree = 3 */,
                                   6.640600568157479679823602193345995e-4L,
                                   3.227716520106894279249709728084626e-3L,
                                   9.619593944683432960546978734646284e-3L,
                                   2.134595382433742403911124458161147e-2L,
                                   3.908166513900489428442993794761185e-2L,
                                   6.266780814639442865832535460550138e-2L,
                                   9.134603732914548552537150753385375e-2L};
#endif
  int degree = 3;
  for (; degree <= maxPadeDegree; ++degree)
    if (normIminusT <= static_cast<long double>(maxNormForPade[degree - 3])) break;
  return degree;
}

template <typename MatrixType>
inline typename MatrixPowerAtomic<MatrixType>::ComplexScalar MatrixPowerAtomic<MatrixType>::computeSuperDiag(
    const ComplexScalar& curr, const ComplexScalar& prev, RealScalar p) {
  using std::ceil;
  using std::exp;
  using std::log;
  using std::sinh;

  ComplexScalar logCurr = log(curr);
  ComplexScalar logPrev = log(prev);
  RealScalar unwindingNumber =
      ceil((numext::imag(logCurr - logPrev) - RealScalar(EIGEN_PI)) / RealScalar(2 * EIGEN_PI));
  ComplexScalar w =
      numext::log1p((curr - prev) / prev) / RealScalar(2) + ComplexScalar(0, RealScalar(EIGEN_PI) * unwindingNumber);
  return RealScalar(2) * exp(RealScalar(0.5) * p * (logCurr + logPrev)) * sinh(p * w) / (curr - prev);
}

template <typename MatrixType>
inline typename MatrixPowerAtomic<MatrixType>::RealScalar MatrixPowerAtomic<MatrixType>::computeSuperDiag(
    RealScalar curr, RealScalar prev, RealScalar p) {
  using std::exp;
  using std::log;
  using std::sinh;

  RealScalar w = numext::log1p((curr - prev) / prev) / RealScalar(2);
  return 2 * exp(p * (log(curr) + log(prev)) / 2) * sinh(p * w) / (curr - prev);
}

/**
 * \ingroup MatrixFunctions_Module
 *
 * \brief Class for computing matrix powers.
 *
 * \tparam MatrixType  type of the base, expected to be an instantiation
 * of the Matrix class template.
 *
 * This class is capable of computing real/complex matrices raised to
 * an arbitrary real power. Meanwhile, it saves the result of Schur
 * decomposition if an non-integral power has even been calculated.
 * Therefore, if you want to compute multiple (>= 2) matrix powers
 * for the same matrix, using the class directly is more efficient than
 * calling MatrixBase::pow().
 *
 * Example:
 * \include MatrixPower_optimal.cpp
 * Output: \verbinclude MatrixPower_optimal.out
 */
template <typename MatrixType>
class MatrixPower : internal::noncopyable {
 private:
  typedef typename MatrixType::Scalar Scalar;
  typedef typename MatrixType::RealScalar RealScalar;

 public:
  /**
   * \brief Constructor.
   *
   * \param[in] A  the base of the matrix power.
   *
   * The class stores a reference to A, so it should not be changed
   * (or destroyed) before evaluation.
   */
  explicit MatrixPower(const MatrixType& A) : m_A(A), m_conditionNumber(0), m_rank(A.cols()), m_nulls(0) {
    eigen_assert(A.rows() == A.cols());
  }

  /**
   * \brief Returns the matrix power.
   *
   * \param[in] p  exponent, a real scalar.
   * \return The expression \f$ A^p \f$, where A is specified in the
   * constructor.
   */
  const MatrixPowerParenthesesReturnValue<MatrixType> operator()(RealScalar p) {
    return MatrixPowerParenthesesReturnValue<MatrixType>(*this, p);
  }

  /**
   * \brief Compute the matrix power.
   *
   * \param[in]  p    exponent, a real scalar.
   * \param[out] res  \f$ A^p \f$ where A is specified in the
   * constructor.
   */
  template <typename ResultType>
  void compute(ResultType& res, RealScalar p);

  Index rows() const { return m_A.rows(); }
  Index cols() const { return m_A.cols(); }

 private:
  typedef internal::make_complex_t<Scalar> ComplexScalar;
  typedef Matrix<ComplexScalar, Dynamic, Dynamic, 0, MatrixType::RowsAtCompileTime, MatrixType::ColsAtCompileTime>
      ComplexMatrix;

  /** \brief Reference to the base of matrix power. */
  typename MatrixType::Nested m_A;

  /** \brief Temporary storage. */
  MatrixType m_tmp;

  /** \brief Store the result of Schur decomposition. */
  ComplexMatrix m_T, m_U;

  /** \brief Store fractional power of m_T. */
  ComplexMatrix m_fT;

  /**
   * \brief Condition number of m_A.
   *
   * It is initialized as 0 to avoid performing unnecessary Schur
   * decomposition, which is the bottleneck.
   */
  RealScalar m_conditionNumber;

  /** \brief Rank of m_A. */
  Index m_rank;

  /** \brief Rank deficiency of m_A. */
  Index m_nulls;

  /**
   * \brief Split p into integral part and fractional part.
   *
   * \param[in]  p        The exponent.
   * \param[out] p        The fractional part ranging in \f$ (-1, 1) \f$.
   * \param[out] intpart  The integral part.
   *
   * Only if the fractional part is nonzero, it calls initialize().
   */
  void split(RealScalar& p, RealScalar& intpart);

  /** \brief Perform Schur decomposition for fractional power. */
  void initialize();

  template <typename ResultType>
  void computeIntPower(ResultType& res, RealScalar p);

  template <typename ResultType>
  void computeFracPower(ResultType& res, RealScalar p);

  template <int Rows, int Cols, int Options, int MaxRows, int MaxCols>
  static void revertSchur(Matrix<ComplexScalar, Rows, Cols, Options, MaxRows, MaxCols>& res, const ComplexMatrix& T,
                          const ComplexMatrix& U);

  template <int Rows, int Cols, int Options, int MaxRows, int MaxCols>
  static void revertSchur(Matrix<RealScalar, Rows, Cols, Options, MaxRows, MaxCols>& res, const ComplexMatrix& T,
                          const ComplexMatrix& U);
};

template <typename MatrixType>
template <typename ResultType>
void MatrixPower<MatrixType>::compute(ResultType& res, RealScalar p) {
  using std::pow;
  switch (cols()) {
    case 0:
      break;
    case 1:
      res(0, 0) = pow(m_A.coeff(0, 0), p);
      break;
    default:
      RealScalar intpart;
      split(p, intpart);

      res = MatrixType::Identity(rows(), cols());
      computeIntPower(res, intpart);
      if (p) computeFracPower(res, p);
  }
}

template <typename MatrixType>
void MatrixPower<MatrixType>::split(RealScalar& p, RealScalar& intpart) {
  using std::floor;
  using std::pow;

  intpart = floor(p);
  p -= intpart;

  // Perform Schur decomposition if it is not yet performed and the power is
  // not an integer.
  if (!m_conditionNumber && p) initialize();

  // Choose the more stable of intpart = floor(p) and intpart = ceil(p).
  if (p > RealScalar(0.5) && p > (1 - p) * pow(m_conditionNumber, p)) {
    --p;
    ++intpart;
  }
}

template <typename MatrixType>
void MatrixPower<MatrixType>::initialize() {
  const ComplexSchur<MatrixType> schurOfA(m_A);
  JacobiRotation<ComplexScalar> rot;
  ComplexScalar eigenvalue;

  m_fT.resizeLike(m_A);
  m_T = schurOfA.matrixT();
  m_U = schurOfA.matrixU();
  m_conditionNumber = m_T.diagonal().array().abs().maxCoeff() / m_T.diagonal().array().abs().minCoeff();

  // Move zero eigenvalues to the bottom right corner.
  for (Index i = cols() - 1; i >= 0; --i) {
    if (m_rank <= 2) return;
    if (m_T.coeff(i, i) == RealScalar(0)) {
      for (Index j = i + 1; j < m_rank; ++j) {
        eigenvalue = m_T.coeff(j, j);
        rot.makeGivens(m_T.coeff(j - 1, j), eigenvalue);
        m_T.applyOnTheRight(j - 1, j, rot);
        m_T.applyOnTheLeft(j - 1, j, rot.adjoint());
        m_T.coeffRef(j - 1, j - 1) = eigenvalue;
        m_T.coeffRef(j, j) = RealScalar(0);
        m_U.applyOnTheRight(j - 1, j, rot);
      }
      --m_rank;
    }
  }

  m_nulls = rows() - m_rank;
  if (m_nulls) {
    eigen_assert(m_T.bottomRightCorner(m_nulls, m_nulls).isZero() &&
                 "Base of matrix power should be invertible or with a semisimple zero eigenvalue.");
    m_fT.bottomRows(m_nulls).fill(RealScalar(0));
  }
}

template <typename MatrixType>
template <typename ResultType>
void MatrixPower<MatrixType>::computeIntPower(ResultType& res, RealScalar p) {
  using std::abs;
  using std::fmod;
  RealScalar pp = abs(p);

  if (p < 0)
    m_tmp = m_A.inverse();
  else
    m_tmp = m_A;

  while (true) {
    if (fmod(pp, 2) >= 1) res = m_tmp * res;
    pp /= 2;
    if (pp < 1) break;
    m_tmp *= m_tmp;
  }
}

template <typename MatrixType>
template <typename ResultType>
void MatrixPower<MatrixType>::computeFracPower(ResultType& res, RealScalar p) {
  Block<ComplexMatrix, Dynamic, Dynamic> blockTp(m_fT, 0, 0, m_rank, m_rank);
  eigen_assert(m_conditionNumber);
  eigen_assert(m_rank + m_nulls == rows());

  MatrixPowerAtomic<ComplexMatrix>(m_T.topLeftCorner(m_rank, m_rank), p).compute(blockTp);
  if (m_nulls) {
    m_fT.topRightCorner(m_rank, m_nulls) = m_T.topLeftCorner(m_rank, m_rank)
                                               .template triangularView<Upper>()
                                               .solve(blockTp * m_T.topRightCorner(m_rank, m_nulls));
  }
  revertSchur(m_tmp, m_fT, m_U);
  res = m_tmp * res;
}

template <typename MatrixType>
template <int Rows, int Cols, int Options, int MaxRows, int MaxCols>
inline void MatrixPower<MatrixType>::revertSchur(Matrix<ComplexScalar, Rows, Cols, Options, MaxRows, MaxCols>& res,
                                                 const ComplexMatrix& T, const ComplexMatrix& U) {
  res.noalias() = U * (T.template triangularView<Upper>() * U.adjoint());
}

template <typename MatrixType>
template <int Rows, int Cols, int Options, int MaxRows, int MaxCols>
inline void MatrixPower<MatrixType>::revertSchur(Matrix<RealScalar, Rows, Cols, Options, MaxRows, MaxCols>& res,
                                                 const ComplexMatrix& T, const ComplexMatrix& U) {
  res.noalias() = (U * (T.template triangularView<Upper>() * U.adjoint())).real();
}

/**
 * \ingroup MatrixFunctions_Module
 *
 * \brief Proxy for the matrix power of some matrix (expression).
 *
 * \tparam Derived  type of the base, a matrix (expression).
 *
 * This class holds the arguments to the matrix power until it is
 * assigned or evaluated for some other reason (so the argument
 * should not be changed in the meantime). It is the return type of
 * MatrixBase::pow() and related functions and most of the
 * time this is the only way it is used.
 */
template <typename Derived>
class MatrixPowerReturnValue : public ReturnByValue<MatrixPowerReturnValue<Derived> > {
 public:
  typedef typename Derived::PlainObject PlainObject;
  typedef typename Derived::RealScalar RealScalar;

  /**
   * \brief Constructor.
   *
   * \param[in] A  %Matrix (expression), the base of the matrix power.
   * \param[in] p  real scalar, the exponent of the matrix power.
   */
  MatrixPowerReturnValue(const Derived& A, RealScalar p) : m_A(A), m_p(p) {}

  /**
   * \brief Compute the matrix power.
   *
   * \param[out] result  \f$ A^p \f$ where \p A and \p p are as in the
   * constructor.
   */
  template <typename ResultType>
  inline void evalTo(ResultType& result) const {
    MatrixPower<PlainObject>(m_A.eval()).compute(result, m_p);
  }

  Index rows() const { return m_A.rows(); }
  Index cols() const { return m_A.cols(); }

 private:
  const Derived& m_A;
  const RealScalar m_p;
};

/**
 * \ingroup MatrixFunctions_Module
 *
 * \brief Proxy for the matrix power of some matrix (expression).
 *
 * \tparam Derived  type of the base, a matrix (expression).
 *
 * This class holds the arguments to the matrix power until it is
 * assigned or evaluated for some other reason (so the argument
 * should not be changed in the meantime). It is the return type of
 * MatrixBase::pow() and related functions and most of the
 * time this is the only way it is used.
 */
template <typename Derived>
class MatrixComplexPowerReturnValue : public ReturnByValue<MatrixComplexPowerReturnValue<Derived> > {
 public:
  typedef typename Derived::PlainObject PlainObject;
  typedef internal::make_complex_t<typename Derived::Scalar> ComplexScalar;

  /**
   * \brief Constructor.
   *
   * \param[in] A  %Matrix (expression), the base of the matrix power.
   * \param[in] p  complex scalar, the exponent of the matrix power.
   */
  MatrixComplexPowerReturnValue(const Derived& A, const ComplexScalar& p) : m_A(A), m_p(p) {}

  /**
   * \brief Compute the matrix power.
   *
   * Because \p p is complex, \f$ A^p \f$ is simply evaluated as \f$
   * \exp(p \log(A)) \f$.
   *
   * \param[out] result  \f$ A^p \f$ where \p A and \p p are as in the
   * constructor.
   */
  template <typename ResultType>
  inline void evalTo(ResultType& result) const {
    result = (m_p * m_A.log()).exp();
  }

  Index rows() const { return m_A.rows(); }
  Index cols() const { return m_A.cols(); }

 private:
  const Derived& m_A;
  const ComplexScalar m_p;
};

namespace internal {

template <typename MatrixPowerType>
struct traits<MatrixPowerParenthesesReturnValue<MatrixPowerType> > {
  typedef typename MatrixPowerType::PlainObject ReturnType;
};

template <typename Derived>
struct traits<MatrixPowerReturnValue<Derived> > {
  typedef typename Derived::PlainObject ReturnType;
};

template <typename Derived>
struct traits<MatrixComplexPowerReturnValue<Derived> > {
  typedef typename Derived::PlainObject ReturnType;
};

}  // namespace internal

template <typename Derived>
const MatrixPowerReturnValue<Derived> MatrixBase<Derived>::pow(const RealScalar& p) const {
  return MatrixPowerReturnValue<Derived>(derived(), p);
}

template <typename Derived>
const MatrixComplexPowerReturnValue<Derived> MatrixBase<Derived>::pow(const internal::make_complex_t<Scalar>& p) const {
  return MatrixComplexPowerReturnValue<Derived>(derived(), p);
}

}  // namespace Eigen

#endif  // EIGEN_MATRIX_POWER
