Line data Source code
1 : /*
2 : * File: TestIndBox.cpp
3 : * Author: Pantelis Sopasakis
4 : *
5 : * Created on Jul 26, 2015, 5:41: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 "TestIndBox.h"
22 :
23 :
24 :
25 1 : CPPUNIT_TEST_SUITE_REGISTRATION(TestIndBox);
26 :
27 6 : TestIndBox::TestIndBox() {
28 6 : }
29 :
30 12 : TestIndBox::~TestIndBox() {
31 12 : }
32 :
33 6 : void TestIndBox::setUp() {
34 6 : }
35 :
36 6 : void TestIndBox::tearDown() {
37 6 : }
38 :
39 1 : void TestIndBox::testCall() {
40 1 : double lb = -1.0;
41 1 : double ub = 4.0;
42 1 : Function *F = new IndBox(lb, ub);
43 :
44 1 : Matrix x(2, 1);
45 1 : x[0] = -1.0;
46 1 : x[1] = 4.0;
47 :
48 1 : double fval = -1;
49 1 : _ASSERT(F->category().defines_f());
50 1 : _ASSERT_EQ(ForBESUtils::STATUS_OK, F->call(x, fval));
51 1 : _ASSERT_EQ(0.0, fval);
52 :
53 1 : x[1] = 5.0;
54 1 : _ASSERT_EQ(ForBESUtils::STATUS_OK, F->call(x, fval));
55 1 : _ASSERT(isinf(fval));
56 :
57 1 : x[0] = -0.5;
58 1 : x[1] = 3.1;
59 1 : _ASSERT_EQ(ForBESUtils::STATUS_OK, F->call(x, fval));
60 1 : _ASSERT_NOT(isinf(fval));
61 1 : _ASSERT_EQ(0.0, fval);
62 :
63 1 : x[0] = -1 - 1e-9;
64 1 : _ASSERT_EQ(ForBESUtils::STATUS_OK, F->call(x, fval));
65 1 : _ASSERT_NEQ(0.0, fval);
66 1 : _ASSERT(isinf(fval));
67 :
68 :
69 1 : delete F;
70 :
71 1 : }
72 :
73 1 : void TestIndBox::testCall2() {
74 1 : const long n = 10;
75 1 : Matrix lb(n, 1);
76 2 : Matrix ub(n, 1);
77 11 : for (long i = 0; i < n; i++) {
78 10 : lb[i] = -i - 1;
79 10 : ub[i] = i + 1;
80 : }
81 :
82 : Function *F;
83 1 : F = new IndBox(lb, ub);
84 :
85 2 : Matrix x(n, 1);
86 :
87 1 : double fval = -1;
88 1 : _ASSERT_EQ(ForBESUtils::STATUS_OK, F->call(x, fval));
89 1 : _ASSERT_EQ(0.0, fval);
90 :
91 1 : x = ub;
92 1 : _ASSERT_EQ(ForBESUtils::STATUS_OK, F->call(x, fval));
93 1 : _ASSERT_EQ(0.0, fval);
94 :
95 1 : x = lb;
96 1 : _ASSERT_EQ(ForBESUtils::STATUS_OK, F->call(x, fval));
97 1 : _ASSERT_EQ(0.0, fval);
98 :
99 :
100 2 : Matrix y(n, n);
101 1 : _ASSERT_EXCEPTION(F->call(y, fval), std::invalid_argument);
102 :
103 1 : lb = Matrix(n, n);
104 1 : _ASSERT_EXCEPTION(F = new IndBox(lb, ub), std::invalid_argument);
105 :
106 :
107 1 : lb = Matrix(n, 1);
108 1 : ub = Matrix(n, n);
109 :
110 1 : _ASSERT_EXCEPTION(F = new IndBox(lb, ub), std::invalid_argument);
111 2 : delete F;
112 1 : }
113 :
114 1 : void TestIndBox::testCall3() {
115 1 : const long n = 30;
116 1 : Matrix lb(n, 1);
117 2 : Matrix ub(n, 1);
118 30 : for (long i = 0; i < n - 1; i++) {
119 29 : lb[i] = -i - 1;
120 29 : ub[i] = i + 1;
121 : }
122 1 : lb[n - 1] = -INFINITY;
123 1 : ub[n - 1] = INFINITY;
124 2 : Matrix x(n, 1);
125 :
126 1 : x[n - 1] = 1e9;
127 :
128 1 : Function *F = new IndBox(lb, ub);
129 :
130 : double f;
131 1 : _ASSERT_EQ(ForBESUtils::STATUS_OK, F->call(x, f));
132 :
133 1 : _ASSERT_EQ(0.0, f);
134 :
135 1 : lb[n - 1] = 0.0;
136 1 : _ASSERT_EQ(ForBESUtils::STATUS_OK, F->call(x, f));
137 1 : _ASSERT_EQ(0.0, f);
138 :
139 1 : x[n - 1] = -0.1;
140 1 : _ASSERT_EQ(ForBESUtils::STATUS_OK, F->call(x, f));
141 1 : _ASSERT(isinf(f));
142 :
143 2 : delete F;
144 1 : }
145 :
146 1 : void TestIndBox::testCallProx() {
147 1 : const double tol = 1e-10;
148 1 : double lb = -1.0;
149 1 : double ub = 4.0;
150 1 : Function *F = new IndBox(lb, ub);
151 :
152 1 : Matrix x(2, 1);
153 1 : x[0] = lb - 1.0;
154 1 : x[1] = (lb + ub) / 2.0;
155 :
156 1 : double gamma = 1.5;
157 :
158 2 : Matrix prox(2, 1);
159 : double fprox;
160 :
161 1 : _ASSERT(F->category().defines_prox());
162 1 : int status = F->callProx(x, gamma, prox, fprox);
163 1 : _ASSERT_EQ(ForBESUtils::STATUS_OK, status);
164 1 : _ASSERT_NUM_EQ(0.0, fprox, tol);
165 :
166 1 : _ASSERT_NUM_EQ(lb, prox[0], tol);
167 1 : _ASSERT_NUM_EQ(x.get(1, 0), prox.get(1, 0), tol);
168 :
169 1 : status = F->callProx(x, gamma, prox);
170 1 : _ASSERT_EQ(ForBESUtils::STATUS_OK, status);
171 :
172 1 : _ASSERT_NUM_EQ(lb, prox.get(0, 0), tol);
173 1 : _ASSERT_NUM_EQ(x.get(1, 0), prox.get(1, 0), tol);
174 :
175 2 : delete F;
176 1 : }
177 :
178 1 : void TestIndBox::testCategory() {
179 1 : double lb = 1.0;
180 1 : double ub = 2.0;
181 1 : Function * ind_box = new IndBox(lb, ub);
182 1 : FunctionOntologicalClass cat = ind_box -> category();
183 1 : _ASSERT(cat.defines_conjugate());
184 1 : _ASSERT(cat.defines_prox());
185 1 : _ASSERT(cat.defines_f());
186 1 : _ASSERT_NOT(cat.defines_conjugate_grad());
187 1 : _ASSERT_NOT(cat.defines_grad());
188 1 : _ASSERT_NOT(cat.defines_hessian());
189 1 : _ASSERT_NOT(cat.defines_hessian_conj());
190 1 : delete ind_box;
191 1 : }
192 :
193 1 : void TestIndBox::testCallConj() {
194 1 : double lb = -1.5;
195 1 : double ub = 2.0;
196 1 : Function * ind_box = new IndBox(lb, ub);
197 :
198 1 : Matrix x(5,1);
199 1 : x[1] = 10;
200 1 : x[2] = -0.5;
201 1 : x[3] = -1.0;
202 1 : x[4] = -1.5;
203 1 : double f_star = 0.0;
204 1 : ind_box->callConj(x, f_star);
205 1 : _ASSERT_NUM_EQ(24.5, f_star, 1e-8);
206 1 : delete ind_box;
207 4 : }
208 :
209 :
|