// Copyright (C) 2010 Davis E. King (davis@dlib.net) // License: Boost Software License See LICENSE.txt for the full license. #ifndef DLIB_OPTIMIZATION_TEST_FUNCTiONS_H_h_ #define DLIB_OPTIMIZATION_TEST_FUNCTiONS_H_h_ #include #include #include /* Most of the code in this file is converted from the set of Fortran 90 routines created by John Burkardt. The original Fortran can be found here: http://orion.math.iastate.edu/burkardt/f_src/testopt/testopt.html */ // GCC 4.8 gives false alarms about some variables being uninitialized. Disable these // false warnings. #if ( defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 8) #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" #endif namespace dlib { namespace test_functions { // ---------------------------------------------------------------------------------------- matrix chebyquad_residuals(const matrix& x); double chebyquad_residual(int i, const matrix& x); int& chebyquad_calls(); double chebyquad(const matrix& x ); matrix chebyquad_derivative (const matrix& x); matrix chebyquad_start (int n); matrix chebyquad_solution (int n); matrix chebyquad_hessian(const matrix& x); // ---------------------------------------------------------------------------------------- class chebyquad_function_model { public: // Define the type used to represent column vectors typedef matrix column_vector; // Define the type used to represent the hessian matrix typedef matrix general_matrix; double operator() ( const column_vector& x ) const { return chebyquad(x); } void get_derivative_and_hessian ( const column_vector& x, column_vector& d, general_matrix& h ) const { d = chebyquad_derivative(x); h = chebyquad_hessian(x); } }; // ---------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------- double brown_residual (int i, const matrix& x); /*! requires - 1 <= i <= 20 ensures - returns the ith brown residual !*/ double brown ( const matrix& x); matrix brown_derivative ( const matrix& x); matrix brown_hessian ( const matrix& x); matrix brown_start (); matrix brown_solution (); class brown_function_model { public: // Define the type used to represent column vectors typedef matrix column_vector; // Define the type used to represent the hessian matrix typedef matrix general_matrix; double operator() ( const column_vector& x ) const { return brown(x); } void get_derivative_and_hessian ( const column_vector& x, column_vector& d, general_matrix& h ) const { d = brown_derivative(x); h = brown_hessian(x); } }; // ---------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------- template matrix rosen_big_start() { matrix x; x = -1.2, -1; return x; } // This is a variation on the Rosenbrock test function but with large residuals. The // minimum is at 1, 1 and the objective value is 1. template T rosen_big_residual (int i, const matrix& m) { using std::pow; const T x = m(0); const T y = m(1); if (i == 1) { return 100*pow(y - x*x,2)+1.0; } else { return pow(1 - x,2) + 1.0; } } template T rosen_big ( const matrix& m) { using std::pow; return 0.5*(pow(rosen_big_residual(1,m),2) + pow(rosen_big_residual(2,m),2)); } template matrix rosen_big_solution () { matrix x; // solution from original documentation. x = 1,1; return x; } // ---------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------- template matrix rosen_start() { matrix x; x = -1.2, -1; return x; } template T rosen ( const matrix& m) { const T x = m(0); const T y = m(1); using std::pow; // compute Rosenbrock's function and return the result return 100.0*pow(y - x*x,2) + pow(1 - x,2); } template T rosen_residual (int i, const matrix& m) { const T x = m(0); const T y = m(1); if (i == 1) { return 10*(y - x*x); } else { return 1 - x; } } template matrix rosen_residual_derivative (int i, const matrix& m) { const T x = m(0); matrix d; if (i == 1) { d = -20*x, 10; } else { d = -1, 0; } return d; } template const matrix rosen_derivative ( const matrix& m) { const T x = m(0); const T y = m(1); // make us a column vector of length 2 matrix res(2); // now compute the gradient vector res(0) = -400*x*(y-x*x) - 2*(1-x); // derivative of rosen() with respect to x res(1) = 200*(y-x*x); // derivative of rosen() with respect to y return res; } template const matrix rosen_hessian ( const matrix& m) { const T x = m(0); const T y = m(1); // make us a column vector of length 2 matrix res; // now compute the gradient vector res(0,0) = -400*y + 3*400*x*x + 2; res(1,1) = 200; res(0,1) = -400*x; res(1,0) = -400*x; return res; } template matrix rosen_solution () { matrix x; // solution from original documentation. x = 1,1; return x; } // ------------------------------------------------------------------------------------ template struct rosen_function_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 = rosen_derivative(x); h = rosen_hessian(x); } }; // ---------------------------------------------------------------------------------------- } } #endif // DLIB_OPTIMIZATION_TEST_FUNCTiONS_H_h_