17faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez// This file is part of Eigen, a lightweight C++ template library
27faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez// for linear algebra.
37faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez//
42b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// Copyright (C) 2012, 2013 Chen-Pang He <jdh8@ms63.hinet.net>
57faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez//
67faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez// This Source Code Form is subject to the terms of the Mozilla
77faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez// Public License v. 2.0. If a copy of the MPL was not distributed
87faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
97faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
107faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "matrix_functions.h"
117faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
127faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeztemplate<typename T>
132b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangvoid test2dRotation(const T& tol)
147faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez{
157faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  Matrix<T,2,2> A, B, C;
167faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  T angle, c, s;
177faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
187faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  A << 0, 1, -1, 0;
197faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  MatrixPower<Matrix<T,2,2> > Apow(A);
207faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
217faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  for (int i=0; i<=20; ++i) {
222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    angle = std::pow(T(10), (i-10) / T(5.));
237faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    c = std::cos(angle);
247faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    s = std::sin(angle);
257faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    B << c, s, -s, c;
267faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
272b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    C = Apow(std::ldexp(angle,1) / T(EIGEN_PI));
287faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    std::cout << "test2dRotation: i = " << i << "   error powerm = " << relerr(C,B) << '\n';
292b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY(C.isApprox(B, tol));
307faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  }
317faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}
327faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
337faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeztemplate<typename T>
342b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangvoid test2dHyperbolicRotation(const T& tol)
357faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez{
367faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  Matrix<std::complex<T>,2,2> A, B, C;
377faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  T angle, ch = std::cosh((T)1);
387faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  std::complex<T> ish(0, std::sinh((T)1));
397faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
407faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  A << ch, ish, -ish, ch;
417faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  MatrixPower<Matrix<std::complex<T>,2,2> > Apow(A);
427faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
437faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  for (int i=0; i<=20; ++i) {
447faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    angle = std::ldexp(static_cast<T>(i-10), -1);
457faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    ch = std::cosh(angle);
467faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    ish = std::complex<T>(0, std::sinh(angle));
477faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    B << ch, ish, -ish, ch;
487faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
497faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    C = Apow(angle);
507faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    std::cout << "test2dHyperbolicRotation: i = " << i << "   error powerm = " << relerr(C,B) << '\n';
512b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY(C.isApprox(B, tol));
522b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  }
532b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}
542b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
552b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename T>
562b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangvoid test3dRotation(const T& tol)
572b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
582b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  Matrix<T,3,1> v;
592b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  T angle;
602b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
612b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  for (int i=0; i<=20; ++i) {
622b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    v = Matrix<T,3,1>::Random();
632b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    v.normalize();
642b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    angle = std::pow(T(10), (i-10) / T(5.));
652b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY(AngleAxis<T>(angle, v).matrix().isApprox(AngleAxis<T>(1,v).matrix().pow(angle), tol));
667faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  }
677faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}
687faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
697faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeztemplate<typename MatrixType>
702b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangvoid testGeneral(const MatrixType& m, const typename MatrixType::RealScalar& tol)
717faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez{
727faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  typedef typename MatrixType::RealScalar RealScalar;
737faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  MatrixType m1, m2, m3, m4, m5;
747faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  RealScalar x, y;
757faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
767faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  for (int i=0; i < g_repeat; ++i) {
777faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    generateTestMatrix<MatrixType>::run(m1, m.rows());
787faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    MatrixPower<MatrixType> mpow(m1);
797faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
807faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    x = internal::random<RealScalar>();
817faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    y = internal::random<RealScalar>();
827faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    m2 = mpow(x);
837faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    m3 = mpow(y);
847faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
857faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    m4 = mpow(x+y);
867faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    m5.noalias() = m2 * m3;
872b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY(m4.isApprox(m5, tol));
887faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
897faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    m4 = mpow(x*y);
907faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    m5 = m2.pow(y);
912b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY(m4.isApprox(m5, tol));
927faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
937faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    m4 = (std::abs(x) * m1).pow(y);
947faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    m5 = std::pow(std::abs(x), y) * m3;
952b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY(m4.isApprox(m5, tol));
962b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  }
972b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}
982b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
992b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename MatrixType>
1002b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangvoid testSingular(const MatrixType& m_const, const typename MatrixType::RealScalar& tol)
1012b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
1022b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  // we need to pass by reference in order to prevent errors with
1032b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  // MSVC for aligned data types ...
1042b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  MatrixType& m = const_cast<MatrixType&>(m_const);
1052b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1062b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  const int IsComplex = NumTraits<typename internal::traits<MatrixType>::Scalar>::IsComplex;
1072b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef typename internal::conditional<IsComplex, TriangularView<MatrixType,Upper>, const MatrixType&>::type TriangularType;
1082b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typename internal::conditional< IsComplex, ComplexSchur<MatrixType>, RealSchur<MatrixType> >::type schur;
1092b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  MatrixType T;
1102b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1112b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  for (int i=0; i < g_repeat; ++i) {
1122b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    m.setRandom();
1132b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    m.col(0).fill(0);
1142b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1152b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    schur.compute(m);
1162b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    T = schur.matrixT();
1172b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    const MatrixType& U = schur.matrixU();
1182b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    processTriangularMatrix<MatrixType>::run(m, T, U);
1192b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    MatrixPower<MatrixType> mpow(m);
1202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1212b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    T = T.sqrt();
1222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY(mpow(0.5L).isApprox(U * (TriangularType(T) * U.adjoint()), tol));
1232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1242b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    T = T.sqrt();
1252b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY(mpow(0.25L).isApprox(U * (TriangularType(T) * U.adjoint()), tol));
1262b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1272b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    T = T.sqrt();
1282b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY(mpow(0.125L).isApprox(U * (TriangularType(T) * U.adjoint()), tol));
1292b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  }
1302b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}
1312b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1322b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename MatrixType>
1332b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangvoid testLogThenExp(const MatrixType& m_const, const typename MatrixType::RealScalar& tol)
1342b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
1352b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  // we need to pass by reference in order to prevent errors with
1362b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  // MSVC for aligned data types ...
1372b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  MatrixType& m = const_cast<MatrixType&>(m_const);
1382b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1392b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef typename MatrixType::Scalar Scalar;
1402b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  Scalar x;
1412b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1422b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  for (int i=0; i < g_repeat; ++i) {
1432b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    generateTestMatrix<MatrixType>::run(m, m.rows());
1442b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    x = internal::random<Scalar>();
1452b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY(m.pow(x).isApprox((x * m.log()).exp(), tol));
1467faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  }
1477faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}
1487faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
1497faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeztypedef Matrix<double,3,3,RowMajor>         Matrix3dRowMajor;
1502b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtypedef Matrix<long double,3,3>             Matrix3e;
1517faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeztypedef Matrix<long double,Dynamic,Dynamic> MatrixXe;
1527faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
1537faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezvoid test_matrix_power()
1547faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez{
1557faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  CALL_SUBTEST_2(test2dRotation<double>(1e-13));
1567faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  CALL_SUBTEST_1(test2dRotation<float>(2e-5));  // was 1e-5, relaxed for clang 2.8 / linux / x86-64
1572b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CALL_SUBTEST_9(test2dRotation<long double>(1e-13L));
1587faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  CALL_SUBTEST_2(test2dHyperbolicRotation<double>(1e-14));
1597faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  CALL_SUBTEST_1(test2dHyperbolicRotation<float>(1e-5));
1602b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CALL_SUBTEST_9(test2dHyperbolicRotation<long double>(1e-14L));
1612b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1622b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CALL_SUBTEST_10(test3dRotation<double>(1e-13));
1632b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CALL_SUBTEST_11(test3dRotation<float>(1e-5));
1642b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CALL_SUBTEST_12(test3dRotation<long double>(1e-13L));
1652b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1662b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CALL_SUBTEST_2(testGeneral(Matrix2d(),         1e-13));
1672b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CALL_SUBTEST_7(testGeneral(Matrix3dRowMajor(), 1e-13));
1682b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CALL_SUBTEST_3(testGeneral(Matrix4cd(),        1e-13));
1692b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CALL_SUBTEST_4(testGeneral(MatrixXd(8,8),      2e-12));
1702b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CALL_SUBTEST_1(testGeneral(Matrix2f(),         1e-4));
1712b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CALL_SUBTEST_5(testGeneral(Matrix3cf(),        1e-4));
1722b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CALL_SUBTEST_8(testGeneral(Matrix4f(),         1e-4));
1732b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CALL_SUBTEST_6(testGeneral(MatrixXf(2,2),      1e-3)); // see bug 614
1742b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CALL_SUBTEST_9(testGeneral(MatrixXe(7,7),      1e-13L));
1752b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CALL_SUBTEST_10(testGeneral(Matrix3d(),        1e-13));
1762b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CALL_SUBTEST_11(testGeneral(Matrix3f(),        1e-4));
1772b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CALL_SUBTEST_12(testGeneral(Matrix3e(),        1e-13L));
1782b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1792b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CALL_SUBTEST_2(testSingular(Matrix2d(),         1e-13));
1802b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CALL_SUBTEST_7(testSingular(Matrix3dRowMajor(), 1e-13));
1812b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CALL_SUBTEST_3(testSingular(Matrix4cd(),        1e-13));
1822b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CALL_SUBTEST_4(testSingular(MatrixXd(8,8),      2e-12));
1832b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CALL_SUBTEST_1(testSingular(Matrix2f(),         1e-4));
1842b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CALL_SUBTEST_5(testSingular(Matrix3cf(),        1e-4));
1852b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CALL_SUBTEST_8(testSingular(Matrix4f(),         1e-4));
1862b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CALL_SUBTEST_6(testSingular(MatrixXf(2,2),      1e-3));
1872b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CALL_SUBTEST_9(testSingular(MatrixXe(7,7),      1e-13L));
1882b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CALL_SUBTEST_10(testSingular(Matrix3d(),        1e-13));
1892b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CALL_SUBTEST_11(testSingular(Matrix3f(),        1e-4));
1902b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CALL_SUBTEST_12(testSingular(Matrix3e(),        1e-13L));
1912b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1922b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CALL_SUBTEST_2(testLogThenExp(Matrix2d(),         1e-13));
1932b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CALL_SUBTEST_7(testLogThenExp(Matrix3dRowMajor(), 1e-13));
1942b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CALL_SUBTEST_3(testLogThenExp(Matrix4cd(),        1e-13));
1952b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CALL_SUBTEST_4(testLogThenExp(MatrixXd(8,8),      2e-12));
1962b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CALL_SUBTEST_1(testLogThenExp(Matrix2f(),         1e-4));
1972b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CALL_SUBTEST_5(testLogThenExp(Matrix3cf(),        1e-4));
1982b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CALL_SUBTEST_8(testLogThenExp(Matrix4f(),         1e-4));
1992b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CALL_SUBTEST_6(testLogThenExp(MatrixXf(2,2),      1e-3));
2002b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CALL_SUBTEST_9(testLogThenExp(MatrixXe(7,7),      1e-13L));
2012b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CALL_SUBTEST_10(testLogThenExp(Matrix3d(),        1e-13));
2022b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CALL_SUBTEST_11(testLogThenExp(Matrix3f(),        1e-4));
2032b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CALL_SUBTEST_12(testLogThenExp(Matrix3e(),        1e-13L));
2047faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}
205