libcruft-util/test/maths_matrix.cpp

134 lines
4.0 KiB
C++
Raw Normal View History

2011-05-23 17:18:52 +10:00
#include "../debug.hpp"
2011-11-04 17:28:04 +11:00
#include "../maths/matrix.hpp"
2011-05-23 17:18:52 +10:00
#include "../maths.hpp"
#include <iostream>
#include <cmath>
using namespace maths;
using namespace std;
std::ostream&
operator <<(std::ostream &os, const matrix &m) {
for (unsigned int i = 0; i < m.rows (); ++i) {
for (unsigned int j = 0; j < m.columns (); ++j) {
os << m[i][j];
if (j != m.columns () - 1)
os << ", ";
}
if (i != m.rows () - 1)
os << "\n";
}
return os;
}
void
2011-05-23 17:18:52 +10:00
test_zeroes (const matrix &m) {
assert (m.rows ());
assert (m.columns ());
for (unsigned int i = 0; i < m.rows (); ++i)
2011-05-23 17:18:52 +10:00
for (unsigned int j = 0; j < m.columns (); ++j)
CHECK (almost_equal (m[i][j], 0.0));
2011-05-23 17:18:52 +10:00
}
void
test_identity (const matrix &m) {
assert (m.rows () == m.columns ());
for (unsigned int i = 0; i < m.rows (); ++i)
for (unsigned int j = 0; j < m.columns (); ++j)
if (i == j) {
CHECK (almost_equal (m[i][j], 1.0));
} else {
CHECK (almost_equal (m[i][j], 0.0));
}
2011-05-23 17:18:52 +10:00
}
int
main (int, char **) {
for (unsigned int i = 1; i < 10; ++i) {
test_zeroes (matrix::zeroes (i));
test_identity (matrix::identity (i));
}
for (unsigned int i = 3; i < 10; i += 2)
2012-05-11 12:34:21 +10:00
CHECK (matrix::magic (i).is_magic ());
2011-05-23 17:18:52 +10:00
// Create a small matrix with unique element values for comparison tests.
// This should be non-square so that row- vs. column-major problems can
// be seen.
matrix a4x2 (4, 2, { 0, 1,
2, 3,
4, 5,
6, 7 });
2012-05-11 12:34:21 +10:00
CHECK_EQ (a4x2, a4x2);
2011-05-23 17:18:52 +10:00
// Test that copy constructors work correctly. Keep this value around so
// that we can check the following operators don't modify the original
// value.
CHECK_EQ (a4x2, a4x2);
2011-05-23 17:18:52 +10:00
// Check multiplication by identity results in the original value.
2012-05-11 12:34:21 +10:00
CHECK_EQ (a4x2, a4x2 * matrix::identity (a4x2.columns ()));
2011-05-23 17:18:52 +10:00
matrix seq2x2(2, 2, { 1, 2, 3, 4 });
matrix magic3(3, 3, { 2, 7, 6,
9, 5, 1,
4, 3, 8 });
matrix magic4(4, 4, { 16, 2, 3, 13,
5, 11, 10, 8,
9, 7, 6, 12,
4, 14, 15, 1 });
2012-05-11 12:34:21 +10:00
CHECK_EQ (magic3[0][0], 2.0);
CHECK_EQ (magic3[0][1], 7.0);
CHECK_EQ (magic3[0][2], 6.0);
CHECK_EQ (magic3[1][0], 9.0);
CHECK_EQ (magic3[1][1], 5.0);
CHECK_EQ (magic3[1][2], 1.0);
CHECK_EQ (magic3[2][0], 4.0);
CHECK_EQ (magic3[2][1], 3.0);
CHECK_EQ (magic3[2][2], 8.0);
2014-08-18 22:14:31 +10:00
2012-05-11 12:34:21 +10:00
CHECK_EQ (seq2x2.determinant (), -2.0);
CHECK_EQ (magic3.determinant (), -360.0);
2011-05-23 17:18:52 +10:00
CHECK ( seq2x2.is_square ());
CHECK ( magic3.is_square ());
CHECK (! a4x2.is_square ());
2011-05-23 17:18:52 +10:00
2012-05-11 12:34:21 +10:00
CHECK_EQ (seq2x2.inverse (), matrix (2, 2, { -2.0, 1.0,
2011-05-23 17:18:52 +10:00
1.5, -0.5 }));
2012-05-11 12:34:21 +10:00
CHECK_EQ (magic3.inverse (), matrix (3, 3, { -37.0, 38.0, 23.0,
2011-05-23 17:18:52 +10:00
68.0, 8.0, -52.0,
- 7.0, -22.0, 53.0 }) /= 360.0);
matrix invertible4 (4, 4, { 4, 14, 15, 1,
2014-08-18 22:14:31 +10:00
9, 7, 6, 12,
2011-05-23 17:18:52 +10:00
5, 11, 10, 8,
0, 0, 0, 1 });
2012-05-11 12:34:21 +10:00
CHECK_EQ (invertible4.inverse (), matrix (4, 4, { 4, 25, -21, -136,
2011-05-23 17:18:52 +10:00
-60, -35, 111, -408,
64, 26, -98, 408,
0, 0, 0, 136 }) /= 136);
const matrix homo3x3 (3, 3, { 1, 2, 0,
3, 4, 0,
0, 0, 1 });
CHECK (homo3x3.is_homogeneous ());
CHECK (!matrix::zeroes (3).is_homogeneous ());
CHECK ( matrix::identity (3).is_homogeneous ());
CHECK (invertible4.is_homogeneous ());
2011-05-23 17:18:52 +10:00
return EXIT_SUCCESS;
}