Add support for matrix exponential of floats and complex numbers.

This commit is contained in:
Jitse Niesen
2009-08-12 15:44:22 +01:00
parent 309d540d4a
commit f71f878bab
2 changed files with 291 additions and 104 deletions

View File

@@ -34,26 +34,47 @@ double binom(int n, int k)
return res;
}
void test2dRotation()
template <typename T>
void test2dRotation(double tol)
{
Matrix2d A, B, C;
double angle;
Matrix<T,2,2> A, B, C;
T angle;
A << 0, 1, -1, 0;
for (int i=0; i<=20; i++)
{
angle = pow(10, i / 5. - 2);
A << 0, angle, -angle, 0;
B << cos(angle), sin(angle), -sin(angle), cos(angle);
ei_matrix_exponential(A, &C);
VERIFY(C.isApprox(B, 1e-14));
ei_matrix_exponential(angle*A, &C);
VERIFY(C.isApprox(B, tol));
}
}
void testPascal()
template <typename T>
void test2dHyperbolicRotation(double tol)
{
Matrix<std::complex<T>,2,2> A, B, C;
std::complex<T> imagUnit(0,1);
T angle, ch, sh;
for (int i=0; i<=20; i++)
{
angle = (i-10) / 2.0;
ch = std::cosh(angle);
sh = std::sinh(angle);
A << 0, angle*imagUnit, -angle*imagUnit, 0;
B << ch, sh*imagUnit, -sh*imagUnit, ch;
ei_matrix_exponential(A, &C);
VERIFY(C.isApprox(B, tol));
}
}
template <typename T>
void testPascal(double tol)
{
for (int size=1; size<20; size++)
{
MatrixXd A(size,size), B(size,size), C(size,size);
Matrix<T,Dynamic,Dynamic> A(size,size), B(size,size), C(size,size);
A.setZero();
for (int i=0; i<size-1; i++)
A(i+1,i) = i+1;
@@ -62,11 +83,12 @@ void testPascal()
for (int j=0; j<=i; j++)
B(i,j) = binom(i,j);
ei_matrix_exponential(A, &C);
VERIFY(C.isApprox(B, 1e-14));
VERIFY(C.isApprox(B, tol));
}
}
template<typename MatrixType> void randomTest(const MatrixType& m)
template<typename MatrixType>
void randomTest(const MatrixType& m, double tol)
{
/* this test covers the following files:
Inverse.h
@@ -80,16 +102,24 @@ template<typename MatrixType> void randomTest(const MatrixType& m)
m1 = MatrixType::Random(rows, cols);
ei_matrix_exponential(m1, &m2);
ei_matrix_exponential(-m1, &m3);
VERIFY(identity.isApprox(m2 * m3, 1e-13));
VERIFY(identity.isApprox(m2 * m3, tol));
}
}
void test_matrixExponential()
{
CALL_SUBTEST(test2dRotation());
CALL_SUBTEST(testPascal());
CALL_SUBTEST(randomTest(Matrix2d()));
CALL_SUBTEST(randomTest(Matrix3d()));
CALL_SUBTEST(randomTest(Matrix4d()));
CALL_SUBTEST(randomTest(MatrixXd(8,8)));
CALL_SUBTEST(test2dRotation<double>(1e-14));
CALL_SUBTEST(test2dRotation<float>(1e-5));
CALL_SUBTEST(test2dHyperbolicRotation<double>(1e-14));
CALL_SUBTEST(test2dHyperbolicRotation<float>(1e-5));
CALL_SUBTEST(testPascal<float>(1e-5));
CALL_SUBTEST(testPascal<double>(1e-14));
CALL_SUBTEST(randomTest(Matrix2d(), 1e-13));
CALL_SUBTEST(randomTest(Matrix<double,3,3,RowMajor>(), 1e-13));
CALL_SUBTEST(randomTest(Matrix4cd(), 1e-13));
CALL_SUBTEST(randomTest(MatrixXd(8,8), 1e-13));
CALL_SUBTEST(randomTest(Matrix2f(), 1e-4));
CALL_SUBTEST(randomTest(Matrix3cf(), 1e-4));
CALL_SUBTEST(randomTest(Matrix4f(), 1e-4));
CALL_SUBTEST(randomTest(MatrixXf(8,8), 1e-4));
}