Browse Source

Math: simplify the SVD test code by making it templated.

pull/162/merge
Vladimír Vondruš 10 years ago
parent
commit
96e57ff876
  1. 92
      src/Magnum/Math/Algorithms/Test/SvdTest.cpp

92
src/Magnum/Math/Algorithms/Test/SvdTest.cpp

@ -32,81 +32,47 @@ namespace Magnum { namespace Math { namespace Algorithms { namespace Test {
struct SvdTest: Corrade::TestSuite::Tester {
explicit SvdTest();
void testDouble();
void testFloat();
template<class T> void test();
};
typedef RectangularMatrix<5, 8, Double> Matrix5x8d;
typedef Matrix<8, Double> Matrix8d;
typedef Matrix<5, Double> Matrix5d;
typedef Vector<8, Double> Vector8d;
typedef Vector<5, Double> Vector5d;
typedef RectangularMatrix<5, 8, Float> Matrix5x8f;
typedef Matrix<8, Float> Matrix8f;
typedef Matrix<5, Float> Matrix5f;
typedef Vector<8, Float> Vector8f;
typedef Vector<5, Float> Vector5f;
constexpr static Matrix5x8d ad(
Vector8d(22.0, 14.0, -1.0, -3.0, 9.0, 9.0, 2.0, 4.0),
Vector8d(10.0, 7.0, 13.0, -2.0, 8.0, 1.0, -6.0, 5.0),
Vector8d( 2.0, 10.0, -1.0, 13.0, 1.0, -7.0, 6.0, 0.0),
Vector8d( 3.0, 0.0, -11.0, -2.0, -2.0, 5.0, 5.0, -2.0),
Vector8d( 7.0, 8.0, 3.0, 4.0, 4.0, -1.0, 1.0, 2.0)
);
static const Vector5d expectedd(std::sqrt(1248.0), 0.0, 20.0, std::sqrt(384.0), 0.0);
constexpr static Matrix5x8f af(
Vector8f(22.0f, 14.0f, -1.0f, -3.0f, 9.0f, 9.0f, 2.0f, 4.0f),
Vector8f(10.0f, 7.0f, 13.0f, -2.0f, 8.0f, 1.0f, -6.0f, 5.0f),
Vector8f( 2.0f, 10.0f, -1.0f, 13.0f, 1.0f, -7.0f, 6.0f, 0.0f),
Vector8f( 3.0f, 0.0f, -11.0f, -2.0f, -2.0f, 5.0f, 5.0f, -2.0f),
Vector8f( 7.0f, 8.0f, 3.0f, 4.0f, 4.0f, -1.0f, 1.0f, 2.0f)
);
static const Vector5f expectedf(std::sqrt(1248.0f), 0.0f, 20.0f, std::sqrt(384.0f), 0.0f);
template<class T> using Matrix5x8 = RectangularMatrix<5, 8, T>;
template<class T> using Matrix8 = Matrix<8, T>;
template<class T> using Matrix5 = Matrix<5, T>;
template<class T> using Vector8 = Vector<8, T>;
template<class T> using Vector5 = Vector<5, T>;
SvdTest::SvdTest() {
addTests({&SvdTest::testDouble,
&SvdTest::testFloat});
addTests<SvdTest>({&SvdTest::test<Float>,
&SvdTest::test<Double>});
}
void SvdTest::testDouble() {
Matrix5x8d u;
Vector5d w;
Matrix5d v;
std::tie(u, w, v) = Algorithms::svd(ad);
template<class T> void SvdTest::test() {
setTestCaseName(std::is_same<T, Double>::value ? "test<Double>" : "test<Float>");
/* Test composition */
Matrix8d u2(u[0], u[1], u[2], u[3], u[4], Vector8d(), Vector8d(), Vector8d());
Matrix5x8d w2 = Matrix5x8d::fromDiagonal(w);
CORRADE_COMPARE(u2*w2*v.transposed(), ad);
/* Test that V is unitary */
CORRADE_COMPARE(v*v.transposed(), Matrix5d{IdentityInit});
CORRADE_COMPARE(v.transposed()*v, Matrix5d{IdentityInit});
/* Test W */
CORRADE_COMPARE(w, expectedd);
}
constexpr const Matrix5x8<T> a{
Vector8<T>{T{22}, T{14}, T{ -1}, T{-3}, T{ 9}, T{ 9}, T{ 2}, T{ 4}},
Vector8<T>{T{10}, T{ 7}, T{ 13}, T{-2}, T{ 8}, T{ 1}, T{-6}, T{ 5}},
Vector8<T>{T{ 2}, T{10}, T{ -1}, T{13}, T{ 1}, T{-7}, T{ 6}, T{ 0}},
Vector8<T>{T{ 3}, T{ 0}, T{-11}, T{-2}, T{-2}, T{ 5}, T{ 5}, T{-2}},
Vector8<T>{T{ 7}, T{ 8}, T{ 3}, T{ 4}, T{ 4}, T{-1}, T{ 1}, T{ 2}}};
const Vector5<T> expected(std::sqrt(T{1248}), T{0}, T{20}, std::sqrt(T{384}), T{0});
void SvdTest::testFloat() {
Matrix5x8f u;
Vector5f w;
Matrix5f v;
std::tie(u, w, v) = Algorithms::svd(af);
Matrix5x8<T> u{NoInit};
Vector5<T> w{NoInit};
Matrix5<T> v{NoInit};
std::tie(u, w, v) = Algorithms::svd(a);
/* Test composition (single precision is not enough, test for similarity) */
Matrix8f u2(u[0], u[1], u[2], u[3], u[4], Vector8f(), Vector8f(), Vector8f());
Matrix5x8f w2 = Matrix5x8f::fromDiagonal(w);
CORRADE_VERIFY(Math::abs((u2*w2*v.transposed()-af).toVector()).max() < 1.0e-5f);
/* Test composition */
Matrix8<T> u2{u[0], u[1], u[2], u[3], u[4], Vector8<T>{}, Vector8<T>{}, Vector8<T>{}};
Matrix5x8<T> w2 = Matrix5x8<T>::fromDiagonal(w);
CORRADE_COMPARE(u2*w2*v.transposed(), a);
/* Test that V is unitary */
CORRADE_COMPARE(v*v.transposed(), Matrix5f{IdentityInit});
CORRADE_COMPARE(v.transposed()*v, Matrix5f{IdentityInit});
CORRADE_COMPARE(v*v.transposed(), Matrix5<T>{IdentityInit});
CORRADE_COMPARE(v.transposed()*v, Matrix5<T>{IdentityInit});
/* Test W (single precision is not enough, test for similarity) */
CORRADE_VERIFY(Math::abs(w-expectedf).max() < 1.0e-5f);
/* Test W */
CORRADE_COMPARE(w, expected);
}
}}}}

Loading…
Cancel
Save