Commit b73f5e81 authored by Davis King's avatar Davis King

merged

parents b16cc99e 172577d2
...@@ -16,6 +16,9 @@ ...@@ -16,6 +16,9 @@
#include "matrix_assign_fwd.h" #include "matrix_assign_fwd.h"
#include "matrix_op.h" #include "matrix_op.h"
#include <utility> #include <utility>
#ifdef DLIB_HAS_RVALUE_REFERENCES
#include <initializer_list>
#endif
#ifdef MATLAB_MEX_FILE #ifdef MATLAB_MEX_FILE
#include <mex.h> #include <mex.h>
...@@ -1112,6 +1115,61 @@ namespace dlib ...@@ -1112,6 +1115,61 @@ namespace dlib
} }
#ifdef DLIB_HAS_RVALUE_REFERENCES #ifdef DLIB_HAS_RVALUE_REFERENCES
matrix(const std::initializer_list<T>& l)
{
if (NR*NC != 0)
{
DLIB_ASSERT(l.size() == NR*NC,
"\t matrix::matrix(const std::initializer_list& l)"
<< "\n\t You are trying to initialize a statically sized matrix with a list that doesn't have a matching size."
<< "\n\t l.size(): "<< l.size()
<< "\n\t NR*NC: "<< NR*NC);
data.set_size(NR, NC);
}
else if (NR!=0)
{
DLIB_ASSERT(l.size()%NR == 0,
"\t matrix::matrix(const std::initializer_list& l)"
<< "\n\t You are trying to initialize a statically sized matrix with a list that doesn't have a compatible size."
<< "\n\t l.size(): "<< l.size()
<< "\n\t NR: "<< NR);
if (l.size() != 0)
data.set_size(NR, l.size()/NR);
}
else if (NC!=0)
{
DLIB_ASSERT(l.size()%NC == 0,
"\t matrix::matrix(const std::initializer_list& l)"
<< "\n\t You are trying to initialize a statically sized matrix with a list that doesn't have a compatible size."
<< "\n\t l.size(): "<< l.size()
<< "\n\t NC: "<< NC);
if (l.size() != 0)
data.set_size(l.size()/NC, NC);
}
else if (l.size() != 0)
{
data.set_size(l.size(),1);
}
if (l.size() != 0)
{
T* d = &data(0,0);
for (auto&& v : l)
*d++ = v;
}
}
matrix& operator=(const std::initializer_list<T>& l)
{
matrix temp(l);
temp.swap(*this);
return *this;
}
matrix(matrix&& item) matrix(matrix&& item)
{ {
#ifdef MATLAB_MEX_FILE #ifdef MATLAB_MEX_FILE
......
...@@ -336,6 +336,30 @@ namespace dlib ...@@ -336,6 +336,30 @@ namespace dlib
- #aliases(*this) == true - #aliases(*this) == true
- #ref().aliases(*this) == true - #ref().aliases(*this) == true
!*/ !*/
matrix(
const std::initializer_list<T>& l
);
/*!
requires
- This matrix is capable of having a size() == l.size(). Therefore, if
NR*NC != 0 then l.size() must equal NR*NC. Alternatively, if NR or NC is
!= 0 then l.size() must be a multiple of the non-zero NR or NC.
ensures
- #size() == l.size()
- The contents of l are enumerated and read into the matrix in row major order.
- if (NR != 0) then
- #nr() == NR
- #nc() == l.size()/NR
- if (NC != 0) then
- #nr() == l.size()/NC
- #nc() == NC
- if (NR*NC==0) then
- #nr() == l.size()
- #nc() == 1
- #aliases(*this) == true
- #ref().aliases(*this) == true
!*/
T& operator() ( T& operator() (
long r, long r,
...@@ -470,6 +494,19 @@ namespace dlib ...@@ -470,6 +494,19 @@ namespace dlib
- returns *this - returns *this
!*/ !*/
matrix& operator=(
const std::initializer_list<T>& l
);
/*!
requires
- This matrix is capable of having a size() == l.size(). Therefore, if
NR*NC != 0 then l.size() must equal NR*NC. Alternatively, if NR or NC is
!= 0 then l.size() must be a multiple of the non-zero NR or NC.
ensures
- Assigns the contents of l to *this by performing: matrix(l).swap(*this)
- returns *this
!*/
template <typename EXP> template <typename EXP>
matrix& operator= ( matrix& operator= (
const matrix_exp<EXP>& m const matrix_exp<EXP>& m
......
// Copyright (C) 2016 Davis E. King (davis@dlib.net)
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_fIND_OPTIMAL_PARAMETERS_Hh_
#define DLIB_fIND_OPTIMAL_PARAMETERS_Hh_
#include "../matrix.h"
#include "find_optimal_parameters_abstract.h"
#include "optimization_bobyqa.h"
#include "optimization_line_search.h"
namespace dlib
{
// ----------------------------------------------------------------------------------------
template <
typename funct
>
double find_optimal_parameters (
double initial_search_radius,
double eps,
const unsigned int max_f_evals,
matrix<double,0,1>& x,
const matrix<double,0,1>& x_lower,
const matrix<double,0,1>& x_upper,
const funct& f
)
/*!
requires
- f(x) must be a valid expression that evaluates to a double
- x.size() == x_lower.size() == x_upper.size()
- x.size() > 0
- 0 < eps < initial_search_radius
- max_f_evals > 1
- min(x_upper - x_lower) > 0
- min(x - x_lower) >= 0 && min(x_upper - x) >= 0
(i.e. the given x should be within the bounds defined by x_lower and x_upper)
ensures
- Performs a constrained minimization of the function f() starting from
the initial point x.
- This function does not require derivatives of f(). Instead, it uses
derivative free methods to find the best setting of x. In particular, it
will begin by searching within a sphere of radius initial_search_radius
around x and will continue searching until either f() has been called
max_f_evals times or the search area has been shrunk to less than eps radius.
- #x == the value of x (within the bounds defined by x_lower and x_upper) that
was found to minimize f(). More precisely, it will always be true that:
- min(#x - x_lower) >= 0 && min(x_upper - #x) >= 0
- returns f(#x).
throws
- No exception is thrown for executing max_f_evals iterations. This function
will simply output the best x it has seen if it runs out of iterations.
!*/
{
DLIB_CASSERT(x.size() == x_lower.size() && x_lower.size() == x_upper.size() && x.size() > 0,
"\t double find_optimal_parameters()"
<< "\n\t x.size(): " << x.size()
<< "\n\t x_lower.size(): " << x_lower.size()
<< "\n\t x_upper.size(): " << x_upper.size()
);
// check the requirements. Also split the assert up so that the error message isn't huge.
DLIB_CASSERT(max_f_evals > 1 && eps > 0 && initial_search_radius > eps,
"\t double find_optimal_parameters()"
<< "\n\t Invalid arguments have been given to this function"
<< "\n\t initial_search_radius: " << initial_search_radius
<< "\n\t eps: " << eps
<< "\n\t max_f_evals: " << max_f_evals
);
DLIB_CASSERT( min(x_upper - x_lower) > 0 &&
min(x - x_lower) >= 0 && min(x_upper - x) >= 0,
"\t double find_optimal_parameters()"
<< "\n\t The bounds constraints have to make sense and also contain the starting point."
<< "\n\t min(x_upper - x_lower): " << min(x_upper - x_lower)
<< "\n\t min(x - x_lower) >= 0 && min(x_upper - x) >= 0: " << (min(x - x_lower) >= 0 && min(x_upper - x) >= 0)
);
// if the search radius is too big then shrink it so it fits inside the bounds.
if (initial_search_radius*2 >= min(x_upper-x_lower))
initial_search_radius = 0.5*min(x_upper-x_lower)*0.99;
double objective_val = std::numeric_limits<double>::infinity();
size_t num_iter_used = 0;
if (x.size() == 1)
{
// BOBYQA requires x to have at least 2 variables in it. So we can't call it in
// this case. Instead we call find_min_single_variable().
matrix<double,0,1> temp(1);
auto ff = [&](const double& xx)
{
temp = xx;
double obj = f(temp);
++num_iter_used;
// keep track of the best x.
if (obj < objective_val)
{
objective_val = obj;
x = temp;
}
return obj;
};
try
{
double dx = x(0);
find_min_single_variable(ff, dx, x_lower(0), x_upper(0), eps, max_f_evals, initial_search_radius);
} catch (optimize_single_variable_failure& )
{
}
}
else
{
auto ff = [&](const matrix<double,0,1>& xx)
{
double obj = f(xx);
++num_iter_used;
// keep track of the best x.
if (obj < objective_val)
{
objective_val = obj;
x = xx;
}
return obj;
};
try
{
matrix<double,0,1> start_x = x;
find_min_bobyqa(ff, start_x, 2*x.size()+1, x_lower, x_upper, initial_search_radius, eps, max_f_evals);
} catch (bobyqa_failure& )
{
}
}
return objective_val;
}
// ----------------------------------------------------------------------------------------
}
#endif // DLIB_fIND_OPTIMAL_PARAMETERS_Hh_
// Copyright (C) 2016 Davis E. King (davis@dlib.net)
// License: Boost Software License See LICENSE.txt for the full license.
#undef DLIB_fIND_OPTIMAL_PARAMETERS_ABSTRACT_Hh_
#ifdef DLIB_fIND_OPTIMAL_PARAMETERS_ABSTRACT_Hh_
#include "../matrix.h"
namespace dlib
{
// ----------------------------------------------------------------------------------------
template <
typename funct
>
double find_optimal_parameters (
double initial_search_radius,
double eps,
const unsigned int max_f_evals,
matrix<double,0,1>& x,
const matrix<double,0,1>& x_lower,
const matrix<double,0,1>& x_upper,
const funct& f
);
/*!
requires
- f(x) must be a valid expression that evaluates to a double
- x.size() == x_lower.size() == x_upper.size()
- x.size() > 0
- 0 < eps < initial_search_radius
- max_f_evals > 1
- min(x_upper - x_lower) > 0
- min(x - x_lower) >= 0 && min(x_upper - x) >= 0
(i.e. the given x should be within the bounds defined by x_lower and x_upper)
ensures
- Performs a constrained minimization of the function f() starting from
the initial point x.
- This function does not require derivatives of f(). Instead, it uses
derivative free methods to find the best setting of x. In particular, it
will begin by searching within a sphere of radius initial_search_radius
around x and will continue searching until either f() has been called
max_f_evals times or the search area has been shrunk to less than eps radius.
- #x == the value of x (within the bounds defined by x_lower and x_upper) that
was found to minimize f(). More precisely, it will always be true that:
- min(#x - x_lower) >= 0 && min(x_upper - #x) >= 0
- returns f(#x).
throws
- No exception is thrown for executing max_f_evals iterations. This function
will simply output the best x it has seen if it runs out of iterations.
!*/
// ----------------------------------------------------------------------------------------
}
#endif // DLIB_fIND_OPTIMAL_PARAMETERS_ABSTRACT_Hh_
...@@ -3360,7 +3360,7 @@ L210: ...@@ -3360,7 +3360,7 @@ L210:
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() &&
x.size() > 1 && max_f_evals > 1, x.size() > 1 && max_f_evals > 1,
"\tvoid find_min_bobyqa()" "\tdouble find_min_bobyqa()"
<< "\n\t Invalid arguments have been given to this function" << "\n\t Invalid arguments have been given to this function"
<< "\n\t is_col_vector(x): " << is_col_vector(x) << "\n\t is_col_vector(x): " << is_col_vector(x)
<< "\n\t is_col_vector(x_lower): " << is_col_vector(x_lower) << "\n\t is_col_vector(x_lower): " << is_col_vector(x_lower)
...@@ -3375,7 +3375,7 @@ L210: ...@@ -3375,7 +3375,7 @@ L210:
0 < rho_end && rho_end < rho_begin && 0 < rho_end && rho_end < rho_begin &&
min(x_upper - x_lower) > 2*rho_begin && min(x_upper - x_lower) > 2*rho_begin &&
min(x - x_lower) >= 0 && min(x_upper - x) >= 0, min(x - x_lower) >= 0 && min(x_upper - x) >= 0,
"\tvoid find_min_bobyqa()" "\tdouble find_min_bobyqa()"
<< "\n\t Invalid arguments have been given to this function" << "\n\t Invalid arguments have been given to this function"
<< "\n\t ntp in valid range: " << (x.size() + 2 <= npt && npt <= (x.size()+1)*(x.size()+2)/2) << "\n\t ntp in valid range: " << (x.size() + 2 <= npt && npt <= (x.size()+1)*(x.size()+2)/2)
<< "\n\t npt: " << npt << "\n\t npt: " << npt
......
...@@ -155,6 +155,7 @@ if (COMPILER_CAN_DO_CPP_11) ...@@ -155,6 +155,7 @@ if (COMPILER_CAN_DO_CPP_11)
set(tests ${tests} set(tests ${tests}
dnn.cpp dnn.cpp
cublas.cpp cublas.cpp
find_optimal_parameters.cpp
) )
endif() endif()
......
// Copyright (C) 2008 Davis E. King (davis@dlib.net)
// License: Boost Software License See LICENSE.txt for the full license.
#include <dlib/optimization/find_optimal_parameters.h>
#include "tester.h"
namespace
{
using namespace test;
using namespace dlib;
using namespace std;
logger dlog("test.find_optimal_parameters");
// ----------------------------------------------------------------------------------------
class find_optimal_parameters : public tester
{
public:
find_optimal_parameters (
) :
tester ("test_find_optimal_parameters",
"Runs tests on find_optimal_parameters().")
{}
void perform_test (
)
{
print_spinner();
matrix<double,0,1> params = {0.5, 0.5};
dlib::find_optimal_parameters(4, 0.001, 100, params, {-0.1, -0.01}, {5, 5}, [](const matrix<double,0,1>& params) {
cout << ".";
return sum(squared(params));
});
matrix<double,0,1> true_params = {0,0};
DLIB_TEST(max(abs(true_params - params)) < 1e-10);
params = {0.1};
dlib::find_optimal_parameters(4, 0.001, 100, params, {-0.01}, {5}, [](const matrix<double,0,1>& params) {
cout << ".";
return sum(squared(params));
});
true_params = {0};
DLIB_TEST(max(abs(true_params - params)) < 1e-10);
}
} a;
}
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