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