// Copyright (C) 2010 Davis E. King (davis@dlib.net) // License: Boost Software License See LICENSE.txt for the full license. #include <dlib/optimization.h> #include "optimization_test_functions.h" #include <sstream> #include <string> #include <cstdlib> #include <ctime> #include <vector> #include "../rand.h" #include "tester.h" namespace { using namespace test; using namespace dlib; using namespace std; using namespace dlib::test_functions; logger dlog("test.trust_region"); // ---------------------------------------------------------------------------------------- template <typename T> struct neg_rosen_model { typedef matrix<T,0,1> column_vector; typedef matrix<T,0,0> general_matrix; T operator() ( column_vector x) const { return -static_cast<T>(rosen<T>(x)); } void get_derivative_and_hessian ( const column_vector& x, column_vector& d, general_matrix& h ) const { d = -matrix_cast<T>(rosen_derivative<T>(x)); h = -matrix_cast<T>(rosen_hessian<T>(x)); } }; // ---------------------------------------------------------------------------------------- dlib::rand rnd; template <typename T> void test_with_rosen() { print_spinner(); matrix<T,2,1> ans; ans = 1,1; matrix<T,2,1> p = 100*matrix_cast<T>(randm(2,1,rnd)) - 50; T obj = find_min_trust_region(objective_delta_stop_strategy(1e-12, 100), rosen_function_model<T>(), p); DLIB_TEST_MSG(std::abs(obj) < 1e-10, "obj: " << obj); DLIB_TEST_MSG(length(p-ans) < 1e-5, "length(p): " << length(p-ans)); matrix<T,0,1> p2 = 100*matrix_cast<T>(randm(2,1,rnd)) - 50; obj = find_max_trust_region(objective_delta_stop_strategy(1e-12, 100), neg_rosen_model<T>(), p2); DLIB_TEST_MSG(std::abs(obj) < 1e-10, "obj: " << obj); DLIB_TEST_MSG(length(p-ans) < 1e-5, "length(p): " << length(p-ans)); } // ---------------------------------------------------------------------------------------- void test_trust_region_sub_problem() { dlog << LINFO << "subproblem test 1"; { matrix<double,2,2> B; B = 1, 0, 0, 1; matrix<double,2,1> g, p, ans; g = 0; ans = 0; solve_trust_region_subproblem(B,g,1,p, 0.001, 10); DLIB_TEST(length(p-ans) < 1e-10); solve_trust_region_subproblem(B,g,1,p, 0.001, 1); DLIB_TEST(length(p-ans) < 1e-10); } dlog << LINFO << "subproblem test 2"; { matrix<double,2,2> B; B = 1, 0, 0, 1; B *= 0.1; matrix<double,2,1> g, p, ans; g = 1; ans = -g / length(g); solve_trust_region_subproblem(B,g,1,p, 1e-6, 20); DLIB_TEST(length(p-ans) < 1e-4); } dlog << LINFO << "subproblem test 3"; { matrix<double,2,2> B; B = 0, 0, 0, 0; matrix<double,2,1> g, p, ans; g = 1; ans = -g / length(g); solve_trust_region_subproblem(B,g,1,p, 1e-6, 20); dlog << LINFO << "ans: " << trans(ans); dlog << LINFO << "p: " << trans(p); DLIB_TEST(length(p-ans) < 1e-4); } return; dlog << LINFO << "subproblem test 4"; { matrix<double,2,2> B; B = 2, 0, 0, -1; matrix<double,2,1> g, p, ans; g = 0; ans = 0, -1; solve_trust_region_subproblem(B,g,1,p, 1e-6, 20); DLIB_TEST(length(p-ans) < 1e-4); } dlog << LINFO << "subproblem test 5"; { matrix<double,2,2> B; B = 2, 0, 0, -1; matrix<double,2,1> g, p, ans; g = 0, 1; ans = 0, -1; solve_trust_region_subproblem(B,g,1,p, 1e-6, 20); DLIB_TEST(length(p-ans) < 1e-4); } dlog << LINFO << "subproblem test 6"; for (int i = 0; i < 10; ++i) { matrix<double,10,10> B; B = randm(10,10, rnd); B = 0.01*B*trans(B); matrix<double,10,1> g, p, ans; g = 1; solve_trust_region_subproblem(B,g,1,p, 1e-6, 20); DLIB_TEST(std::abs(length(p) - 1) < 1e-4); } } // ---------------------------------------------------------------------------------------- void test_problems() { print_spinner(); { matrix<double,4,1> ch; ch = brown_start(); find_min_trust_region(objective_delta_stop_strategy(1e-7, 80), brown_function_model(), ch); dlog << LINFO << "brown obj: " << brown(ch); dlog << LINFO << "brown der: " << length(brown_derivative(ch)); dlog << LINFO << "brown error: " << length(ch - brown_solution()); DLIB_TEST(length(ch - brown_solution()) < 1e-5); } print_spinner(); { matrix<double,2,1> ch; ch = rosen_start<double>(); find_min_trust_region(objective_delta_stop_strategy(1e-7, 80), rosen_function_model<double>(), ch); dlog << LINFO << "rosen obj: " << rosen(ch); dlog << LINFO << "rosen der: " << length(rosen_derivative(ch)); dlog << LINFO << "rosen error: " << length(ch - rosen_solution<double>()); DLIB_TEST(length(ch - rosen_solution<double>()) < 1e-5); } print_spinner(); { matrix<double,0,1> ch; ch = chebyquad_start(2); find_min_trust_region(objective_delta_stop_strategy(1e-7, 80), chebyquad_function_model(), ch); dlog << LINFO << "chebyquad 2 obj: " << chebyquad(ch); dlog << LINFO << "chebyquad 2 der: " << length(chebyquad_derivative(ch)); dlog << LINFO << "chebyquad 2 error: " << length(ch - chebyquad_solution(2)); DLIB_TEST(length(ch - chebyquad_solution(2)) < 1e-5); } print_spinner(); { matrix<double,0,1> ch; ch = chebyquad_start(4); find_min_trust_region(objective_delta_stop_strategy(1e-7, 80), chebyquad_function_model(), ch); dlog << LINFO << "chebyquad 4 obj: " << chebyquad(ch); dlog << LINFO << "chebyquad 4 der: " << length(chebyquad_derivative(ch)); dlog << LINFO << "chebyquad 4 error: " << length(ch - chebyquad_solution(4)); DLIB_TEST(length(ch - chebyquad_solution(4)) < 1e-5); } print_spinner(); { matrix<double,0,1> ch; ch = chebyquad_start(6); find_min_trust_region(objective_delta_stop_strategy(1e-12, 80), chebyquad_function_model(), ch); dlog << LINFO << "chebyquad 6 obj: " << chebyquad(ch); dlog << LINFO << "chebyquad 6 der: " << length(chebyquad_derivative(ch)); dlog << LINFO << "chebyquad 6 error: " << length(ch - chebyquad_solution(6)); DLIB_TEST(length(ch - chebyquad_solution(6)) < 1e-5); } print_spinner(); { matrix<double,0,1> ch; ch = chebyquad_start(8); find_min_trust_region(objective_delta_stop_strategy(1e-10, 80), chebyquad_function_model(), ch); dlog << LINFO << "chebyquad 8 obj: " << chebyquad(ch); dlog << LINFO << "chebyquad 8 der: " << length(chebyquad_derivative(ch)); dlog << LINFO << "chebyquad 8 error: " << length(ch - chebyquad_solution(8)); DLIB_TEST(length(ch - chebyquad_solution(8)) < 1e-5); } } class optimization_tester : public tester { public: optimization_tester ( ) : tester ("test_trust_region", "Runs tests on the trust region optimization component.") {} void perform_test ( ) { dlog << LINFO << "test with rosen<float>"; for (int i = 0; i < 50; ++i) test_with_rosen<float>(); dlog << LINFO << "test with rosen<double>"; for (int i = 0; i < 50; ++i) test_with_rosen<double>(); test_trust_region_sub_problem(); test_problems(); } } a; }