LCOV - code coverage report
Current view: top level - problems/tests - test_WLSProblem.cpp (source / functions) Hit Total Coverage
Test: test_coverage.info.cleaned Lines: 189 234 80.8 %
Date: 2022-02-28 03:37:41 Functions: 13 19 68.4 %

          Line data    Source code
       1             : /**
       2             :  * @file test_WLSProblem.cpp
       3             :  *
       4             :  * @brief Tests for the WLSProblem class
       5             :  *
       6             :  * @author Matthias Wieczorek - initial code
       7             :  * @author Maximilian Hornung - modularization
       8             :  * @author David Frank - rewrite
       9             :  * @author Tobias Lasser - rewrite, modernization
      10             :  * @author Nikola Dinev - added tests for conversion constructor
      11             :  */
      12             : 
      13             : #include "doctest/doctest.h"
      14             : 
      15             : #include "WLSProblem.h"
      16             : #include "Identity.h"
      17             : #include "Scaling.h"
      18             : #include "L2NormPow2.h"
      19             : #include "WeightedL2NormPow2.h"
      20             : #include "Quadric.h"
      21             : #include "TikhonovProblem.h"
      22             : #include "BlockLinearOperator.h"
      23             : #include "RandomBlocksDescriptor.h"
      24             : #include "VolumeDescriptor.h"
      25             : #include "testHelpers.h"
      26             : 
      27             : using namespace elsa;
      28             : using namespace doctest;
      29             : 
      30             : TEST_SUITE_BEGIN("problems");
      31             : 
      32          26 : TEST_CASE_TEMPLATE("WLSProblems: Testing with operator and data", TestType, float, double)
      33             : {
      34          16 :     GIVEN("the operator and data")
      35             :     {
      36          16 :         IndexVector_t numCoeff(2);
      37           8 :         numCoeff << 7, 13;
      38          16 :         VolumeDescriptor dd(numCoeff);
      39             : 
      40          16 :         Eigen::Matrix<TestType, Eigen::Dynamic, 1> bVec(dd.getNumberOfCoefficients());
      41           8 :         bVec.setRandom();
      42          16 :         DataContainer<TestType> dcB(dd, bVec);
      43             : 
      44          16 :         Identity<TestType> idOp(dd);
      45             : 
      46          12 :         WHEN("setting up a ls problem without x0")
      47             :         {
      48           8 :             WLSProblem<TestType> prob(idOp, dcB);
      49             : 
      50           6 :             THEN("the clone works correctly")
      51             :             {
      52           4 :                 auto probClone = prob.clone();
      53             : 
      54           2 :                 REQUIRE_NE(probClone.get(), &prob);
      55           2 :                 REQUIRE_EQ(*probClone, prob);
      56             :             }
      57             : 
      58           6 :             THEN("the problem behaves as expected")
      59             :             {
      60           4 :                 DataContainer<TestType> dcZero(dd);
      61           2 :                 dcZero = 0;
      62           2 :                 REQUIRE_UNARY(isApprox(prob.getCurrentSolution(), dcZero));
      63             : 
      64           2 :                 REQUIRE_UNARY(
      65             :                     checkApproxEq(prob.evaluate(), as<TestType>(0.5) * bVec.squaredNorm()));
      66           2 :                 REQUIRE_UNARY(
      67             :                     checkApproxEq(prob.getGradient(), static_cast<TestType>(-1.0f) * dcB));
      68             : 
      69           2 :                 auto hessian = prob.getHessian();
      70           2 :                 REQUIRE_UNARY(isApprox(hessian.apply(dcB), dcB));
      71             :             }
      72             :         }
      73             : 
      74          12 :         WHEN("setting up a ls problem with x0")
      75             :         {
      76           8 :             Eigen::Matrix<TestType, Eigen::Dynamic, 1> x0Vec(dd.getNumberOfCoefficients());
      77           4 :             x0Vec.setRandom();
      78           8 :             DataContainer<TestType> dcX0(dd, x0Vec);
      79             : 
      80           8 :             WLSProblem<TestType> prob(idOp, dcB, dcX0);
      81             : 
      82           6 :             THEN("the clone works correctly")
      83             :             {
      84           4 :                 auto probClone = prob.clone();
      85             : 
      86           2 :                 REQUIRE_NE(probClone.get(), &prob);
      87           2 :                 REQUIRE_EQ(*probClone, prob);
      88             :             }
      89             : 
      90           6 :             THEN("the problem behaves as expected")
      91             :             {
      92             : 
      93           2 :                 REQUIRE_UNARY(isApprox(prob.getCurrentSolution(), dcX0));
      94             : 
      95           2 :                 REQUIRE_UNARY(checkApproxEq(prob.evaluate(),
      96             :                                             as<TestType>(0.5) * (x0Vec - bVec).squaredNorm()));
      97           2 :                 REQUIRE_UNARY(isApprox(prob.getGradient(), dcX0 - dcB));
      98             : 
      99           2 :                 auto hessian = prob.getHessian();
     100           2 :                 REQUIRE_UNARY(isApprox(hessian.apply(dcB), dcB));
     101             :             }
     102             :         }
     103             :     }
     104           8 : }
     105             : 
     106          18 : TEST_CASE_TEMPLATE("WLSProblems: Testing with weights, operator and data", TestType, float, double)
     107             : {
     108           0 :     GIVEN("weights, operator and data")
     109             :     {
     110           0 :         IndexVector_t numCoeff(3);
     111           0 :         numCoeff << 7, 13, 17;
     112           0 :         VolumeDescriptor dd(numCoeff);
     113             : 
     114           0 :         Eigen::Matrix<TestType, Eigen::Dynamic, 1> bVec(dd.getNumberOfCoefficients());
     115           0 :         bVec.setRandom();
     116           0 :         DataContainer<TestType> dcB(dd, bVec);
     117             : 
     118           0 :         Identity<TestType> idOp(dd);
     119             : 
     120           0 :         Eigen::Matrix<TestType, Eigen::Dynamic, 1> weightsVec(dd.getNumberOfCoefficients());
     121           0 :         weightsVec.setRandom();
     122           0 :         DataContainer dcWeights(dd, weightsVec);
     123           0 :         Scaling scaleOp(dd, dcWeights);
     124             : 
     125           0 :         WHEN("setting up a wls problem without x0")
     126             :         {
     127           0 :             WLSProblem<TestType> prob(scaleOp, idOp, dcB);
     128             : 
     129           0 :             THEN("the clone works correctly")
     130             :             {
     131           0 :                 auto probClone = prob.clone();
     132             : 
     133           0 :                 REQUIRE_NE(probClone.get(), &prob);
     134           0 :                 REQUIRE_EQ(*probClone, prob);
     135             :             }
     136             : 
     137           0 :             THEN("the problem behaves as expected")
     138             :             {
     139           0 :                 DataContainer<TestType> dcZero(dd);
     140           0 :                 dcZero = 0;
     141           0 :                 REQUIRE_UNARY(isApprox(prob.getCurrentSolution(), dcZero));
     142             : 
     143           0 :                 REQUIRE_UNARY(checkApproxEq(
     144             :                     prob.evaluate(),
     145             :                     as<TestType>(0.5) * bVec.dot((weightsVec.array() * bVec.array()).matrix())));
     146           0 :                 DataContainer<TestType> tmpDc = as<TestType>(-1) * dcWeights * dcB;
     147           0 :                 REQUIRE_UNARY(isApprox(prob.getGradient(), tmpDc));
     148             : 
     149           0 :                 auto hessian = prob.getHessian();
     150           0 :                 REQUIRE_UNARY(isApprox(hessian.apply(dcB), dcWeights * dcB));
     151             :             }
     152             :         }
     153             : 
     154           0 :         WHEN("setting up a wls problem with x0")
     155             :         {
     156           0 :             Eigen::Matrix<TestType, Eigen::Dynamic, 1> x0Vec(dd.getNumberOfCoefficients());
     157           0 :             x0Vec.setRandom();
     158           0 :             DataContainer<TestType> dcX0(dd, x0Vec);
     159             : 
     160           0 :             WLSProblem<TestType> prob(scaleOp, idOp, dcB, dcX0);
     161             : 
     162           0 :             THEN("the clone works correctly")
     163             :             {
     164           0 :                 auto probClone = prob.clone();
     165             : 
     166           0 :                 REQUIRE_NE(probClone.get(), &prob);
     167           0 :                 REQUIRE_EQ(*probClone, prob);
     168             :             }
     169             : 
     170           0 :             THEN("the problem behaves as expected")
     171             :             {
     172           0 :                 DataContainer<TestType> dcZero(dd);
     173           0 :                 dcZero = 0;
     174           0 :                 REQUIRE_UNARY(isApprox(prob.getCurrentSolution(), dcX0));
     175             : 
     176           0 :                 REQUIRE_UNARY(checkApproxEq(
     177             :                     prob.evaluate(),
     178             :                     as<TestType>(0.5)
     179             :                         * (x0Vec - bVec)
     180             :                               .dot((weightsVec.array() * (x0Vec - bVec).array()).matrix())));
     181           0 :                 REQUIRE_UNARY(isApprox(prob.getGradient(), dcWeights * (dcX0 - dcB)));
     182             : 
     183           0 :                 auto hessian = prob.getHessian();
     184           0 :                 REQUIRE_UNARY(isApprox(hessian.apply(dcB), dcWeights * dcB));
     185             :             }
     186             :         }
     187             :     }
     188           0 : }
     189             : 
     190          36 : TEST_CASE_TEMPLATE("WLSProblems: Testing different optimization problems", TestType, float, double)
     191             : {
     192          20 :     GIVEN("an optimization problem with only a (w)ls data term")
     193             :     {
     194           4 :         VolumeDescriptor desc{IndexVector_t::Constant(1, 343)};
     195             : 
     196           4 :         Scaling<TestType> W{desc, static_cast<TestType>(3.0)};
     197             : 
     198           4 :         LinearResidual<TestType> residual{desc};
     199           4 :         L2NormPow2<TestType> func{residual};
     200           4 :         WeightedL2NormPow2<TestType> weightedFunc{residual, W};
     201           4 :         Problem<TestType> prob{func};
     202           4 :         Problem<TestType> weightedProb{weightedFunc};
     203             : 
     204           4 :         WHEN("converting to a wls problem")
     205             :         {
     206           4 :             WLSProblem<TestType> lsProb{prob};
     207           4 :             WLSProblem<TestType> wlsProb{weightedProb};
     208             : 
     209           4 :             THEN("only the type of the problem changes")
     210             :             {
     211           2 :                 REQUIRE_EQ(lsProb.getDataTerm(), prob.getDataTerm());
     212           2 :                 REQUIRE_EQ(lsProb.getRegularizationTerms(), prob.getRegularizationTerms());
     213           2 :                 REQUIRE_EQ(wlsProb.getDataTerm(), weightedProb.getDataTerm());
     214           2 :                 REQUIRE_EQ(wlsProb.getRegularizationTerms(), weightedProb.getRegularizationTerms());
     215             :             }
     216             :         }
     217             :     }
     218             : 
     219          20 :     GIVEN("an optimization problem with a non-(w)ls data term")
     220             :     {
     221           4 :         VolumeDescriptor desc{IndexVector_t::Constant(1, 343)};
     222             : 
     223           4 :         Quadric<TestType> quadric{desc};
     224           4 :         Problem prob{quadric};
     225             : 
     226           4 :         WHEN("converting to a WLSProblem")
     227             :         {
     228           6 :             THEN("an exception is thrown") { REQUIRE_THROWS(WLSProblem<TestType>{prob}); }
     229             :         }
     230             :     }
     231             : 
     232          20 :     GIVEN("an optimization problem with a non-(w)ls regularization term")
     233             :     {
     234           4 :         VolumeDescriptor desc{IndexVector_t::Constant(1, 343)};
     235             : 
     236           4 :         Quadric<TestType> quadric{desc};
     237           4 :         RegularizationTerm regTerm{static_cast<TestType>(5), quadric};
     238           4 :         Problem prob{L2NormPow2<TestType>{desc}, regTerm};
     239             : 
     240           4 :         WHEN("converting to a WLSProblem")
     241             :         {
     242           6 :             THEN("an exception is thrown") { REQUIRE_THROWS(WLSProblem<TestType>{prob}); }
     243             :         }
     244             :     }
     245             : 
     246          22 :     GIVEN("an optimization problem with a wls data term that has negative weighting factors")
     247             :     {
     248           8 :         VolumeDescriptor desc{IndexVector_t::Constant(1, 343)};
     249             : 
     250           8 :         Scaling<TestType> W1{desc, static_cast<TestType>(-3.0)};
     251             : 
     252           8 :         Eigen::Matrix<TestType, Eigen::Dynamic, 1> anisotropicW =
     253             :             Eigen::Matrix<TestType, Eigen::Dynamic, 1>::Constant(343, 1);
     254           4 :         anisotropicW[256] = -3.0;
     255             : 
     256           8 :         Scaling<TestType> W2{desc, DataContainer(desc, anisotropicW)};
     257             : 
     258           8 :         LinearResidual<TestType> residual{desc};
     259           8 :         WeightedL2NormPow2<TestType> weightedFunc1{residual, W1};
     260           8 :         WeightedL2NormPow2<TestType> weightedFunc2{residual, W2};
     261             : 
     262           6 :         WHEN("convering to a WLSProblem and no regularization terms are present")
     263             :         {
     264           4 :             Problem prob1{weightedFunc1};
     265           4 :             Problem prob2{weightedFunc2};
     266             : 
     267           4 :             WLSProblem converted1{prob1};
     268           4 :             WLSProblem converted2{prob2};
     269             : 
     270           4 :             THEN("only the type of the problem changes")
     271             :             {
     272           2 :                 REQUIRE_EQ(prob1.getDataTerm(), converted1.getDataTerm());
     273           2 :                 REQUIRE_EQ(prob1.getRegularizationTerms(), converted1.getRegularizationTerms());
     274           2 :                 REQUIRE_EQ(prob2.getDataTerm(), converted2.getDataTerm());
     275           2 :                 REQUIRE_EQ(prob2.getRegularizationTerms(), converted2.getRegularizationTerms());
     276             :             }
     277             :         }
     278             : 
     279           6 :         WHEN("convering to a WLSProblem and regularization terms are present")
     280             :         {
     281           4 :             RegularizationTerm regTerm{static_cast<TestType>(1.0), L2NormPow2<TestType>{desc}};
     282           4 :             Problem prob1{weightedFunc1, regTerm};
     283           4 :             Problem prob2{weightedFunc2, regTerm};
     284             : 
     285           4 :             THEN("an exception is thrown")
     286             :             {
     287           4 :                 REQUIRE_THROWS(WLSProblem{prob1});
     288           4 :                 REQUIRE_THROWS(WLSProblem{prob2});
     289             :             }
     290             :         }
     291             :     }
     292             : 
     293          20 :     GIVEN("an optimization problem with a (w)ls regularization term that has negative weighting "
     294             :           "factors")
     295             :     {
     296           4 :         VolumeDescriptor desc{IndexVector_t::Constant(1, 343)};
     297             : 
     298           4 :         Scaling<TestType> W1{desc, static_cast<TestType>(-3.0)};
     299             : 
     300           4 :         Eigen::Matrix<TestType, Eigen::Dynamic, 1> anisotropicW =
     301             :             Eigen::Matrix<TestType, Eigen::Dynamic, 1>::Constant(343, 1);
     302           2 :         anisotropicW[256] = -3.0;
     303             : 
     304           4 :         Scaling<TestType> W2{desc, DataContainer(desc, anisotropicW)};
     305             : 
     306           4 :         LinearResidual<TestType> residual{desc};
     307           4 :         WeightedL2NormPow2<TestType> weightedFunc1{residual, W1};
     308           4 :         WeightedL2NormPow2<TestType> weightedFunc2{residual, W2};
     309           4 :         L2NormPow2<TestType> nonWeightedFunc{desc};
     310             : 
     311           4 :         RegularizationTerm negWeights{static_cast<TestType>(1.0), weightedFunc1};
     312           4 :         RegularizationTerm mixedWeights{static_cast<TestType>(1.0), weightedFunc2};
     313           4 :         RegularizationTerm noWeightsNegLambda{static_cast<TestType>(-1.0), nonWeightedFunc};
     314           4 :         WHEN("convering to a WLSProblem")
     315             :         {
     316           4 :             Problem prob1{L2NormPow2<TestType>{desc}, negWeights};
     317           4 :             Problem prob2{L2NormPow2<TestType>{desc}, mixedWeights};
     318           4 :             Problem prob3{L2NormPow2<TestType>{desc}, noWeightsNegLambda};
     319             : 
     320           4 :             THEN("an exception is thrown")
     321             :             {
     322           4 :                 REQUIRE_THROWS(WLSProblem{prob1});
     323           4 :                 REQUIRE_THROWS(WLSProblem{prob2});
     324           4 :                 REQUIRE_THROWS(WLSProblem{prob3});
     325             :             }
     326             :         }
     327             :     }
     328             : 
     329          22 :     GIVEN("an OptimizationProblem with only (w)ls terms")
     330             :     {
     331           8 :         VolumeDescriptor desc{IndexVector_t::Constant(1, 343)};
     332           8 :         Eigen::Matrix<TestType, Eigen::Dynamic, 1> vec =
     333             :             Eigen::Matrix<TestType, Eigen::Dynamic, 1>::Random(343);
     334           8 :         DataContainer<TestType> b{desc, vec};
     335             : 
     336           8 :         Scaling<TestType> A{desc, static_cast<TestType>(2.0)};
     337             : 
     338           8 :         Scaling<TestType> isoW{desc, static_cast<TestType>(3.0)};
     339           8 :         Eigen::Matrix<TestType, Eigen::Dynamic, 1> vecW =
     340             :             Eigen::abs(Eigen::Matrix<TestType, Eigen::Dynamic, 1>::Random(343).array());
     341           8 :         DataContainer<TestType> dcW{desc, vecW};
     342           8 :         Scaling<TestType> nonIsoW{desc, dcW};
     343             : 
     344           8 :         std::vector<std::unique_ptr<Functional<TestType>>> dataTerms;
     345             : 
     346           4 :         dataTerms.push_back(std::make_unique<L2NormPow2<TestType>>(desc));
     347           4 :         dataTerms.push_back(std::make_unique<L2NormPow2<TestType>>(LinearResidual{b}));
     348           4 :         dataTerms.push_back(std::make_unique<L2NormPow2<TestType>>(LinearResidual{A}));
     349           4 :         dataTerms.push_back(std::make_unique<L2NormPow2<TestType>>(LinearResidual{A, b}));
     350           4 :         dataTerms.push_back(
     351             :             std::make_unique<WeightedL2NormPow2<TestType>>(LinearResidual{A, b}, isoW));
     352           4 :         dataTerms.push_back(
     353             :             std::make_unique<WeightedL2NormPow2<TestType>>(LinearResidual{A, b}, nonIsoW));
     354             : 
     355           8 :         Eigen::Matrix<TestType, Eigen::Dynamic, 1> regVec =
     356             :             Eigen::Matrix<TestType, Eigen::Dynamic, 1>::Random(343);
     357           8 :         DataContainer<TestType> bReg{desc, regVec};
     358             : 
     359           8 :         Scaling<TestType> AReg{desc, static_cast<TestType>(0.25)};
     360             : 
     361           8 :         Scaling<TestType> isoWReg{desc, static_cast<TestType>(1.5)};
     362           8 :         Eigen::Matrix<TestType, Eigen::Dynamic, 1> vecWReg =
     363             :             Eigen::abs(Eigen::Matrix<TestType, Eigen::Dynamic, 1>::Random(343).array());
     364           8 :         DataContainer<TestType> dcWReg{desc, vecWReg};
     365           8 :         Scaling<TestType> nonIsoWReg{desc, dcWReg};
     366             : 
     367           8 :         std::vector<std::unique_ptr<RegularizationTerm<TestType>>> regTerms;
     368           4 :         auto weight = static_cast<TestType>(0.5);
     369           4 :         regTerms.push_back(
     370             :             std::make_unique<RegularizationTerm<TestType>>(weight, L2NormPow2<TestType>{desc}));
     371           4 :         regTerms.push_back(std::make_unique<RegularizationTerm<TestType>>(
     372             :             weight, L2NormPow2<TestType>{LinearResidual{bReg}}));
     373           4 :         regTerms.push_back(std::make_unique<RegularizationTerm<TestType>>(
     374             :             weight, L2NormPow2<TestType>{LinearResidual{AReg}}));
     375           4 :         regTerms.push_back(std::make_unique<RegularizationTerm<TestType>>(
     376             :             weight, L2NormPow2<TestType>{LinearResidual{AReg, bReg}}));
     377           4 :         regTerms.push_back(std::make_unique<RegularizationTerm<TestType>>(
     378             :             weight, WeightedL2NormPow2{LinearResidual{AReg, bReg}, isoWReg}));
     379           4 :         regTerms.push_back(std::make_unique<RegularizationTerm<TestType>>(
     380             :             weight, WeightedL2NormPow2{LinearResidual{AReg, bReg}, nonIsoWReg}));
     381             : 
     382           4 :         std::array descriptions = {"has no operator and no vector",
     383             :                                    "has no operator, but has a vector",
     384             :                                    "has an operator, but no vector",
     385             :                                    "has an operator and a vector",
     386             :                                    "has an operator and a vector, and is weighted (isotropic)",
     387             :                                    "has an operator and a vector, and is weighted (nonisotropic)"};
     388             : 
     389          28 :         for (std::size_t i = 0; i < descriptions.size(); i++) {
     390         168 :             for (std::size_t j = 0; j < descriptions.size(); j++) {
     391         146 :                 WHEN("Trying different settings")
     392             :                 {
     393           4 :                     INFO("The data term ", descriptions[i]);
     394           4 :                     INFO("The regularization term ", descriptions[j]);
     395           4 :                     Eigen::Matrix<TestType, Eigen::Dynamic, 1> xVec =
     396             :                         Eigen::Matrix<TestType, Eigen::Dynamic, 1>::Random(343);
     397           4 :                     DataContainer<TestType> x{desc, xVec};
     398           4 :                     Problem prob{*dataTerms[i], *regTerms[j], x};
     399             : 
     400           4 :                     THEN("the problem can be converted and all operations yield the same result as "
     401             :                          "for the initial problem")
     402             :                     {
     403           4 :                         WLSProblem<TestType> converted{prob};
     404           2 :                         REQUIRE_UNARY(checkApproxEq(prob.evaluate(), converted.evaluate()));
     405             : 
     406           2 :                         auto gradDiff = prob.getGradient();
     407           2 :                         gradDiff -= converted.getGradient();
     408           2 :                         REQUIRE_UNARY(checkApproxEq(gradDiff.squaredL2Norm(), 0));
     409             :                     }
     410             :                 }
     411             :             }
     412             :         }
     413             :     }
     414             : 
     415          20 :     GIVEN("a TikhonovProblem with L2 regularization")
     416             :     {
     417           4 :         VolumeDescriptor desc{IndexVector_t::Constant(1, 343)};
     418           4 :         Eigen::Matrix<TestType, Eigen::Dynamic, 1> vec =
     419             :             Eigen::Matrix<TestType, Eigen::Dynamic, 1>::Random(343);
     420           4 :         DataContainer<TestType> b{desc, vec};
     421             : 
     422           4 :         Scaling<TestType> A{desc, static_cast<TestType>(2.0)};
     423           4 :         WLSProblem<TestType> prob{A, b};
     424             : 
     425           2 :         TestType regWeight = 4.0;
     426           6 :         TikhonovProblem<TestType> l2Reg{prob,
     427             :                                         RegularizationTerm{regWeight, L2NormPow2<TestType>{desc}}};
     428             : 
     429           4 :         THEN("the problem can be converted into a block form WLSProblem")
     430             :         {
     431           4 :             WLSProblem<TestType> conv{l2Reg};
     432             : 
     433           4 :             Scaling<TestType> lambdaScaling(desc, std::sqrt(regWeight));
     434           4 :             std::vector<std::unique_ptr<LinearOperator<TestType>>> opList(0);
     435           2 :             opList.push_back(A.clone());
     436           2 :             opList.push_back(lambdaScaling.clone());
     437           4 :             BlockLinearOperator<TestType> blockOp{opList,
     438             :                                                   BlockLinearOperator<TestType>::BlockType::ROW};
     439             : 
     440           4 :             std::vector<std::unique_ptr<DataDescriptor>> descList(0);
     441           2 :             descList.push_back(desc.clone());
     442           2 :             descList.push_back(desc.clone());
     443           4 :             RandomBlocksDescriptor vecDesc{descList};
     444           4 :             DataContainer<TestType> blockVec{vecDesc};
     445           2 :             blockVec.getBlock(0) = b;
     446           2 :             blockVec.getBlock(1) = 0;
     447             : 
     448           2 :             L2NormPow2<TestType> blockWls{LinearResidual<TestType>{blockOp, blockVec}};
     449           2 :             REQUIRE_EQ(conv.getDataTerm(), blockWls);
     450           2 :             REQUIRE_UNARY(conv.getRegularizationTerms().empty());
     451             :         }
     452             :     }
     453          18 : }
     454             : 
     455             : TEST_SUITE_END();

Generated by: LCOV version 1.15