Commit af8f65d4 authored by Davis King's avatar Davis King

- Added a compile time check for function references

  - Made the optimization routines return the value of the objective
    function at the end of optimization.

--HG--
extra : convert_revision : svn%3Afdd8eb12-d10e-0410-9acb-85c331704f74/trunk%403219
parent 79a71914
...@@ -130,7 +130,7 @@ namespace dlib ...@@ -130,7 +130,7 @@ namespace dlib
typename funct_der, typename funct_der,
typename T typename T
> >
void find_min ( double find_min (
search_strategy_type search_strategy, search_strategy_type search_strategy,
stop_strategy_type stop_strategy, stop_strategy_type stop_strategy,
const funct& f, const funct& f,
...@@ -175,6 +175,8 @@ namespace dlib ...@@ -175,6 +175,8 @@ namespace dlib
// Take the search step indicated by the above line search // Take the search step indicated by the above line search
x += alpha*s; x += alpha*s;
} }
return f_value;
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -186,7 +188,7 @@ namespace dlib ...@@ -186,7 +188,7 @@ namespace dlib
typename funct_der, typename funct_der,
typename T typename T
> >
void find_max ( double find_max (
search_strategy_type search_strategy, search_strategy_type search_strategy,
stop_strategy_type stop_strategy, stop_strategy_type stop_strategy,
const funct& f, const funct& f,
...@@ -239,6 +241,7 @@ namespace dlib ...@@ -239,6 +241,7 @@ namespace dlib
f_value *= -1; f_value *= -1;
} }
return -f_value;
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -249,7 +252,7 @@ namespace dlib ...@@ -249,7 +252,7 @@ namespace dlib
typename funct, typename funct,
typename T typename T
> >
void find_min_using_approximate_derivatives ( double find_min_using_approximate_derivatives (
search_strategy_type search_strategy, search_strategy_type search_strategy,
stop_strategy_type stop_strategy, stop_strategy_type stop_strategy,
const funct& f, const funct& f,
...@@ -297,6 +300,7 @@ namespace dlib ...@@ -297,6 +300,7 @@ namespace dlib
g = derivative(f,derivative_eps)(x); g = derivative(f,derivative_eps)(x);
} }
return f_value;
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -307,7 +311,7 @@ namespace dlib ...@@ -307,7 +311,7 @@ namespace dlib
typename funct, typename funct,
typename T typename T
> >
void find_max_using_approximate_derivatives ( double find_max_using_approximate_derivatives (
search_strategy_type search_strategy, search_strategy_type search_strategy,
stop_strategy_type stop_strategy, stop_strategy_type stop_strategy,
const funct& f, const funct& f,
...@@ -333,7 +337,7 @@ namespace dlib ...@@ -333,7 +337,7 @@ namespace dlib
); );
// Just negate the necessary things and call the find_min version of this function. // Just negate the necessary things and call the find_min version of this function.
find_min_using_approximate_derivatives( return -find_min_using_approximate_derivatives(
search_strategy, search_strategy,
stop_strategy, stop_strategy,
negate_function(f), negate_function(f),
......
...@@ -102,7 +102,7 @@ namespace dlib ...@@ -102,7 +102,7 @@ namespace dlib
typename funct_der, typename funct_der,
typename T typename T
> >
void find_min ( double find_min (
search_strategy_type search_strategy, search_strategy_type search_strategy,
stop_strategy_type stop_strategy, stop_strategy_type stop_strategy,
const funct& f, const funct& f,
...@@ -125,6 +125,7 @@ namespace dlib ...@@ -125,6 +125,7 @@ namespace dlib
- The function is optimized until stop_strategy decides that an acceptable - The function is optimized until stop_strategy decides that an acceptable
point has been found or f(#x) < min_f. point has been found or f(#x) < min_f.
- #x == the value of x that was found to minimize f() - #x == the value of x that was found to minimize f()
- returns f(#x).
- When this function makes calls to f() and der() it always does so by - When this function makes calls to f() and der() it always does so by
first calling f() and then calling der(). That is, these two functions first calling f() and then calling der(). That is, these two functions
are always called in pairs with f() being called first and then der() are always called in pairs with f() being called first and then der()
...@@ -140,7 +141,7 @@ namespace dlib ...@@ -140,7 +141,7 @@ namespace dlib
typename funct_der, typename funct_der,
typename T typename T
> >
void find_max ( double find_max (
search_strategy_type search_strategy, search_strategy_type search_strategy,
stop_strategy_type stop_strategy, stop_strategy_type stop_strategy,
const funct& f, const funct& f,
...@@ -163,6 +164,7 @@ namespace dlib ...@@ -163,6 +164,7 @@ namespace dlib
- The function is optimized until stop_strategy decides that an acceptable - The function is optimized until stop_strategy decides that an acceptable
point has been found or f(#x) > max_f. point has been found or f(#x) > max_f.
- #x == the value of x that was found to maximize f() - #x == the value of x that was found to maximize f()
- returns f(#x).
- When this function makes calls to f() and der() it always does so by - When this function makes calls to f() and der() it always does so by
first calling f() and then calling der(). That is, these two functions first calling f() and then calling der(). That is, these two functions
are always called in pairs with f() being called first and then der() are always called in pairs with f() being called first and then der()
...@@ -177,7 +179,7 @@ namespace dlib ...@@ -177,7 +179,7 @@ namespace dlib
typename funct, typename funct,
typename T typename T
> >
void find_min_using_approximate_derivatives ( double find_min_using_approximate_derivatives (
search_strategy_type search_strategy, search_strategy_type search_strategy,
stop_strategy_type stop_strategy, stop_strategy_type stop_strategy,
const funct& f, const funct& f,
...@@ -200,6 +202,7 @@ namespace dlib ...@@ -200,6 +202,7 @@ namespace dlib
- The function is optimized until stop_strategy decides that an acceptable - The function is optimized until stop_strategy decides that an acceptable
point has been found or f(#x) < min_f. point has been found or f(#x) < min_f.
- #x == the value of x that was found to minimize f() - #x == the value of x that was found to minimize f()
- returns f(#x).
- Uses the dlib::derivative(f,derivative_eps) function to compute gradient - Uses the dlib::derivative(f,derivative_eps) function to compute gradient
information. information.
!*/ !*/
...@@ -212,7 +215,7 @@ namespace dlib ...@@ -212,7 +215,7 @@ namespace dlib
typename funct, typename funct,
typename T typename T
> >
void find_max_using_approximate_derivatives ( double find_max_using_approximate_derivatives (
search_strategy_type search_strategy, search_strategy_type search_strategy,
stop_strategy_type stop_strategy, stop_strategy_type stop_strategy,
const funct& f, const funct& f,
...@@ -235,6 +238,7 @@ namespace dlib ...@@ -235,6 +238,7 @@ namespace dlib
- The function is optimized until stop_strategy decides that an acceptable - The function is optimized until stop_strategy decides that an acceptable
point has been found or f(#x) > max_f. point has been found or f(#x) > max_f.
- #x == the value of x that was found to maximize f() - #x == the value of x that was found to maximize f()
- returns f(#x).
- Uses the dlib::derivative(f,derivative_eps) function to compute gradient - Uses the dlib::derivative(f,derivative_eps) function to compute gradient
information. information.
!*/ !*/
......
...@@ -46,7 +46,7 @@ namespace dlib ...@@ -46,7 +46,7 @@ namespace dlib
typename T, typename T,
typename U typename U
> >
void find_min ( double find_min (
const funct& f, const funct& f,
T& x, T& x,
long npt, long npt,
...@@ -68,23 +68,23 @@ namespace dlib ...@@ -68,23 +68,23 @@ namespace dlib
matrix<double,0,1> xu(xu_); matrix<double,0,1> xu(xu_);
bobyqa_ (f, return bobyqa_ (f,
x.size(), x.size(),
npt, npt,
&x(0), &x(0),
&xl(0), &xl(0),
&xu(0), &xu(0),
rhobeg, rhobeg,
rhoend, rhoend,
max_f_evals, max_f_evals,
w.get() ); w.get() );
} }
private: private:
template <typename funct> template <typename funct>
void bobyqa_( doublereal bobyqa_(
const funct& calfun, const funct& calfun,
const integer n, const integer n,
const integer npt, const integer npt,
...@@ -225,7 +225,7 @@ namespace dlib ...@@ -225,7 +225,7 @@ namespace dlib
/* Make the call of BOBYQB. */ /* Make the call of BOBYQB. */
bobyqb_(calfun, n, npt, &x[1], &xl[1], &xu[1], rhobeg, rhoend, maxfun, &w[ return bobyqb_(calfun, n, npt, &x[1], &xl[1], &xu[1], rhobeg, rhoend, maxfun, &w[
ixb], &w[ixp], &w[ifv], &w[ixo], &w[igo], &w[ihq], &w[ipq], &w[ ixb], &w[ixp], &w[ifv], &w[ixo], &w[igo], &w[ihq], &w[ipq], &w[
ibmat], &w[izmat], ndim, &w[isl], &w[isu], &w[ixn], &w[ixa], &w[ ibmat], &w[izmat], ndim, &w[isl], &w[isu], &w[ixn], &w[ixa], &w[
id], &w[ivl], &w[iw]); id], &w[ivl], &w[iw]);
...@@ -236,7 +236,7 @@ namespace dlib ...@@ -236,7 +236,7 @@ namespace dlib
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename funct> template <typename funct>
void bobyqb_( doublereal bobyqb_(
const funct& calfun, const funct& calfun,
const integer n, const integer n,
const integer npt, const integer npt,
...@@ -271,7 +271,7 @@ namespace dlib ...@@ -271,7 +271,7 @@ namespace dlib
doublereal d__1, d__2, d__3, d__4; doublereal d__1, d__2, d__3, d__4;
/* Local variables */ /* Local variables */
doublereal f; doublereal f = 0;
integer i__, j, k, ih, nf, jj, nh, ip, jp; integer i__, j, k, ih, nf, jj, nh, ip, jp;
doublereal dx; doublereal dx;
integer np; integer np;
...@@ -1320,6 +1320,7 @@ L720: ...@@ -1320,6 +1320,7 @@ L720:
f = fval[kopt]; f = fval[kopt];
} }
return f;
} /* bobyqb_ */ } /* bobyqb_ */
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -3344,7 +3345,7 @@ L210: ...@@ -3344,7 +3345,7 @@ L210:
typename T, typename T,
typename U typename U
> >
void find_min_bobyqa ( double find_min_bobyqa (
const funct& f, const funct& f,
T& x, T& x,
long npt, long npt,
...@@ -3355,6 +3356,14 @@ L210: ...@@ -3355,6 +3356,14 @@ L210:
const long max_f_evals const long max_f_evals
) )
{ {
// You get an error on this line when you pass in a global function to this function.
// You have to either use a function object or pass a pointer to your global function
// by taking its address using the & operator. (This check is here because gcc 4.0
// has a bug that causes it to silently corrupt return values from functions that
// invoked through a reference)
COMPILE_TIME_ASSERT(is_function<funct>::value == false);
// check the requirements. Also split the assert up so that the error message isn't huge. // check the requirements. Also split the assert up so that the error message isn't huge.
DLIB_CASSERT(is_col_vector(x) && is_col_vector(x_lower) && is_col_vector(x_upper) && DLIB_CASSERT(is_col_vector(x) && is_col_vector(x_lower) && is_col_vector(x_upper) &&
x.size() == x_lower.size() && x_lower.size() == x_upper.size() && x.size() == x_lower.size() && x_lower.size() == x_upper.size() &&
...@@ -3386,7 +3395,7 @@ L210: ...@@ -3386,7 +3395,7 @@ L210:
bobyqa_implementation impl; bobyqa_implementation impl;
impl.find_min(f, x, npt, x_lower, x_upper, rho_begin, rho_end, max_f_evals); return impl.find_min(f, x, npt, x_lower, x_upper, rho_begin, rho_end, max_f_evals);
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -3396,7 +3405,7 @@ L210: ...@@ -3396,7 +3405,7 @@ L210:
typename T, typename T,
typename U typename U
> >
void find_max_bobyqa ( double find_max_bobyqa (
const funct& f, const funct& f,
T& x, T& x,
long npt, long npt,
...@@ -3407,7 +3416,7 @@ L210: ...@@ -3407,7 +3416,7 @@ L210:
const long max_f_evals const long max_f_evals
) )
{ {
find_min_bobyqa(negate_function(f), x, npt, x_lower, x_upper, rho_begin, rho_end, max_f_evals); return -find_min_bobyqa(negate_function(f), x, npt, x_lower, x_upper, rho_begin, rho_end, max_f_evals);
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
......
...@@ -41,7 +41,7 @@ namespace dlib ...@@ -41,7 +41,7 @@ namespace dlib
typename T, typename T,
typename U typename U
> >
void find_min_bobyqa ( double find_min_bobyqa (
const funct& f, const funct& f,
T& x, T& x,
long npt, long npt,
...@@ -75,6 +75,7 @@ namespace dlib ...@@ -75,6 +75,7 @@ namespace dlib
- #x == the value of x (within the bounds defined by x_lower and x_upper) that - #x == the value of x (within the bounds defined by x_lower and x_upper) that
was found to minimize f(). More precisely: was found to minimize f(). More precisely:
- min(#x - x_lower) >= 0 && min(x_upper - #x) >= 0 - min(#x - x_lower) >= 0 && min(x_upper - #x) >= 0
- returns f(#x).
- rho_begin and rho_end are used as the initial and final values of a trust - rho_begin and rho_end are used as the initial and final values of a trust
region radius. Typically, rho_begin should be about one tenth of the greatest region radius. Typically, rho_begin should be about one tenth of the greatest
expected change to a variable, while rho_end should indicate the accuracy that expected change to a variable, while rho_end should indicate the accuracy that
...@@ -94,7 +95,7 @@ namespace dlib ...@@ -94,7 +95,7 @@ namespace dlib
typename T, typename T,
typename U typename U
> >
void find_max_bobyqa ( double find_max_bobyqa (
const funct& f, const funct& f,
T& x, T& x,
long npt, long npt,
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment