// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009, 2010 Jitse Niesen <jitse@maths.leeds.ac.uk>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.

#ifndef EIGEN_MATRIX_FUNCTION
#define EIGEN_MATRIX_FUNCTION

#include "StemFunction.h"
#include "MatrixFunctionAtomic.h"


/** \ingroup MatrixFunctions_Module
  * \brief Class for computing matrix exponentials.
  * \tparam MatrixType type of the argument of the matrix function,
  * expected to be an instantiation of the Matrix class template.
  */
template <typename MatrixType, int IsComplex = NumTraits<typename ei_traits<MatrixType>::Scalar>::IsComplex>
class MatrixFunction
{  
  private:

    typedef typename ei_traits<MatrixType>::Index Index;
    typedef typename ei_traits<MatrixType>::Scalar Scalar;    
    typedef typename ei_stem_function<Scalar>::type StemFunction;

  public:

    /** \brief Constructor. 
      *
      * \param[in]  A      argument of matrix function, should be a square matrix.
      * \param[in]  f      an entire function; \c f(x,n) should compute the n-th derivative of f at x.
      *
      * The class stores a reference to \p A, so it should not be
      * changed (or destroyed) before compute() is called.
      */
    MatrixFunction(const MatrixType& A, StemFunction f);

    /** \brief Compute the matrix function.
      *
      * \param[out] result  the function \p f applied to \p A, as
      * specified in the constructor.
      *
      * See MatrixBase::matrixFunction() for details on how this computation
      * is implemented.
      */
    template <typename ResultType> 
    void compute(ResultType &result);    
};


/** \ingroup MatrixFunctions_Module 
  * \brief Partial specialization of MatrixFunction for real matrices \internal 
  */
template <typename MatrixType>
class MatrixFunction<MatrixType, 0>
{  
  private:

    typedef ei_traits<MatrixType> Traits;
    typedef typename Traits::Scalar Scalar;
    static const int Rows = Traits::RowsAtCompileTime;
    static const int Cols = Traits::ColsAtCompileTime;
    static const int Options = MatrixType::Options;
    static const int MaxRows = Traits::MaxRowsAtCompileTime;
    static const int MaxCols = Traits::MaxColsAtCompileTime;

    typedef std::complex<Scalar> ComplexScalar;
    typedef Matrix<ComplexScalar, Rows, Cols, Options, MaxRows, MaxCols> ComplexMatrix;
    typedef typename ei_stem_function<Scalar>::type StemFunction;

  public:

    /** \brief Constructor. 
      *
      * \param[in]  A      argument of matrix function, should be a square matrix.
      * \param[in]  f      an entire function; \c f(x,n) should compute the n-th derivative of f at x.
      */
    MatrixFunction(const MatrixType& A, StemFunction f) : m_A(A), m_f(f) { }

    /** \brief Compute the matrix function.
      *
      * \param[out] result  the function \p f applied to \p A, as
      * specified in the constructor.
      *
      * This function converts the real matrix \c A to a complex matrix,
      * uses MatrixFunction<MatrixType,1> and then converts the result back to
      * a real matrix.
      */
    template <typename ResultType>
    void compute(ResultType& result) 
    {
      ComplexMatrix CA = m_A.template cast<ComplexScalar>();
      ComplexMatrix Cresult;
      MatrixFunction<ComplexMatrix> mf(CA, m_f);
      mf.compute(Cresult);
      result = Cresult.real();
    }

  private:
    typename ei_nested<MatrixType>::type m_A; /**< \brief Reference to argument of matrix function. */
    StemFunction *m_f; /**< \brief Stem function for matrix function under consideration */    

    MatrixFunction& operator=(const MatrixFunction&);
};

      
/** \ingroup MatrixFunctions_Module 
  * \brief Partial specialization of MatrixFunction for complex matrices \internal 
  */
template <typename MatrixType>
class MatrixFunction<MatrixType, 1>
{
  private:

    typedef ei_traits<MatrixType> Traits;
    typedef typename MatrixType::Scalar Scalar;
    typedef typename MatrixType::Index Index;
    static const int RowsAtCompileTime = Traits::RowsAtCompileTime;
    static const int ColsAtCompileTime = Traits::ColsAtCompileTime;
    static const int Options = MatrixType::Options;
    typedef typename NumTraits<Scalar>::Real RealScalar;
    typedef typename ei_stem_function<Scalar>::type StemFunction;
    typedef Matrix<Scalar, Traits::RowsAtCompileTime, 1> VectorType;
    typedef Matrix<Index, Traits::RowsAtCompileTime, 1> IntVectorType;
    typedef Matrix<Index, Dynamic, 1> DynamicIntVectorType;
    typedef std::list<Scalar> Cluster;
    typedef std::list<Cluster> ListOfClusters;
    typedef Matrix<Scalar, Dynamic, Dynamic, Options, RowsAtCompileTime, ColsAtCompileTime> DynMatrixType;

  public:

    MatrixFunction(const MatrixType& A, StemFunction f);
    template <typename ResultType> void compute(ResultType& result);

  private:

    void computeSchurDecomposition();
    void partitionEigenvalues();
    typename ListOfClusters::iterator findCluster(Scalar key);
    void computeClusterSize();
    void computeBlockStart();
    void constructPermutation();
    void permuteSchur();
    void swapEntriesInSchur(Index index);
    void computeBlockAtomic();
    Block<MatrixType> block(const MatrixType& A, Index i, Index j);
    void computeOffDiagonal();
    DynMatrixType solveTriangularSylvester(const DynMatrixType& A, const DynMatrixType& B, const DynMatrixType& C);

    typename ei_nested<MatrixType>::type m_A; /**< \brief Reference to argument of matrix function. */
    StemFunction *m_f; /**< \brief Stem function for matrix function under consideration */
    MatrixType m_T; /**< \brief Triangular part of Schur decomposition */
    MatrixType m_U; /**< \brief Unitary part of Schur decomposition */
    MatrixType m_fT; /**< \brief %Matrix function applied to #m_T */
    ListOfClusters m_clusters; /**< \brief Partition of eigenvalues into clusters of ei'vals "close" to each other */
    DynamicIntVectorType m_eivalToCluster; /**< \brief m_eivalToCluster[i] = j means i-th ei'val is in j-th cluster */
    DynamicIntVectorType m_clusterSize; /**< \brief Number of eigenvalues in each clusters  */
    DynamicIntVectorType m_blockStart; /**< \brief Row index at which block corresponding to i-th cluster starts */
    IntVectorType m_permutation; /**< \brief Permutation which groups ei'vals in the same cluster together */

    /** \brief Maximum distance allowed between eigenvalues to be considered "close".
      *
      * This is morally a \c static \c const \c Scalar, but only
      * integers can be static constant class members in C++. The
      * separation constant is set to 0.1, a value taken from the
      * paper by Davies and Higham. */
    static const RealScalar separation() { return static_cast<RealScalar>(0.1); }

    MatrixFunction& operator=(const MatrixFunction&);
};

/** \brief Constructor. 
 *
 * \param[in]  A      argument of matrix function, should be a square matrix.
 * \param[in]  f      an entire function; \c f(x,n) should compute the n-th derivative of f at x.
 */
template <typename MatrixType>
MatrixFunction<MatrixType,1>::MatrixFunction(const MatrixType& A, StemFunction f) :
  m_A(A), m_f(f)
{
  /* empty body */
}

/** \brief Compute the matrix function.
  *
  * \param[out] result  the function \p f applied to \p A, as
  * specified in the constructor.
  */
template <typename MatrixType>
template <typename ResultType>
void MatrixFunction<MatrixType,1>::compute(ResultType& result) 
{
  computeSchurDecomposition();
  partitionEigenvalues();
  computeClusterSize();
  computeBlockStart();
  constructPermutation();
  permuteSchur();
  computeBlockAtomic();
  computeOffDiagonal();
  result = m_U * m_fT * m_U.adjoint();
}

/** \brief Store the Schur decomposition of #m_A in #m_T and #m_U */
template <typename MatrixType>
void MatrixFunction<MatrixType,1>::computeSchurDecomposition()
{
  const ComplexSchur<MatrixType> schurOfA(m_A);  
  m_T = schurOfA.matrixT();
  m_U = schurOfA.matrixU();
}

/** \brief Partition eigenvalues in clusters of ei'vals close to each other
  * 
  * This function computes #m_clusters. This is a partition of the
  * eigenvalues of #m_T in clusters, such that
  * # Any eigenvalue in a certain cluster is at most separation() away
  *   from another eigenvalue in the same cluster.
  * # The distance between two eigenvalues in different clusters is
  *   more than separation().
  * The implementation follows Algorithm 4.1 in the paper of Davies
  * and Higham. 
  */
