11 #ifndef EIGEN_MATRIX_EXPONENTIAL 
   12 #define EIGEN_MATRIX_EXPONENTIAL 
   23 template <
typename RealScalar>
 
   64 template <
typename MatA, 
typename MatU, 
typename MatV>
 
   71   const MatrixType tmp = 
b[3] * 
A2 + 
b[1] * MatrixType::Identity(
A.rows(), 
A.cols());
 
   72   U.noalias() = 
A * tmp;
 
   73   V = 
b[2] * 
A2 + 
b[0] * MatrixType::Identity(
A.rows(), 
A.cols());
 
   81 template <
typename MatA, 
typename MatU, 
typename MatV>
 
   86   const RealScalar b[] = {30240.L, 15120.L, 3360.L, 420.L, 30.L, 1.L};
 
   89   const MatrixType tmp = 
b[5] * 
A4 + 
b[3] * 
A2 + 
b[1] * MatrixType::Identity(
A.rows(), 
A.cols());
 
   90   U.noalias() = 
A * tmp;
 
   91   V = 
b[4] * 
A4 + 
b[2] * 
A2 + 
b[0] * MatrixType::Identity(
A.rows(), 
A.cols());
 
   99 template <
typename MatA, 
typename MatU, 
typename MatV>
 
  102   typedef typename MatA::PlainObject 
MatrixType;
 
  104   const RealScalar b[] = {17297280.L, 8648640.L, 1995840.L, 277200.L, 25200.L, 1512.L, 56.L, 1.L};
 
  109     + 
b[1] * MatrixType::Identity(
A.rows(), 
A.cols());
 
  110   U.noalias() = 
A * tmp;
 
  111   V = 
b[6] * 
A6 + 
b[4] * 
A4 + 
b[2] * 
A2 + 
b[0] * MatrixType::Identity(
A.rows(), 
A.cols());
 
  120 template <
typename MatA, 
typename MatU, 
typename MatV>
 
  123   typedef typename MatA::PlainObject 
MatrixType;
 
  125   const RealScalar b[] = {17643225600.L, 8821612800.L, 2075673600.L, 302702400.L, 30270240.L,
 
  126                           2162160.L, 110880.L, 3960.L, 90.L, 1.L};
 
  132     + 
b[1] * MatrixType::Identity(
A.rows(), 
A.cols());
 
  133   U.noalias() = 
A * tmp;
 
  134   V = 
b[8] * 
A8 + 
b[6] * 
A6 + 
b[4] * 
A4 + 
b[2] * 
A2 + 
b[0] * MatrixType::Identity(
A.rows(), 
A.cols());
 
  142 template <
typename MatA, 
typename MatU, 
typename MatV>
 
  145   typedef typename MatA::PlainObject 
MatrixType;
 
  147   const RealScalar b[] = {64764752532480000.L, 32382376266240000.L, 7771770303897600.L,
 
  148                           1187353796428800.L, 129060195264000.L, 10559470521600.L, 670442572800.L,
 
  149                           33522128640.L, 1323241920.L, 40840800.L, 960960.L, 16380.L, 182.L, 1.L};
 
  155   tmp += 
b[7] * 
A6 + 
b[5] * 
A4 + 
b[3] * 
A2 + 
b[1] * MatrixType::Identity(
A.rows(), 
A.cols());
 
  156   U.noalias() = 
A * tmp;
 
  157   tmp = 
b[12] * 
A6 + 
b[10] * 
A4 + 
b[8] * 
A2;
 
  158   V.noalias() = 
A6 * tmp;
 
  159   V += 
b[6] * 
A6 + 
b[4] * 
A4 + 
b[2] * 
A2 + 
b[0] * MatrixType::Identity(
A.rows(), 
A.cols());
 
  169 #if LDBL_MANT_DIG > 64 
  170 template <
typename MatA, 
typename MatU, 
typename MatV>
 
  171 void matrix_exp_pade17(
const MatA& 
A, MatU& 
U, MatV& 
V)
 
  173   typedef typename MatA::PlainObject 
MatrixType;
 
  175   const RealScalar b[] = {830034394580628357120000.L, 415017197290314178560000.L,
 
  176                           100610229646136770560000.L, 15720348382208870400000.L,
 
  177                           1774878043152614400000.L, 153822763739893248000.L, 10608466464820224000.L,
 
  178                           595373117923584000.L, 27563570274240000.L, 1060137318240000.L,
 
  179                           33924394183680.L, 899510451840.L, 19554575040.L, 341863200.L, 4651200.L,
 
  180                           46512.L, 306.L, 1.L};
 
  188     + 
b[1] * MatrixType::Identity(
A.rows(), 
A.cols());
 
  189   U.noalias() = 
A * tmp;
 
  190   tmp = 
b[16] * 
A8 + 
b[14] * 
A6 + 
b[12] * 
A4 + 
b[10] * 
A2;
 
  191   V.noalias() = tmp * 
