LCOV - code coverage report
Current view: top level - tests/linalg - t_linsys.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 86 86 100.0 %
Date: 2024-05-13 05:06:06 Functions: 44 44 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /**
       2             :  * Unit tests for the Linear Algebra module's Linear Systems class
       3             :  */
       4             : #include <cmath>
       5             : #include <cstdint>
       6             : #include <cstdlib>
       7             : #include <gtest/gtest.h>
       8             : #include <iostream>
       9             : #include <openGPMP/linalg/linsys.hpp>
      10             : #include <stdexcept>
      11             : #include <utility>
      12             : #include <vector>
      13             : 
      14             : const double TOLERANCE = 1e-3;
      15             : 
      16           4 : TEST(LinSysTest, SolveGauss) {
      17             :     std::vector<std::vector<double>> square_mat = {{3.0, 2.0, -4.0, 3.0},
      18             :                                                    {2.0, 3.0, 3.0, 15.0},
      19           6 :                                                    {5.0, -3, 1.0, 14.0}};
      20           1 :     gpmp::linalg::LinSys linSysSquare(square_mat);
      21             : 
      22             :     // execute solve_gauss method
      23           1 :     std::vector<double> solution = linSysSquare.solve_gauss();
      24             : 
      25             :     // expected solution for the test matrix
      26           1 :     std::vector<double> expected_sol = {3, 1, 2};
      27             : 
      28             :     // assert solution vector
      29           1 :     ASSERT_EQ(solution.size(), expected_sol.size());
      30             : 
      31           4 :     for (int i = 0; i < solution.size(); i++) {
      32           3 :         ASSERT_NEAR(solution[i], expected_sol[i], TOLERANCE);
      33             :     }
      34           1 : }
      35             : 
      36           4 : TEST(LinSysTest, DeterminantTest) {
      37             :     /*std::vector<std::vector<double>> square_mat = {
      38             :         {3.0, 2.0, -4.0, 3.0},
      39             :         {2.0, 3.0, 3.0, 15.0},
      40             :         {5.0, -3.0, 1.0, 14.0},
      41             :         {1.0, 1.0, 1.0, 6.0}};
      42             :     */
      43             : 
      44           5 :     std::vector<std::vector<double>> square_mat = {{2, 1}, {5, 3}};
      45           1 :     gpmp::linalg::LinSys linSysSquare(square_mat);
      46             : 
      47           1 :     double det = linSysSquare.determinant();
      48             : 
      49           1 :     double expectedDet = 1;
      50             : 
      51           1 :     ASSERT_DOUBLE_EQ(expectedDet, det);
      52           1 : }
      53             : 
      54           4 : TEST(LinSysTest, DeterminantTestB) {
      55             :     std::vector<std::vector<double>> square_mat = {{4, 4, 3, 1},
      56             :                                                    {2, 8, 8, 6},
      57             :                                                    {4, 3, 2, 2},
      58           7 :                                                    {4, 1, 5, 6}};
      59             : 
      60           1 :     gpmp::linalg::LinSys linSysSquare(square_mat);
      61             : 
      62           1 :     double det = linSysSquare.determinant();
      63             : 
      64           1 :     double expectedDet = -226;
      65             : 
      66           1 :     ASSERT_DOUBLE_EQ(expectedDet, det);
      67           1 : }
      68             : 
      69           4 : TEST(LinSysTest, LUDecompositionTest) {
      70             :     // Define a square matrix
      71             :     std::vector<std::vector<double>> square_mat = {{3.0, 2.0, -4.0, 3.0},
      72             :                                                    {2.0, 3.0, 3.0, 15.0},
      73             :                                                    {5.0, -3.0, 1.0, 14.0},
      74           7 :                                                    {1.0, 1.0, 1.0, 6.0}};
      75             : 
      76             :     // expected lower
      77             :     std::vector<std::vector<double>> L = {{1, 0, 0, 0},
      78             :                                           {0.666667, 1, 0, 0},
      79             :                                           {1.66667, -3.8, 1, 0},
      80           7 :                                           {0.333333, 0.2, 0.0410959, 1}};
      81             : 
      82             :     // expected upper
      83             :     std::vector<std::vector<double>> U = {{3, 2, -4, 3},
      84             :                                           {0, 1.66667, 5.66667, 13},
      85             :                                           {0, 0, 29.2, 58.4},
      86           7 :                                           {0, 0, 0, 0}};
      87             : 
      88             :     // Create a LinSys object
      89           1 :     gpmp::linalg::LinSys linSysSquare(square_mat);
      90             : 
      91             :     // execute LU decomposition
      92           1 :     auto LU_mtx = linSysSquare.lu_decomp();
      93             : 
      94             :     // Check the dimensions of L and U
      95           1 :     ASSERT_EQ(LU_mtx.first.size(), L.size());
      96           1 :     ASSERT_EQ(LU_mtx.second.size(), U.size());
      97             : 
      98             :     // Check each element of L and U against the expected values
      99           5 :     for (uint32_t i = 0; i < LU_mtx.first.size(); i++) {
     100          20 :         for (uint32_t j = 0; j < LU_mtx.first[i].size(); j++) {
     101          16 :             ASSERT_NEAR(LU_mtx.first[i][j], L[i][j], TOLERANCE);
     102          16 :             ASSERT_NEAR(LU_mtx.second[i][j], U[i][j], TOLERANCE);
     103             :         }
     104             :     }
     105           1 : }
     106             : 
     107           4 : TEST(LinSysTest, IsSymmetric) {
     108             :     //  symmetric positive-definite matrix
     109             :     std::vector<std::vector<double>> symmetric_mat = {{4.0, 1.0, 2.0},
     110             :                                                       {1.0, 5.0, 3.0},
     111           6 :                                                       {2.0, 3.0, 6.0}};
     112           1 :     gpmp::linalg::LinSys linSysSymmetric(symmetric_mat);
     113             : 
     114           1 :     EXPECT_TRUE(linSysSymmetric.is_symmetric());
     115             : 
     116             :     //  non-symmetric matrix
     117             :     std::vector<std::vector<double>> nonSymmetric_mat = {{1.0, 2.0, 3.0},
     118             :                                                          {2.0, 4.0, 5.0},
     119           7 :                                                          {3.0, 5.0, 6.0}};
     120           2 :     gpmp::linalg::LinSys linSysNonSymmetric(nonSymmetric_mat);
     121             : 
     122           1 :     EXPECT_FALSE(linSysNonSymmetric.is_symmetric());
     123           1 : }
     124             : 
     125           4 : TEST(LinSysTest, FrobeniusNorm) {
     126             :     std::vector<std::vector<double>> test_mat = {{1.0, 2.0, 3.0},
     127             :                                                  {4.0, 5.0, 6.0},
     128           6 :                                                  {7.0, 8.0, 9.0}};
     129           1 :     gpmp::linalg::LinSys linSys(test_mat);
     130             : 
     131             :     // expected Frobenius norm for the test matrix
     132           1 :     double expected_norm = std::sqrt(1 * 1 + 2 * 2 + 3 * 3 + 4 * 4 + 5 * 5 +
     133             :                                      6 * 6 + 7 * 7 + 8 * 8 + 9 * 9);
     134             : 
     135           1 :     EXPECT_DOUBLE_EQ(linSys.frobenius_norm(), expected_norm);
     136           1 : }
     137             : 
     138           4 : TEST(LinSysTest, OneNorm) {
     139             :     std::vector<std::vector<double>> testMat = {{1.0, 2.0, 3.0},
     140             :                                                 {4.0, 5.0, 6.0},
     141           6 :                                                 {7.0, 8.0, 9.0}};
     142           1 :     gpmp::linalg::LinSys linSys(testMat);
     143             : 
     144             :     // expected 1-norm for the test matrix
     145           1 :     double expectedNorm = 18;
     146             : 
     147           1 :     EXPECT_DOUBLE_EQ(linSys.one_norm(), expectedNorm);
     148           1 : }
     149             : 
     150           4 : TEST(LinSysTest, InfNorm) {
     151             :     std::vector<std::vector<double>> testMat = {{1.0, 2.0, 3.0},
     152             :                                                 {4.0, 5.0, 6.0},
     153           6 :                                                 {7.0, 8.0, 9.0}};
     154           1 :     gpmp::linalg::LinSys linSys(testMat);
     155             : 
     156           1 :     double expectedNorm = 24;
     157             : 
     158           1 :     EXPECT_DOUBLE_EQ(linSys.inf_norm(), expectedNorm);
     159           1 : }
     160             : 
     161           4 : TEST(LinSysTest, DiagonallyDominant) {
     162             :     // diagonally dominant matrix
     163             :     std::vector<std::vector<double>> diagonallyDominantMat = {{4.0, -1.0, 0.0},
     164             :                                                               {-1.0, 4.0, -1.0},
     165           6 :                                                               {0.0, -1.0, 3.0}};
     166           1 :     gpmp::linalg::LinSys LinSysA(diagonallyDominantMat);
     167             : 
     168           1 :     EXPECT_TRUE(LinSysA.diagonally_dominant());
     169             : 
     170             :     // non-diagonally dominant matrix
     171             :     std::vector<std::vector<double>> nonDiagonallyDominantMat = {
     172             :         {1.0, 2.0, 3.0},
     173             :         {4.0, 5.0, 6.0},
     174           7 :         {7.0, 8.0, 9.0}};
     175           2 :     gpmp::linalg::LinSys LinSysB(nonDiagonallyDominantMat);
     176             : 
     177           1 :     EXPECT_FALSE(LinSysB.diagonally_dominant());
     178           1 : }
     179             : 
     180           4 : TEST(LinSysTest, IsConsistent) {
     181             :     // create a consistent system
     182             :     std::vector<std::vector<double>> consistentMat = {{1.0, 2.0, 3.0},
     183             :                                                       {4.0, 5.0, 6.0},
     184           6 :                                                       {7.0, 8.0, 9.0}};
     185           1 :     gpmp::linalg::LinSys linSysConsistent(consistentMat);
     186             : 
     187           1 :     EXPECT_TRUE(linSysConsistent.is_consistent());
     188             : 
     189             :     // create an inconsistent system
     190             :     std::vector<std::vector<double>> inconsistentMat = {{0.0, 0.0, 0.0, 1.0},
     191             :                                                         {0.0, 0.0, 0.0, 2.0},
     192           7 :                                                         {0.0, 0.0, 0.0, 3.0}};
     193           2 :     gpmp::linalg::LinSys linSysInconsistent(inconsistentMat);
     194             : 
     195             :     // check if the system is inconsistent
     196           1 :     EXPECT_FALSE(linSysInconsistent.is_consistent());
     197           1 : }
     198             : 
     199           4 : TEST(LinSysTest, IsHomogeneous) {
     200             :     // create a homogeneous system
     201             :     std::vector<std::vector<double>> homogeneousMat = {{1.0, 2.0, 3.0, 0.0},
     202             :                                                        {4.0, 5.0, 6.0, 0.0},
     203           6 :                                                        {7.0, 8.0, 9.0, 0.0}};
     204           1 :     gpmp::linalg::LinSys LinSysA(homogeneousMat);
     205             : 
     206           1 :     EXPECT_TRUE(LinSysA.is_homogeneous());
     207             : 
     208             :     // create a non-homogeneous system
     209             :     std::vector<std::vector<double>> nonHomogeneousMat = {{1.0, 2.0, 3.0, 1.0},
     210             :                                                           {4.0, 5.0, 6.0, 2.0},
     211           7 :                                                           {7.0, 8.0, 9.0, 3.0}};
     212           2 :     gpmp::linalg::LinSys LinSysB(nonHomogeneousMat);
     213             : 
     214           1 :     EXPECT_FALSE(LinSysB.is_homogeneous());
     215           1 : }

Generated by: LCOV version 1.14