Line data Source code
1 : #include "FBSplitting.h"
2 : #include "FBProblem.h"
3 : #include "FBStoppingRelative.h"
4 : #include "MatrixFactory.h"
5 : #include "MatrixOperator.h"
6 : #include "TestFBSplitting.h"
7 :
8 : // #include <iostream>
9 :
10 : #define DOUBLES_EQUAL_DELTA 1e-4
11 : #define MAXIT 1000
12 : #define TOLERANCE 1e-6
13 :
14 1 : CPPUNIT_TEST_SUITE_REGISTRATION(TestFBSplitting);
15 :
16 3 : TestFBSplitting::TestFBSplitting() {
17 3 : }
18 :
19 6 : TestFBSplitting::~TestFBSplitting() {
20 6 : }
21 :
22 3 : void TestFBSplitting::setUp() {
23 3 : }
24 :
25 3 : void TestFBSplitting::tearDown() {
26 3 : }
27 :
28 1 : void TestFBSplitting::testBoxQP_small() {
29 1 : size_t n = 4;
30 : // problem data
31 : double data_Q[] = {
32 : 7, 2, -2, -1,
33 : 2, 3, 0, -1,
34 : -2, 0, 3, -1,
35 : -1, -1, -1, 1
36 1 : };
37 : double data_q[] = {
38 : 1, 2, 3, 4
39 1 : };
40 1 : double gamma = 0.1;
41 1 : double lb = -1;
42 1 : double ub = +1;
43 : // starting points
44 1 : double data_x1[] = {+0.5, +1.2, -0.7, -1.1};
45 1 : double data_x2[] = {-1.0, -1.0, -1.0, -1.0};
46 : // reference results
47 1 : double ref_xstar[] = {-0.352941176470588, -0.764705882352941, -1.000000000000000, -1.000000000000000};
48 :
49 1 : Matrix * Q = new Matrix(n, n, data_Q);
50 1 : Matrix * q = new Matrix(n, 1, data_q);
51 : Matrix * x0;
52 1 : Matrix xstar;
53 1 : Function * f = new Quadratic(*Q, *q);
54 1 : Function * g = new IndBox(lb, ub);
55 2 : FBProblem prob(*f, *g);
56 2 : FBStoppingRelative sc(TOLERANCE);
57 : FBSplitting * solver;
58 :
59 : // test FB operations starting from x1
60 1 : size_t repeat = 100;
61 101 : for (size_t r = 0; r < repeat; r++) {
62 100 : x0 = new Matrix(n, 1, data_x1);
63 100 : solver = new FBSplitting(prob, *x0, gamma, sc, MAXIT);
64 100 : solver->run();
65 100 : xstar = solver->getSolution();
66 : // cout << "*** iters (slow) : " << solver->getIt() << endl;
67 100 : _ASSERT(solver->getIt() < MAXIT);
68 500 : for (int i=0; i < n; i++) {
69 400 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_xstar[i], xstar.get(i, 0), DOUBLES_EQUAL_DELTA);
70 : }
71 100 : delete x0;
72 100 : delete solver;
73 :
74 : // test FB operations starting from x2
75 100 : x0 = new Matrix(n, 1, data_x2);
76 100 : solver = new FBSplitting(prob, *x0, gamma, sc, MAXIT);
77 100 : solver->run();
78 100 : xstar = solver->getSolution();
79 : // cout << "*** iters (slow) : " << solver->getIt() << endl;
80 100 : _ASSERT(solver->getIt() < MAXIT);
81 500 : for (int i=0; i < n; i++) {
82 400 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_xstar[i], xstar.get(i, 0), DOUBLES_EQUAL_DELTA);
83 : }
84 100 : delete x0;
85 100 : delete solver;
86 : }
87 :
88 1 : delete Q;
89 1 : delete q;
90 1 : delete f;
91 2 : delete g;
92 1 : }
93 :
94 1 : void TestFBSplitting::testLasso_small() {
95 1 : size_t n = 5;
96 1 : size_t m = 4;
97 : // problem data
98 : double data_A[] = {
99 : 1, 2, -1, -1,
100 : -2, -1, 0, -1,
101 : 3, 0, 4, -1,
102 : -4, -1, -3, 1,
103 : 5, 3, 2, 3
104 1 : };
105 1 : double data_minusb[] = {-1, -2, -3, -4};
106 1 : double gamma = 0.01;
107 : // starting points
108 1 : double data_x1[] = {0, 0, 0, 0, 0};
109 : // reference results
110 1 : double ref_xstar[] = {-0.010238907849511, 0, 0, 0, 0.511945392491421};
111 :
112 1 : Matrix * A = new Matrix(m, n, data_A);
113 1 : Matrix * minusb = new Matrix(m, 1, data_minusb);
114 : Matrix * x0;
115 1 : Matrix xstar;
116 1 : Function * f = new QuadraticLoss();
117 1 : LinearOperator * OpA = new MatrixOperator(*A);
118 1 : Function * g = new Norm1(5.0);
119 2 : FBProblem prob(*f, *OpA, *minusb, *g);
120 2 : FBStoppingRelative sc(TOLERANCE);
121 : FBSplitting * solver;
122 :
123 : // test FB operations starting from x1
124 1 : size_t repeat = 100;
125 101 : for (size_t r = 0; r < repeat; r++) {
126 100 : x0 = new Matrix(n, 1, data_x1);
127 100 : solver = new FBSplitting(prob, *x0, gamma, sc, MAXIT);
128 100 : solver->run();
129 100 : xstar = solver->getSolution();
130 : // cout << "*** iters (slow) : " << solver->getIt() << endl;
131 100 : _ASSERT(solver->getIt() < MAXIT);
132 600 : for (int i=0; i < n; i++) {
133 500 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_xstar[i], xstar.get(i, 0), DOUBLES_EQUAL_DELTA);
134 : }
135 100 : delete x0;
136 100 : delete solver;
137 : }
138 :
139 1 : delete A;
140 1 : delete minusb;
141 1 : delete OpA;
142 1 : delete f;
143 2 : delete g;
144 1 : }
145 :
146 1 : void TestFBSplitting::testSparseLogReg_small() {
147 1 : size_t n = 5;
148 1 : size_t m = 4;
149 : // problem data
150 : double data_A[] = {
151 : 1, 2, -1, -1,
152 : -2, -1, 0, -1,
153 : 3, 0, 4, -1,
154 : -4, -1, -3, 1,
155 : 5, 3, 2, 3
156 1 : };
157 : double data_minusb[] = {
158 : -1, 1, -1, 1
159 1 : };
160 1 : double gamma = 0.1;
161 : // starting points
162 1 : double data_x1[] = {0, 0, 0, 0, 0};
163 : // reference results
164 1 : double ref_xstar[] = {0.0, 0.0, 0.215341883018748, 0.0, 0.675253988559914};
165 :
166 1 : Matrix * A = new Matrix(m, n, data_A);
167 1 : Matrix * minusb = new Matrix(m, 1, data_minusb);
168 : Matrix * x0;
169 1 : Matrix xstar;
170 1 : Function * f = new LogLogisticLoss();
171 1 : LinearOperator * OpA = new MatrixOperator(*A);
172 1 : Function * g = new Norm1(1.0);
173 2 : FBProblem prob(*f, *OpA, *minusb, *g);
174 2 : FBStoppingRelative sc(TOLERANCE);
175 : FBSplitting * solver;
176 :
177 : // test FB operations starting from x1
178 1 : size_t repeat = 100;
179 101 : for (size_t r = 0; r < repeat; r++) {
180 100 : x0 = new Matrix(n, 1, data_x1);
181 100 : solver = new FBSplitting(prob, *x0, gamma, sc, MAXIT);
182 100 : solver->run();
183 100 : xstar = solver->getSolution();
184 : // cout << "*** iters (slow) : " << solver->getIt() << endl;
185 100 : _ASSERT(solver->getIt() < MAXIT);
186 600 : for (int i=0; i < n; i++) {
187 500 : CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_xstar[i], xstar.get(i, 0), DOUBLES_EQUAL_DELTA);
188 : }
189 100 : delete x0;
190 100 : delete solver;
191 : }
192 :
193 1 : delete A;
194 1 : delete minusb;
195 1 : delete OpA;
196 1 : delete f;
197 2 : delete g;
198 4 : }
199 :
|