diff options
Diffstat (limited to 'src/math/test/matrix_test.cpp')
-rw-r--r-- | src/math/test/matrix_test.cpp | 287 |
1 files changed, 287 insertions, 0 deletions
diff --git a/src/math/test/matrix_test.cpp b/src/math/test/matrix_test.cpp new file mode 100644 index 0000000..c7e9c01 --- /dev/null +++ b/src/math/test/matrix_test.cpp @@ -0,0 +1,287 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2012, Polish Portal of Colobot (PPC) +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// math/test/matrix_test.cpp + +/* Unit tests for Matrix struct + + Test data was randomly generated and the expected + results calculated using GNU Octave. + + */ + +#include "../func.h" +#include "../matrix.h" + +#include <cstdio> + +using namespace std; + +const float TEST_TOLERANCE = 1e-5; + +int TestCofactor() +{ + const float TEST_MATRIX[16] = + { + -0.306479, + -0.520207, + 0.127906, + 0.632922, + + -0.782876, + 0.015264, + 0.337479, + 1.466013, + + 0.072725, + -0.315123, + 1.613198, + -0.577377, + + 0.962397, + -1.320724, + 1.467588, + 0.579020 + }; + + const float EXPECTED_RESULTS[4][4] = + { + { 2.791599, -0.249952, 1.065075, -1.356570 }, + { 3.715943, -1.537511, 0.094812, -0.074520 }, + { 1.034500, -0.731752, -0.920756, -0.196235 }, + { 1.213928, -1.236857, 0.779741, -0.678482 } + }; + + Math::Matrix mat(TEST_MATRIX); + + for (int r = 0; r < 4; ++r) + { + for (int c = 0; c < 4; ++c) + { + float ret = mat.Cofactor(r, c); + float exp = EXPECTED_RESULTS[r][c]; + if (! Math::IsEqual(ret, exp, TEST_TOLERANCE)) + { + fprintf(stderr, "Cofactor r=%d, c=%d, %f (returned) != %f (expected)\n", r, c, ret, exp); + return 4*c+r; + } + } + } + + return 0; +} + +int TestDet() +{ + const float TEST_MATRIX[16] = + { + 0.85554, + 0.11624, + 1.30411, + 0.81467, + + 0.49692, + -1.92483, + -1.33543, + 0.85042, + + -0.16775, + 0.35344, + 1.40673, + 0.13961, + + 1.40709, + 0.11731, + 0.69042, + 0.91216 + }; + + const float EXPECTED_RESULT = 0.084360; + + float ret = Math::Matrix(TEST_MATRIX).Det(); + if (! Math::IsEqual(ret, EXPECTED_RESULT, TEST_TOLERANCE)) + { + fprintf(stderr, "Det %f (returned) != %f (expected)\n", ret, EXPECTED_RESULT); + return 1; + } + + return 0; +} + +int TestInvert() +{ + const float TEST_MATRIX[16] = + { + 1.4675123, + -0.2857923, + -0.0496217, + -1.2825408, + + -0.2804135, + -0.0826255, + -0.6825495, + 1.1661259, + + 0.0032798, + 0.5999200, + -1.8359883, + -1.1894424, + + -1.1501538, + -2.8792485, + 0.0299345, + 0.3730919 + }; + + const float EXPECTED_RESULT[16] = + { + 0.685863, + 0.562274, + -0.229722, + -0.132079, + + -0.266333, + -0.139862, + 0.054211, + -0.305568, + + -0.130817, + -0.494076, + -0.358226, + -0.047477, + + 0.069486, + 0.693649, + -0.261074, + -0.081200 + }; + + Math::Matrix mat(TEST_MATRIX); + mat.Invert(); + + if (! Math::MatricesEqual(mat, EXPECTED_RESULT, TEST_TOLERANCE)) + { + fprintf(stderr, "Invert mismatch\n"); + return 1; + } + + return 0; +} + +int TestMultiply() +{ + const float TEST_MATRIX_A[16] = + { + -1.931420, + 0.843410, + 0.476929, + -0.493435, + 1.425659, + -0.176331, + 0.129096, + 0.551081, + -0.543530, + -0.190783, + -0.084744, + 1.379547, + -0.473377, + 1.643398, + 0.400539, + 0.702937 + }; + + const float TEST_MATRIX_B[16] = + { + 0.3517561, + 1.3903778, + -0.8048254, + -0.4090024, + + -1.5542159, + -0.6798636, + 1.6003393, + -0.1467117, + + 0.5043620, + -0.0068779, + 2.0697285, + -0.0463650, + + 0.9605451, + -0.4620149, + 1.2525952, + -1.3409909 + }; + + const float EXPECTED_RESULT[16] = + { + 1.933875, + -0.467099, + 0.251638, + -0.805156, + + 1.232207, + -1.737383, + -1.023401, + 2.496859, + + -2.086953, + -0.044468, + 0.045688, + 2.570036, + + -2.559921, + -1.551155, + -0.244802, + 0.056808 + }; + + Math::Matrix matA(TEST_MATRIX_A); + Math::Matrix matB(TEST_MATRIX_B); + + Math::Matrix mat; + Math::MultiplyMatrices(matA, matB, mat); + if (! Math::MatricesEqual(mat, Math::Matrix(EXPECTED_RESULT), TEST_TOLERANCE ) ) + { + fprintf(stderr, "Multiply mismath!\n"); + return 1; + } + + return 0; +} + +int main() +{ + int result = 0; + + result = TestCofactor(); + if (result != 0) + return result; + + result = TestDet(); + if (result != 0) + return result; + + result = TestInvert(); + if (result != 0) + return result; + + result = TestMultiply(); + if (result != 0) + return result; + + return result; +} |