LCOV - code coverage report
Current view: top level - source/tests - TestSumOfNorm2.cpp (source / functions) Hit Total Coverage
Test: LibForBES Unit Tests Lines: 135 135 100.0 %
Date: 2016-04-18 Functions: 13 13 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * File:   TestSumOfNorm2.cpp
       3             :  * Author: chung
       4             :  *
       5             :  * Created on Feb 29, 2016, 5:18:46 PM
       6             :  */
       7             : 
       8             : #include "TestSumOfNorm2.h"
       9             : #include "SumOfNorm2.h"
      10             : 
      11             : 
      12           1 : CPPUNIT_TEST_SUITE_REGISTRATION(TestSumOfNorm2);
      13             : 
      14           6 : TestSumOfNorm2::TestSumOfNorm2() {
      15           6 : }
      16             : 
      17          12 : TestSumOfNorm2::~TestSumOfNorm2() {
      18          12 : }
      19             : 
      20           6 : void TestSumOfNorm2::setUp() {
      21           6 : }
      22             : 
      23           6 : void TestSumOfNorm2::tearDown() {
      24           6 : }
      25             : 
      26           1 : void TestSumOfNorm2::testCall() {
      27           1 :     const size_t k = 2;
      28           1 :     const double mu = 1.0;
      29           1 :     const double tolerance = 1e-8;
      30           1 :     Norm * f0 = new SumOfNorm2(k);
      31           1 :     Norm * f = new SumOfNorm2(mu, k);
      32           1 :     Matrix x(4, 1);
      33           1 :     double f_val = -1.0;
      34             : 
      35           1 :     _ASSERT(f->category().defines_f());
      36           1 :     int status = f->call(x, f_val);
      37           1 :     _ASSERT(ForBESUtils::is_status_ok(status));
      38           1 :     _ASSERT_NUM_EQ(0.00, f_val, tolerance);
      39             : 
      40           1 :     x[0] = -1.0;
      41           1 :     x[1] = 1.0;
      42           1 :     x[2] = 2.0;
      43           1 :     x[3] = -1.0;
      44             : 
      45           1 :     const double correct_val = 3.65028153987288;
      46           1 :     status = f->call(x, f_val);
      47           1 :     _ASSERT(ForBESUtils::is_status_ok(status));
      48           1 :     _ASSERT_NUM_EQ(correct_val, f_val, tolerance);
      49             : 
      50           1 :     status = f0->call(x, f_val);
      51           1 :     _ASSERT(ForBESUtils::is_status_ok(status));
      52           1 :     _ASSERT_NUM_EQ(correct_val, f_val, tolerance);
      53             : 
      54           1 :     delete f;
      55           1 :     delete f0;
      56           1 : }
      57             : 
      58           1 : void TestSumOfNorm2::testDualNorm() {
      59           1 :     const size_t k = 3;
      60           1 :     const size_t n = 12;
      61           1 :     const double mu = 1.0;
      62           1 :     const double tolerance = 1e-8;
      63             : 
      64             :     double x_data[n] = {
      65             :         1, -2, -1,
      66             :         2, -1, 1,
      67             :         0, 1, 3,
      68             :         2, 1.5, 0.5
      69           1 :     };
      70             : 
      71           1 :     const double correct_val = 10.6107669025311;
      72           1 :     const double correct_val_dual = 3.16227766016838;
      73             : 
      74           1 :     Norm * son = new SumOfNorm2(mu, k);
      75             : 
      76           1 :     int status = -1;
      77             : 
      78           1 :     Matrix x = MatrixFactory::ShallowVector(x_data, n, static_cast<size_t> (0));
      79             :     double f_val;
      80           1 :     _ASSERT(son->category().defines_f());
      81           1 :     status = son->call(x, f_val);
      82           1 :     _ASSERT(ForBESUtils::is_status_ok(status));
      83           1 :     _ASSERT_NUM_EQ(correct_val, f_val, tolerance);
      84             : 
      85             :     double f_val_dual;
      86           1 :     _ASSERT(son->category().defines_conjugate());
      87           1 :     status = son->dualNorm(x, f_val_dual);
      88           1 :     _ASSERT(ForBESUtils::is_status_ok(status));
      89           1 :     _ASSERT_NUM_EQ(correct_val_dual, f_val_dual, tolerance);
      90             : 
      91           1 :     delete son;
      92           1 : }
      93             : 
      94           1 : void TestSumOfNorm2::testProx() {
      95           1 :     const size_t k = 3;
      96           1 :     const size_t n = 12;
      97           1 :     const double mu = 1.0;
      98           1 :     const double gamma = 0.8;
      99             : 
     100             :     double v_data[n] = {
     101             :         -1, 1, -1,
     102             :         3, -1, 1,
     103             :         1, -1.5, 2,
     104             :         -2, 1.5, 0.5
     105           1 :     };
     106             : 
     107           1 :     Norm * son = new SumOfNorm2(mu, k);
     108             : 
     109           1 :     Matrix prox(n, 1);
     110           2 :     Matrix v = MatrixFactory::ShallowVector(v_data, n, static_cast<size_t> (0));
     111             :     int status;
     112           1 :     _ASSERT(son->category().defines_prox());
     113           1 :     status = son->callProx(v, gamma, prox);
     114             : 
     115             : 
     116           1 :     _ASSERT(ForBESUtils::is_status_ok(status));
     117             : 
     118             :     double prox_correct_data[] = {
     119             :         -0.538119784648299,
     120             :         0.538119784648299,
     121             :         -0.538119784648299,
     122             :         2.276372773013367,
     123             :         -0.758790924337789,
     124             :         0.758790924337789,
     125             :         0.702887458916717,
     126             :         -1.054331188375075,
     127             :         1.405774917833434,
     128             :         -1.372428367557811,
     129             :         1.029321275668358,
     130             :         0.343107091889453
     131           1 :     };
     132             : 
     133           2 :     Matrix prox_correct = MatrixFactory::ShallowVector(prox_correct_data, n, 0);
     134           1 :     _ASSERT_EQ(prox_correct, prox);
     135             : 
     136           2 :     delete son;
     137           1 : }
     138             : 
     139           1 : void TestSumOfNorm2::testFaultyDims() {
     140           1 :     const size_t k = 3;
     141           1 :     const size_t n = 16;
     142           1 :     const double gamma = 0.8;
     143             : 
     144           1 :     Norm * son = new SumOfNorm2(k);
     145             : 
     146           1 :     Matrix x(n, 1);
     147             :     double val;
     148             : 
     149           1 :     _ASSERT_EXCEPTION(son->call(x, val), std::invalid_argument);
     150           1 :     _ASSERT_EXCEPTION(son->dualNorm(x, val), std::invalid_argument);
     151             : 
     152           2 :     Matrix prox(n, 1);
     153           1 :     _ASSERT_EXCEPTION(son->callProx(x, gamma, prox), std::invalid_argument);
     154             : 
     155           2 :     delete son;
     156             : 
     157           1 : }
     158             : 
     159           1 : void TestSumOfNorm2::testFunAtProx() {
     160           1 :     const size_t k = 3;
     161           1 :     const size_t n = 9;
     162           1 :     const double mu = 3.5;
     163           1 :     const double gamma = 0.8;
     164             : 
     165             : 
     166           1 :     Function * son = new SumOfNorm2(mu, k);
     167             : 
     168           1 :     Matrix prox(n, 1);
     169           2 :     Matrix v = MatrixFactory::MakeRandomMatrix(n, 1, 0.0, 2.0);
     170             :     int status;
     171           1 :     double f_at_prox = 0.0;
     172           1 :     double f_at_prox2 = 0.0;
     173           1 :     _ASSERT(son->category().defines_prox());
     174           1 :     status = son->callProx(v, gamma, prox, f_at_prox);
     175           1 :     _ASSERT(ForBESUtils::is_status_ok(status));
     176             : 
     177           1 :     status = son->call(prox, f_at_prox2);
     178           1 :     _ASSERT(ForBESUtils::is_status_ok(status));
     179           1 :     _ASSERT_NUM_EQ(f_at_prox, f_at_prox2, 1e-7);
     180             : 
     181           2 :     delete son;
     182           1 : }
     183             : 
     184           1 : void TestSumOfNorm2::testVerification() {
     185             :     /**
     186             :      * Verify SumOfNorm2 by comparing to SumOfNorm2(mu, k=1) with Norm1(mu)
     187             :      */
     188             :     
     189           1 :     const size_t n = 50;
     190           1 :     const double mu = 0.857;
     191           1 :     Norm * norm1 = new Norm1(mu);
     192           1 :     Norm * son = new SumOfNorm2(mu, 1);
     193           1 :     const double gamma = 0.975;
     194             : 
     195           1 :     double f1 = -1.0;
     196           1 :     double f2 = -2.0;
     197             :     int status;
     198             : 
     199           1 :     Matrix x = MatrixFactory::MakeRandomMatrix(n, 1, -0.5, 1.5);
     200             : 
     201             :     /* Check values */
     202           1 :     status = norm1->call(x, f1);
     203           1 :     _ASSERT(ForBESUtils::is_status_ok(status));
     204           1 :     status = son->call(x, f2);
     205           1 :     _ASSERT(ForBESUtils::is_status_ok(status));
     206           1 :     _ASSERT_NUM_EQ(f1, f2, 1e-8);
     207             :     
     208             :     
     209             :     /* Check dual norm values */
     210           1 :     double dual_norm_1 = -1.0;
     211           1 :     double dual_norm_2 = -2.0;
     212           1 :     status = norm1->dualNorm(x, dual_norm_1);
     213           1 :     _ASSERT(ForBESUtils::is_status_ok(status));    
     214           1 :     status = son->dualNorm(x, dual_norm_2);
     215           1 :     _ASSERT(ForBESUtils::is_status_ok(status));
     216           1 :     _ASSERT_NUM_EQ(dual_norm_1, dual_norm_2, 1e-8);
     217             :     
     218             :     /* Check proximals */
     219           2 :     Matrix prox1(n, 1);
     220           2 :     Matrix prox2(n, 1);
     221             :     double f_at_prox_1;
     222             :     double f_at_prox_2;
     223           1 :     status = norm1->callProx(x, gamma, prox1, f_at_prox_1);
     224           1 :     _ASSERT(ForBESUtils::is_status_ok(status));
     225           1 :     status = son->callProx(x, gamma, prox2, f_at_prox_2);
     226           1 :     _ASSERT(ForBESUtils::is_status_ok(status));
     227           1 :     _ASSERT_EQ(prox1, prox2);
     228           1 :     _ASSERT_NUM_EQ(f_at_prox_1, f_at_prox_2, 1e-8);
     229             : 
     230           1 :     delete norm1;
     231           2 :     delete son;
     232           4 : }

Generated by: LCOV version 1.10