template <typename MatrixType>
void MatrixFunction<MatrixType,1>::partitionEigenvalues()
{
  const Index rows = m_T.rows();
  VectorType diag = m_T.diagonal(); // contains eigenvalues of A

  for (Index i=0; i<rows; ++i) {
    // Find set containing diag(i), adding a new set if necessary
    typename ListOfClusters::iterator qi = findCluster(diag(i));
    if (qi == m_clusters.end()) {
      Cluster l;
      l.push_back(diag(i));
      m_clusters.push_back(l);
      qi = m_clusters.end();
      --qi;
    }

    // Look for other element to add to the set
    for (Index j=i+1; j<rows; ++j) {
      if (ei_abs(diag(j) - diag(i)) <= separation() && std::find(qi->begin(), qi->end(), diag(j)) == qi->end()) {
	typename ListOfClusters::iterator qj = findCluster(diag(j));
	if (qj == m_clusters.end()) {
	  qi->push_back(diag(j));
	} else {
	  qi->insert(qi->end(), qj->begin(), qj->end());
	  m_clusters.erase(qj);
	}
      }
    }
  }
}

/** \brief Find cluster in #m_clusters containing some value 
  * \param[in] key Value to find
  * \returns Iterator to cluster containing \c key, or
  * \c m_clusters.end() if no cluster in m_clusters contains \c key.
  */
template <typename MatrixType>
typename MatrixFunction<MatrixType,1>::ListOfClusters::iterator MatrixFunction<MatrixType,1>::findCluster(Scalar key)
{
  typename Cluster::iterator j;
  for (typename ListOfClusters::iterator i = m_clusters.begin(); i != m_clusters.end(); ++i) {
    j = std::find(i->begin(), i->end(), key);
    if (j != i->end())
      return i;
  }
  return m_clusters.end();
}

/** \brief Compute #m_clusterSize and #m_eivalToCluster using #m_clusters */
template <typename MatrixType>
void MatrixFunction<MatrixType,1>::computeClusterSize()
{
  const Index rows = m_T.rows();
  VectorType diag = m_T.diagonal(); 
  const Index numClusters = static_cast<Index>(m_clusters.size());

  m_clusterSize.setZero(numClusters);
  m_eivalToCluster.resize(rows);
  Index clusterIndex = 0;
  for (typename ListOfClusters::const_iterator cluster = m_clusters.begin(); cluster != m_clusters.end(); ++cluster) {
    for (Index i = 0; i < diag.rows(); ++i) {
      if (std::find(cluster->begin(), cluster->end(), diag(i)) != cluster->end()) {
        ++m_clusterSize[clusterIndex];
        m_eivalToCluster[i] = clusterIndex;
      }
    }
    ++clusterIndex;
  }
}

/** \brief Compute #m_blockStart using #m_clusterSize */
template <typename MatrixType>
void MatrixFunction<MatrixType,1>::computeBlockStart()
{
  m_blockStart.resize(m_clusterSize.rows());
  m_blockStart(0) = 0;
  for (Index i = 1; i < m_clusterSize.rows(); i++) {
    m_blockStart(i) = m_blockStart(i-1) + m_clusterSize(i-1);
  }
}

/** \brief Compute #m_permutation using #m_eivalToCluster and #m_blockStart */
template <typename MatrixType>
void MatrixFunction<MatrixType,1>::constructPermutation()
{
  DynamicIntVectorType indexNextEntry = m_blockStart;
  m_permutation.resize(m_T.rows());
  for (Index i = 0; i < m_T.rows(); i++) {
    Index cluster = m_eivalToCluster[i];
    m_permutation[i] = indexNextEntry[cluster];
    ++indexNextEntry[cluster];
  }
}  

/** \brief Permute Schur decomposition in #m_U and #m_T according to #m_permutation */
template <typename MatrixType>
void MatrixFunction<MatrixType,1>::permuteSchur()
{
  IntVectorType p = m_permutation;
  for (Index i = 0; i < p.rows() - 1; i++) {
    Index j;
    for (j = i; j < p.rows(); j++) {
      if (p(j) == i) break;
    }
    ei_assert(p(j) == i);
    for (Index k = j-1; k >= i; k--) {
      swapEntriesInSchur(k);
      std::swap(p.coeffRef(k), p.coeffRef(k+1));
    }
  }
}

/** \brief Swap rows \a index and \a index+1 in Schur decomposition in #m_U and #m_T */
template <typename MatrixType>
void MatrixFunction<MatrixType,1>::swapEntriesInSchur(Index index)
{
  PlanarRotation<Scalar> rotation;
  rotation.makeGivens(m_T(index, index+1), m_T(index+1, index+1) - m_T(index, index));
  m_T.applyOnTheLeft(index, index+1, rotation.adjoint());
  m_T.applyOnTheRight(index, index+1, rotation);
  m_U.applyOnTheRight(index, index+1, rotation);
}  

