From 0def678cc5da635d20abfd2b1aacb0be80d136b4 Mon Sep 17 00:00:00 2001 From: Pascal Serrarens Date: Fri, 19 Dec 2025 14:52:11 +0100 Subject: [PATCH] Updated Matrix tests --- Matrix.cpp | 4 + Matrix.h | 6 +- test/Matrix_test.cc | 315 +++++++++++++++++++++++++------------------- 3 files changed, 186 insertions(+), 139 deletions(-) diff --git a/Matrix.cpp b/Matrix.cpp index 0f99850..ec38bb5 100644 --- a/Matrix.cpp +++ b/Matrix.cpp @@ -1377,6 +1377,10 @@ void Matrix2Of::UpdateSlice(int rowStart, // return r; // } +template class Matrix2Of; +template class Matrix2Of; +template class Matrix2Of; + #pragma endregion Matrix2Of } // namespace LinearAlgebra diff --git a/Matrix.h b/Matrix.h index 2aa7e0f..26e2356 100644 --- a/Matrix.h +++ b/Matrix.h @@ -127,7 +127,7 @@ using Matrix1Int = Matrix1Of; using Matrix1Float = Matrix1Of; using Matrix1Double = Matrix1Of; -using Matrix1 = Matrix1Float; +//using Matrix1 = Matrix1Float; /* class Matrix2; @@ -406,10 +406,6 @@ Matrix2Of operator/(U f, const Matrix2Of& m) { #pragma endregion friend functions -template class Matrix2Of; -template class Matrix2Of; -template class Matrix2Of; - using Matrix2Int = Matrix2Of; using Matrix2Float = Matrix2Of; using Matrix2Double = Matrix2Of; diff --git a/test/Matrix_test.cc b/test/Matrix_test.cc index 4cb66b8..7f167eb 100644 --- a/test/Matrix_test.cc +++ b/test/Matrix_test.cc @@ -5,211 +5,258 @@ #include "Matrix.h" -TEST(Matrix2, Zero) { - // Test case 1: 2x2 zero matrix - Matrix2 zeroMatrix = Matrix2::Zero(2, 2); - EXPECT_TRUE(zeroMatrix.nRows == 2); - EXPECT_TRUE(zeroMatrix.nCols == 2); - for (int i = 0; i < zeroMatrix.nValues; ++i) { - EXPECT_TRUE(zeroMatrix.data[i] == 0.0f); - } - std::cout << "Test case 1 passed: 2x2 zero matrix\n"; - - // Test case 2: 3x3 zero matrix - zeroMatrix = Matrix2::Zero(3, 3); - EXPECT_TRUE(zeroMatrix.nRows == 3); - EXPECT_TRUE(zeroMatrix.nCols == 3); - for (int i = 0; i < zeroMatrix.nValues; ++i) { - EXPECT_TRUE(zeroMatrix.data[i] == 0.0f); - } - std::cout << "Test case 2 passed: 3x3 zero matrix\n"; - - // Test case 3: 1x1 zero matrix - zeroMatrix = Matrix2::Zero(1, 1); - EXPECT_TRUE(zeroMatrix.nRows == 1); - EXPECT_TRUE(zeroMatrix.nCols == 1); - EXPECT_TRUE(zeroMatrix.data[0] == 0.0f); - std::cout << "Test case 3 passed: 1x1 zero matrix\n"; - - // Test case 4: 0x0 matrix (edge case) - zeroMatrix = Matrix2::Zero(0, 0); - EXPECT_TRUE(zeroMatrix.nRows == 0); - EXPECT_TRUE(zeroMatrix.nCols == 0); - EXPECT_TRUE(zeroMatrix.data == nullptr); - std::cout << "Test case 4 passed: 0x0 matrix\n"; +template +bool isDefaultValue(const T& value) { + // Use std::is_floating_point to determine if T is a floating type + if constexpr (std::is_arithmetic::value) { + return value == T(); // Default constructed value for T (0 or 0.0) + } + //return false; // Improve this if you handle non-arithmetic types } -TEST(Matrix2, Multiplication) { - // Test 1: Multiplying two 2x2 matrices - float dataA[] = {1, 2, 3, 4}; - float dataB[] = {5, 6, 7, 8}; - Matrix2 A(dataA, 2, 2); - Matrix2 B(dataB, 2, 2); +using MatrixTypes = ::testing::Types, Matrix2Of>; - Matrix2 result = A * B; +template +class Matrix2Test : public ::testing::Test {}; +TYPED_TEST_SUITE(Matrix2Test, MatrixTypes); - float expectedData[] = {19, 22, 43, 50}; - for (int i = 0; i < 4; ++i) - EXPECT_TRUE(result.data[i] == expectedData[i]); - std::cout << "Test 1 passed: 2x2 matrix multiplication.\n"; - - - // Test 2: Multiplying a 3x2 matrix with a 2x3 matrix - float dataC[] = {1, 2, 3, 4, 5, 6}; - float dataD[] = {7, 8, 9, 10, 11, 12}; - Matrix2 C(dataC, 3, 2); - Matrix2 D(dataD, 2, 3); - - Matrix2 result2 = C * D; - - float expectedData2[] = {27, 30, 33, 61, 68, 75, 95, 106, 117}; - for (int i = 0; i < 9; ++i) - EXPECT_TRUE(result2.data[i] == expectedData2[i]); - std::cout << "Test 2 passed: 3x2 * 2x3 matrix multiplication.\n"; - - // Test 3: Multiplying with a zero matrix +TYPED_TEST(Matrix2Test, Zero) { + using Matrix2 = TypeParam; + // Test case 1: 2x2 zero matrix Matrix2 zeroMatrix = Matrix2::Zero(2, 2); - Matrix2 result3 = A * zeroMatrix; + EXPECT_TRUE(zeroMatrix.RowCount() == 2); + EXPECT_TRUE(zeroMatrix.ColCount() == 2); + for (unsigned int rowIx = 0; rowIx < zeroMatrix.RowCount(); ++rowIx) { + for (unsigned int colIx = 0; colIx < zeroMatrix.ColCount(); ++colIx) + EXPECT_TRUE(isDefaultValue(zeroMatrix(rowIx, colIx))); + } + std::cout << "Test case 1 passed: 2x2 zero matrix\n"; - for (int i = 0; i < 4; ++i) - EXPECT_TRUE(result3.data[i] == 0); - std::cout << "Test 3 passed: Multiplication with zero matrix.\n"; - - // Test 4: Multiplying with an identity matrix - Matrix2 identityMatrix = Matrix2::Identity(2); - Matrix2 result4 = A * identityMatrix; + // Test case 2: 3x3 zero matrix + zeroMatrix = Matrix2::Zero(3, 3); + EXPECT_TRUE(zeroMatrix.RowCount() == 3); + EXPECT_TRUE(zeroMatrix.ColCount() == 3); + for (unsigned int rowIx = 0; rowIx < zeroMatrix.RowCount(); ++rowIx) { + for (unsigned int colIx = 0; colIx < zeroMatrix.ColCount(); ++colIx) + EXPECT_TRUE(isDefaultValue(zeroMatrix(rowIx, colIx))); + } + std::cout << "Test case 2 passed: 3x3 zero matrix\n"; - for (int i = 0; i < 4; ++i) - EXPECT_TRUE(result4.data[i] == A.data[i]); - std::cout << "Test 4 passed: Multiplication with identity matrix.\n"; - + // Test case 3: 1x1 zero matrix + zeroMatrix = Matrix2::Zero(1, 1); + EXPECT_TRUE(zeroMatrix.RowCount() == 1); + EXPECT_TRUE(zeroMatrix.ColCount() == 1); + EXPECT_TRUE(isDefaultValue(zeroMatrix(0, 0))); + std::cout << "Test case 3 passed: 1x1 zero matrix\n"; + + // Test case 4: 0x0 matrix (edge case) + zeroMatrix = Matrix2::Zero(0, 0); + EXPECT_TRUE(zeroMatrix.RowCount() == 0); + EXPECT_TRUE(zeroMatrix.ColCount() == 0); + std::cout << "Test case 4 passed: 0x0 matrix\n"; } -TEST(MatrixSingle, Init) { +// TYPED_TEST(Matrix2Test, Multiplication) { +// using T = typename TestFixture::TypeParam; +// using Matrix2 = TypeParam; +// // Test 1: Multiplying two 2x2 matrices +// T dataA[] = {1, 2, 3, 4}; +// T dataB[] = {5, 6, 7, 8}; +// Matrix2 A(dataA, 2, 2); +// Matrix2 B(dataB, 2, 2); + +// Matrix2 result = A * B; + +// float expectedData[] = {19, 22, 43, 50}; +// for (int i = 0; i < 4; ++i) +// EXPECT_TRUE(result.data[i] == expectedData[i]); +// std::cout << "Test 1 passed: 2x2 matrix multiplication.\n"; + +// // Test 2: Multiplying a 3x2 matrix with a 2x3 matrix +// float dataC[] = {1, 2, 3, 4, 5, 6}; +// float dataD[] = {7, 8, 9, 10, 11, 12}; +// Matrix2 C(dataC, 3, 2); +// Matrix2 D(dataD, 2, 3); + +// Matrix2 result2 = C * D; + +// float expectedData2[] = {27, 30, 33, 61, 68, 75, 95, 106, 117}; +// for (int i = 0; i < 9; ++i) +// EXPECT_TRUE(result2.data[i] == expectedData2[i]); +// std::cout << "Test 2 passed: 3x2 * 2x3 matrix multiplication.\n"; + +// // Test 3: Multiplying with a zero matrix +// Matrix2 zeroMatrix = Matrix2::Zero(2, 2); +// Matrix2 result3 = A * zeroMatrix; + +// for (int i = 0; i < 4; ++i) +// EXPECT_TRUE(result3.data[i] == 0); +// std::cout << "Test 3 passed: Multiplication with zero matrix.\n"; + +// // Test 4: Multiplying with an identity matrix +// Matrix2 identityMatrix = Matrix2::Identity(2); +// Matrix2 result4 = A * identityMatrix; + +// for (int i = 0; i < 4; ++i) +// EXPECT_TRUE(result4.data[i] == A.data[i]); +// std::cout << "Test 4 passed: Multiplication with identity matrix.\n"; +// } + +template +class Matrix1Test : public ::testing::Test { + protected: +}; +TYPED_TEST_SUITE(Matrix1Test, MatrixTypes); + +TYPED_TEST(Matrix2Test, Init) { + using Matrix2 = TypeParam; // zero - MatrixOf m0 = MatrixOf(0, 0); + Matrix2 m0 = Matrix2(0, 0); // one - float data1[] = {1.0F}; - MatrixOf m1 = MatrixOf(1, 1, data1); + Matrix2 m1 = Matrix2(1, 1); + m1(0, 0) = 1; // two - float data2[] = {1.0F, 2.0F, 3.0F, 4.0F}; - MatrixOf m2 = MatrixOf(2, 2, data2); + Matrix2 m2 = Matrix2(2, 2); + m2(0, 0) = 1; + m2(0, 1) = 2; + m2(1, 0) = 3; + m2(1, 1) = 4; // negative - // MatrixOf m_1 = MatrixOf(-1, -1); + // Matrix1 m_1 = Matrix1(-1, -1); // parameters are unsigned } -TEST(MatrixSingle, Transpose) { - float data1[] = {1.0F}; - MatrixOf m = MatrixOf(1, 1, data1); +TYPED_TEST(Matrix2Test, Transpose) { + using Matrix2 = TypeParam; + Matrix2 m = Matrix2(1, 1); + m(0, 0) = 1; - MatrixOf r = MatrixOf(1, 1); - m.Transpose(&r); + Matrix2 r = Matrix2(1, 1); + m = r.Transposed(); // 2 x 2 - float data3[] = {1.0F, 2.0F, 3.0F, 4.0F}; - MatrixOf m22 = MatrixOf(2, 2, data3); + Matrix2 m22 = Matrix2(2, 2); + m22(0, 0) = 1; + m22(0, 1) = 2; + m22(1, 0) = 3; + m22(1, 1) = 4; EXPECT_EQ(m22.RowCount(), 2); EXPECT_EQ(m22.ColCount(), 2); - float data4[] = {0.0F, 0.0F, 0.0F, 0.0F}; - MatrixOf r22 = MatrixOf(2, 2, data4); + Matrix2 r22 = Matrix2(2, 2); + r22(0, 0) = 1; + r22(0, 1) = 2; + r22(1, 0) = 3; + r22(1, 1) = 4; EXPECT_EQ(r22.RowCount(), 2); EXPECT_EQ(r22.ColCount(), 2); - m22.Transpose(&r22); + r22 = m22.Transposed(); EXPECT_EQ(r22.RowCount(), 2); EXPECT_EQ(r22.ColCount(), 2); - EXPECT_FLOAT_EQ(r22.Get(0, 0), 1.0F); - EXPECT_FLOAT_EQ(r22.Get(0, 1), 3.0F); - EXPECT_FLOAT_EQ(r22.Get(1, 0), 2.0F); - EXPECT_FLOAT_EQ(r22.Get(1, 1), 4.0F); + EXPECT_EQ(r22(0, 0), 1); + EXPECT_EQ(r22(0, 1), 3); + EXPECT_EQ(r22(1, 0), 2); + EXPECT_EQ(r22(1, 1), 4); // 1 x 2 - float data12[] = {1.0F, 2.0F}; - MatrixOf m12 = MatrixOf(1, 2, data12); + Matrix2 m12 = Matrix2(1, 2); + m12(0, 0) = 1; + m12(0, 1) = 2; EXPECT_EQ(m12.RowCount(), 1); EXPECT_EQ(m12.ColCount(), 2); - float data21[] = {0.0F, 0.0F}; - MatrixOf r21 = MatrixOf(2, 1, data21); + //float data21[] = {0.0F, 0.0F}; + Matrix2 r21 = Matrix2(2, 1); + r21(0,0) = 0; + r21(1,0) = 0; EXPECT_EQ(r21.RowCount(), 2); EXPECT_EQ(r21.ColCount(), 1); - m12.Transpose(&r21); + //m12.Transpose(&r21); + r21 = m12.Transposed(); EXPECT_EQ(r21.RowCount(), 2); EXPECT_EQ(r21.ColCount(), 1); - EXPECT_FLOAT_EQ(r21.Get(0, 0), 1.0F); - EXPECT_FLOAT_EQ(r21.Get(1, 0), 2.0F); + EXPECT_EQ(r21(0, 0), 1); + EXPECT_EQ(r21(1, 0), 2); // changing dimensions, same size is okay - MatrixOf r12 = MatrixOf(1, 2, data21); + Matrix2 r12 = Matrix2::Zero(1, 2); EXPECT_EQ(r12.RowCount(), 1); EXPECT_EQ(r12.ColCount(), 2); - m12.Transpose(&r12); + //m12.Transpose(&r12); + r12 = m12.Transposed(); EXPECT_EQ(r12.RowCount(), 2); EXPECT_EQ(r12.ColCount(), 1); - EXPECT_FLOAT_EQ(r12.Get(0, 0), 1.0F); - EXPECT_FLOAT_EQ(r12.Get(0, 1), 2.0F); + EXPECT_EQ(r12(0, 0), 1); + EXPECT_EQ(r12(0, 1), 2); } -TEST(MatrixSingle, Multiply) { - float m12data[] = {1.0F, 2.0F}; - MatrixOf m12 = MatrixOf(1, 2, m12data); +TYPED_TEST(Matrix2Test, Multiply) { + using Matrix1 = TypeParam; + Matrix1 m12 = Matrix1(1, 2); + m12(0,0) = 1; + m12(0,1) = 2; EXPECT_EQ(m12.RowCount(), 1); EXPECT_EQ(m12.ColCount(), 2); - EXPECT_FLOAT_EQ(m12.Get(0, 0), 1.0F); - EXPECT_FLOAT_EQ(m12.Get(0, 1), 2.0F); + EXPECT_EQ(m12(0, 0), 1); + EXPECT_EQ(m12(0, 1), 2); - float m21data[] = {3.0F, 4.0F}; - MatrixOf m21 = MatrixOf(2, 1, m21data); + //float m21data[] = {3.0F, 4.0F}; + Matrix1 m21 = Matrix1(2, 1); //, m21data); + m21(0,0) = 3; + m21(1,0) = 4; EXPECT_EQ(m21.RowCount(), 2); EXPECT_EQ(m21.ColCount(), 1); - EXPECT_FLOAT_EQ(m21.Get(0, 0), 3.0F); - EXPECT_FLOAT_EQ(m21.Get(1, 0), 4.0F); + EXPECT_EQ(m21(0, 0), 3); + EXPECT_EQ(m21(1, 0), 4); - float r11data[] = {0.0F}; - MatrixOf r11 = MatrixOf(1, 1, r11data); + //float r11data[] = {0.0F}; + Matrix1 r11 = Matrix1::Zero(1, 1); //, r11data); EXPECT_EQ(r11.RowCount(), 1); EXPECT_EQ(r11.ColCount(), 1); - MatrixOf::Multiply(&m12, &m21, &r11); + r11 = m12 * m21; //Matrix1::Multiply(&m12, &m21, &r11); EXPECT_EQ(r11.RowCount(), 1); EXPECT_EQ(r11.ColCount(), 1); - EXPECT_FLOAT_EQ(r11.Get(0, 0), 11.0F); + EXPECT_EQ(r11(0, 0), 11); - float r22data[] = {0.0F, 0.0F, 0.0F, 0.0F}; - MatrixOf r22 = MatrixOf(2, 2, r22data); + //float r22data[] = {0.0F, 0.0F, 0.0F, 0.0F}; + Matrix1 r22 = Matrix1::Zero(2, 2); //, r22data); - MatrixOf::Multiply(&m21, &m12, &r22); + //Matrix1::Multiply(&m21, &m12, &r22); + r22 = m21 * m12; EXPECT_EQ(r22.RowCount(), 2); EXPECT_EQ(r22.ColCount(), 2); - EXPECT_FLOAT_EQ(r22.Get(0, 0), 3.0F); - EXPECT_FLOAT_EQ(r22.Get(0, 1), 4.0F); - EXPECT_FLOAT_EQ(r22.Get(1, 0), 6.0F); - EXPECT_FLOAT_EQ(r22.Get(1, 1), 8.0F); + EXPECT_EQ(r22(0, 0), 3); + EXPECT_EQ(r22(0, 1), 6); + EXPECT_EQ(r22(1, 0), 4); + EXPECT_EQ(r22(1, 1), 8); } -TEST(MatrixSingle, Multiply_Vector3) { - Vector3 v = Vector3(1.0, 2.0, 3.0); - Vector3 r = Vector3::zero; +// TYPED_TEST(Matrix2Test, Multiply_Vector3) { +// using Matrix2 = TypeParam; +// auto v = Vector3(1.0, 2.0, 3.0); +// Matrix1Of r = Matrix1Of::zero; - // float m13data[] = {3.0, 4.0, 5.0}; - // MatrixOf m13 = MatrixOf(1, 3, m13data); - // Vector3 r = MatrixOf::Multiply(&m13, v); +// // float m13data[] = {3.0, 4.0, 5.0}; +// // Matrix1 m13 = Matrix1(1, 3, m13data); +// // Vector3 r = Matrix1::Multiply(&m13, v); - float m33data[] = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}; - MatrixOf m33 = MatrixOf(3, 3, m33data); - r = MatrixOf::Multiply(&m33, v); - EXPECT_FLOAT_EQ(Vector3::Distance(r, Vector3(1.0f, 2.0f, 3.0f)), 0); -} +// //float m33data[] = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}; +// Matrix2 m33 = Matrix2::Identity(3, 3); //, m33data); + +// //r = Matrix1::Multiply(&m33, v); +// r = m33 * v; +// EXPECT_FLOAT_EQ(Vector3::Distance(r, Vector3(1.0f, 2.0f, 3.0f)), 0); +// } #endif \ No newline at end of file