Line data Source code
1 : #include "FBCache.h"
2 : #include "FBProblem.h"
3 :
4 : #include "TestFBCache.h"
5 :
6 : #define DOUBLES_EQUAL_DELTA 1e-8
7 :
8 1 : CPPUNIT_TEST_SUITE_REGISTRATION(TestFBCache);
9 :
10 5 : TestFBCache::TestFBCache() {
11 5 : }
12 :
13 10 : TestFBCache::~TestFBCache() {
14 10 : }
15 :
16 5 : void TestFBCache::setUp() {
17 5 : }
18 :
19 5 : void TestFBCache::tearDown() {
20 5 : }
21 :
22 1 : void TestFBCache::testBoxQP_small() {
23 1 : size_t n = 4;
24 : // problem data
25 : double data_Q[] = {
26 : 7, 2, -2, -1,
27 : 2, 3, 0, -1,
28 : -2, 0, 3, -1,
29 : -1, -1, -1, 1
30 1 : };
31 : double data_q[] = {
32 : 1, 2, 3, 4
33 1 : };
34 1 : double gamma1 = 0.1;
35 1 : double gamma2 = 0.2;
36 1 : double lb = -1;
37 1 : double ub = +1;
38 : // starting points
39 1 : double data_x1[] = {+0.5, +1.2, -0.7, -1.1};
40 1 : double data_x2[] = {-1.0, -1.0, -1.0, -1.0};
41 : // reference results 1
42 1 : double ref_fx1 = +3.774999999999999;
43 1 : double ref_y1_g01[] = {-0.44, +0.43, -0.80, -1.29};
44 1 : double ref_z1_g01[] = {-0.44, +0.43, -0.80, -1.00};
45 1 : double ref_y1_g02[] = {-1.38, -0.34, -0.90, -1.48};
46 1 : double ref_z1_g02[] = {-1.00, -0.34, -0.90, -1.00};
47 1 : double ref_FBEx1_g01 = -3.417500000000000;
48 1 : double ref_FBEx1_g02 = -10.514000000000003;
49 : /*
50 : * WARNING: The following two arrays are never used
51 : */
52 1 : double ref_gradFBEx1_g01[] = {1.379999999999999, 3.409999999999999, 2.480000000000000, 0.909999999999999};
53 1 : double ref_gradFBEx1_g02[] = {-5.779999999999999, -0.020000000000000, 3.300000000000000, 2.840000000000000};
54 :
55 : // reference results 2
56 1 : double ref_fx2 = -6.000000000000000;
57 1 : double ref_y2_g01[] = {-0.50, -0.80, -1.30, -1.60};
58 1 : double ref_z2_g01[] = {-0.50, -0.80, -1.00, -1.00};
59 1 : double ref_y2_g02[] = {+0.00, -0.60, -1.60, -2.20};
60 1 : double ref_z2_g02[] = {+0.00, -0.60, -1.00, -1.00};
61 1 : double ref_FBEx2_g01 = -7.450000000000000;
62 1 : double ref_FBEx2_g02 = -8.900000000000000;
63 :
64 1 : Matrix Q(n, n, data_Q);
65 2 : Matrix q(n, 1, data_q);
66 2 : Quadratic f(Q, q);
67 2 : IndBox g(lb, ub);
68 2 : FBProblem prob(f, g);
69 :
70 : FBCache * cache;
71 : Matrix * x, * y, * z, * gradFBEx;
72 : double fx, FBEx;
73 :
74 : // test FB operations starting from x1
75 1 : x = new Matrix(n, 1, data_x1);
76 1 : cache = new FBCache(prob, *x, 1.0);
77 1 : fx = cache->get_eval_f();
78 1 : y = cache->get_forward_step(gamma1);
79 1 : z = cache->get_forward_backward_step(gamma1);
80 1 : FBEx = cache->get_eval_FBE(gamma1);
81 1 : gradFBEx = cache->get_grad_FBE(gamma1);
82 :
83 1 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_fx1, fx, DOUBLES_EQUAL_DELTA);
84 5 : for (int i = 0; i < n; i++) {
85 4 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_y1_g01[i], y->get(i, 0), DOUBLES_EQUAL_DELTA);
86 4 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_z1_g01[i], z->get(i, 0), DOUBLES_EQUAL_DELTA);
87 : // CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_gradFBEx1_g01[i], gradFBEx->get(i, 0), DOUBLES_EQUAL_DELTA);
88 : }
89 1 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_FBEx1_g01, FBEx, DOUBLES_EQUAL_DELTA);
90 :
91 : // change gamma
92 1 : y = cache->get_forward_step(gamma2);
93 1 : z = cache->get_forward_backward_step(gamma2);
94 1 : FBEx = cache->get_eval_FBE(gamma2);
95 1 : gradFBEx = cache->get_grad_FBE(gamma2);
96 :
97 1 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_fx1, fx, DOUBLES_EQUAL_DELTA);
98 5 : for (int i = 0; i < n; i++) {
99 4 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_y1_g02[i], y->get(i, 0), DOUBLES_EQUAL_DELTA);
100 4 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_z1_g02[i], z->get(i, 0), DOUBLES_EQUAL_DELTA);
101 : // CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_gradFBEx1_g02[i], gradFBEx->get(i, 0), DOUBLES_EQUAL_DELTA);
102 : }
103 1 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_FBEx1_g02, FBEx, DOUBLES_EQUAL_DELTA);
104 :
105 1 : delete x;
106 :
107 : // change point x
108 1 : x = new Matrix(n, 1, data_x2);
109 1 : cache->set_point(*x);
110 1 : fx = cache->get_eval_f();
111 1 : y = cache->get_forward_step(gamma1);
112 1 : z = cache->get_forward_backward_step(gamma1);
113 1 : FBEx = cache->get_eval_FBE(gamma1);
114 1 : gradFBEx = cache->get_grad_FBE(gamma1);
115 :
116 1 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_fx2, fx, DOUBLES_EQUAL_DELTA);
117 5 : for (int i = 0; i < n; i++) {
118 4 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_y2_g01[i], y->get(i, 0), DOUBLES_EQUAL_DELTA);
119 4 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_z2_g01[i], z->get(i, 0), DOUBLES_EQUAL_DELTA);
120 : }
121 1 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_FBEx2_g01, FBEx, DOUBLES_EQUAL_DELTA);
122 :
123 : // change gamma
124 1 : y = cache->get_forward_step(gamma2);
125 1 : z = cache->get_forward_backward_step(gamma2);
126 1 : FBEx = cache->get_eval_FBE(gamma2);
127 1 : gradFBEx = cache->get_grad_FBE(gamma2);
128 :
129 1 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_fx2, fx, DOUBLES_EQUAL_DELTA);
130 5 : for (int i = 0; i < n; i++) {
131 4 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_y2_g02[i], y->get(i, 0), DOUBLES_EQUAL_DELTA);
132 4 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_z2_g02[i], z->get(i, 0), DOUBLES_EQUAL_DELTA);
133 : }
134 1 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_FBEx2_g02, FBEx, DOUBLES_EQUAL_DELTA);
135 :
136 1 : delete x;
137 2 : delete cache;
138 1 : }
139 :
140 1 : void TestFBCache::testSparseLeastSquares_small() {
141 1 : size_t n = 10;
142 1 : size_t m = 5;
143 : // problem data
144 : double data_A[] = {
145 : 4, -5, 0, -3, 1,
146 : -4, 2, 3, 8, -1,
147 : -11, -5, 6, -6, 4,
148 : 0, 7, -10, -1, -7,
149 : 14, 4, 6, -6, -3,
150 : -2, 5, -2, 3, -11,
151 : -2, -5, -8, 2, 1,
152 : 0, -7, 5, 1, -2,
153 : 0, -2, -9, -2, -5,
154 : -5, -6, -3, -11, 4
155 1 : };
156 1 : double data_minusb[] = {1, 4, -6, 2, 3};
157 1 : double gamma1 = 0.0017;
158 1 : double gamma2 = 0.003;
159 : // starting points
160 1 : double data_x1[] = {-0.14, -0.24, -0.15, 0.03, 0.03, 0.04, -0.02, 0.01, -0.05, 0.08};
161 1 : double data_x2[] = {-0.14, 0.04, -0.09, -0.04, 0.05, 0.10, -0.12, 0.12, 0.06, -0.01};
162 : // reference results 1
163 1 : double ref_fx1 = 47.978750000000005;
164 1 : double ref_y1_g1[] = {-0.118172, -0.202073, 0.015444, -0.128984, 0.015125, 0.021640, -0.072156, 0.141121, -0.124545, 0.114323};
165 1 : double ref_z1_g1[] = {-0.116472, -0.200373, 0.013744, -0.127284, 0.013425, 0.019940, -0.070456, 0.139421, -0.122845, 0.112623};
166 1 : double ref_y1_g2[] = {-0.10148, -0.17307, 0.14196, -0.25056, 0.00375, 0.00760, -0.11204, 0.24139, -0.18155, 0.14057};
167 1 : double ref_z1_g2[] = {-0.09848, -0.17007, 0.13896, -0.24756, 0.00075, 0.00460, -0.10904, 0.23839, -0.17855, 0.13757};
168 1 : double ref_FBEx1_g1 = 24.874158335000004;
169 1 : double ref_FBEx1_g2 = 6.877117650000010;
170 : // reference results 2
171 1 : double ref_fx2 = 33.691600000000001;
172 1 : double ref_y2_g1[] = {-0.093607, 0.018614, 0.070837, -0.171631, 0.050833, 0.043475, -0.145942, 0.222323, 0.021240, 0.091524};
173 1 : double ref_z2_g1[] = {-0.091907, 0.016914, 0.069137, -0.169931, 0.049133, 0.041775, -0.144242, 0.220623, 0.019540, 0.089824};
174 1 : double ref_y2_g2[] = {-0.05813, 0.00226, 0.19383, -0.27229, 0.05147, 0.00025, -0.16578, 0.30057, -0.00840, 0.16916};
175 1 : double ref_z2_g2[] = {-0.05513, 0, 0.19083, -0.26929, 0.04847, 0, -0.16278, 0.29757, -0.00540, 0.16616};
176 1 : double ref_FBEx2_g1 = 13.450436129999996;
177 1 : double ref_FBEx2_g2 = -2.445831616666666;
178 :
179 1 : Matrix A(m, n, data_A);
180 2 : Matrix minusb(m, 1, data_minusb);
181 2 : MatrixOperator OpA(A);
182 2 : QuadraticLoss f;
183 2 : Norm1 g;
184 2 : FBProblem prob(f, OpA, minusb, g);
185 :
186 : FBCache * cache;
187 : Matrix * x, * y, * z, * gradFBEx;
188 : double fx, FBEx;
189 :
190 : // test FB operations starting from x1
191 1 : x = new Matrix(n, 1, data_x1);
192 1 : cache = new FBCache(prob, *x, 1.0);
193 1 : fx = cache->get_eval_f();
194 1 : y = cache->get_forward_step(gamma1);
195 1 : z = cache->get_forward_backward_step(gamma1);
196 1 : FBEx = cache->get_eval_FBE(gamma1);
197 1 : gradFBEx = cache->get_grad_FBE(gamma1);
198 :
199 1 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_fx1, fx, DOUBLES_EQUAL_DELTA);
200 11 : for (int i = 0; i < n; i++) {
201 10 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_y1_g1[i], y->get(i, 0), DOUBLES_EQUAL_DELTA);
202 10 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_z1_g1[i], z->get(i, 0), DOUBLES_EQUAL_DELTA);
203 : }
204 1 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_FBEx1_g1, FBEx, DOUBLES_EQUAL_DELTA);
205 :
206 : // change gamma
207 1 : y = cache->get_forward_step(gamma2);
208 1 : z = cache->get_forward_backward_step(gamma2);
209 1 : FBEx = cache->get_eval_FBE(gamma2);
210 1 : gradFBEx = cache->get_grad_FBE(gamma2);
211 :
212 1 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_fx1, fx, DOUBLES_EQUAL_DELTA);
213 11 : for (int i = 0; i < n; i++) {
214 10 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_y1_g2[i], y->get(i, 0), DOUBLES_EQUAL_DELTA);
215 10 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_z1_g2[i], z->get(i, 0), DOUBLES_EQUAL_DELTA);
216 : }
217 1 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_FBEx1_g2, FBEx, DOUBLES_EQUAL_DELTA);
218 :
219 1 : delete x;
220 :
221 : // test FB operations starting from x2
222 1 : x = new Matrix(n, 1, data_x2);
223 1 : cache->set_point(*x);
224 1 : fx = cache->get_eval_f();
225 1 : y = cache->get_forward_step(gamma1);
226 1 : z = cache->get_forward_backward_step(gamma1);
227 1 : FBEx = cache->get_eval_FBE(gamma1);
228 1 : gradFBEx = cache->get_grad_FBE(gamma1);
229 :
230 1 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_fx2, fx, DOUBLES_EQUAL_DELTA);
231 11 : for (int i = 0; i < n; i++) {
232 10 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_y2_g1[i], y->get(i, 0), DOUBLES_EQUAL_DELTA);
233 10 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_z2_g1[i], z->get(i, 0), DOUBLES_EQUAL_DELTA);
234 : }
235 1 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_FBEx2_g1, FBEx, DOUBLES_EQUAL_DELTA);
236 :
237 : // change gamma
238 1 : y = cache->get_forward_step(gamma2);
239 1 : z = cache->get_forward_backward_step(gamma2);
240 1 : FBEx = cache->get_eval_FBE(gamma2);
241 1 : gradFBEx = cache->get_grad_FBE(gamma2);
242 :
243 1 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_fx2, fx, DOUBLES_EQUAL_DELTA);
244 11 : for (int i = 0; i < n; i++) {
245 10 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_y2_g2[i], y->get(i, 0), DOUBLES_EQUAL_DELTA);
246 10 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_z2_g2[i], z->get(i, 0), DOUBLES_EQUAL_DELTA);
247 : }
248 1 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_FBEx2_g2, FBEx, DOUBLES_EQUAL_DELTA);
249 :
250 1 : delete x;
251 2 : delete cache;
252 1 : }
253 :
254 1 : void TestFBCache::testSparseLogReg_small() {
255 1 : size_t n = 5;
256 1 : size_t m = 4;
257 : // problem data
258 : double data_A[] = {
259 : 1, 2, -1, -1,
260 : -2, -1, 0, -1,
261 : 3, 0, 4, -1,
262 : -4, -1, -3, 1,
263 : 5, 3, 2, 3
264 1 : };
265 : double data_minusb[] = {
266 : -1, 1, -1, 1
267 1 : };
268 1 : double gamma1 = 0.1;
269 1 : double gamma2 = 0.05;
270 : // starting points
271 1 : double data_x1[] = {0, 0, 0, 0, 0};
272 : // reference results
273 1 : double ref_fx1 = 3.253046750072892;
274 1 : double ref_y1_g1[] = {0.026894142137000, -0.200000000000000, 0.484846862904004, -0.511741005041004, 0.673105857863000};
275 1 : double ref_z1_g1[] = {0, -0.100000000000000, 0.384846862904004, -0.411741005041004, 0.573105857863001};
276 1 : double ref_FBEx1_g1 = -0.027393687107681;
277 1 : double ref_y1_g2[] = {0.013447071068500, -0.100000000000000, 0.242423431452002, -0.255870502520502, 0.336552928931500};
278 1 : double ref_z1_g2[] = {0, -0.050000000000000, 0.192423431452002, -0.205870502520502, 0.286552928931500};
279 1 : double ref_FBEx1_g2 = 1.612826531482605;
280 :
281 1 : Matrix A(m, n, data_A);
282 2 : Matrix minusb(m, 1, data_minusb);
283 2 : Matrix xstar;
284 2 : LogLogisticLoss f(1.0);
285 2 : MatrixOperator OpA(A);
286 2 : Norm1 g(1.0);
287 2 : FBProblem prob(f, OpA, minusb, g);
288 :
289 : FBCache * cache;
290 : Matrix * x, * y, * z, * gradFBEx;
291 : double fx, FBEx;
292 :
293 : // test FB operations starting from x1
294 1 : x = new Matrix(n, 1, data_x1);
295 1 : cache = new FBCache(prob, *x, 1.0);
296 1 : fx = cache->get_eval_f();
297 1 : y = cache->get_forward_step(gamma1);
298 1 : z = cache->get_forward_backward_step(gamma1);
299 1 : FBEx = cache->get_eval_FBE(gamma1);
300 1 : gradFBEx = cache->get_grad_FBE(gamma1);
301 :
302 1 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_fx1, fx, DOUBLES_EQUAL_DELTA);
303 6 : for (int i = 0; i < n; i++) {
304 5 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_y1_g1[i], y->get(i, 0), DOUBLES_EQUAL_DELTA);
305 5 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_z1_g1[i], z->get(i, 0), DOUBLES_EQUAL_DELTA);
306 : }
307 1 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_FBEx1_g1, FBEx, DOUBLES_EQUAL_DELTA);
308 :
309 : // change gamma
310 1 : y = cache->get_forward_step(gamma2);
311 1 : z = cache->get_forward_backward_step(gamma2);
312 1 : FBEx = cache->get_eval_FBE(gamma2);
313 1 : gradFBEx = cache->get_grad_FBE(gamma2);
314 :
315 1 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_fx1, fx, DOUBLES_EQUAL_DELTA);
316 6 : for (int i = 0; i < n; i++) {
317 5 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_y1_g2[i], y->get(i, 0), DOUBLES_EQUAL_DELTA);
318 5 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_z1_g2[i], z->get(i, 0), DOUBLES_EQUAL_DELTA);
319 : }
320 1 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_FBEx1_g2, FBEx, DOUBLES_EQUAL_DELTA);
321 :
322 1 : delete x;
323 :
324 2 : delete cache;
325 1 : }
326 :
327 1 : void TestFBCache::testLogLossPlusL1_small() {
328 1 : size_t n = 5;
329 1 : size_t m = 5;
330 1 : double gamma1 = 0.1;
331 1 : double gamma2 = 0.05;
332 : // starting points
333 1 : double data_x1[] = {1, -2, 3, -4, 5};
334 : // reference results
335 1 : double ref_fx1 = 6.513642326541865;
336 1 : double ref_y1_g1[] = {1.026894142136999, -1.911920292202212, 3.004742587317756, -3.901798620996209, 5.000669285092428};
337 1 : double ref_z1_g1[] = {0.926894142136999, -1.811920292202212, 2.904742587317756, -3.801798620996209, 4.900669285092428};
338 1 : double ref_FBEx1_g1 = 21.018928350676088;
339 1 : double ref_gradFBEx1_g1[] = {0.716685094584284, -1.861049915114549, 0.948270715102844, -1.978513017309498, 0.992646792853859};
340 1 : double ref_y1_g2[] = {1.013447071068500, -1.955960146101106, 3.002371293658878, -3.950899310498105, 5.000334642546214};
341 1 : double ref_z1_g2[] = {0.963447071068500, -1.905960146101106, 2.952371293658878, -3.900899310498105, 4.950334642546214};
342 1 : double ref_FBEx1_g2 = 21.266285338608977;
343 1 : double ref_gradFBEx1_g2[] = {0.723871836607145, -1.870923496546218, 0.950422420962636, -1.980263403673695, 0.992976970964787};
344 :
345 1 : Function * f = new LogLogisticLoss(1.0);
346 1 : Function * g = new Norm1(1.0);
347 1 : FBProblem * prob = new FBProblem(*f, *g);
348 :
349 : FBCache * cache;
350 : Matrix * x, * y, * z, * gradFBEx;
351 : double fx, FBEx;
352 :
353 : // test FB operations starting from x1
354 1 : x = new Matrix(n, 1, data_x1);
355 1 : cache = new FBCache(*prob, *x, 1.0);
356 1 : fx = cache->get_eval_f();
357 1 : y = cache->get_forward_step(gamma1);
358 1 : z = cache->get_forward_backward_step(gamma1);
359 1 : FBEx = cache->get_eval_FBE(gamma1);
360 1 : gradFBEx = cache->get_grad_FBE(gamma1);
361 :
362 1 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_fx1, fx, DOUBLES_EQUAL_DELTA);
363 6 : for (int i = 0; i < n; i++) {
364 5 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_y1_g1[i], y->get(i, 0), DOUBLES_EQUAL_DELTA);
365 5 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_z1_g1[i], z->get(i, 0), DOUBLES_EQUAL_DELTA);
366 5 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_gradFBEx1_g1[i], gradFBEx->get(i, 0), DOUBLES_EQUAL_DELTA);
367 : }
368 1 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_FBEx1_g1, FBEx, DOUBLES_EQUAL_DELTA);
369 :
370 : // change gamma
371 1 : y = cache->get_forward_step(gamma2);
372 1 : z = cache->get_forward_backward_step(gamma2);
373 1 : FBEx = cache->get_eval_FBE(gamma2);
374 1 : gradFBEx = cache->get_grad_FBE(gamma2);
375 :
376 1 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_fx1, fx, DOUBLES_EQUAL_DELTA);
377 6 : for (int i = 0; i < n; i++) {
378 5 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_y1_g2[i], y->get(i, 0), DOUBLES_EQUAL_DELTA);
379 5 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_z1_g2[i], z->get(i, 0), DOUBLES_EQUAL_DELTA);
380 5 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_gradFBEx1_g2[i], gradFBEx->get(i, 0), DOUBLES_EQUAL_DELTA);
381 : }
382 1 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_FBEx1_g2, FBEx, DOUBLES_EQUAL_DELTA);
383 :
384 1 : delete x;
385 1 : delete cache;
386 :
387 1 : delete prob;
388 1 : delete f;
389 1 : delete g;
390 1 : }
391 :
392 1 : void TestFBCache::testNormFPR() {
393 1 : const size_t n = 4;
394 : double data_Q[] = {
395 : 0.38709031607167643, 0.05275627355087711, -0.00567041452897057, -0.04552299262801366,
396 : 0.05275627355087711, 0.41944974781767824, 0.00264334247883102, 0.14679014798515927,
397 : -0.00567041452897057, 0.00264334247883102, 0.45001600696097127, -0.11712342226158394,
398 : -0.04552299262801366, 0.14679014798515927, -0.11712342226158394, 0.40344392914967364
399 1 : };
400 : double data_q[] = {
401 : 0.0671663832879185,
402 : 0.3177112577015106,
403 : 0.6169198108394168,
404 : 0.2980171238013654
405 1 : };
406 : double data_x[] = {
407 : -0.915621290369497,
408 : -0.519777906036200,
409 : 2.188590138643507,
410 : -0.518338872582518
411 1 : };
412 1 : double gamma = 0.04;
413 1 : double lambda = 0.3;
414 :
415 : double data_exp_fs[] = {
416 : -0.903481403431719,
417 : -0.519021263328163,
418 : 2.121936217451373,
419 : -0.510256665820712
420 1 : };
421 :
422 : double data_exp_fs2[] = {
423 : -0.891341516493941,
424 : -0.518264620620125,
425 : 2.055282296259238,
426 : -0.502174459058907
427 1 : };
428 :
429 : double data_exp_fbs[] = {
430 : -0.891481403431719,
431 : -0.507021263328163,
432 : 2.109936217451373,
433 : -0.498256665820712
434 1 : };
435 :
436 : double data_exp_FPR[] = {
437 : -0.0241398869377781,
438 : -0.0127566427080374,
439 : 0.0786539211921347,
440 : -0.0200822067618059
441 1 : };
442 :
443 1 : double exp_norm_fpr = 0.0856457846123888;
444 :
445 1 : Matrix Q(n, n, data_Q);
446 2 : Matrix q(n, 1, data_q);
447 2 : Matrix x(n, 1, data_x);
448 2 : Matrix exp_fs(n, 1, data_exp_fs);
449 2 : Matrix exp_fs2(n, 1, data_exp_fs2);
450 2 : Matrix exp_fbs(n, 1, data_exp_fbs);
451 2 : Matrix exp_FPR(n, 1, data_exp_FPR);
452 :
453 1 : Function * quadratic = new Quadratic(Q, q);
454 1 : Function * norm1 = new Norm1(lambda);
455 :
456 1 : FBProblem * prob = new FBProblem(*quadratic, *norm1);
457 1 : FBCache * cache = new FBCache(*prob, x, gamma);
458 :
459 :
460 1 : double norm_fpr = cache->get_norm_fpr();
461 1 : _ASSERT_NUM_EQ(exp_norm_fpr, norm_fpr, 1e-12);
462 :
463 1 : Matrix * fb = cache->get_forward_step(gamma);
464 1 : _ASSERT_EQ(*fb, exp_fs);
465 :
466 1 : Matrix * fbs = cache->get_forward_backward_step(gamma);
467 1 : _ASSERT_EQ(*fbs, exp_fbs);
468 :
469 1 : Matrix * fpr = cache->get_fpr();
470 1 : _ASSERT_EQ(*fpr, exp_FPR);
471 :
472 1 : fb = cache->get_forward_step(2 * gamma);
473 1 : _ASSERT_EQ(*fb, exp_fs2);
474 :
475 1 : delete cache;
476 1 : delete quadratic;
477 1 : delete norm1;
478 2 : delete prob;
479 4 : }
|