A8;
 
  193     + 
b[0] * MatrixType::Identity(
A.rows(), 
A.cols());
 
  210 template <
typename MatrixType>
 
  213   template <
typename ArgType>
 
  218     const float l1norm = 
arg.cwiseAbs().colwise().sum().maxCoeff();
 
  220     if (l1norm < 4.258730016922831
e-001
f) {
 
  222     } 
else if (l1norm < 1.880152677804762
e+000
f) {
 
  225       const float maxnorm = 3.925724783138660f;
 
  226       frexp(l1norm / maxnorm, &squarings);
 
  227       if (squarings < 0) squarings = 0;
 
  234 template <
typename MatrixType>
 
  238   template <
typename ArgType>
 
  243     const RealScalar l1norm = 
arg.cwiseAbs().colwise().sum().maxCoeff();
 
  245     if (l1norm < 1.495585217958292
e-002) {
 
  247     } 
else if (l1norm < 2.539398330063230
e-001) {
 
  249     } 
else if (l1norm < 9.504178996162932
e-001) {
 
  251     } 
else if (l1norm < 2.097847961257068
e+000) {
 
  255       frexp(l1norm / maxnorm, &squarings);
 
  256       if (squarings < 0) squarings = 0;
 
  263 template <
typename MatrixType>
 
  266   template <
typename ArgType>
 
  269 #if   LDBL_MANT_DIG == 53   // double precision 
  276     const long double l1norm = 
arg.cwiseAbs().colwise().sum().maxCoeff();
 
  279 #if LDBL_MANT_DIG <= 64   // extended precision 
  281     if (l1norm < 4.1968497232266989671
e-003
L) {
 
  283     } 
else if (l1norm < 1.1848116734693823091
e-001
L) {
 
  285     } 
else if (l1norm < 5.5170388480686700274
e-001
L) {
 
  287     } 
else if (l1norm < 1.3759868875587845383
e+000
L) {
 
  290       const long double maxnorm = 4.0246098906697353063L;
 
  291       frexp(l1norm / maxnorm, &squarings);
 
  292       if (squarings < 0) squarings = 0;
 
  297 #elif LDBL_MANT_DIG <= 106  // double-double 
  299     if (l1norm < 3.2787892205607026992947488108213
e-005
L) {
 
  301     } 
else if (l1norm < 6.4467025060072760084130906076332
e-003
L) {
 
  303     } 
else if (l1norm < 6.8988028496595374751374122881143
e-002
L) {
 
  305     } 
else if (l1norm < 2.7339737518502231741495857201670
e-001
L) {
 
  307     } 
else if (l1norm < 1.3203382096514474905666448850278
e+000
L) {
 
  310       const long double maxnorm = 3.2579440895405400856599663723517L;
 
  311       frexp(l1norm / maxnorm, &squarings);
 
  312       if (squarings < 0) squarings = 0;
 
  314       matrix_exp_pade17(
A, 
U, 
V);
 
  317 #elif LDBL_MANT_DIG <= 113  // quadruple precision 
  319     if (l1norm < 1.639394610288918690547467954466970
e-005
L) {
 
  321     } 
else if (l1norm < 4.253237712165275566025884344433009
e-003
L) {
 
  323     } 
else if (l1norm < 5.125804063165764409885122032933142
e-002
L) {
 
  325     } 
else if (l1norm < 2.170000765161155195453205651889853
e-001
L) {
 
  327     } 
else if (l1norm < 1.125358383453143065081397882891878
e+000
L) {
 
  330       const long double maxnorm = 2.884233277829519311757165057717815L;
 
  331       frexp(l1norm / maxnorm, &squarings);
 
  332       if (squarings < 0) squarings = 0;
 
  334       matrix_exp_pade17(
A, 
U, 
V);
 
  343 #endif  // LDBL_MANT_DIG 
  350 #if LDBL_MANT_DIG <= 113 
  354 template <
typename ArgType, 
typename ResultType>
 
  357   typedef typename ArgType::PlainObject 
MatrixType;
 
  363   result = denom.partialPivLu().solve(numer);
 
  364   for (
int i=0; 
i<squarings; 
i++)
 
  374 template <
typename ArgType, 
typename ResultType>
 
  377   typedef typename ArgType::PlainObject 
MatrixType;
 
  380   typedef typename std::complex<RealScalar> ComplexScalar;
 
  381   result = 
arg.matrixFunction(internal::stem_function_exp<ComplexScalar>);
 
  396 template<
typename Derived> 
struct MatrixExponentialReturnValue
 
  397 : 
public ReturnByValue<MatrixExponentialReturnValue<Derived> >
 
  410     template <
typename ResultType>
 
  425 template<
typename Derived>
 
  432 template <
typename Derived>
 
  441 #endif // EIGEN_MATRIX_EXPONENTIAL