// 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 std::complex<RealScalar> 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 std::complex<RealScalar> 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 typename std::complex<typename Derived::RealScalar> 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 std::complex<RealScalar>& p) const {
  return MatrixComplexPowerReturnValue<Derived>(derived(), p);
}

}  // namespace Eigen

#endif  // EIGEN_MATRIX_POWER
