Line data Source code
1 : /*
2 : * File: TestNorm2.cpp
3 : * Author: Pantelis Sopasakis
4 : *
5 : * Created on Oct 30, 2015, 9:53:14 PM
6 : *
7 : * ForBES is free software: you can redistribute it and/or modify
8 : * it under the terms of the GNU Lesser General Public License as published by
9 : * the Free Software Foundation, either version 3 of the License, or
10 : * (at your option) any later version.
11 : *
12 : * ForBES is distributed in the hope that it will be useful,
13 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : * GNU Lesser General Public License for more details.
16 : *
17 : * You should have received a copy of the GNU Lesser General Public License
18 : * along with ForBES. If not, see <http://www.gnu.org/licenses/>.
19 : */
20 :
21 : #include "TestNorm2.h"
22 : #include "Norm2.h"
23 : #include <iostream>
24 : #include <cmath>
25 :
26 1 : CPPUNIT_TEST_SUITE_REGISTRATION(TestNorm2);
27 :
28 3 : TestNorm2::TestNorm2() {
29 3 : }
30 :
31 6 : TestNorm2::~TestNorm2() {
32 6 : }
33 :
34 3 : void TestNorm2::setUp() {
35 3 : }
36 :
37 3 : void TestNorm2::tearDown() {
38 3 : }
39 :
40 1 : void TestNorm2::testCall() {
41 1 : const size_t n = 10;
42 : const double x_data[n] = {
43 : 0.537667139546100,
44 : 1.833885014595086,
45 : -2.258846861003648,
46 : 0.862173320368121,
47 : 0.318765239858981,
48 : -1.307688296305273,
49 : -0.433592022305684,
50 : 0.342624466538650,
51 : 3.578396939725760,
52 : 2.769437029884877
53 1 : };
54 1 : Matrix x(n, 1, x_data);
55 1 : double mu = 1.1;
56 : double f;
57 1 : Function * norm2_fun = new Norm2(mu);
58 :
59 1 : _ASSERT(norm2_fun -> category().defines_f());
60 1 : int status = norm2_fun ->call(x, f);
61 1 : _ASSERT_EQ(ForBESUtils::STATUS_OK, status);
62 1 : _ASSERT_NUM_EQ(6.231255997317550, f, 1e-12);
63 1 : delete norm2_fun;
64 1 : }
65 :
66 1 : void TestNorm2::testCallProx() {
67 1 : const size_t n = 10;
68 : const double x_data[n] = {
69 : -5.399547760626085,
70 : 12.139693865327418,
71 : 2.901616899784422,
72 : -0.252219492758625,
73 : 2.858971615304383,
74 : -0.819864233199099,
75 : -0.496577392865248,
76 : 5.958790431141860,
77 : 5.636137959201917,
78 : 5.668769653718456
79 1 : };
80 1 : Matrix x(n, 1, x_data);
81 2 : Matrix prox(n, 1);
82 : double f_at_prox;
83 1 : double mu = 2.3760;
84 1 : Function * norm2_fun = new Norm2(mu);
85 1 : _ASSERT(norm2_fun -> category().defines_prox());
86 1 : double gamma = 0.50;
87 1 : _ASSERT(norm2_fun -> category().defines_f());
88 1 : int status = norm2_fun ->callProx(x, gamma, prox, f_at_prox);
89 1 : _ASSERT_EQ(ForBESUtils::STATUS_OK, status);
90 1 : _ASSERT_NUM_EQ(37.883327020592596, f_at_prox, 1e-12);
91 :
92 : const double prox_expected_data[n] = {
93 : -5.025125487612237,
94 : 11.297887852628843,
95 : 2.700409309223781,
96 : -0.234729769551485,
97 : 2.660721188020410,
98 : -0.763012170143809,
99 : -0.462143094956132,
100 : 5.545588445243951,
101 : 5.245309749274328,
102 : 5.275678655539919
103 1 : };
104 2 : Matrix prox_expected(n,1,prox_expected_data);
105 1 : _ASSERT_EQ(prox_expected, prox);
106 :
107 1 : status = norm2_fun ->callProx(x, gamma, prox);
108 1 : _ASSERT_EQ(ForBESUtils::STATUS_OK, status);
109 1 : _ASSERT_EQ(prox_expected, prox);
110 :
111 1 : x *= 0.05;
112 1 : status = norm2_fun ->callProx(x, gamma, prox, f_at_prox);
113 1 : _ASSERT(ForBESUtils::is_status_ok(status));
114 1 : _ASSERT_EQ(0.0, f_at_prox);
115 :
116 2 : delete norm2_fun;
117 1 : }
118 :
119 1 : void TestNorm2::testDualNorm() {
120 1 : const size_t n = 3;
121 1 : Matrix x(n,1);
122 1 : x[0]=1.0;
123 1 : x[1]=3.0;
124 :
125 2 : Norm2 norm;
126 : double f;
127 : double fd;
128 1 : norm.call(x,f);
129 1 : norm.dualNorm(x,fd);
130 1 : _ASSERT_NUM_EQ(3.162277660168380, f, 1e-12);
131 2 : _ASSERT_NUM_EQ(f, fd, 1e-10);
132 :
133 4 : }
|