Line data Source code
1 : /*
2 : * File: TestIndPos.cpp
3 : * Author: Pantelis Sopasakis
4 : *
5 : * Created on Jan 12, 2016, 4:06:34 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 <cmath>
22 :
23 : #include "TestIndPos.h"
24 : #include "IndPos.h"
25 : #include "ForBES.h"
26 :
27 :
28 1 : CPPUNIT_TEST_SUITE_REGISTRATION(TestIndPos);
29 :
30 10 : TestIndPos::TestIndPos() {
31 10 : }
32 :
33 20 : TestIndPos::~TestIndPos() {
34 20 : }
35 :
36 10 : void TestIndPos::setUp() {
37 10 : }
38 :
39 10 : void TestIndPos::tearDown() {
40 10 : }
41 :
42 1 : void TestIndPos::testCall1() {
43 1 : Function * ind_pos = new IndPos();
44 1 : Matrix x(5, 1);
45 1 : x[1] = 10.0;
46 1 : double f = 123.0;
47 1 : int status = ind_pos -> call(x, f);
48 1 : _ASSERT(ForBESUtils::is_status_ok(status));
49 1 : _ASSERT_NUM_EQ(0.0, f, 1e-14);
50 :
51 1 : x[3] = -1;
52 1 : status = ind_pos -> call(x, f);
53 1 : _ASSERT(ForBESUtils::is_status_ok(status));
54 :
55 1 : _ASSERT(std::isinf(f));
56 :
57 1 : delete ind_pos;
58 1 : }
59 :
60 1 : void TestIndPos::testCall2() {
61 :
62 1 : size_t n = 10;
63 1 : Matrix lb(n, 1);
64 11 : for (size_t i = 0; i < n; i++) {
65 10 : lb[i] = 3.0 + i;
66 : }
67 :
68 1 : Function * ind_pos = new IndPos(lb);
69 :
70 2 : Matrix x(lb);
71 :
72 1 : double f = 123.0;
73 1 : int status = ind_pos -> call(x, f);
74 1 : _ASSERT(ForBESUtils::is_status_ok(status));
75 1 : _ASSERT_NUM_EQ(0.0, f, 1e-14);
76 :
77 1 : x[3] = 4.9999;
78 1 : status = ind_pos -> call(x, f);
79 1 : _ASSERT(ForBESUtils::is_status_ok(status));
80 1 : _ASSERT(std::isinf(f));
81 :
82 2 : delete ind_pos;
83 1 : }
84 :
85 1 : void TestIndPos::testCall3() {
86 1 : size_t n = 10;
87 1 : double lb = 1.50;
88 :
89 1 : Function * ind_pos = new IndPos(lb);
90 :
91 1 : Matrix x(n, 1);
92 11 : for (size_t i = 0; i < n; i++) {
93 10 : x[i] = lb;
94 : }
95 :
96 1 : double f = 123.0;
97 1 : int status = ind_pos -> call(x, f);
98 1 : _ASSERT(ForBESUtils::is_status_ok(status));
99 1 : _ASSERT_NUM_EQ(0.0, f, 1e-14);
100 :
101 1 : x[2] = 100.0;
102 1 : status = ind_pos -> call(x, f);
103 1 : _ASSERT(ForBESUtils::is_status_ok(status));
104 1 : _ASSERT_NUM_EQ(0.0, f, 1e-14);
105 :
106 1 : x[5] = 1.49999;
107 1 : status = ind_pos -> call(x, f);
108 1 : _ASSERT(ForBESUtils::is_status_ok(status));
109 1 : _ASSERT(std::isinf(f));
110 :
111 1 : delete ind_pos;
112 1 : }
113 :
114 1 : void TestIndPos::testConjugate1() {
115 1 : Function * ind_pos = new IndPos();
116 1 : size_t n = 200;
117 1 : Matrix y(n, 1);
118 :
119 1 : double f_star = 1234.567;
120 1 : int status = ind_pos->callConj(y, f_star);
121 1 : _ASSERT(ForBESUtils::is_status_ok(status));
122 1 : _ASSERT_NUM_EQ(0.0, f_star, 1e-14);
123 :
124 1 : y[0] = -1.5;
125 1 : status = ind_pos->callConj(y, f_star);
126 1 : _ASSERT(ForBESUtils::is_status_ok(status));
127 1 : _ASSERT_NUM_EQ(0.0, f_star, 1e-14);
128 :
129 1 : y[4] = 1.0;
130 1 : status = ind_pos->callConj(y, f_star);
131 1 : _ASSERT(ForBESUtils::is_status_ok(status));
132 1 : _ASSERT(std::isinf(f_star));
133 :
134 1 : delete ind_pos;
135 1 : }
136 :
137 1 : void TestIndPos::testConjugate2() {
138 1 : double uniform_lb = -1.50;
139 1 : Function * ind_pos = new IndPos(uniform_lb);
140 1 : size_t n = 200;
141 1 : Matrix y(n, 1); // y = 0
142 :
143 : double f_star;
144 1 : int status = ind_pos->callConj(y, f_star);
145 1 : _ASSERT(ForBESUtils::is_status_ok(status));
146 1 : _ASSERT_NUM_EQ(0.0, f_star, 1e-14);
147 :
148 :
149 :
150 1 : y[0] = 1e-10;
151 1 : status = ind_pos->callConj(y, f_star);
152 1 : _ASSERT(ForBESUtils::is_status_ok(status));
153 1 : _ASSERT(std::isinf(f_star));
154 :
155 1 : y[0] = 1.0;
156 1 : y[1] = 2.0;
157 1 : status = ind_pos->callConj(y, f_star);
158 1 : _ASSERT(ForBESUtils::is_status_ok(status));
159 1 : _ASSERT(std::isinf(f_star));
160 :
161 1 : y[0] = -1.0;
162 1 : y[1] = -2.0;
163 1 : status = ind_pos->callConj(y, f_star);
164 1 : _ASSERT(ForBESUtils::is_status_ok(status));
165 1 : _ASSERT_NUM_EQ(4.50, f_star, 1e-14);
166 :
167 1 : y[0] = -1.0;
168 1 : y[1] = -2.0;
169 1 : y[1] = 1.0;
170 1 : status = ind_pos->callConj(y, f_star);
171 1 : _ASSERT(ForBESUtils::is_status_ok(status));
172 1 : _ASSERT(std::isinf(f_star));
173 :
174 1 : delete ind_pos;
175 1 : }
176 :
177 1 : void TestIndPos::testConjugate3() {
178 1 : size_t n = 100;
179 1 : Matrix lb(n, 1);
180 101 : for (size_t i = 0; i < n; i++) {
181 100 : lb[i] = 3.0 + i;
182 : }
183 1 : Function * ind_pos = new IndPos(lb);
184 :
185 2 : Matrix y(n, 1);
186 :
187 : double f_star;
188 1 : int status = ind_pos->callConj(y, f_star);
189 1 : _ASSERT(ForBESUtils::is_status_ok(status));
190 1 : _ASSERT_NUM_EQ(0.0, f_star, 1e-14);
191 :
192 1 : y[0] = 1.0;
193 1 : status = ind_pos->callConj(y, f_star);
194 1 : _ASSERT(ForBESUtils::is_status_ok(status));
195 1 : _ASSERT(std::isinf(f_star));
196 :
197 1 : y[0] = -1.0;
198 1 : y[1] = -2.0;
199 1 : y[2] = -3.0;
200 1 : status = ind_pos->callConj(y, f_star);
201 1 : _ASSERT(ForBESUtils::is_status_ok(status));
202 1 : _ASSERT_NUM_EQ(-26.0, f_star, 1e-14);
203 :
204 :
205 2 : delete ind_pos;
206 1 : }
207 :
208 1 : void TestIndPos::testProx1() {
209 1 : Function * ind_pos = new IndPos();
210 :
211 1 : size_t n = 10;
212 :
213 1 : Matrix x(n, 1);
214 1 : x[0] = 10.0;
215 1 : x[1] = -10.0;
216 1 : x[n - 2] = -1.2;
217 1 : x[n - 1] = 3.4;
218 :
219 2 : Matrix z(n, 1);
220 1 : x.plusop(&z);
221 :
222 2 : Matrix prox(n, 1);
223 1 : int status = ind_pos -> callProx(x, 1.0, prox);
224 :
225 1 : _ASSERT(ForBESUtils::is_status_ok(status));
226 1 : _ASSERT_EQ(z, prox);
227 :
228 2 : delete ind_pos;
229 1 : }
230 :
231 1 : void TestIndPos::testProx2() {
232 1 : size_t n = 50;
233 1 : Matrix lb(n, 1);
234 2 : Matrix prox(n, 1);
235 2 : Matrix x(n, 1);
236 51 : for (size_t i = 0; i < n; i++) {
237 50 : lb[i] = -3.0 + i;
238 50 : x[i] = lb[i] + std::pow(-1, i + 1);
239 : }
240 1 : Function * ind_pos = new IndPos(lb);
241 :
242 1 : int status = ind_pos -> callProx(x, 1.0, prox);
243 1 : _ASSERT(ForBESUtils::is_status_ok(status));
244 :
245 51 : for (size_t i = 0; i < n; i++) {
246 50 : if (i % 2 == 0) {
247 25 : _ASSERT_NUM_EQ(lb[i], prox[i], 1e-14);
248 : } else {
249 25 : _ASSERT_NUM_EQ(x[i], prox[i], 1e-14);
250 : }
251 : }
252 :
253 2 : delete ind_pos;
254 1 : }
255 :
256 1 : void TestIndPos::testProx3() {
257 1 : double uniform_lb = -1.50;
258 1 : Function * ind_pos = new IndPos(uniform_lb);
259 1 : size_t n = 10;
260 1 : Matrix x(n, 1); // y = 0
261 :
262 :
263 2 : Matrix prox(n, 1);
264 :
265 1 : int status = ind_pos -> callProx(x, 1.0, prox);
266 1 : _ASSERT(ForBESUtils::is_status_ok(status));
267 1 : _ASSERT_EQ(x, prox);
268 :
269 11 : for (size_t i = 0; i < n; i++) {
270 10 : if (i % 2 == 0) {
271 5 : x[i] = -1.0*i - 2.0;
272 : } else {
273 5 : x[i] = 1.0*i + 2.0;
274 : }
275 : }
276 1 : status = ind_pos -> callProx(x, 1.0, prox);
277 1 : _ASSERT(ForBESUtils::is_status_ok(status));
278 11 : for (size_t i = 0; i < n; i++) {
279 10 : _ASSERT_NUM_EQ(std::max(uniform_lb, x[i]), prox[i], 1e-14);
280 10 : if (i % 2 == 0) {
281 5 : _ASSERT_NUM_EQ(uniform_lb, prox[i], 1e-14);
282 : } else {
283 5 : _ASSERT_NUM_EQ(i + 2.0, prox[i], 1e-14);
284 : }
285 : }
286 :
287 2 : delete ind_pos;
288 1 : }
289 :
290 1 : void TestIndPos::testCategory() {
291 1 : Function * ind_pos = new IndPos();
292 1 : FunctionOntologicalClass cat = ind_pos -> category();
293 1 : _ASSERT(cat.defines_conjugate());
294 1 : _ASSERT(cat.defines_prox());
295 1 : _ASSERT(cat.defines_f());
296 1 : _ASSERT_NOT(cat.defines_conjugate_grad());
297 1 : _ASSERT_NOT(cat.defines_grad());
298 1 : _ASSERT_NOT(cat.defines_hessian());
299 1 : _ASSERT_NOT(cat.defines_hessian_conj());
300 1 : delete ind_pos;
301 4 : }
302 :
303 :
|