1 #include <gtest/gtest.h>
2 #include <stan/optimization/bfgs_update.hpp>
3
TEST(OptimizationBfgsUpdate,bfgs_update_secant)4 TEST(OptimizationBfgsUpdate, bfgs_update_secant) {
5 const int nDim = 10;
6
7 typedef stan::optimization::BFGSUpdate_HInv<double, nDim> QNUpdateT;
8 typedef QNUpdateT::VectorT VectorT;
9
10 QNUpdateT bfgsUp;
11 VectorT yk(nDim), sk(nDim), sdir(nDim);
12
13 // Construct a set of BFGS update vectors and check that
14 // the secant equation H*yk = sk is always satisfied.
15 for (int i = 0; i < nDim; i++) {
16 sk.setZero(nDim);
17 yk.setZero(nDim);
18 sk[i] = 1;
19 yk[i] = 1;
20
21 bfgsUp.update(yk, sk, i == 0);
22
23 // Because the constructed update vectors are all orthogonal the secant
24 // equation should be exactly satisfied for all nDim updates.
25 for (int j = 0; j <= i; j++) {
26 sk.setZero(nDim);
27 yk.setZero(nDim);
28 sk[i - j] = 1;
29 yk[i - j] = 1;
30
31 bfgsUp.search_direction(sdir, yk);
32
33 EXPECT_NEAR((sdir + sk).norm(), 0.0, 1e-10);
34 }
35 }
36 }
37
TEST(OptimizationBfgsUpdate,BFGSUpdate_HInv_update)38 TEST(OptimizationBfgsUpdate, BFGSUpdate_HInv_update) {
39 const int nDim = 10;
40
41 typedef stan::optimization::BFGSUpdate_HInv<double, nDim> QNUpdateT;
42 typedef QNUpdateT::VectorT VectorT;
43
44 QNUpdateT bfgsUp;
45 VectorT yk(nDim), sk(nDim), sdir(nDim);
46
47 for (int i = 0; i < nDim; i++) {
48 sk.setZero(nDim);
49 yk.setZero(nDim);
50 sk[i] = 1;
51 yk[i] = 1;
52
53 bfgsUp.update(yk, sk, i == 0);
54 }
55 }
56
TEST(OptimizationBfgsUpdate,BFGSUpdate_HInv_search_direction)57 TEST(OptimizationBfgsUpdate, BFGSUpdate_HInv_search_direction) {
58 const int nDim = 10;
59 typedef stan::optimization::BFGSUpdate_HInv<double, nDim> QNUpdateT;
60 typedef QNUpdateT::VectorT VectorT;
61
62 QNUpdateT bfgsUp;
63 VectorT yk(nDim), sk(nDim), sdir(nDim);
64 sk.setZero(nDim);
65 yk.setZero(nDim);
66 sk[0] = 1;
67 yk[0] = 1;
68 bfgsUp.update(yk, sk, true);
69
70 for (int i = 0; i < nDim; i++) {
71 for (int j = 0; j <= i; j++) {
72 yk.setZero(nDim);
73 yk[i - j] = 1;
74
75 bfgsUp.search_direction(sdir, yk);
76 }
77 }
78 }
79