1 // Copyright (C) 2010  Davis E. King (davis@dlib.net)
2 // License: Boost Software License   See LICENSE.txt for the full license.
3 
4 
5 #include <dlib/optimization.h>
6 #include "optimization_test_functions.h"
7 #include <sstream>
8 #include <string>
9 #include <cstdlib>
10 #include <ctime>
11 #include <vector>
12 #include "../rand.h"
13 
14 #include "tester.h"
15 
16 
17 namespace
18 {
19 
20     using namespace test;
21     using namespace dlib;
22     using namespace std;
23     using namespace dlib::test_functions;
24 
25     logger dlog("test.trust_region");
26 
27 // ----------------------------------------------------------------------------------------
28 
29     template <typename T>
30     struct neg_rosen_model
31     {
32         typedef matrix<T,0,1> column_vector;
33         typedef matrix<T,0,0> general_matrix;
34 
operator ()__anon1c2e56f50111::neg_rosen_model35         T operator() ( column_vector x) const
36         {
37             return -static_cast<T>(rosen<T>(x));
38         }
39 
get_derivative_and_hessian__anon1c2e56f50111::neg_rosen_model40         void get_derivative_and_hessian (
41             const column_vector& x,
42             column_vector& d,
43             general_matrix& h
44         ) const
45         {
46             d = -matrix_cast<T>(rosen_derivative<T>(x));
47             h = -matrix_cast<T>(rosen_hessian<T>(x));
48         }
49 
50     };
51 
52 // ----------------------------------------------------------------------------------------
53 
54     dlib::rand rnd;
55 
56     template <typename T>
test_with_rosen()57     void test_with_rosen()
58     {
59         print_spinner();
60 
61         matrix<T,2,1> ans;
62         ans = 1,1;
63 
64         matrix<T,2,1> p = 100*matrix_cast<T>(randm(2,1,rnd)) - 50;
65 
66         T obj = find_min_trust_region(objective_delta_stop_strategy(1e-12, 100), rosen_function_model<T>(), p);
67 
68         DLIB_TEST_MSG(std::abs(obj) < 1e-10, "obj: " << obj);
69         DLIB_TEST_MSG(length(p-ans) < 1e-5, "length(p): " << length(p-ans));
70 
71         matrix<T,0,1> p2 = 100*matrix_cast<T>(randm(2,1,rnd)) - 50;
72         obj = find_max_trust_region(objective_delta_stop_strategy(1e-12, 100), neg_rosen_model<T>(), p2);
73 
74         DLIB_TEST_MSG(std::abs(obj) < 1e-10, "obj: " << obj);
75         DLIB_TEST_MSG(length(p-ans) < 1e-5, "length(p): " << length(p-ans));
76     }
77 
78 // ----------------------------------------------------------------------------------------
79 
test_trust_region_sub_problem()80     void test_trust_region_sub_problem()
81     {
82         dlog << LINFO << "subproblem test 1";
83         {
84             matrix<double,2,2> B;
85             B = 1, 0,
86                 0, 1;
87 
88             matrix<double,2,1> g, p, ans;
89             g = 0;
90 
91             ans = 0;
92 
93             solve_trust_region_subproblem(B,g,1,p, 0.001, 10);
94 
95             DLIB_TEST(length(p-ans) < 1e-10);
96             solve_trust_region_subproblem(B,g,1,p, 0.001, 1);
97             DLIB_TEST(length(p-ans) < 1e-10);
98         }
99 
100         dlog << LINFO << "subproblem test 2";
101         {
102             matrix<double,2,2> B;
103             B = 1, 0,
104                 0, 1;
105 
106             B *= 0.1;
107 
108             matrix<double,2,1> g, p, ans;
109             g = 1;
110 
111             ans = -g / length(g);
112 
113             solve_trust_region_subproblem(B,g,1,p, 1e-6, 20);
114 
115             DLIB_TEST(length(p-ans) < 1e-4);
116         }
117 
118         dlog << LINFO << "subproblem test 3";
119         {
120             matrix<double,2,2> B;
121             B = 0, 0,
122                 0, 0;
123 
124             matrix<double,2,1> g, p, ans;
125             g = 1;
126 
127             ans = -g / length(g);
128 
129             solve_trust_region_subproblem(B,g,1,p, 1e-6, 20);
130 
131             dlog << LINFO << "ans: " << trans(ans);
132             dlog << LINFO << "p: " << trans(p);
133             DLIB_TEST(length(p-ans) < 1e-4);
134         }
135         return;
136 
137         dlog << LINFO << "subproblem test 4";
138         {
139             matrix<double,2,2> B;
140             B = 2, 0,
141                 0, -1;
142 
143 
144             matrix<double,2,1> g, p, ans;
145             g = 0;
146 
147             ans = 0, -1;
148 
149             solve_trust_region_subproblem(B,g,1,p, 1e-6, 20);
150 
151             DLIB_TEST(length(p-ans) < 1e-4);
152         }
153 
154 
155         dlog << LINFO << "subproblem test 5";
156         {
157             matrix<double,2,2> B;
158             B = 2, 0,
159                 0, -1;
160 
161 
162             matrix<double,2,1> g, p, ans;
163             g = 0, 1;
164 
165             ans = 0, -1;
166 
167             solve_trust_region_subproblem(B,g,1,p, 1e-6, 20);
168 
169             DLIB_TEST(length(p-ans) < 1e-4);
170         }
171 
172         dlog << LINFO << "subproblem test 6";
173         for (int i = 0; i < 10; ++i)
174         {
175             matrix<double,10,10> B;
176 
177             B = randm(10,10, rnd);
178 
179             B = 0.01*B*trans(B);
180 
181 
182             matrix<double,10,1> g, p, ans;
183             g = 1;
184 
185             solve_trust_region_subproblem(B,g,1,p, 1e-6, 20);
186 
187             DLIB_TEST(std::abs(length(p) - 1) < 1e-4);
188         }
189     }
190 
191 // ----------------------------------------------------------------------------------------
192 
test_problems()193     void test_problems()
194     {
195         print_spinner();
196         {
197             matrix<double,4,1> ch;
198 
199             ch = brown_start();
200 
201             find_min_trust_region(objective_delta_stop_strategy(1e-7, 80),
202                                   brown_function_model(),
203                                   ch);
204 
205             dlog << LINFO << "brown obj: " << brown(ch);
206             dlog << LINFO << "brown der: " << length(brown_derivative(ch));
207             dlog << LINFO << "brown error: " << length(ch - brown_solution());
208 
209             DLIB_TEST(length(ch - brown_solution()) < 1e-5);
210 
211         }
212         print_spinner();
213         {
214             matrix<double,2,1> ch;
215 
216             ch = rosen_start<double>();
217 
218             find_min_trust_region(objective_delta_stop_strategy(1e-7, 80),
219                                   rosen_function_model<double>(),
220                                   ch);
221 
222             dlog << LINFO << "rosen obj: " << rosen(ch);
223             dlog << LINFO << "rosen der: " << length(rosen_derivative(ch));
224             dlog << LINFO << "rosen error: " << length(ch - rosen_solution<double>());
225 
226             DLIB_TEST(length(ch - rosen_solution<double>()) < 1e-5);
227         }
228 
229         print_spinner();
230         {
231             matrix<double,0,1> ch;
232 
233             ch = chebyquad_start(2);
234 
235             find_min_trust_region(objective_delta_stop_strategy(1e-7, 80),
236                                   chebyquad_function_model(),
237                                   ch);
238 
239             dlog << LINFO << "chebyquad 2 obj: " << chebyquad(ch);
240             dlog << LINFO << "chebyquad 2 der: " << length(chebyquad_derivative(ch));
241             dlog << LINFO << "chebyquad 2 error: " << length(ch - chebyquad_solution(2));
242 
243             DLIB_TEST(length(ch - chebyquad_solution(2)) < 1e-5);
244 
245         }
246         print_spinner();
247         {
248             matrix<double,0,1> ch;
249 
250             ch = chebyquad_start(4);
251 
252             find_min_trust_region(objective_delta_stop_strategy(1e-7, 80),
253                                   chebyquad_function_model(),
254                                   ch);
255 
256             dlog << LINFO << "chebyquad 4 obj: " << chebyquad(ch);
257             dlog << LINFO << "chebyquad 4 der: " << length(chebyquad_derivative(ch));
258             dlog << LINFO << "chebyquad 4 error: " << length(ch - chebyquad_solution(4));
259 
260             DLIB_TEST(length(ch - chebyquad_solution(4)) < 1e-5);
261         }
262         print_spinner();
263         {
264             matrix<double,0,1> ch;
265 
266             ch = chebyquad_start(6);
267 
268             find_min_trust_region(objective_delta_stop_strategy(1e-12, 80),
269                                   chebyquad_function_model(),
270                                   ch);
271 
272             dlog << LINFO << "chebyquad 6 obj: " << chebyquad(ch);
273             dlog << LINFO << "chebyquad 6 der: " << length(chebyquad_derivative(ch));
274             dlog << LINFO << "chebyquad 6 error: " << length(ch - chebyquad_solution(6));
275 
276             DLIB_TEST(length(ch - chebyquad_solution(6)) < 1e-5);
277 
278         }
279         print_spinner();
280         {
281             matrix<double,0,1> ch;
282 
283             ch = chebyquad_start(8);
284 
285             find_min_trust_region(objective_delta_stop_strategy(1e-10, 80),
286                                   chebyquad_function_model(),
287                                   ch);
288 
289             dlog << LINFO << "chebyquad 8 obj: " << chebyquad(ch);
290             dlog << LINFO << "chebyquad 8 der: " << length(chebyquad_derivative(ch));
291             dlog << LINFO << "chebyquad 8 error: " << length(ch - chebyquad_solution(8));
292 
293             DLIB_TEST(length(ch - chebyquad_solution(8)) < 1e-5);
294         }
295 
296     }
297 
298 
299 
300     class optimization_tester : public tester
301     {
302     public:
optimization_tester()303         optimization_tester (
304         ) :
305             tester ("test_trust_region",
306                     "Runs tests on the trust region optimization component.")
307         {}
308 
perform_test()309         void perform_test (
310         )
311         {
312             dlog << LINFO << "test with rosen<float>";
313             for (int i = 0; i < 50; ++i)
314                 test_with_rosen<float>();
315 
316             dlog << LINFO << "test with rosen<double>";
317             for (int i = 0; i < 50; ++i)
318                 test_with_rosen<double>();
319 
320 
321             test_trust_region_sub_problem();
322 
323             test_problems();
324         }
325     } a;
326 
327 }
328 
329 
330