Line data Source code
1 : /*
2 : * File: TestNorm1.cpp
3 : * Author: Pantelis Sopasakis
4 : *
5 : * Created on Oct 30, 2015, 6:15:56 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 "TestNorm1.h"
22 : #include "Norm1.h"
23 : #include <cmath>
24 :
25 1 : CPPUNIT_TEST_SUITE_REGISTRATION(TestNorm1);
26 :
27 5 : TestNorm1::TestNorm1() {
28 5 : }
29 :
30 10 : TestNorm1::~TestNorm1() {
31 10 : }
32 :
33 5 : void TestNorm1::setUp() {
34 5 : }
35 :
36 5 : void TestNorm1::tearDown() {
37 5 : }
38 :
39 1 : void TestNorm1::testCall() {
40 1 : const size_t n = 10;
41 : const double x_data[n] = {
42 : 0.106216344928664,
43 : -0.372409740055537,
44 : 0.198118402542975,
45 : -0.489687638016024,
46 : -0.339493413390758,
47 : 0.951630464777727,
48 : 0.920332039836564,
49 : -0.052676997680793,
50 : 0.737858095516997,
51 : -0.269119426398556
52 1 : };
53 1 : const Matrix x(n, 1, x_data);
54 1 : double mu = 0.8;
55 1 : Function * norm1_fun = new Norm1(mu);
56 : double f;
57 1 : _ASSERT(norm1_fun->category().defines_f());
58 1 : int status = norm1_fun->call(const_cast<Matrix&>(x), f);
59 1 : _ASSERT_EQ(ForBESUtils::STATUS_OK, status);
60 1 : _ASSERT_NUM_EQ(3.550034050515676, f, 1e-12);
61 1 : delete norm1_fun;
62 1 : }
63 :
64 1 : void TestNorm1::testCallProx() {
65 1 : const size_t n = 10;
66 : const double x_data[n] = {
67 : 0.106216344928664,
68 : 0.372409740055537,
69 : 0.198118402542975,
70 : 0.489687638016024,
71 : 0.339493413390758,
72 : 0.951630464777727,
73 : 0.920332039836564,
74 : 0.052676997680793,
75 : 0.737858095516997,
76 : 0.269119426398556
77 1 : };
78 1 : Matrix x(n, 1, x_data);
79 :
80 1 : double mu = 0.8;
81 1 : Function * norm1_fun = new Norm1(mu);
82 :
83 : const double prox_expected_data[n] = {
84 : 0,
85 : 0,
86 : 0,
87 : 0.089687638016024,
88 : 0,
89 : 0.551630464777727,
90 : 0.520332039836564,
91 : 0,
92 : 0.337858095516997,
93 : 0
94 1 : };
95 :
96 2 : Matrix prox_expected(n, 1, prox_expected_data);
97 :
98 1 : const double gamma = 0.5;
99 2 : Matrix prox(n, 1);
100 : double value_at_prox;
101 1 : _ASSERT(norm1_fun->category().defines_prox());
102 1 : int status = norm1_fun->callProx(x, gamma, prox, value_at_prox);
103 1 : _ASSERT_EQ(ForBESUtils::STATUS_OK, status);
104 :
105 1 : _ASSERT_EQ(prox_expected, prox);
106 1 : _ASSERT_NUM_EQ(1.199606590517850, value_at_prox, 1e-12);
107 :
108 2 : delete norm1_fun;
109 1 : }
110 :
111 1 : void TestNorm1::testCallProx2() {
112 1 : const size_t n = 10;
113 : const double x_data[n] = {
114 : 0.537667139546100,
115 : 1.833885014595086,
116 : -2.258846861003648,
117 : 0.862173320368121,
118 : 0.318765239858981,
119 : -1.307688296305273,
120 : -0.433592022305684,
121 : 0.342624466538650,
122 : 3.578396939725760,
123 : 2.769437029884877
124 1 : };
125 1 : Matrix x(n, 1, x_data);
126 :
127 1 : double mu = 1.2;
128 1 : Function * norm1_fun = new Norm1(mu);
129 :
130 : const double prox_expected_data[n] = {
131 : 0,
132 : 1.233885014595086,
133 : -1.658846861003648,
134 : 0.262173320368121,
135 : 0,
136 : -0.707688296305273,
137 : 0,
138 : 0,
139 : 2.978396939725760,
140 : 2.169437029884877
141 1 : };
142 :
143 2 : Matrix prox_expected(n, 1, prox_expected_data);
144 :
145 1 : const double gamma = 0.5;
146 2 : Matrix prox(n, 1);
147 1 : _ASSERT(norm1_fun->category().defines_prox());
148 1 : int status = norm1_fun->callProx(x, gamma, prox);
149 1 : _ASSERT_EQ(ForBESUtils::STATUS_OK, status);
150 :
151 1 : _ASSERT_EQ(prox_expected, prox);
152 :
153 2 : delete norm1_fun;
154 1 : }
155 :
156 1 : void TestNorm1::testDualNorm() {
157 1 : const double mu = 2.5;
158 1 : Norm1 normFun(mu);
159 2 : Matrix x(3, 1, Matrix::MATRIX_DENSE);
160 1 : x[0] = 0.5;
161 1 : x[1] = -0.9;
162 1 : x[2] = 0.85;
163 :
164 : double norm;
165 : double normDual;
166 1 : const double tol = 1e-12;
167 :
168 1 : int status = normFun.call(x, norm);
169 1 : _ASSERT_EQ(ForBESUtils::STATUS_OK, status);
170 1 : _ASSERT_NUM_EQ(5.6250, norm, tol);
171 :
172 1 : status = normFun.dualNorm(x, normDual);
173 1 : _ASSERT_EQ(ForBESUtils::STATUS_OK, status);
174 1 : _ASSERT_NUM_EQ(0.3600, normDual, tol);
175 :
176 2 : Norm1 normFun2;
177 : double normDual2;
178 1 : normFun2.dualNorm(x, normDual2);
179 2 : _ASSERT_NUM_EQ(normDual2 / mu, normDual, tol);
180 1 : }
181 :
182 1 : void TestNorm1::testConjugate() {
183 1 : const size_t n = 2;
184 1 : Matrix x(n,1); x[0] = 1;
185 2 : Norm1 norm;
186 : double f_1;
187 : double f_inf;
188 : double f_1_star;
189 1 : norm.call(x,f_1);
190 1 : norm.dualNorm(x, f_inf);
191 1 : _ASSERT_EQ(1.0, f_1);
192 1 : _ASSERT_EQ(1.0, f_inf);
193 :
194 1 : norm.callConj(x, f_1_star);
195 1 : _ASSERT_EQ(0.0, f_1_star);
196 :
197 1 : x[0] = 2.0;
198 1 : norm.callConj(x, f_1_star);
199 2 : _ASSERT(std::isinf(f_1_star));
200 :
201 :
202 4 : }
203 :
|