mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
Add support for matrix exponential of floats and complex numbers.
This commit is contained in:
@@ -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));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user