// Copyright (C) 2010 Davis E. King (davis@dlib.net) // License: Boost Software License See LICENSE.txt for the full license. #include #include "optimization_test_functions.h" #include #include #include #include #include #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 struct neg_rosen_model { typedef matrix column_vector; typedef matrix general_matrix; T operator() ( column_vector x) const { return -static_cast(rosen(x)); } void get_derivative_and_hessian ( const column_vector& x, column_vector& d, general_matrix& h ) const { d = -matrix_cast(rosen_derivative(x)); h = -matrix_cast(rosen_hessian(x)); } }; // ---------------------------------------------------------------------------------------- dlib::rand rnd; template void test_with_rosen() { print_spinner(); matrix ans; ans = 1,1; matrix p = 100*matrix_cast(randm(2,1,rnd)) - 50; T obj = find_min_trust_region(objective_delta_stop_strategy(1e-12, 100), rosen_function_model(), 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 p2 = 100*matrix_cast(randm(2,1,rnd)) - 50; obj = find_max_trust_region(objective_delta_stop_strategy(1e-12, 100), neg_rosen_model(), 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 B; B = 1, 0, 0, 1; matrix 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 B; B = 1, 0, 0, 1; B *= 0.1; matrix 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 B; B = 0, 0, 0, 0; matrix 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 B; B = 2, 0, 0, -1; matrix 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 B; B = 2, 0, 0, -1; matrix 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 B; B = randm(10,10, rnd); B = 0.01*B*trans(B); matrix 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 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 ch; ch = rosen_start(); find_min_trust_region(objective_delta_stop_strategy(1e-7, 80), rosen_function_model(), ch); dlog << LINFO << "rosen obj: " << rosen(ch); dlog << LINFO << "rosen der: " << length(rosen_derivative(ch)); dlog << LINFO << "rosen error: " << length(ch - rosen_solution()); DLIB_TEST(length(ch - rosen_solution()) < 1e-5); } print_spinner(); { matrix 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 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 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 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"; for (int i = 0; i < 50; ++i) test_with_rosen(); dlog << LINFO << "test with rosen"; for (int i = 0; i < 50; ++i) test_with_rosen(); test_trust_region_sub_problem(); test_problems(); } } a; }