// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
//
// Copyright (C) 2009 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_EXPONENTIAL
#define EIGEN_MATRIX_EXPONENTIAL

#ifdef _MSC_VER
template <typename Scalar> Scalar log2(Scalar v) { return std::log(v)/std::log(Scalar(2)); }
#endif

/** Compute the matrix exponential. 
 *
 * \param M      matrix whose exponential is to be computed.
 * \param result pointer to the matrix in which to store the result.
 *
 * The matrix exponential of \f$ M \f$ is defined by
 * \f[ \exp(M) = \sum_{k=0}^\infty \frac{M^k}{k!}. \f]
 * The matrix exponential can be used to solve linear ordinary
 * differential equations: the solution of \f$ y' = My \f$ with the
 * initial condition \f$ y(0) = y_0 \f$ is given by 
 * \f$ y(t) = \exp(M) y_0 \f$.
 *
 * The cost of the computation is approximately \f$ 20 n^3 \f$ for
 * matrices of size \f$ n \f$. The number 20 depends weakly on the
 * norm of the matrix.
 *
 * The matrix exponential is computed using the scaling-and-squaring
 * method combined with Pad&eacute; approximation. The matrix is first
 * rescaled, then the exponential of the reduced matrix is computed
 * approximant, and then the rescaling is undone by repeated
 * squaring. The degree of the Pad&eacute; approximant is chosen such
 * that the approximation error is less than the round-off
 * error. However, errors may accumulate during the squaring phase.
 * 
 * Details of the algorithm can be found in: Nicholas J. Higham, "The
 * scaling and squaring method for the matrix exponential revisited,"
 * <em>SIAM J. %Matrix Anal. Applic.</em>, <b>26</b>:1179&ndash;1193,
 * 2005. 
 *
 * \note Currently, \p M has to be a matrix of \c double .
 */
template <typename Derived>
void ei_matrix_exponential(const MatrixBase<Derived> &M, typename ei_plain_matrix_type<Derived>::type* result)
{
  typedef typename ei_traits<Derived>::Scalar Scalar;
  typedef typename NumTraits<Scalar>::Real RealScalar;
  typedef typename ei_plain_matrix_type<Derived>::type PlainMatrixType;

  ei_assert(M.rows() == M.cols());
  EIGEN_STATIC_ASSERT(NumTraits<Scalar>::HasFloatingPoint,NUMERIC_TYPE_MUST_BE_FLOATING_POINT)

  PlainMatrixType num, den, U, V;
  PlainMatrixType Id = PlainMatrixType::Identity(M.rows(), M.cols());
  RealScalar l1norm = M.cwise().abs().colwise().sum().maxCoeff();
  int squarings = 0;
  
  // Choose degree of Pade approximant, depending on norm of M
  if (l1norm < 1.495585217958292e-002) {
    
    // Use (3,3)-Pade
    const Scalar b[] = {120., 60., 12., 1.};
    PlainMatrixType M2;
    M2 = (M * M).lazy();
    num = b[3]*M2 + b[1]*Id;
    U = (M * num).lazy();
    V = b[2]*M2 + b[0]*Id;

  } else if (l1norm < 2.539398330063230e-001) {

    // Use (5,5)-Pade
    const Scalar b[] = {30240., 15120., 3360., 420., 30., 1.};
    PlainMatrixType M2, M4;
    M2 = (M * M).lazy();
    M4 = (M2 * M2).lazy();
    num = b[5]*M4 + b[3]*M2 + b[1]*Id;
    U = (M * num).lazy();
    V = b[4]*M4 + b[2]*M2 + b[0]*Id;

  } else if (l1norm < 9.504178996162932e-001) {

    // Use (7,7)-Pade
    const Scalar b[] = {17297280., 8648640., 1995840., 277200., 25200., 1512., 56., 1.};
    PlainMatrixType M2, M4, M6;
    M2 = (M * M).lazy();
    M4 = (M2 * M2).lazy();
    M6 = (M4 * M2).lazy();
    num = b[7]*M6 + b[5]*M4 + b[3]*M2 + b[1]*Id;
    U = (M * num).lazy();
    V = b[6]*M6 + b[4]*M4 + b[2]*M2 + b[0]*Id;

  } else if (l1norm < 2.097847961257068e+000) {

    // Use (9,9)-Pade
    const Scalar b[] = {17643225600., 8821612800., 2075673600., 302702400., 30270240.,
                         2162160., 110880., 3960., 90., 1.};
    PlainMatrixType M2, M4, M6, M8;
    M2 = (M * M).lazy();
    M4 = (M2 * M2).lazy();
    M6 = (M4 * M2).lazy();
    M8 = (M6 * M2).lazy();
    num = b[9]*M8 + b[7]*M6 + b[5]*M4 + b[3]*M2 + b[1]*Id;
    U = (M * num).lazy();
    V = b[8]*M8 + b[6]*M6 + b[4]*M4 + b[2]*M2 + b[0]*Id;

  } else {

    // Use (13,13)-Pade; scale matrix by power of 2 so that its norm
    // is small enough 

    const Scalar maxnorm = 5.371920351148152;
    const Scalar b[] = {64764752532480000., 32382376266240000., 7771770303897600., 
			1187353796428800., 129060195264000., 10559470521600., 670442572800., 
			33522128640., 1323241920., 40840800., 960960., 16380., 182., 1.};
    
    squarings = std::max(0, (int)ceil(log2(l1norm / maxnorm)));
    PlainMatrixType A, A2, A4, A6;
    A = M / pow(Scalar(2), squarings);
    A2 = (A * A).lazy();
    A4 = (A2 * A2).lazy();
    A6 = (A4 * A2).lazy();
    num = b[13]*A6 + b[11]*A4 + b[9]*A2;
    V = (A6 * num).lazy();
    num = V + b[7]*A6 + b[5]*A4 + b[3]*A2 + b[1]*Id;
    U = (A * num).lazy();
    num = b[12]*A6 + b[10]*A4 + b[8]*A2;
    V = (A6 * num).lazy() + b[6]*A6 + b[4]*A4 + b[2]*A2 + b[0]*Id;
  }

  num = U + V;			// numerator of Pade approximant
  den = -U + V;			// denominator of Pade approximant
  den.lu().solve(num, result);

  // Undo scaling by repeated squaring
  for (int i=0; i<squarings; i++)
    *result *= *result;
}

#endif // EIGEN_MATRIX_EXPONENTIAL