/** \brief Compute block diagonal part of #m_fT.
  *
  * This routine computes the matrix function #m_f applied to the block
  * diagonal part of #m_T, with the blocking given by #m_blockStart. The
  * result is stored in #m_fT. The off-diagonal parts of #m_fT are set
  * to zero.
  */
template <typename MatrixType>
void MatrixFunction<MatrixType,1>::computeBlockAtomic()
{ 
  m_fT.resize(m_T.rows(), m_T.cols());
  m_fT.setZero();
  MatrixFunctionAtomic<DynMatrixType> mfa(m_f);
  for (Index i = 0; i < m_clusterSize.rows(); ++i) {
    block(m_fT, i, i) = mfa.compute(block(m_T, i, i));
  }
}

/** \brief Return block of matrix according to blocking given by #m_blockStart */
template <typename MatrixType>
Block<MatrixType> MatrixFunction<MatrixType,1>::block(const MatrixType& A, Index i, Index j)
{
  return A.block(m_blockStart(i), m_blockStart(j), m_clusterSize(i), m_clusterSize(j));
}

/** \brief Compute part of #m_fT above block diagonal.
  *
  * This routine assumes that the block diagonal part of #m_fT (which
  * equals #m_f applied to #m_T) has already been computed and computes
  * the part above the block diagonal. The part below the diagonal is
  * zero, because #m_T is upper triangular.
  */
template <typename MatrixType>
void MatrixFunction<MatrixType,1>::computeOffDiagonal()
{ 
  for (Index diagIndex = 1; diagIndex < m_clusterSize.rows(); diagIndex++) {
    for (Index blockIndex = 0; blockIndex < m_clusterSize.rows() - diagIndex; blockIndex++) {
      // compute (blockIndex, blockIndex+diagIndex) block
      DynMatrixType A = block(m_T, blockIndex, blockIndex);
      DynMatrixType B = -block(m_T, blockIndex+diagIndex, blockIndex+diagIndex);
      DynMatrixType C = block(m_fT, blockIndex, blockIndex) * block(m_T, blockIndex, blockIndex+diagIndex);
      C -= block(m_T, blockIndex, blockIndex+diagIndex) * block(m_fT, blockIndex+diagIndex, blockIndex+diagIndex);
      for (Index k = blockIndex + 1; k < blockIndex + diagIndex; k++) {
	C += block(m_fT, blockIndex, k) * block(m_T, k, blockIndex+diagIndex);
	C -= block(m_T, blockIndex, k) * block(m_fT, k, blockIndex+diagIndex);
      }
      block(m_fT, blockIndex, blockIndex+diagIndex) = solveTriangularSylvester(A, B, C);
    }
  }
}

/** \brief Solve a triangular Sylvester equation AX + XB = C 
  *
  * \param[in]  A  the matrix A; should be square and upper triangular
  * \param[in]  B  the matrix B; should be square and upper triangular
  * \param[in]  C  the matrix C; should have correct size.
  *
  * \returns the solution X.
  *
  * If A is m-by-m and B is n-by-n, then both C and X are m-by-n. 
  * The (i,j)-th component of the Sylvester equation is
  * \f[ 
  *     \sum_{k=i}^m A_{ik} X_{kj} + \sum_{k=1}^j X_{ik} B_{kj} = C_{ij}. 
  * \f]
  * This can be re-arranged to yield:
  * \f[ 
  *     X_{ij} = \frac{1}{A_{ii} + B_{jj}} \Bigl( C_{ij}
  *     - \sum_{k=i+1}^m A_{ik} X_{kj} - \sum_{k=1}^{j-1} X_{ik} B_{kj} \Bigr).
  * \f]
  * It is assumed that A and B are such that the numerator is never
  * zero (otherwise the Sylvester equation does not have a unique
  * solution). In that case, these equations can be evaluated in the
  * order \f$ i=m,\ldots,1 \f$ and \f$ j=1,\ldots,n \f$.
  */
