// 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);
    Scalar a = m_A.coeff(i - 1, i - 1);
    Scalar b = m_A.coeff(i, i);
    Scalar diff = b - a;
    // Use the derivative formula when eigenvalues are nearly equal to avoid
    // catastrophic cancellation in the difference quotient.
    if (abs(diff) <= RealScalar(2) * (std::numeric_limits<RealScalar>::epsilon)() * (std::max)(abs(a), abs(b)))
      res.coeffRef(i - 1, i) = p * pow(b, p - 1);
    else if (2 * abs(a) < abs(b) || 2 * abs(b) < abs(a))
      res.coeffRef(i - 1, i) = (res.coeff(i, i) - res.coeff(i - 1, i - 1)) / diff;
    else
      res.coeffRef(i - 1, i) = computeSuperDiag(b, a, 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
