colobot/src/math/test/matrix_test.cpp

288 lines
4.8 KiB
C++
Raw Normal View History

2012-04-29 21:21:35 +00:00
// * 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;
}