1 // Copyright (C) 2008 Davis E. King (davis@dlib.net) 2 // License: Boost Software License See LICENSE.txt for the full license. 3 4 5 #include "optimization_test_functions.h" 6 #include <dlib/optimization.h> 7 #include <dlib/statistics.h> 8 #include <sstream> 9 #include <string> 10 #include <cstdlib> 11 #include <ctime> 12 #include <vector> 13 #include "../stl_checked.h" 14 #include "../array.h" 15 #include "../rand.h" 16 17 #include "tester.h" 18 19 20 namespace 21 { 22 23 using namespace test; 24 using namespace dlib; 25 using namespace std; 26 27 logger dlog("test.optimization"); 28 29 // ---------------------------------------------------------------------------------------- 30 approx_equal(double a,double b)31 bool approx_equal ( 32 double a, 33 double b 34 ) 35 { 36 return std::abs(a - b) < 100*std::numeric_limits<double>::epsilon(); 37 } 38 39 // ---------------------------------------------------------------------------------------- 40 41 long total_count = 0; 42 43 44 template <typename T> apq(const T & x)45 double apq ( const T& x) 46 { 47 DLIB_ASSERT(x.nr() > 1 && x.nc() == 1,""); 48 COMPILE_TIME_ASSERT(is_matrix<T>::value); 49 double temp = 0; 50 for (long r = 0; r < x.nr(); ++r) 51 { 52 temp += (r+1)*x(r)*x(r); 53 } 54 55 ++total_count; 56 57 return temp + 1/100.0*(x(0) + x(x.nr()-1))*(x(0) + x(x.nr()-1)); 58 } 59 60 template <typename T> der_apq(const T & x)61 T der_apq ( const T& x) 62 { 63 DLIB_ASSERT(x.nr() > 1 && x.nc() == 1,""); 64 COMPILE_TIME_ASSERT(is_matrix<T>::value); 65 T temp(x.nr()); 66 for (long r = 0; r < x.nr(); ++r) 67 { 68 temp(r) = 2*(r+1)*x(r) ; 69 } 70 71 temp(0) += 1/50.0*(x(0) + x(x.nr()-1)); 72 temp(x.nr()-1) += 1/50.0*(x(0) + x(x.nr()-1)); 73 74 ++total_count; 75 76 return temp; 77 } 78 79 // ---------------------------------------------------------------------------------------- 80 81 // Rosenbrock's function. minimum at (1,1) rosen(const matrix<double,2,1> & x)82 double rosen ( const matrix<double,2,1>& x) 83 { 84 ++total_count; 85 return 100*pow(x(1) - x(0)*x(0),2) + pow(1 - x(0),2); 86 } 87 der_rosen(const matrix<double,2,1> & x)88 matrix<double,2,1> der_rosen ( const matrix<double,2,1>& x) 89 { 90 ++total_count; 91 matrix<double,2,1> res; 92 res(0) = -400*x(0)*(x(1)-x(0)*x(0)) - 2*(1-x(0)); 93 res(1) = 200*(x(1)-x(0)*x(0)); 94 return res; 95 } 96 97 // ---------------------------------------------------------------------------------------- 98 99 // negative of Rosenbrock's function. minimum at (1,1) neg_rosen(const matrix<double,2,1> & x)100 double neg_rosen ( const matrix<double,2,1>& x) 101 { 102 ++total_count; 103 return -(100*pow(x(1) - x(0)*x(0),2) + pow(1 - x(0),2)); 104 } 105 der_neg_rosen(const matrix<double,2,1> & x)106 matrix<double,2,1> der_neg_rosen ( const matrix<double,2,1>& x) 107 { 108 ++total_count; 109 matrix<double,2,1> res; 110 res(0) = -400*x(0)*(x(1)-x(0)*x(0)) - 2*(1-x(0)); 111 res(1) = 200*(x(1)-x(0)*x(0)); 112 return -res; 113 } 114 115 // ---------------------------------------------------------------------------------------- 116 simple(const matrix<double,2,1> & x)117 double simple ( const matrix<double,2,1>& x) 118 { 119 ++total_count; 120 return 10*x(0)*x(0) + x(1)*x(1); 121 } 122 der_simple(const matrix<double,2,1> & x)123 matrix<double,2,1> der_simple ( const matrix<double,2,1>& x) 124 { 125 ++total_count; 126 matrix<double,2,1> res; 127 res(0) = 20*x(0); 128 res(1) = 2*x(1); 129 return res; 130 } 131 132 // ---------------------------------------------------------------------------------------- 133 powell(const matrix<double,4,1> & x)134 double powell ( const matrix<double,4,1>& x) 135 { 136 ++total_count; 137 return pow(x(0) + 10*x(1),2) + 138 pow(std::sqrt(5.0)*(x(2) - x(3)),2) + 139 pow((x(1) - 2*x(2))*(x(1) - 2*x(2)),2) + 140 pow(std::sqrt(10.0)*(x(0) - x(3))*(x(0) - x(3)),2); 141 } 142 143 // ---------------------------------------------------------------------------------------- 144 145 // a simple function with a minimum at zero single_variable_function(double x)146 double single_variable_function ( double x) 147 { 148 ++total_count; 149 return 3*x*x + 5; 150 } 151 152 // ---------------------------------------------------------------------------------------- 153 // ---------------------------------------------------------------------------------------- 154 // ---------------------------------------------------------------------------------------- 155 test_apq(const matrix<double,0,1> p)156 void test_apq ( 157 const matrix<double,0,1> p 158 ) 159 { 160 typedef matrix<double,0,1> T; 161 const double eps = 1e-12; 162 const double minf = -10; 163 matrix<double,0,1> x(p.nr()), opt(p.nr()); 164 set_all_elements(opt, 0); 165 double val = 0; 166 167 if (p.size() < 20) 168 dlog << LINFO << "testing with apq and the start point: " << trans(p); 169 else 170 dlog << LINFO << "testing with apq and a big vector with " << p.size() << " components."; 171 172 // don't use bfgs on really large vectors 173 if (p.size() < 20) 174 { 175 total_count = 0; 176 x = p; 177 val = find_min(bfgs_search_strategy(), 178 objective_delta_stop_strategy(eps), 179 wrap_function(apq<T>), wrap_function(der_apq<T>), x, minf); 180 DLIB_TEST_MSG(dlib::equal(x,opt, 1e-5),opt-x); 181 DLIB_TEST(approx_equal(val , apq(x))); 182 dlog << LINFO << "find_min() bgfs: got apq in " << total_count; 183 184 total_count = 0; 185 x = p; 186 find_min(bfgs_search_strategy(), 187 gradient_norm_stop_strategy(), 188 wrap_function(apq<T>), wrap_function(der_apq<T>), x, minf); 189 DLIB_TEST_MSG(dlib::equal(x,opt, 1e-5),opt-x); 190 dlog << LINFO << "find_min() bgfs(gn): got apq in " << total_count; 191 } 192 193 194 if (p.size() < 100) 195 { 196 total_count = 0; 197 x = p; 198 val=find_min_bobyqa(wrap_function(apq<T>), x, 2*x.size()+1, 199 uniform_matrix<double>(x.size(),1,-1e100), 200 uniform_matrix<double>(x.size(),1,1e100), 201 (max(abs(x))+1)/10, 202 1e-6, 203 10000); 204 DLIB_TEST_MSG(dlib::equal(x,opt, 1e-5),opt-x); 205 DLIB_TEST(approx_equal(val , apq(x))); 206 dlog << LINFO << "find_min_bobyqa(): got apq in " << total_count; 207 } 208 209 total_count = 0; 210 x = p; 211 val=find_min(lbfgs_search_strategy(10), 212 objective_delta_stop_strategy(eps), 213 wrap_function(apq<T>), wrap_function(der_apq<T>), x, minf); 214 DLIB_TEST_MSG(dlib::equal(x,opt, 1e-5),opt-x); 215 DLIB_TEST(approx_equal(val , apq(x))); 216 dlog << LINFO << "find_min() lbgfs-10: got apq in " << total_count; 217 218 219 total_count = 0; 220 x = p; 221 val=find_min(lbfgs_search_strategy(1), 222 objective_delta_stop_strategy(eps), 223 wrap_function(apq<T>), wrap_function(der_apq<T>), x, minf); 224 DLIB_TEST_MSG(dlib::equal(x,opt, 1e-5),opt-x); 225 DLIB_TEST(approx_equal(val , apq(x))); 226 dlog << LINFO << "find_min() lbgfs-1: got apq in " << total_count; 227 228 229 total_count = 0; 230 x = p; 231 val=find_min(cg_search_strategy(), 232 objective_delta_stop_strategy(eps), 233 wrap_function(apq<T>), wrap_function(der_apq<T>), x, minf); 234 DLIB_TEST_MSG(dlib::equal(x,opt, 1e-5),opt-x); 235 DLIB_TEST(approx_equal(val , apq(x))); 236 dlog << LINFO << "find_min() cg: got apq in " << total_count; 237 238 239 // don't do approximate derivative tests if the input point is really long 240 if (p.size() < 20) 241 { 242 total_count = 0; 243 x = p; 244 val=find_min(bfgs_search_strategy(), 245 objective_delta_stop_strategy(eps), 246 wrap_function(apq<T>), derivative(wrap_function(apq<T>)), x, minf); 247 DLIB_TEST_MSG(dlib::equal(x,opt, 1e-5),opt-x); 248 DLIB_TEST(approx_equal(val , apq(x))); 249 dlog << LINFO << "find_min() bfgs: got apq/noder in " << total_count; 250 251 252 total_count = 0; 253 x = p; 254 val=find_min(cg_search_strategy(), 255 objective_delta_stop_strategy(eps), 256 wrap_function(apq<T>), derivative(wrap_function(apq<T>)), x, minf); 257 DLIB_TEST_MSG(dlib::equal(x,opt, 1e-5),opt-x); 258 DLIB_TEST(approx_equal(val , apq(x))); 259 dlog << LINFO << "find_min() cg: got apq/noder in " << total_count; 260 261 262 total_count = 0; 263 x = p; 264 val=find_min_using_approximate_derivatives(bfgs_search_strategy(), 265 objective_delta_stop_strategy(eps), 266 wrap_function(apq<T>), x, minf); 267 DLIB_TEST_MSG(dlib::equal(x,opt, 1e-5),opt-x); 268 DLIB_TEST(approx_equal(val , apq(x))); 269 dlog << LINFO << "find_min() bfgs: got apq/noder2 in " << total_count; 270 271 272 total_count = 0; 273 x = p; 274 val=find_min_using_approximate_derivatives(lbfgs_search_strategy(10), 275 objective_delta_stop_strategy(eps), 276 wrap_function(apq<T>), x, minf); 277 DLIB_TEST_MSG(dlib::equal(x,opt, 1e-5),opt-x); 278 dlog << LINFO << "find_min() lbfgs-10: got apq/noder2 in " << total_count; 279 280 281 total_count = 0; 282 x = p; 283 val=find_min_using_approximate_derivatives(cg_search_strategy(), 284 objective_delta_stop_strategy(eps), 285 wrap_function(apq<T>), x, minf); 286 DLIB_TEST_MSG(dlib::equal(x,opt, 1e-5),opt-x); 287 DLIB_TEST(approx_equal(val , apq(x))); 288 dlog << LINFO << "find_min() cg: got apq/noder2 in " << total_count; 289 } 290 } 291 test_powell(const matrix<double,4,1> p)292 void test_powell ( 293 const matrix<double,4,1> p 294 ) 295 { 296 const double eps = 1e-15; 297 const double minf = -1; 298 matrix<double,4,1> x, opt; 299 opt(0) = 0; 300 opt(1) = 0; 301 opt(2) = 0; 302 opt(3) = 0; 303 304 double val = 0; 305 306 dlog << LINFO << "testing with powell and the start point: " << trans(p); 307 308 /* 309 total_count = 0; 310 x = p; 311 val=find_min(bfgs_search_strategy(), 312 objective_delta_stop_strategy(eps), 313 powell, derivative(powell,1e-8), x, minf); 314 DLIB_TEST_MSG(dlib::equal(x,opt, 1e-2),opt-x); 315 DLIB_TEST(approx_equal(val , powell(x))); 316 dlog << LINFO << "find_min() bfgs: got powell/noder in " << total_count; 317 318 319 total_count = 0; 320 x = p; 321 val=find_min(cg_search_strategy(), 322 objective_delta_stop_strategy(eps), 323 powell, derivative(powell,1e-9), x, minf); 324 DLIB_TEST_MSG(dlib::equal(x,opt, 1e-2),opt-x); 325 DLIB_TEST(approx_equal(val , powell(x))); 326 dlog << LINFO << "find_min() cg: got powell/noder in " << total_count; 327 */ 328 329 total_count = 0; 330 x = p; 331 val=find_min_using_approximate_derivatives(bfgs_search_strategy(), 332 objective_delta_stop_strategy(eps), 333 powell, x, minf, 1e-10); 334 DLIB_TEST_MSG(dlib::equal(x,opt, 1e-1),opt-x); 335 DLIB_TEST(approx_equal(val , powell(x))); 336 dlog << LINFO << "find_min() bfgs: got powell/noder2 in " << total_count; 337 338 339 total_count = 0; 340 x = p; 341 val=find_min_using_approximate_derivatives(lbfgs_search_strategy(4), 342 objective_delta_stop_strategy(eps), 343 powell, x, minf, 1e-10); 344 DLIB_TEST_MSG(dlib::equal(x,opt, 1e-1),opt-x); 345 DLIB_TEST(approx_equal(val , powell(x))); 346 dlog << LINFO << "find_min() lbfgs-4: got powell/noder2 in " << total_count; 347 348 349 total_count = 0; 350 x = p; 351 val=find_min_using_approximate_derivatives(lbfgs_search_strategy(4), 352 gradient_norm_stop_strategy(), 353 powell, x, minf, 1e-10); 354 DLIB_TEST_MSG(dlib::equal(x,opt, 1e-1),opt-x); 355 DLIB_TEST(approx_equal(val , powell(x))); 356 dlog << LINFO << "find_min() lbfgs-4(gn): got powell/noder2 in " << total_count; 357 358 359 total_count = 0; 360 x = p; 361 val=find_min_using_approximate_derivatives(cg_search_strategy(), 362 objective_delta_stop_strategy(eps), 363 powell, x, minf, 1e-10); 364 DLIB_TEST_MSG(dlib::equal(x,opt, 1e-1),opt-x); 365 DLIB_TEST(approx_equal(val , powell(x))); 366 dlog << LINFO << "find_min() cg: got powell/noder2 in " << total_count; 367 368 369 total_count = 0; 370 x = p; 371 val=find_min_bobyqa(powell, x, 2*x.size()+1, 372 uniform_matrix<double>(x.size(),1,-1e100), 373 uniform_matrix<double>(x.size(),1,1e100), 374 (max(abs(x))+1)/10, 375 1e-8, 376 10000); 377 DLIB_TEST_MSG(dlib::equal(x,opt, 1e-3),opt-x); 378 DLIB_TEST(approx_equal(val , powell(x))); 379 dlog << LINFO << "find_min_bobyqa(): got powell in " << total_count; 380 381 } 382 383 384 test_simple(const matrix<double,2,1> p)385 void test_simple ( 386 const matrix<double,2,1> p 387 ) 388 { 389 const double eps = 1e-12; 390 const double minf = -10000; 391 matrix<double,2,1> x, opt; 392 opt(0) = 0; 393 opt(1) = 0; 394 double val = 0; 395 396 dlog << LINFO << "testing with simple and the start point: " << trans(p); 397 398 total_count = 0; 399 x = p; 400 val=find_min(bfgs_search_strategy(), 401 objective_delta_stop_strategy(eps), 402 simple, der_simple, x, minf); 403 DLIB_TEST_MSG(dlib::equal(x,opt, 1e-5),opt-x); 404 DLIB_TEST(approx_equal(val , simple(x))); 405 dlog << LINFO << "find_min() bfgs: got simple in " << total_count; 406 407 408 total_count = 0; 409 x = p; 410 val=find_min(bfgs_search_strategy(), 411 gradient_norm_stop_strategy(), 412 simple, der_simple, x, minf); 413 DLIB_TEST_MSG(dlib::equal(x,opt, 1e-5),opt-x); 414 DLIB_TEST(approx_equal(val , simple(x))); 415 dlog << LINFO << "find_min() bfgs(gn): got simple in " << total_count; 416 417 418 total_count = 0; 419 x = p; 420 val=find_min(lbfgs_search_strategy(3), 421 objective_delta_stop_strategy(eps), 422 simple, der_simple, x, minf); 423 DLIB_TEST_MSG(dlib::equal(x,opt, 1e-5),opt-x); 424 DLIB_TEST(approx_equal(val , simple(x))); 425 dlog << LINFO << "find_min() lbfgs-3: got simple in " << total_count; 426 427 428 total_count = 0; 429 x = p; 430 val=find_min(cg_search_strategy(), 431 objective_delta_stop_strategy(eps), 432 simple, der_simple, x, minf); 433 DLIB_TEST_MSG(dlib::equal(x,opt, 1e-5),opt-x); 434 DLIB_TEST(approx_equal(val , simple(x))); 435 dlog << LINFO << "find_min() cg: got simple in " << total_count; 436 437 438 439 total_count = 0; 440 x = p; 441 val=find_min(bfgs_search_strategy(), 442 objective_delta_stop_strategy(eps), 443 simple, derivative(simple), x, minf); 444 DLIB_TEST_MSG(dlib::equal(x,opt, 1e-5),opt-x); 445 DLIB_TEST(approx_equal(val , simple(x))); 446 dlog << LINFO << "find_min() bfgs: got simple/noder in " << total_count; 447 448 449 total_count = 0; 450 x = p; 451 val=find_min(lbfgs_search_strategy(8), 452 objective_delta_stop_strategy(eps), 453 simple, derivative(simple), x, minf); 454 DLIB_TEST_MSG(dlib::equal(x,opt, 1e-5),opt-x); 455 DLIB_TEST(approx_equal(val , simple(x))); 456 dlog << LINFO << "find_min() lbfgs-8: got simple/noder in " << total_count; 457 458 459 total_count = 0; 460 x = p; 461 val=find_min(cg_search_strategy(), 462 objective_delta_stop_strategy(eps), 463 simple, derivative(simple), x, minf); 464 DLIB_TEST_MSG(dlib::equal(x,opt, 1e-5),opt-x); 465 DLIB_TEST(approx_equal(val , simple(x))); 466 dlog << LINFO << "find_min() cg: got simple/noder in " << total_count; 467 468 469 470 total_count = 0; 471 x = p; 472 val=find_min_using_approximate_derivatives(bfgs_search_strategy(), 473 objective_delta_stop_strategy(eps), 474 simple, x, minf); 475 DLIB_TEST_MSG(dlib::equal(x,opt, 1e-5),opt-x); 476 DLIB_TEST(approx_equal(val , simple(x))); 477 dlog << LINFO << "find_min() bfgs: got simple/noder2 in " << total_count; 478 479 480 total_count = 0; 481 x = p; 482 val=find_min_using_approximate_derivatives(lbfgs_search_strategy(6), 483 objective_delta_stop_strategy(eps), 484 simple, x, minf); 485 DLIB_TEST_MSG(dlib::equal(x,opt, 1e-5),opt-x); 486 DLIB_TEST(approx_equal(val , simple(x))); 487 dlog << LINFO << "find_min() lbfgs-6: got simple/noder2 in " << total_count; 488 489 490 total_count = 0; 491 x = p; 492 val=find_min_using_approximate_derivatives(cg_search_strategy(), 493 objective_delta_stop_strategy(eps), 494 simple, x, minf); 495 DLIB_TEST_MSG(dlib::equal(x,opt, 1e-5),opt-x); 496 DLIB_TEST(approx_equal(val , simple(x))); 497 dlog << LINFO << "find_min() cg: got simple/noder2 in " << total_count; 498 499 500 total_count = 0; 501 x = p; 502 val=find_min_bobyqa(simple, x, 2*x.size()+1, 503 uniform_matrix<double>(x.size(),1,-1e100), 504 uniform_matrix<double>(x.size(),1,1e100), 505 (max(abs(x))+1)/10, 506 1e-6, 507 10000); 508 DLIB_TEST_MSG(dlib::equal(x,opt, 1e-5),opt-x); 509 DLIB_TEST(approx_equal(val , simple(x))); 510 dlog << LINFO << "find_min_bobyqa(): got simple in " << total_count; 511 512 } 513 514 test_rosen(const matrix<double,2,1> p)515 void test_rosen ( 516 const matrix<double,2,1> p 517 ) 518 { 519 const double eps = 1e-15; 520 const double minf = -10; 521 matrix<double,2,1> x, opt; 522 opt(0) = 1; 523 opt(1) = 1; 524 525 double val = 0; 526 527 dlog << LINFO << "testing with rosen and the start point: " << trans(p); 528 529 total_count = 0; 530 x = p; 531 val=find_min(bfgs_search_strategy(), 532 objective_delta_stop_strategy(eps), 533 rosen, der_rosen, x, minf); 534 DLIB_TEST_MSG(dlib::equal(x,opt, 1e-7),opt-x); 535 DLIB_TEST(approx_equal(val , rosen(x))); 536 dlog << LINFO << "find_min() bfgs: got rosen in " << total_count; 537 538 539 total_count = 0; 540 x = p; 541 val=find_min(bfgs_search_strategy(), 542 gradient_norm_stop_strategy(), 543 rosen, der_rosen, x, minf); 544 DLIB_TEST_MSG(dlib::equal(x,opt, 1e-7),opt-x); 545 DLIB_TEST(approx_equal(val , rosen(x))); 546 dlog << LINFO << "find_min() bfgs(gn): got rosen in " << total_count; 547 548 549 total_count = 0; 550 x = p; 551 val=find_min(lbfgs_search_strategy(20), 552 objective_delta_stop_strategy(eps), 553 rosen, der_rosen, x, minf); 554 DLIB_TEST_MSG(dlib::equal(x,opt, 1e-7),opt-x); 555 DLIB_TEST(approx_equal(val , rosen(x))); 556 dlog << LINFO << "find_min() lbfgs-20: got rosen in " << total_count; 557 558 559 total_count = 0; 560 x = p; 561 val=find_min(cg_search_strategy(), 562 objective_delta_stop_strategy(eps), 563 rosen, der_rosen, x, minf); 564 DLIB_TEST_MSG(dlib::equal(x,opt, 1e-7),opt-x); 565 DLIB_TEST(approx_equal(val , rosen(x))); 566 dlog << LINFO << "find_min() cg: got rosen in " << total_count; 567 568 569 570 total_count = 0; 571 x = p; 572 val=find_min(bfgs_search_strategy(), 573 objective_delta_stop_strategy(eps), 574 rosen, derivative(rosen,1e-5), x, minf); 575 DLIB_TEST_MSG(dlib::equal(x,opt, 1e-4),opt-x); 576 DLIB_TEST(approx_equal(val , rosen(x))); 577 dlog << LINFO << "find_min() bfgs: got rosen/noder in " << total_count; 578 579 580 total_count = 0; 581 x = p; 582 val=find_min(lbfgs_search_strategy(5), 583 objective_delta_stop_strategy(eps), 584 rosen, derivative(rosen,1e-5), x, minf); 585 DLIB_TEST_MSG(dlib::equal(x,opt, 1e-4),opt-x); 586 DLIB_TEST(approx_equal(val , rosen(x))); 587 dlog << LINFO << "find_min() lbfgs-5: got rosen/noder in " << total_count; 588 589 590 total_count = 0; 591 x = p; 592 val=find_min(cg_search_strategy(), 593 objective_delta_stop_strategy(eps), 594 rosen, derivative(rosen,1e-5), x, minf); 595 DLIB_TEST_MSG(dlib::equal(x,opt, 1e-4),opt-x); 596 DLIB_TEST(approx_equal(val , rosen(x))); 597 dlog << LINFO << "find_min() cg: got rosen/noder in " << total_count; 598 599 600 total_count = 0; 601 x = p; 602 val=find_min_using_approximate_derivatives(cg_search_strategy(), 603 objective_delta_stop_strategy(eps), 604 rosen, x, minf); 605 DLIB_TEST_MSG(dlib::equal(x,opt, 1e-4),opt-x); 606 DLIB_TEST(approx_equal(val , rosen(x))); 607 dlog << LINFO << "find_min() cg: got rosen/noder2 in " << total_count; 608 609 610 if (max(abs(p)) < 1000) 611 { 612 total_count = 0; 613 x = p; 614 val=find_min_bobyqa(rosen, x, 2*x.size()+1, 615 uniform_matrix<double>(x.size(),1,-1e100), 616 uniform_matrix<double>(x.size(),1,1e100), 617 (max(abs(x))+1)/10, 618 1e-6, 619 10000); 620 DLIB_TEST_MSG(dlib::equal(x,opt, 1e-5),opt-x); 621 DLIB_TEST(approx_equal(val , rosen(x))); 622 dlog << LINFO << "find_min_bobyqa(): got rosen in " << total_count; 623 } 624 } 625 626 test_neg_rosen(const matrix<double,2,1> p)627 void test_neg_rosen ( 628 const matrix<double,2,1> p 629 ) 630 { 631 const double eps = 1e-15; 632 const double maxf = 10; 633 matrix<double,2,1> x, opt; 634 opt(0) = 1; 635 opt(1) = 1; 636 637 double val = 0; 638 639 dlog << LINFO << "testing with neg_rosen and the start point: " << trans(p); 640 641 total_count = 0; 642 x = p; 643 val=find_max( 644 bfgs_search_strategy(), 645 objective_delta_stop_strategy(eps), neg_rosen, der_neg_rosen, x, maxf); 646 DLIB_TEST_MSG(dlib::equal(x,opt, 1e-7),opt-x); 647 DLIB_TEST(approx_equal(val , neg_rosen(x))); 648 dlog << LINFO << "find_max() bfgs: got neg_rosen in " << total_count; 649 650 total_count = 0; 651 x = p; 652 val=find_max( 653 lbfgs_search_strategy(5), 654 objective_delta_stop_strategy(eps), neg_rosen, der_neg_rosen, x, maxf); 655 DLIB_TEST_MSG(dlib::equal(x,opt, 1e-7),opt-x); 656 DLIB_TEST(approx_equal(val , neg_rosen(x))); 657 dlog << LINFO << "find_max() lbfgs-5: got neg_rosen in " << total_count; 658 659 total_count = 0; 660 x = p; 661 val=find_max( 662 lbfgs_search_strategy(5), 663 objective_delta_stop_strategy(eps), neg_rosen, derivative(neg_rosen), x, maxf); 664 DLIB_TEST_MSG(dlib::equal(x,opt, 1e-7),opt-x); 665 DLIB_TEST(approx_equal(val , neg_rosen(x))); 666 dlog << LINFO << "find_max() lbfgs-5: got neg_rosen/noder in " << total_count; 667 668 669 total_count = 0; 670 x = p; 671 val=find_max_using_approximate_derivatives( 672 cg_search_strategy(), 673 objective_delta_stop_strategy(eps), neg_rosen, x, maxf); 674 DLIB_TEST_MSG(dlib::equal(x,opt, 1e-7),opt-x); 675 DLIB_TEST(approx_equal(val , neg_rosen(x))); 676 dlog << LINFO << "find_max() cg: got neg_rosen/noder2 in " << total_count; 677 678 679 total_count = 0; 680 x = p; 681 val=find_max_bobyqa(neg_rosen, x, 2*x.size()+1, 682 uniform_matrix<double>(x.size(),1,-1e100), 683 uniform_matrix<double>(x.size(),1,1e100), 684 (max(abs(x))+1)/10, 685 1e-6, 686 10000); 687 DLIB_TEST_MSG(dlib::equal(x,opt, 1e-5),opt-x); 688 DLIB_TEST(approx_equal(val , neg_rosen(x))); 689 dlog << LINFO << "find_max_bobyqa(): got neg_rosen in " << total_count; 690 } 691 692 // ---------------------------------------------------------------------------------------- 693 test_single_variable_function(const double p)694 void test_single_variable_function ( 695 const double p 696 ) 697 { 698 const double eps = 1e-7; 699 700 701 dlog << LINFO << "testing with single_variable_function and the start point: " << p; 702 double out, x; 703 704 total_count = 0; 705 x = p; 706 out = find_min_single_variable(single_variable_function, x, -1e100, 1e100, eps, 1000); 707 DLIB_TEST_MSG(std::abs(out-5) < 1e-6, out-5); 708 DLIB_TEST_MSG(std::abs(x) < 1e-6, x); 709 dlog << LINFO << "find_min_single_variable(): got single_variable_function in " << total_count; 710 711 712 total_count = 0; 713 x = p; 714 out = -find_max_single_variable(negate_function(single_variable_function), x, -1e100, 1e100, eps, 1000); 715 DLIB_TEST_MSG(std::abs(out-5) < 1e-6, out-5); 716 DLIB_TEST_MSG(std::abs(x) < 1e-6, x); 717 dlog << LINFO << "find_max_single_variable(): got single_variable_function in " << total_count; 718 719 720 if (p > 0) 721 { 722 total_count = 0; 723 x = p; 724 out = find_min_single_variable(single_variable_function, x, -1e-4, 1e100, eps, 1000); 725 DLIB_TEST_MSG(std::abs(out-5) < 1e-6, out-5); 726 DLIB_TEST_MSG(std::abs(x) < 1e-6, x); 727 dlog << LINFO << "find_min_single_variable(): got single_variable_function in " << total_count; 728 729 730 if (p > 3) 731 { 732 total_count = 0; 733 x = p; 734 out = -find_max_single_variable(negate_function(single_variable_function), x, 3, 1e100, eps, 1000); 735 DLIB_TEST_MSG(std::abs(out - (3*3*3+5)) < 1e-6, out-(3*3*3+5)); 736 DLIB_TEST_MSG(std::abs(x-3) < 1e-6, x); 737 dlog << LINFO << "find_max_single_variable(): got single_variable_function in " << total_count; 738 } 739 } 740 741 if (p < 0) 742 { 743 total_count = 0; 744 x = p; 745 out = find_min_single_variable(single_variable_function, x, -1e100, 1e-4, eps, 1000); 746 DLIB_TEST_MSG(std::abs(out-5) < 1e-6, out-5); 747 DLIB_TEST_MSG(std::abs(x) < 1e-6, x); 748 dlog << LINFO << "find_min_single_variable(): got single_variable_function in " << total_count; 749 750 if (p < -3) 751 { 752 total_count = 0; 753 x = p; 754 out = find_min_single_variable(single_variable_function, x, -1e100, -3, eps, 1000); 755 DLIB_TEST_MSG(std::abs(out - (3*3*3+5)) < 1e-6, out-(3*3*3+5)); 756 DLIB_TEST_MSG(std::abs(x+3) < 1e-6, x); 757 dlog << LINFO << "find_min_single_variable(): got single_variable_function in " << total_count; 758 } 759 } 760 761 } 762 763 // ---------------------------------------------------------------------------------------- 764 optimization_test()765 void optimization_test ( 766 ) 767 /*! 768 ensures 769 - runs tests on the optimization stuff compliance with the specs 770 !*/ 771 { 772 matrix<double,0,1> p; 773 774 print_spinner(); 775 776 p.set_size(2); 777 778 // test with single_variable_function 779 test_single_variable_function(0); 780 test_single_variable_function(1); 781 test_single_variable_function(-10); 782 test_single_variable_function(-100); 783 test_single_variable_function(900.53); 784 785 // test with the rosen function 786 p(0) = 9; 787 p(1) = -4.9; 788 test_rosen(p); 789 test_neg_rosen(p); 790 791 p(0) = 0; 792 p(1) = 0; 793 test_rosen(p); 794 795 p(0) = 5323; 796 p(1) = 98248; 797 test_rosen(p); 798 799 // test with the simple function 800 p(0) = 1; 801 p(1) = 1; 802 test_simple(p); 803 804 p(0) = 0.5; 805 p(1) = -9; 806 test_simple(p); 807 808 p(0) = 645; 809 p(1) = 839485; 810 test_simple(p); 811 812 print_spinner(); 813 814 // test with the apq function 815 p.set_size(5); 816 817 p(0) = 1; 818 p(1) = 1; 819 p(2) = 1; 820 p(3) = 1; 821 p(4) = 1; 822 test_apq(p); 823 824 p(0) = 1; 825 p(1) = 2; 826 p(2) = 3; 827 p(3) = 4; 828 p(4) = 5; 829 test_apq(p); 830 831 p(0) = 1; 832 p(1) = 2; 833 p(2) = -3; 834 p(3) = 4; 835 p(4) = 5; 836 test_apq(p); 837 838 print_spinner(); 839 840 p(0) = 1; 841 p(1) = 2324; 842 p(2) = -3; 843 p(3) = 4; 844 p(4) = 534534; 845 test_apq(p); 846 847 p.set_size(10); 848 p(0) = 1; 849 p(1) = 2; 850 p(2) = -3; 851 p(3) = 4; 852 p(4) = 5; 853 p(5) = 1; 854 p(6) = 2; 855 p(7) = -3; 856 p(8) = 4; 857 p(9) = 5; 858 test_apq(p); 859 860 // test apq with a big vector 861 p.set_size(500); 862 dlib::rand rnd; 863 for (long i = 0; i < p.size(); ++i) 864 { 865 p(i) = rnd.get_random_double()*20 - 10; 866 } 867 test_apq(p); 868 869 print_spinner(); 870 871 // test with the powell function 872 p.set_size(4); 873 874 p(0) = 3; 875 p(1) = -1; 876 p(2) = 0; 877 p(3) = 1; 878 test_powell(p); 879 880 { 881 matrix<double,2,1> m; 882 m(0) = -0.43; 883 m(1) = 0.919; 884 DLIB_TEST(dlib::equal(der_rosen(m) , derivative(rosen)(m),1e-5)); 885 886 DLIB_TEST_MSG(std::abs(derivative(make_line_search_function(rosen,m,m))(0) - 887 make_line_search_function(derivative(rosen),m,m)(0)) < 1e-5,""); 888 DLIB_TEST_MSG(std::abs(derivative(make_line_search_function(rosen,m,m))(1) - 889 make_line_search_function(derivative(rosen),m,m)(1)) < 1e-5,""); 890 891 DLIB_TEST_MSG(std::abs(derivative(make_line_search_function(rosen,m,m))(0) - 892 make_line_search_function(der_rosen,m,m)(0)) < 1e-5,""); 893 DLIB_TEST_MSG(std::abs(derivative(make_line_search_function(rosen,m,m))(1) - 894 make_line_search_function(der_rosen,m,m)(1)) < 1e-5,""); 895 } 896 { 897 matrix<double,2,1> m; 898 m(0) = 1; 899 m(1) = 2; 900 DLIB_TEST(dlib::equal(der_rosen(m) , derivative(rosen)(m),1e-5)); 901 902 DLIB_TEST_MSG(std::abs(derivative(make_line_search_function(rosen,m,m))(0) - 903 make_line_search_function(derivative(rosen),m,m)(0)) < 1e-5,""); 904 DLIB_TEST_MSG(std::abs(derivative(make_line_search_function(rosen,m,m))(1) - 905 make_line_search_function(derivative(rosen),m,m)(1)) < 1e-5,""); 906 907 DLIB_TEST_MSG(std::abs(derivative(make_line_search_function(rosen,m,m))(0) - 908 make_line_search_function(der_rosen,m,m)(0)) < 1e-5,""); 909 DLIB_TEST_MSG(std::abs(derivative(make_line_search_function(rosen,m,m))(1) - 910 make_line_search_function(der_rosen,m,m)(1)) < 1e-5,""); 911 } 912 913 { 914 matrix<double,2,1> m; 915 m = 1,2; 916 DLIB_TEST(std::abs(neg_rosen(m) - negate_function(rosen)(m) ) < 1e-16); 917 } 918 919 } 920 921 template <typename der_funct, typename T> unconstrained_gradient_magnitude(const der_funct & grad,const T & x,const T & lower,const T & upper)922 double unconstrained_gradient_magnitude ( 923 const der_funct& grad, 924 const T& x, 925 const T& lower, 926 const T& upper 927 ) 928 { 929 T g = grad(x); 930 931 double unorm = 0; 932 933 for (long i = 0; i < g.size(); ++i) 934 { 935 if (lower(i) < x(i) && x(i) < upper(i)) 936 unorm += g(i)*g(i); 937 else if (x(i) == lower(i) && g(i) < 0) 938 unorm += g(i)*g(i); 939 else if (x(i) == upper(i) && g(i) > 0) 940 unorm += g(i)*g(i); 941 } 942 943 return unorm; 944 } 945 946 template <typename der_funct, typename T> unconstrained_gradient_magnitude_neg_funct(const der_funct & grad,const T & x,const T & lower,const T & upper)947 double unconstrained_gradient_magnitude_neg_funct ( 948 const der_funct& grad, 949 const T& x, 950 const T& lower, 951 const T& upper 952 ) 953 { 954 T g = grad(x); 955 956 double unorm = 0; 957 958 for (long i = 0; i < g.size(); ++i) 959 { 960 if (lower(i) < x(i) && x(i) < upper(i)) 961 unorm += g(i)*g(i); 962 else if (x(i) == lower(i) && g(i) > 0) 963 unorm += g(i)*g(i); 964 else if (x(i) == upper(i) && g(i) < 0) 965 unorm += g(i)*g(i); 966 } 967 968 return unorm; 969 } 970 971 template <typename search_strategy_type> test_bound_solver_neg_rosen(dlib::rand & rnd,search_strategy_type search_strategy)972 double test_bound_solver_neg_rosen (dlib::rand& rnd, search_strategy_type search_strategy) 973 { 974 using namespace dlib::test_functions; 975 print_spinner(); 976 matrix<double,2,1> starting_point, lower, upper, x; 977 978 979 // pick random bounds 980 lower = rnd.get_random_gaussian()+1, rnd.get_random_gaussian()+1; 981 upper = rnd.get_random_gaussian()+1, rnd.get_random_gaussian()+1; 982 while (upper(0) < lower(0)) upper(0) = rnd.get_random_gaussian()+1; 983 while (upper(1) < lower(1)) upper(1) = rnd.get_random_gaussian()+1; 984 985 starting_point = rnd.get_random_double()*(upper(0)-lower(0))+lower(0), 986 rnd.get_random_double()*(upper(1)-lower(1))+lower(1); 987 988 dlog << LINFO << "lower: "<< trans(lower); 989 dlog << LINFO << "upper: "<< trans(upper); 990 dlog << LINFO << "starting: "<< trans(starting_point); 991 992 x = starting_point; 993 double val = find_max_box_constrained( 994 search_strategy, 995 objective_delta_stop_strategy(1e-16, 500), 996 neg_rosen, der_neg_rosen, x, 997 lower, 998 upper 999 ); 1000 1001 DLIB_TEST_MSG(std::abs(val - neg_rosen(x)) < 1e-11, std::abs(val - neg_rosen(x))); 1002 dlog << LINFO << "neg_rosen solution:\n" << x; 1003 1004 dlog << LINFO << "neg_rosen gradient: "<< trans(der_neg_rosen(x)); 1005 const double gradient_residual = unconstrained_gradient_magnitude_neg_funct(der_neg_rosen, x, lower, upper); 1006 dlog << LINFO << "gradient_residual: "<< gradient_residual; 1007 1008 return gradient_residual; 1009 } 1010 1011 template <typename search_strategy_type> test_bound_solver_rosen(dlib::rand & rnd,search_strategy_type search_strategy)1012 double test_bound_solver_rosen (dlib::rand& rnd, search_strategy_type search_strategy) 1013 { 1014 using namespace dlib::test_functions; 1015 print_spinner(); 1016 matrix<double,2,1> starting_point, lower, upper, x; 1017 1018 1019 // pick random bounds and sometimes put the upper bound at zero so we can have 1020 // a test where the optimal value has a bound active at 0 so make sure this case 1021 // works properly. 1022 if (rnd.get_random_double() > 0.2) 1023 { 1024 lower = rnd.get_random_gaussian()+1, rnd.get_random_gaussian()+1; 1025 upper = rnd.get_random_gaussian()+1, rnd.get_random_gaussian()+1; 1026 while (upper(0) < lower(0)) upper(0) = rnd.get_random_gaussian()+1; 1027 while (upper(1) < lower(1)) upper(1) = rnd.get_random_gaussian()+1; 1028 } 1029 else 1030 { 1031 upper = 0,0; 1032 if (rnd.get_random_double() > 0.5) 1033 upper(0) = -rnd.get_random_double(); 1034 if (rnd.get_random_double() > 0.5) 1035 upper(1) = -rnd.get_random_double(); 1036 1037 lower = rnd.get_random_double()+1, rnd.get_random_double()+1; 1038 lower = upper - lower; 1039 } 1040 const bool pick_uniform_bounds = rnd.get_random_double() > 0.9; 1041 if (pick_uniform_bounds) 1042 { 1043 double x = rnd.get_random_gaussian()*2; 1044 double y = rnd.get_random_gaussian()*2; 1045 lower = min(x,y); 1046 upper = max(x,y); 1047 } 1048 1049 starting_point = rnd.get_random_double()*(upper(0)-lower(0))+lower(0), 1050 rnd.get_random_double()*(upper(1)-lower(1))+lower(1); 1051 1052 dlog << LINFO << "lower: "<< trans(lower); 1053 dlog << LINFO << "upper: "<< trans(upper); 1054 dlog << LINFO << "starting: "<< trans(starting_point); 1055 1056 x = starting_point; 1057 double val; 1058 if (!pick_uniform_bounds) 1059 { 1060 val = find_min_box_constrained( 1061 search_strategy, 1062 objective_delta_stop_strategy(1e-16, 500), 1063 rosen, der_rosen, x, 1064 lower, 1065 upper 1066 ); 1067 } 1068 else 1069 { 1070 val = find_min_box_constrained( 1071 search_strategy, 1072 objective_delta_stop_strategy(1e-16, 500), 1073 rosen, der_rosen, x, 1074 lower(0), 1075 upper(0) 1076 ); 1077 } 1078 1079 1080 DLIB_TEST_MSG(std::abs(val - rosen(x)) < 1e-11, std::abs(val - rosen(x))); 1081 dlog << LINFO << "rosen solution:\n" << x; 1082 1083 dlog << LINFO << "rosen gradient: "<< trans(der_rosen(x)); 1084 const double gradient_residual = unconstrained_gradient_magnitude(der_rosen, x, lower, upper); 1085 dlog << LINFO << "gradient_residual: "<< gradient_residual; 1086 1087 return gradient_residual; 1088 } 1089 1090 template <typename search_strategy_type> test_bound_solver_brown(dlib::rand & rnd,search_strategy_type search_strategy)1091 double test_bound_solver_brown (dlib::rand& rnd, search_strategy_type search_strategy) 1092 { 1093 using namespace dlib::test_functions; 1094 print_spinner(); 1095 matrix<double,4,1> starting_point(4), lower(4), upper(4), x; 1096 1097 const matrix<double,0,1> solution = brown_solution(); 1098 1099 // pick random bounds 1100 lower = rnd.get_random_gaussian(), rnd.get_random_gaussian(), rnd.get_random_gaussian(), rnd.get_random_gaussian(); 1101 lower = lower*10 + solution; 1102 upper = rnd.get_random_gaussian(), rnd.get_random_gaussian(), rnd.get_random_gaussian(), rnd.get_random_gaussian(); 1103 upper = upper*10 + solution; 1104 for (int i = 0; i < lower.size(); ++i) 1105 { 1106 if (upper(i) < lower(i)) 1107 swap(upper(i),lower(i)); 1108 } 1109 1110 starting_point = rnd.get_random_double()*(upper(0)-lower(0))+lower(0), 1111 rnd.get_random_double()*(upper(1)-lower(1))+lower(1), 1112 rnd.get_random_double()*(upper(2)-lower(2))+lower(2), 1113 rnd.get_random_double()*(upper(3)-lower(3))+lower(3); 1114 1115 dlog << LINFO << "lower: "<< trans(lower); 1116 dlog << LINFO << "upper: "<< trans(upper); 1117 dlog << LINFO << "starting: "<< trans(starting_point); 1118 1119 // The contract for find_min_box_constrained() says we always call obj() before der(). So 1120 // these lambdas verify that this is so. 1121 dlib::matrix<double,0,1> last_x; 1122 auto obj = [&](const dlib::matrix<double,0,1> &x) { last_x = x; return brown(x); }; 1123 auto der = [&](const dlib::matrix<double,0,1> &x) { 1124 // check that obj(x) was called before der(x). 1125 DLIB_TEST_MSG(max(abs(x - last_x)) == 0, max(abs(x - last_x))); 1126 return brown_derivative(x); 1127 }; 1128 1129 x = starting_point; 1130 double val = find_min_box_constrained( 1131 search_strategy, 1132 objective_delta_stop_strategy(1e-16, 500), 1133 obj, der, x, 1134 lower, 1135 upper 1136 ); 1137 1138 DLIB_TEST(std::abs(val - brown(x)) < 1e-14); 1139 dlog << LINFO << "brown solution:\n" << x; 1140 return unconstrained_gradient_magnitude(brown_derivative, x, lower, upper); 1141 } 1142 1143 template <typename search_strategy_type> test_box_constrained_optimizers(search_strategy_type search_strategy)1144 void test_box_constrained_optimizers(search_strategy_type search_strategy) 1145 { 1146 dlib::rand rnd; 1147 running_stats<double> rs; 1148 1149 dlog << LINFO << "test find_min_box_constrained() on rosen"; 1150 for (int i = 0; i < 10000; ++i) 1151 rs.add(test_bound_solver_rosen(rnd, search_strategy)); 1152 dlog << LINFO << "mean rosen gradient: " << rs.mean(); 1153 dlog << LINFO << "max rosen gradient: " << rs.max(); 1154 DLIB_TEST(rs.mean() < 1e-12); 1155 DLIB_TEST(rs.max() < 1e-9); 1156 1157 dlog << LINFO << "test find_min_box_constrained() on brown"; 1158 rs.clear(); 1159 for (int i = 0; i < 1000; ++i) 1160 rs.add(test_bound_solver_brown(rnd, search_strategy)); 1161 dlog << LINFO << "mean brown gradient: " << rs.mean(); 1162 dlog << LINFO << "max brown gradient: " << rs.max(); 1163 dlog << LINFO << "min brown gradient: " << rs.min(); 1164 DLIB_TEST(rs.mean() < 4e-5); 1165 DLIB_TEST_MSG(rs.max() < 3e-2, rs.max()); 1166 DLIB_TEST(rs.min() < 1e-10); 1167 1168 dlog << LINFO << "test find_max_box_constrained() on neg_rosen"; 1169 rs.clear(); 1170 for (int i = 0; i < 1000; ++i) 1171 rs.add(test_bound_solver_neg_rosen(rnd, search_strategy)); 1172 dlog << LINFO << "mean neg_rosen gradient: " << rs.mean(); 1173 dlog << LINFO << "max neg_rosen gradient: " << rs.max(); 1174 DLIB_TEST(rs.mean() < 1e-12); 1175 DLIB_TEST(rs.max() < 1e-9); 1176 1177 } 1178 test_poly_min_extract_2nd()1179 void test_poly_min_extract_2nd() 1180 { 1181 double off; 1182 1183 off = 0.0; DLIB_TEST(std::abs( poly_min_extrap(off*off, -2*off, (1-off)*(1-off)) - off) < 1e-13); 1184 off = 0.1; DLIB_TEST(std::abs( poly_min_extrap(off*off, -2*off, (1-off)*(1-off)) - off) < 1e-13); 1185 off = 0.2; DLIB_TEST(std::abs( poly_min_extrap(off*off, -2*off, (1-off)*(1-off)) - off) < 1e-13); 1186 off = 0.3; DLIB_TEST(std::abs( poly_min_extrap(off*off, -2*off, (1-off)*(1-off)) - off) < 1e-13); 1187 off = 0.4; DLIB_TEST(std::abs( poly_min_extrap(off*off, -2*off, (1-off)*(1-off)) - off) < 1e-13); 1188 off = 0.5; DLIB_TEST(std::abs( poly_min_extrap(off*off, -2*off, (1-off)*(1-off)) - off) < 1e-13); 1189 off = 0.6; DLIB_TEST(std::abs( poly_min_extrap(off*off, -2*off, (1-off)*(1-off)) - off) < 1e-13); 1190 off = 0.8; DLIB_TEST(std::abs( poly_min_extrap(off*off, -2*off, (1-off)*(1-off)) - off) < 1e-13); 1191 off = 0.9; DLIB_TEST(std::abs( poly_min_extrap(off*off, -2*off, (1-off)*(1-off)) - off) < 1e-13); 1192 off = 1.0; DLIB_TEST(std::abs( poly_min_extrap(off*off, -2*off, (1-off)*(1-off)) - off) < 1e-13); 1193 } 1194 test_solve_trust_region_subproblem_bounded()1195 void test_solve_trust_region_subproblem_bounded() 1196 { 1197 print_spinner(); 1198 matrix<double> H(2,2); 1199 H = 1, 0, 1200 0, 1; 1201 matrix<double,0,1> g, lower, upper, p, true_p; 1202 g = {0, 0}; 1203 1204 double radius = 0.5; 1205 lower = {0.5, 0}; 1206 upper = {10, 10}; 1207 1208 1209 solve_trust_region_subproblem_bounded(H,g, radius, p, 0.001, 500, lower, upper); 1210 true_p = { 0.5, 0}; 1211 DLIB_TEST_MSG(length(p-true_p) < 1e-12, p); 1212 1213 } 1214 1215 // ---------------------------------------------------------------------------------------- 1216 test_find_min_single_variable()1217 void test_find_min_single_variable() 1218 { 1219 auto f = [](double x) { return (x-0.2)*(x-0.2); }; 1220 double x = 0.8; 1221 try 1222 { 1223 find_min_single_variable(f, x, 0, 1, 1e-9); 1224 DLIB_TEST(std::abs(x-0.2) < 1e-7); 1225 } 1226 catch(optimize_single_variable_failure&) 1227 { 1228 DLIB_TEST(false); 1229 } 1230 } 1231 1232 // ---------------------------------------------------------------------------------------- 1233 1234 class optimization_tester : public tester 1235 { 1236 public: optimization_tester()1237 optimization_tester ( 1238 ) : 1239 tester ("test_optimization", 1240 "Runs tests on the optimization component.") 1241 {} 1242 perform_test()1243 void perform_test ( 1244 ) 1245 { 1246 dlog << LINFO << "test_box_constrained_optimizers(bfgs_search_strategy())"; 1247 test_box_constrained_optimizers(bfgs_search_strategy()); 1248 dlog << LINFO << "test_box_constrained_optimizers(lbfgs_search_strategy(5))"; 1249 test_box_constrained_optimizers(lbfgs_search_strategy(5)); 1250 test_poly_min_extract_2nd(); 1251 optimization_test(); 1252 test_solve_trust_region_subproblem_bounded(); 1253 test_find_min_single_variable(); 1254 } 1255 } a; 1256 1257 } 1258 1259 1260