template <typename MatrixType>
typename MatrixFunction<MatrixType,1>::DynMatrixType MatrixFunction<MatrixType,1>::solveTriangularSylvester(
  const DynMatrixType& A, 
  const DynMatrixType& B, 
  const DynMatrixType& C)
{
  ei_assert(A.rows() == A.cols());
  ei_assert(A.isUpperTriangular());
  ei_assert(B.rows() == B.cols());
  ei_assert(B.isUpperTriangular());
  ei_assert(C.rows() == A.rows());
  ei_assert(C.cols() == B.rows());

  Index m = A.rows();
  Index n = B.rows();
  DynMatrixType X(m, n);

  for (Index i = m - 1; i >= 0; --i) {
    for (Index j = 0; j < n; ++j) {

      // Compute AX = \sum_{k=i+1}^m A_{ik} X_{kj}
      Scalar AX;
      if (i == m - 1) {
	AX = 0; 
      } else {
	Matrix<Scalar,1,1> AXmatrix = A.row(i).tail(m-1-i) * X.col(j).tail(m-1-i);
	AX = AXmatrix(0,0);
      }

      // Compute XB = \sum_{k=1}^{j-1} X_{ik} B_{kj}
      Scalar XB;
      if (j == 0) {
	XB = 0; 
      } else {
	Matrix<Scalar,1,1> XBmatrix = X.row(i).head(j) * B.col(j).head(j);
	XB = XBmatrix(0,0);
      }

      X(i,j) = (C(i,j) - AX - XB) / (A(i,i) + B(j,j));
    }
  }
  return X;
}

/** \ingroup MatrixFunctions_Module
  *
  * \brief Proxy for the matrix function of some matrix (expression).
  *
  * \tparam Derived  Type of the argument to the matrix function.
  *
  * This class holds the argument to the matrix function 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::matrixFunction() and related functions and most of the
  * time this is the only way it is used.
  */
template<typename Derived> class MatrixFunctionReturnValue
: public ReturnByValue<MatrixFunctionReturnValue<Derived> >
{
  public:

    typedef typename Derived::Scalar Scalar;
    typedef typename Derived::Index Index;
    typedef typename ei_stem_function<Scalar>::type StemFunction;

   /** \brief Constructor.
      *
      * \param[in] A  %Matrix (expression) forming the argument of the
      * matrix function.
      * \param[in] f  Stem function for matrix function under consideration.
      */
    MatrixFunctionReturnValue(const Derived& A, StemFunction f) : m_A(A), m_f(f) { }

    /** \brief Compute the matrix function.
      *
      * \param[out] result \p f applied to \p A, where \p f and \p A
      * are as in the constructor.
      */
    template <typename ResultType>
    inline void evalTo(ResultType& result) const
    {
      const typename Derived::PlainObject Aevaluated = m_A.eval();
      MatrixFunction<typename Derived::PlainObject> mf(Aevaluated, m_f);
      mf.compute(result);
    }

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

  private:
    typename ei_nested<Derived>::type m_A;
    StemFunction *m_f;

    MatrixFunctionReturnValue& operator=(const MatrixFunctionReturnValue&);
};

template<typename Derived>
struct ei_traits<MatrixFunctionReturnValue<Derived> >
{
  typedef typename Derived::PlainObject ReturnType;
};


/********** MatrixBase methods **********/


template <typename Derived>
const MatrixFunctionReturnValue<Derived> MatrixBase<Derived>::matrixFunction(typename ei_stem_function<typename ei_traits<Derived>::Scalar>::type f) const
{
  ei_assert(rows() == cols());
  return MatrixFunctionReturnValue<Derived>(derived(), f);
}

template <typename Derived>
const MatrixFunctionReturnValue<Derived> MatrixBase<Derived>::sin() const
{
  ei_assert(rows() == cols());
  typedef typename ei_stem_function<Scalar>::ComplexScalar ComplexScalar;
  return MatrixFunctionReturnValue<Derived>(derived(), StdStemFunctions<ComplexScalar>::sin);
}

template <typename Derived>
const MatrixFunctionReturnValue<Derived> MatrixBase<Derived>::cos() const
{
  ei_assert(rows() == cols());
  typedef typename ei_stem_function<Scalar>::ComplexScalar ComplexScalar;
  return MatrixFunctionReturnValue<Derived>(derived(), StdStemFunctions<ComplexScalar>::cos);
}

template <typename Derived>
const MatrixFunctionReturnValue<Derived> MatrixBase<Derived>::sinh() const
{
  ei_assert(rows() == cols());
  typedef typename ei_stem_function<Scalar>::ComplexScalar ComplexScalar;
  return MatrixFunctionReturnValue<Derived>(derived(), StdStemFunctions<ComplexScalar>::sinh);
}

template <typename Derived>
const MatrixFunctionReturnValue<Derived> MatrixBase<Derived>::cosh() const
{
  ei_assert(rows() == cols());
  typedef typename ei_stem_function<Scalar>::ComplexScalar ComplexScalar;
  return MatrixFunctionReturnValue<Derived>(derived(), StdStemFunctions<ComplexScalar>::cosh);
}

#endif // EIGEN_MATRIX_FUNCTION
