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;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-08-18 22:16:18 +10:00
|
|
|
void
|
2011-05-23 17:18:52 +10:00
|
|
|
test_zeroes (const matrix &m) {
|
|
|
|
assert (m.rows ());
|
|
|
|
assert (m.columns ());
|
|
|
|
|
2014-08-18 22:16:18 +10:00
|
|
|
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)
|
2015-01-28 14:49:34 +11:00
|
|
|
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)
|
2014-05-09 13:13:18 +10:00
|
|
|
if (i == j) {
|
2015-01-28 14:49:34 +11:00
|
|
|
CHECK (almost_equal (m[i][j], 1.0));
|
2014-05-09 13:13:18 +10:00
|
|
|
} else {
|
2015-01-28 14:49:34 +11:00
|
|
|
CHECK (almost_equal (m[i][j], 0.0));
|
2014-05-09 13:13:18 +10:00
|
|
|
}
|
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.
|
2014-12-16 15:28:59 +11:00
|
|
|
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
|
|
|
|
2015-01-28 14:49:34 +11: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 });
|
2015-01-28 14:49:34 +11:00
|
|
|
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;
|
|
|
|
}
|