1 #include <gtest/gtest.h>
2 #include <stan/optimization/bfgs.hpp>
3 #include <test/test-models/good/optimization/rosenbrock.hpp>
4 #include <sstream>
5
6 typedef rosenbrock_model_namespace::rosenbrock_model Model;
7 typedef stan::optimization::BFGSMinimizer<
8 stan::optimization::ModelAdaptor<Model>,
9 stan::optimization::BFGSUpdate_HInv<> >
10 Optimizer;
11
12 class OptimizationBfgsMinimizer : public testing::Test {
13 public:
14 Eigen::Matrix<double, Eigen::Dynamic, 1> cont_vector;
15 std::vector<int> disc_vector;
16
SetUp()17 void SetUp() {
18 cont_vector.resize(2);
19 cont_vector[0] = -1;
20 cont_vector[1] = 1;
21 }
22 };
23
TEST_F(OptimizationBfgsMinimizer,constructor)24 TEST_F(OptimizationBfgsMinimizer, constructor) {
25 static const std::string DATA("");
26 std::stringstream data_stream(DATA);
27 stan::io::dump dummy_context(data_stream);
28 Model rb_model(dummy_context);
29 std::stringstream out;
30 stan::optimization::ModelAdaptor<Model> _adaptor(rb_model, disc_vector, &out);
31 EXPECT_EQ("", out.str());
32 Optimizer bfgs(_adaptor);
33 }
34
TEST_F(OptimizationBfgsMinimizer,ls_opts)35 TEST_F(OptimizationBfgsMinimizer, ls_opts) {
36 static const std::string DATA("");
37 std::stringstream data_stream(DATA);
38 stan::io::dump dummy_context(data_stream);
39 Model rb_model(dummy_context);
40 std::stringstream out;
41 stan::optimization::ModelAdaptor<Model> _adaptor(rb_model, disc_vector, &out);
42 EXPECT_EQ("", out.str());
43 Optimizer bfgs(_adaptor);
44
45 EXPECT_FLOAT_EQ(bfgs._ls_opts.c1, 1e-4);
46 EXPECT_FLOAT_EQ(bfgs._ls_opts.c2, 0.9);
47 EXPECT_FLOAT_EQ(bfgs._ls_opts.minAlpha, 1e-12);
48 EXPECT_FLOAT_EQ(bfgs._ls_opts.alpha0, 1e-3);
49 }
50
TEST_F(OptimizationBfgsMinimizer,conv_opts)51 TEST_F(OptimizationBfgsMinimizer, conv_opts) {
52 static const std::string DATA("");
53 std::stringstream data_stream(DATA);
54 stan::io::dump dummy_context(data_stream);
55 Model rb_model(dummy_context);
56 std::stringstream out;
57 stan::optimization::ModelAdaptor<Model> _adaptor(rb_model, disc_vector, &out);
58 EXPECT_EQ("", out.str());
59 Optimizer bfgs(_adaptor);
60
61 EXPECT_FLOAT_EQ(bfgs._conv_opts.maxIts, 10000);
62 EXPECT_FLOAT_EQ(bfgs._conv_opts.fScale, 1);
63 EXPECT_FLOAT_EQ(bfgs._conv_opts.tolAbsX, 1e-8);
64 EXPECT_FLOAT_EQ(bfgs._conv_opts.tolAbsF, 1e-12);
65 EXPECT_FLOAT_EQ(bfgs._conv_opts.tolAbsGrad, 1e-8);
66 EXPECT_FLOAT_EQ(bfgs._conv_opts.tolRelF, 1e+4);
67 EXPECT_FLOAT_EQ(bfgs._conv_opts.tolRelGrad, 1e+3);
68 }
69
TEST_F(OptimizationBfgsMinimizer,get_qnupdate)70 TEST_F(OptimizationBfgsMinimizer, get_qnupdate) {
71 static const std::string DATA("");
72 std::stringstream data_stream(DATA);
73 stan::io::dump dummy_context(data_stream);
74 Model rb_model(dummy_context);
75 std::stringstream out;
76 stan::optimization::ModelAdaptor<Model> _adaptor(rb_model, disc_vector, &out);
77 EXPECT_EQ("", out.str());
78 Optimizer bfgs(_adaptor);
79 bfgs.initialize(cont_vector);
80
81 bfgs.get_qnupdate();
82 }
83
TEST_F(OptimizationBfgsMinimizer,curr_f)84 TEST_F(OptimizationBfgsMinimizer, curr_f) {
85 static const std::string DATA("");
86 std::stringstream data_stream(DATA);
87 stan::io::dump dummy_context(data_stream);
88 Model rb_model(dummy_context);
89 std::stringstream out;
90 stan::optimization::ModelAdaptor<Model> _adaptor(rb_model, disc_vector, &out);
91 EXPECT_EQ("", out.str());
92 Optimizer bfgs(_adaptor);
93 bfgs.initialize(cont_vector);
94
95 EXPECT_FLOAT_EQ(bfgs.curr_f(), 4);
96 }
97
TEST_F(OptimizationBfgsMinimizer,curr_x)98 TEST_F(OptimizationBfgsMinimizer, curr_x) {
99 static const std::string DATA("");
100 std::stringstream data_stream(DATA);
101 stan::io::dump dummy_context(data_stream);
102 Model rb_model(dummy_context);
103 std::stringstream out;
104 stan::optimization::ModelAdaptor<Model> _adaptor(rb_model, disc_vector, &out);
105 EXPECT_EQ("", out.str());
106 Optimizer bfgs(_adaptor);
107 bfgs.initialize(cont_vector);
108
109 EXPECT_FLOAT_EQ(bfgs.curr_x()[0], -1);
110 EXPECT_FLOAT_EQ(bfgs.curr_x()[1], 1);
111 }
112
TEST_F(OptimizationBfgsMinimizer,curr_g)113 TEST_F(OptimizationBfgsMinimizer, curr_g) {
114 static const std::string DATA("");
115 std::stringstream data_stream(DATA);
116 stan::io::dump dummy_context(data_stream);
117 Model rb_model(dummy_context);
118 std::stringstream out;
119 stan::optimization::ModelAdaptor<Model> _adaptor(rb_model, disc_vector, &out);
120 EXPECT_EQ("", out.str());
121 Optimizer bfgs(_adaptor);
122 bfgs.initialize(cont_vector);
123
124 EXPECT_FLOAT_EQ(bfgs.curr_g()[0], -4);
125 EXPECT_FLOAT_EQ(bfgs.curr_g()[1], 0);
126 }
127
TEST_F(OptimizationBfgsMinimizer,curr_p)128 TEST_F(OptimizationBfgsMinimizer, curr_p) {
129 static const std::string DATA("");
130 std::stringstream data_stream(DATA);
131 stan::io::dump dummy_context(data_stream);
132 Model rb_model(dummy_context);
133 std::stringstream out;
134 stan::optimization::ModelAdaptor<Model> _adaptor(rb_model, disc_vector, &out);
135 EXPECT_EQ("", out.str());
136 Optimizer bfgs(_adaptor);
137 bfgs.initialize(cont_vector);
138
139 EXPECT_FLOAT_EQ(bfgs.curr_p()[0], 4);
140 EXPECT_FLOAT_EQ(bfgs.curr_p()[1], 0);
141 }
142
TEST_F(OptimizationBfgsMinimizer,prev_f)143 TEST_F(OptimizationBfgsMinimizer, prev_f) {
144 static const std::string DATA("");
145 std::stringstream data_stream(DATA);
146 stan::io::dump dummy_context(data_stream);
147 Model rb_model(dummy_context);
148 std::stringstream out;
149 stan::optimization::ModelAdaptor<Model> _adaptor(rb_model, disc_vector, &out);
150 EXPECT_EQ("", out.str());
151 Optimizer bfgs(_adaptor);
152 bfgs.initialize(cont_vector);
153
154 bfgs.step();
155 EXPECT_FLOAT_EQ(bfgs.prev_f(), 4);
156 }
157
TEST_F(OptimizationBfgsMinimizer,prev_x)158 TEST_F(OptimizationBfgsMinimizer, prev_x) {
159 static const std::string DATA("");
160 std::stringstream data_stream(DATA);
161 stan::io::dump dummy_context(data_stream);
162 Model rb_model(dummy_context);
163 std::stringstream out;
164 stan::optimization::ModelAdaptor<Model> _adaptor(rb_model, disc_vector, &out);
165 EXPECT_EQ("", out.str());
166 Optimizer bfgs(_adaptor);
167 bfgs.initialize(cont_vector);
168
169 bfgs.step();
170 EXPECT_FLOAT_EQ(bfgs.prev_x()[0], -1);
171 EXPECT_FLOAT_EQ(bfgs.prev_x()[1], 1);
172 }
173
TEST_F(OptimizationBfgsMinimizer,prev_g)174 TEST_F(OptimizationBfgsMinimizer, prev_g) {
175 static const std::string DATA("");
176 std::stringstream data_stream(DATA);
177 stan::io::dump dummy_context(data_stream);
178 Model rb_model(dummy_context);
179 std::stringstream out;
180 stan::optimization::ModelAdaptor<Model> _adaptor(rb_model, disc_vector, &out);
181 EXPECT_EQ("", out.str());
182 Optimizer bfgs(_adaptor);
183 bfgs.initialize(cont_vector);
184
185 bfgs.step();
186 EXPECT_FLOAT_EQ(bfgs.prev_g()[0], -4);
187 EXPECT_FLOAT_EQ(bfgs.prev_g()[1], 0);
188 }
189
TEST_F(OptimizationBfgsMinimizer,prev_p)190 TEST_F(OptimizationBfgsMinimizer, prev_p) {
191 static const std::string DATA("");
192 std::stringstream data_stream(DATA);
193 stan::io::dump dummy_context(data_stream);
194 Model rb_model(dummy_context);
195 std::stringstream out;
196 stan::optimization::ModelAdaptor<Model> _adaptor(rb_model, disc_vector, &out);
197 EXPECT_EQ("", out.str());
198 Optimizer bfgs(_adaptor);
199 bfgs.initialize(cont_vector);
200
201 bfgs.step();
202 EXPECT_FLOAT_EQ(bfgs.prev_p()[0], 0.0040116129);
203 EXPECT_FLOAT_EQ(bfgs.prev_p()[1], 0);
204 }
205
TEST_F(OptimizationBfgsMinimizer,prev_step_size)206 TEST_F(OptimizationBfgsMinimizer, prev_step_size) {
207 static const std::string DATA("");
208 std::stringstream data_stream(DATA);
209 stan::io::dump dummy_context(data_stream);
210 Model rb_model(dummy_context);
211 std::stringstream out;
212 stan::optimization::ModelAdaptor<Model> _adaptor(rb_model, disc_vector, &out);
213 EXPECT_EQ("", out.str());
214 Optimizer bfgs(_adaptor);
215 bfgs.initialize(cont_vector);
216
217 bfgs.step();
218 EXPECT_FLOAT_EQ(bfgs.prev_step_size(), 0.0040000002);
219 }
220
TEST_F(OptimizationBfgsMinimizer,rel_grad_norm)221 TEST_F(OptimizationBfgsMinimizer, rel_grad_norm) {
222 static const std::string DATA("");
223 std::stringstream data_stream(DATA);
224 stan::io::dump dummy_context(data_stream);
225 Model rb_model(dummy_context);
226 std::stringstream out;
227 stan::optimization::ModelAdaptor<Model> _adaptor(rb_model, disc_vector, &out);
228 EXPECT_EQ("", out.str());
229 Optimizer bfgs(_adaptor);
230 bfgs.initialize(cont_vector);
231
232 bfgs.step();
233 EXPECT_FLOAT_EQ(bfgs.rel_grad_norm(), 0.0012151747);
234 }
235
TEST_F(OptimizationBfgsMinimizer,rel_obj_decrease)236 TEST_F(OptimizationBfgsMinimizer, rel_obj_decrease) {
237 static const std::string DATA("");
238 std::stringstream data_stream(DATA);
239 stan::io::dump dummy_context(data_stream);
240 Model rb_model(dummy_context);
241 std::stringstream out;
242 stan::optimization::ModelAdaptor<Model> _adaptor(rb_model, disc_vector, &out);
243 EXPECT_EQ("", out.str());
244 Optimizer bfgs(_adaptor);
245 bfgs.initialize(cont_vector);
246
247 bfgs.step();
248 EXPECT_FLOAT_EQ(bfgs.rel_obj_decrease(), 0.0024023936);
249 }
250
TEST_F(OptimizationBfgsMinimizer,alpha0)251 TEST_F(OptimizationBfgsMinimizer, alpha0) {
252 static const std::string DATA("");
253 std::stringstream data_stream(DATA);
254 stan::io::dump dummy_context(data_stream);
255 Model rb_model(dummy_context);
256 std::stringstream out;
257 stan::optimization::ModelAdaptor<Model> _adaptor(rb_model, disc_vector, &out);
258 EXPECT_EQ("", out.str());
259 Optimizer bfgs(_adaptor);
260 bfgs.initialize(cont_vector);
261
262 bfgs.step();
263 EXPECT_FLOAT_EQ(bfgs.alpha0(), 0.001);
264 }
265
TEST_F(OptimizationBfgsMinimizer,alpha)266 TEST_F(OptimizationBfgsMinimizer, alpha) {
267 static const std::string DATA("");
268 std::stringstream data_stream(DATA);
269 stan::io::dump dummy_context(data_stream);
270 Model rb_model(dummy_context);
271 std::stringstream out;
272 stan::optimization::ModelAdaptor<Model> _adaptor(rb_model, disc_vector, &out);
273 EXPECT_EQ("", out.str());
274 Optimizer bfgs(_adaptor);
275 bfgs.initialize(cont_vector);
276
277 bfgs.step();
278 EXPECT_FLOAT_EQ(bfgs.alpha(), 0.001);
279 }
280
TEST_F(OptimizationBfgsMinimizer,iter_num)281 TEST_F(OptimizationBfgsMinimizer, iter_num) {
282 static const std::string DATA("");
283 std::stringstream data_stream(DATA);
284 stan::io::dump dummy_context(data_stream);
285 Model rb_model(dummy_context);
286 std::stringstream out;
287 stan::optimization::ModelAdaptor<Model> _adaptor(rb_model, disc_vector, &out);
288 EXPECT_EQ("", out.str());
289 Optimizer bfgs(_adaptor);
290 bfgs.initialize(cont_vector);
291
292 EXPECT_FLOAT_EQ(bfgs.iter_num(), 0);
293 bfgs.step();
294 EXPECT_FLOAT_EQ(bfgs.iter_num(), 1);
295 }
296
TEST_F(OptimizationBfgsMinimizer,note)297 TEST_F(OptimizationBfgsMinimizer, note) {
298 static const std::string DATA("");
299 std::stringstream data_stream(DATA);
300 stan::io::dump dummy_context(data_stream);
301 Model rb_model(dummy_context);
302 std::stringstream out;
303 stan::optimization::ModelAdaptor<Model> _adaptor(rb_model, disc_vector, &out);
304 EXPECT_EQ("", out.str());
305 Optimizer bfgs(_adaptor);
306 bfgs.initialize(cont_vector);
307
308 bfgs.step();
309 EXPECT_TRUE(bfgs.note() == "");
310 }
311
TEST_F(OptimizationBfgsMinimizer,get_code_string)312 TEST_F(OptimizationBfgsMinimizer, get_code_string) {
313 static const std::string DATA("");
314 std::stringstream data_stream(DATA);
315 stan::io::dump dummy_context(data_stream);
316 Model rb_model(dummy_context);
317 std::stringstream out;
318 stan::optimization::ModelAdaptor<Model> _adaptor(rb_model, disc_vector, &out);
319 EXPECT_EQ("", out.str());
320 Optimizer bfgs(_adaptor);
321 bfgs.initialize(cont_vector);
322
323 EXPECT_TRUE(bfgs.get_code_string(0) == "Successful step completed");
324 EXPECT_TRUE(
325 bfgs.get_code_string(10)
326 == "Convergence detected: absolute parameter change was below tolerance");
327 EXPECT_TRUE(bfgs.get_code_string(20) == "Convergence detected: absolute change in objective function was below tolerance");
328 EXPECT_TRUE(bfgs.get_code_string(21) == "Convergence detected: relative change in objective function was below tolerance");
329 EXPECT_TRUE(bfgs.get_code_string(30)
330 == "Convergence detected: gradient norm is below tolerance");
331 EXPECT_TRUE(
332 bfgs.get_code_string(31)
333 == "Convergence detected: relative gradient magnitude is below "
334 "tolerance");
335 EXPECT_TRUE(bfgs.get_code_string(40)
336 == "Maximum number of iterations hit, may not be at an optima");
337 EXPECT_TRUE(bfgs.get_code_string(-1) == "Line search failed to achieve a sufficient decrease, no more progress can be made");
338 EXPECT_TRUE(bfgs.get_code_string(42) == "Unknown termination code");
339 EXPECT_TRUE(bfgs.get_code_string(32) == "Unknown termination code");
340 EXPECT_TRUE(bfgs.get_code_string(23) == "Unknown termination code");
341 EXPECT_TRUE(bfgs.get_code_string(94) == "Unknown termination code");
342 }
343
TEST_F(OptimizationBfgsMinimizer,initialize)344 TEST_F(OptimizationBfgsMinimizer, initialize) {
345 static const std::string DATA("");
346 std::stringstream data_stream(DATA);
347 stan::io::dump dummy_context(data_stream);
348 Model rb_model(dummy_context);
349 std::stringstream out;
350 stan::optimization::ModelAdaptor<Model> _adaptor(rb_model, disc_vector, &out);
351 EXPECT_EQ("", out.str());
352 Optimizer bfgs(_adaptor);
353
354 EXPECT_FLOAT_EQ(bfgs.curr_x().size(), 0);
355 EXPECT_FLOAT_EQ(bfgs.curr_p().size(), 0);
356 EXPECT_FLOAT_EQ(bfgs.curr_g().size(), 0);
357
358 bfgs.initialize(cont_vector);
359 EXPECT_FLOAT_EQ(bfgs.curr_x().size(), 2);
360 EXPECT_FLOAT_EQ(bfgs.curr_x()[0], -1);
361 EXPECT_FLOAT_EQ(bfgs.curr_x()[1], 1);
362 EXPECT_FLOAT_EQ(bfgs.curr_p().size(), 2);
363 EXPECT_FLOAT_EQ(bfgs.curr_p()[0], 4);
364 EXPECT_FLOAT_EQ(bfgs.curr_p()[1], 0);
365 EXPECT_FLOAT_EQ(bfgs.curr_g().size(), 2);
366 EXPECT_FLOAT_EQ(bfgs.curr_g()[0], -4);
367 EXPECT_FLOAT_EQ(bfgs.curr_g()[1], 0);
368 EXPECT_FLOAT_EQ(bfgs.iter_num(), 0);
369 EXPECT_TRUE(bfgs.note() == "");
370 }
371
TEST_F(OptimizationBfgsMinimizer,step)372 TEST_F(OptimizationBfgsMinimizer, step) {
373 static const std::string DATA("");
374 std::stringstream data_stream(DATA);
375 stan::io::dump dummy_context(data_stream);
376 Model rb_model(dummy_context);
377 std::stringstream out;
378 stan::optimization::ModelAdaptor<Model> _adaptor(rb_model, disc_vector, &out);
379 EXPECT_EQ("", out.str());
380 Optimizer bfgs(_adaptor);
381 bfgs.initialize(cont_vector);
382 bfgs.step();
383 }
384
TEST_F(OptimizationBfgsMinimizer,minimize)385 TEST_F(OptimizationBfgsMinimizer, minimize) {
386 static const std::string DATA("");
387 std::stringstream data_stream(DATA);
388 stan::io::dump dummy_context(data_stream);
389 Model rb_model(dummy_context);
390 std::stringstream out;
391 stan::optimization::ModelAdaptor<Model> _adaptor(rb_model, disc_vector, &out);
392 EXPECT_EQ("", out.str());
393 Optimizer bfgs(_adaptor);
394
395 EXPECT_FLOAT_EQ(bfgs.minimize(cont_vector), 31);
396 }
397