Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
OpenDAS
dlib
Commits
e273f515
"tools/git@developer.sourcefind.cn:OpenDAS/dlib.git" did not exist on "5f26972551dac0820b8abb27891f1f4e26f11702"
Commit
e273f515
authored
Dec 02, 2017
by
Davis King
Browse files
Added find_min_global() overloads.
parent
3284f575
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
440 additions
and
63 deletions
+440
-63
dlib/global_optimization/find_max_global.h
dlib/global_optimization/find_max_global.h
+220
-52
dlib/global_optimization/find_max_global_abstract.h
dlib/global_optimization/find_max_global_abstract.h
+150
-2
dlib/test/global_optimization.cpp
dlib/test/global_optimization.cpp
+61
-0
examples/optimization_ex.cpp
examples/optimization_ex.cpp
+9
-9
No files found.
dlib/global_optimization/find_max_global.h
View file @
e273f515
...
@@ -112,75 +112,109 @@ template <typename T> static auto go(T&& f, const matrix<double, 0, 1>& a) -> de
...
@@ -112,75 +112,109 @@ template <typename T> static auto go(T&& f, const matrix<double, 0, 1>& a) -> de
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template
<
namespace
impl
typename
funct
>
std
::
pair
<
size_t
,
function_evaluation
>
find_max_global
(
std
::
vector
<
funct
>&
functions
,
std
::
vector
<
function_spec
>
specs
,
const
max_function_calls
num
,
const
std
::
chrono
::
nanoseconds
max_runtime
=
FOREVER
,
double
solver_epsilon
=
0
)
{
{
// Decide which parameters should be searched on a log scale. Basically, it's
template
<
// common for machine learning models to have parameters that should be searched on
typename
funct
// a log scale (e.g. SVM C). These parameters are usually identifiable because
>
// they have bounds like [1e-5 1e10], that is, they span a very large range of
std
::
pair
<
size_t
,
function_evaluation
>
find_max_global
(
// magnitudes from really small to really big. So there we are going to check for
std
::
vector
<
funct
>&
functions
,
// that and if we find parameters with that kind of bound constraints we will
std
::
vector
<
function_spec
>
specs
,
// transform them to a log scale automatically.
const
max_function_calls
num
,
std
::
vector
<
std
::
vector
<
bool
>>
log_scale
(
specs
.
size
());
const
std
::
chrono
::
nanoseconds
max_runtime
,
for
(
size_t
i
=
0
;
i
<
specs
.
size
();
++
i
)
double
solver_epsilon
,
double
ymult
)
{
{
for
(
long
j
=
0
;
j
<
specs
[
i
].
lower
.
size
();
++
j
)
// Decide which parameters should be searched on a log scale. Basically, it's
// common for machine learning models to have parameters that should be searched on
// a log scale (e.g. SVM C). These parameters are usually identifiable because
// they have bounds like [1e-5 1e10], that is, they span a very large range of
// magnitudes from really small to really big. So there we are going to check for
// that and if we find parameters with that kind of bound constraints we will
// transform them to a log scale automatically.
std
::
vector
<
std
::
vector
<
bool
>>
log_scale
(
specs
.
size
());
for
(
size_t
i
=
0
;
i
<
specs
.
size
();
++
i
)
{
{
if
(
!
specs
[
i
].
is_integer_variable
[
j
]
&&
specs
[
i
].
lower
(
j
)
>
0
&&
specs
[
i
].
upper
(
j
)
/
specs
[
i
].
lower
(
j
)
>
1000
)
for
(
long
j
=
0
;
j
<
specs
[
i
].
lower
.
size
();
++
j
)
{
{
log_scale
[
i
].
push_back
(
true
);
if
(
!
specs
[
i
].
is_integer_variable
[
j
]
&&
specs
[
i
].
lower
(
j
)
>
0
&&
specs
[
i
].
upper
(
j
)
/
specs
[
i
].
lower
(
j
)
>
1000
)
specs
[
i
].
lower
(
j
)
=
std
::
log
(
specs
[
i
].
lower
(
j
));
{
specs
[
i
].
upper
(
j
)
=
std
::
log
(
specs
[
i
].
upper
(
j
));
log_scale
[
i
].
push_back
(
true
);
specs
[
i
].
lower
(
j
)
=
std
::
log
(
specs
[
i
].
lower
(
j
));
specs
[
i
].
upper
(
j
)
=
std
::
log
(
specs
[
i
].
upper
(
j
));
}
else
{
log_scale
[
i
].
push_back
(
false
);
}
}
}
else
}
global_function_search
opt
(
specs
);
opt
.
set_solver_epsilon
(
solver_epsilon
);
const
auto
time_to_stop
=
std
::
chrono
::
steady_clock
::
now
()
+
max_runtime
;
// Now run the main solver loop.
for
(
size_t
i
=
0
;
i
<
num
.
max_calls
&&
std
::
chrono
::
steady_clock
::
now
()
<
time_to_stop
;
++
i
)
{
auto
next
=
opt
.
get_next_x
();
matrix
<
double
,
0
,
1
>
x
=
next
.
x
();
// Undo any log-scaling that was applied to the variables before we pass them
// to the functions being optimized.
for
(
long
j
=
0
;
j
<
x
.
size
();
++
j
)
{
{
log_scale
[
i
].
push_back
(
false
);
if
(
log_scale
[
next
.
function_idx
()][
j
])
x
(
j
)
=
std
::
exp
(
x
(
j
));
}
}
double
y
=
ymult
*
call_function_and_expand_args
(
functions
[
next
.
function_idx
()],
x
);
next
.
set
(
y
);
}
}
}
global_function_search
opt
(
specs
);
opt
.
set_solver_epsilon
(
solver_epsilon
);
const
auto
time_to_stop
=
std
::
chrono
::
steady_clock
::
now
()
+
max_runtime
;
matrix
<
double
,
0
,
1
>
x
;
double
y
;
// Now run the main solver loop.
size_t
function_idx
;
for
(
size_t
i
=
0
;
i
<
num
.
max_calls
&&
std
::
chrono
::
steady_clock
::
now
()
<
time_to_stop
;
++
i
)
opt
.
get_best_function_eval
(
x
,
y
,
function_idx
);
{
// Undo any log-scaling that was applied to the variables before we output them.
auto
next
=
opt
.
get_next_x
();
matrix
<
double
,
0
,
1
>
x
=
next
.
x
();
// Undo any log-scaling that was applied to the variables before we pass them
// to the functions being optimized.
for
(
long
j
=
0
;
j
<
x
.
size
();
++
j
)
for
(
long
j
=
0
;
j
<
x
.
size
();
++
j
)
{
{
if
(
log_scale
[
next
.
function_idx
()
][
j
])
if
(
log_scale
[
function_idx
][
j
])
x
(
j
)
=
std
::
exp
(
x
(
j
));
x
(
j
)
=
std
::
exp
(
x
(
j
));
}
}
double
y
=
call_function_and_expand_args
(
functions
[
next
.
function_idx
()],
x
);
return
std
::
make_pair
(
function_idx
,
function_evaluation
(
x
,
y
/
ymult
));
next
.
set
(
y
);
}
}
}
// ----------------------------------------------------------------------------------------
matrix
<
double
,
0
,
1
>
x
;
template
<
double
y
;
typename
funct
size_t
function_idx
;
>
opt
.
get_best_function_eval
(
x
,
y
,
function_idx
);
std
::
pair
<
size_t
,
function_evaluation
>
find_max_global
(
// Undo any log-scaling that was applied to the variables before we output them.
std
::
vector
<
funct
>&
functions
,
for
(
long
j
=
0
;
j
<
x
.
size
();
++
j
)
std
::
vector
<
function_spec
>
specs
,
{
const
max_function_calls
num
,
if
(
log_scale
[
function_idx
][
j
])
const
std
::
chrono
::
nanoseconds
max_runtime
=
FOREVER
,
x
(
j
)
=
std
::
exp
(
x
(
j
));
double
solver_epsilon
=
0
}
)
return
std
::
make_pair
(
function_idx
,
function_evaluation
(
x
,
std
::
move
(
y
)));
{
return
impl
::
find_max_global
(
functions
,
std
::
move
(
specs
),
num
,
max_runtime
,
solver_epsilon
,
+
1
);
}
template
<
typename
funct
>
std
::
pair
<
size_t
,
function_evaluation
>
find_min_global
(
std
::
vector
<
funct
>&
functions
,
std
::
vector
<
function_spec
>
specs
,
const
max_function_calls
num
,
const
std
::
chrono
::
nanoseconds
max_runtime
=
FOREVER
,
double
solver_epsilon
=
0
)
{
return
impl
::
find_max_global
(
functions
,
std
::
move
(
specs
),
num
,
max_runtime
,
solver_epsilon
,
-
1
);
}
}
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
...
@@ -203,6 +237,24 @@ template <typename T> static auto go(T&& f, const matrix<double, 0, 1>& a) -> de
...
@@ -203,6 +237,24 @@ template <typename T> static auto go(T&& f, const matrix<double, 0, 1>& a) -> de
return
find_max_global
(
functions
,
std
::
move
(
specs
),
num
,
max_runtime
,
solver_epsilon
).
second
;
return
find_max_global
(
functions
,
std
::
move
(
specs
),
num
,
max_runtime
,
solver_epsilon
).
second
;
}
}
template
<
typename
funct
>
function_evaluation
find_min_global
(
funct
f
,
const
matrix
<
double
,
0
,
1
>&
bound1
,
const
matrix
<
double
,
0
,
1
>&
bound2
,
const
std
::
vector
<
bool
>&
is_integer_variable
,
const
max_function_calls
num
,
const
std
::
chrono
::
nanoseconds
max_runtime
=
FOREVER
,
double
solver_epsilon
=
0
)
{
std
::
vector
<
funct
>
functions
(
1
,
std
::
move
(
f
));
std
::
vector
<
function_spec
>
specs
(
1
,
function_spec
(
bound1
,
bound2
,
is_integer_variable
));
return
find_min_global
(
functions
,
std
::
move
(
specs
),
num
,
max_runtime
,
solver_epsilon
).
second
;
}
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template
<
template
<
...
@@ -220,6 +272,21 @@ template <typename T> static auto go(T&& f, const matrix<double, 0, 1>& a) -> de
...
@@ -220,6 +272,21 @@ template <typename T> static auto go(T&& f, const matrix<double, 0, 1>& a) -> de
return
find_max_global
(
std
::
move
(
f
),
bound1
,
bound2
,
is_integer_variable
,
num
,
FOREVER
,
solver_epsilon
);
return
find_max_global
(
std
::
move
(
f
),
bound1
,
bound2
,
is_integer_variable
,
num
,
FOREVER
,
solver_epsilon
);
}
}
template
<
typename
funct
>
function_evaluation
find_min_global
(
funct
f
,
const
matrix
<
double
,
0
,
1
>&
bound1
,
const
matrix
<
double
,
0
,
1
>&
bound2
,
const
std
::
vector
<
bool
>&
is_integer_variable
,
const
max_function_calls
num
,
double
solver_epsilon
)
{
return
find_min_global
(
std
::
move
(
f
),
bound1
,
bound2
,
is_integer_variable
,
num
,
FOREVER
,
solver_epsilon
);
}
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template
<
template
<
...
@@ -237,6 +304,21 @@ template <typename T> static auto go(T&& f, const matrix<double, 0, 1>& a) -> de
...
@@ -237,6 +304,21 @@ template <typename T> static auto go(T&& f, const matrix<double, 0, 1>& a) -> de
return
find_max_global
(
std
::
move
(
f
),
bound1
,
bound2
,
std
::
vector
<
bool
>
(
bound1
.
size
(),
false
),
num
,
max_runtime
,
solver_epsilon
);
return
find_max_global
(
std
::
move
(
f
),
bound1
,
bound2
,
std
::
vector
<
bool
>
(
bound1
.
size
(),
false
),
num
,
max_runtime
,
solver_epsilon
);
}
}
template
<
typename
funct
>
function_evaluation
find_min_global
(
funct
f
,
const
matrix
<
double
,
0
,
1
>&
bound1
,
const
matrix
<
double
,
0
,
1
>&
bound2
,
const
max_function_calls
num
,
const
std
::
chrono
::
nanoseconds
max_runtime
=
FOREVER
,
double
solver_epsilon
=
0
)
{
return
find_min_global
(
std
::
move
(
f
),
bound1
,
bound2
,
std
::
vector
<
bool
>
(
bound1
.
size
(),
false
),
num
,
max_runtime
,
solver_epsilon
);
}
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template
<
template
<
...
@@ -253,6 +335,20 @@ template <typename T> static auto go(T&& f, const matrix<double, 0, 1>& a) -> de
...
@@ -253,6 +335,20 @@ template <typename T> static auto go(T&& f, const matrix<double, 0, 1>& a) -> de
return
find_max_global
(
std
::
move
(
f
),
bound1
,
bound2
,
std
::
vector
<
bool
>
(
bound1
.
size
(),
false
),
num
,
FOREVER
,
solver_epsilon
);
return
find_max_global
(
std
::
move
(
f
),
bound1
,
bound2
,
std
::
vector
<
bool
>
(
bound1
.
size
(),
false
),
num
,
FOREVER
,
solver_epsilon
);
}
}
template
<
typename
funct
>
function_evaluation
find_min_global
(
funct
f
,
const
matrix
<
double
,
0
,
1
>&
bound1
,
const
matrix
<
double
,
0
,
1
>&
bound2
,
const
max_function_calls
num
,
double
solver_epsilon
)
{
return
find_min_global
(
std
::
move
(
f
),
bound1
,
bound2
,
std
::
vector
<
bool
>
(
bound1
.
size
(),
false
),
num
,
FOREVER
,
solver_epsilon
);
}
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template
<
template
<
...
@@ -270,6 +366,21 @@ template <typename T> static auto go(T&& f, const matrix<double, 0, 1>& a) -> de
...
@@ -270,6 +366,21 @@ template <typename T> static auto go(T&& f, const matrix<double, 0, 1>& a) -> de
return
find_max_global
(
std
::
move
(
f
),
matrix
<
double
,
0
,
1
>
({
bound1
}),
matrix
<
double
,
0
,
1
>
({
bound2
}),
num
,
max_runtime
,
solver_epsilon
);
return
find_max_global
(
std
::
move
(
f
),
matrix
<
double
,
0
,
1
>
({
bound1
}),
matrix
<
double
,
0
,
1
>
({
bound2
}),
num
,
max_runtime
,
solver_epsilon
);
}
}
template
<
typename
funct
>
function_evaluation
find_min_global
(
funct
f
,
const
double
bound1
,
const
double
bound2
,
const
max_function_calls
num
,
const
std
::
chrono
::
nanoseconds
max_runtime
=
FOREVER
,
double
solver_epsilon
=
0
)
{
return
find_min_global
(
std
::
move
(
f
),
matrix
<
double
,
0
,
1
>
({
bound1
}),
matrix
<
double
,
0
,
1
>
({
bound2
}),
num
,
max_runtime
,
solver_epsilon
);
}
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template
<
template
<
...
@@ -286,6 +397,20 @@ template <typename T> static auto go(T&& f, const matrix<double, 0, 1>& a) -> de
...
@@ -286,6 +397,20 @@ template <typename T> static auto go(T&& f, const matrix<double, 0, 1>& a) -> de
return
find_max_global
(
std
::
move
(
f
),
matrix
<
double
,
0
,
1
>
({
bound1
}),
matrix
<
double
,
0
,
1
>
({
bound2
}),
num
,
FOREVER
,
solver_epsilon
);
return
find_max_global
(
std
::
move
(
f
),
matrix
<
double
,
0
,
1
>
({
bound1
}),
matrix
<
double
,
0
,
1
>
({
bound2
}),
num
,
FOREVER
,
solver_epsilon
);
}
}
template
<
typename
funct
>
function_evaluation
find_min_global
(
funct
f
,
const
double
bound1
,
const
double
bound2
,
const
max_function_calls
num
,
double
solver_epsilon
)
{
return
find_min_global
(
std
::
move
(
f
),
matrix
<
double
,
0
,
1
>
({
bound1
}),
matrix
<
double
,
0
,
1
>
({
bound2
}),
num
,
FOREVER
,
solver_epsilon
);
}
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template
<
template
<
...
@@ -302,6 +427,20 @@ template <typename T> static auto go(T&& f, const matrix<double, 0, 1>& a) -> de
...
@@ -302,6 +427,20 @@ template <typename T> static auto go(T&& f, const matrix<double, 0, 1>& a) -> de
return
find_max_global
(
std
::
move
(
f
),
bound1
,
bound2
,
max_function_calls
(),
max_runtime
,
solver_epsilon
);
return
find_max_global
(
std
::
move
(
f
),
bound1
,
bound2
,
max_function_calls
(),
max_runtime
,
solver_epsilon
);
}
}
template
<
typename
funct
>
function_evaluation
find_min_global
(
funct
f
,
const
matrix
<
double
,
0
,
1
>&
bound1
,
const
matrix
<
double
,
0
,
1
>&
bound2
,
const
std
::
chrono
::
nanoseconds
max_runtime
,
double
solver_epsilon
=
0
)
{
return
find_min_global
(
std
::
move
(
f
),
bound1
,
bound2
,
max_function_calls
(),
max_runtime
,
solver_epsilon
);
}
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template
<
template
<
...
@@ -318,6 +457,20 @@ template <typename T> static auto go(T&& f, const matrix<double, 0, 1>& a) -> de
...
@@ -318,6 +457,20 @@ template <typename T> static auto go(T&& f, const matrix<double, 0, 1>& a) -> de
return
find_max_global
(
std
::
move
(
f
),
bound1
,
bound2
,
max_function_calls
(),
max_runtime
,
solver_epsilon
);
return
find_max_global
(
std
::
move
(
f
),
bound1
,
bound2
,
max_function_calls
(),
max_runtime
,
solver_epsilon
);
}
}
template
<
typename
funct
>
function_evaluation
find_min_global
(
funct
f
,
const
double
bound1
,
const
double
bound2
,
const
std
::
chrono
::
nanoseconds
max_runtime
,
double
solver_epsilon
=
0
)
{
return
find_min_global
(
std
::
move
(
f
),
bound1
,
bound2
,
max_function_calls
(),
max_runtime
,
solver_epsilon
);
}
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template
<
template
<
...
@@ -335,6 +488,21 @@ template <typename T> static auto go(T&& f, const matrix<double, 0, 1>& a) -> de
...
@@ -335,6 +488,21 @@ template <typename T> static auto go(T&& f, const matrix<double, 0, 1>& a) -> de
return
find_max_global
(
std
::
move
(
f
),
bound1
,
bound2
,
is_integer_variable
,
max_function_calls
(),
max_runtime
,
solver_epsilon
);
return
find_max_global
(
std
::
move
(
f
),
bound1
,
bound2
,
is_integer_variable
,
max_function_calls
(),
max_runtime
,
solver_epsilon
);
}
}
template
<
typename
funct
>
function_evaluation
find_min_global
(
funct
f
,
const
matrix
<
double
,
0
,
1
>&
bound1
,
const
matrix
<
double
,
0
,
1
>&
bound2
,
const
std
::
vector
<
bool
>&
is_integer_variable
,
const
std
::
chrono
::
nanoseconds
max_runtime
,
double
solver_epsilon
=
0
)
{
return
find_min_global
(
std
::
move
(
f
),
bound1
,
bound2
,
is_integer_variable
,
max_function_calls
(),
max_runtime
,
solver_epsilon
);
}
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
}
}
...
...
dlib/global_optimization/find_max_global_abstract.h
View file @
e273f515
...
@@ -53,7 +53,7 @@ namespace dlib
...
@@ -53,7 +53,7 @@ namespace dlib
/*!
/*!
WHAT THIS OBJECT REPRESENTS
WHAT THIS OBJECT REPRESENTS
This is a simple typed integer class used to strongly type the "max number
This is a simple typed integer class used to strongly type the "max number
of function calls" argument to find_max_global().
of function calls" argument to find_max_global()
and find_min_global()
.
!*/
!*/
...
@@ -136,6 +136,21 @@ namespace dlib
...
@@ -136,6 +136,21 @@ namespace dlib
optimizer.
optimizer.
!*/
!*/
template
<
typename
funct
>
std
::
pair
<
size_t
,
function_evaluation
>
find_min_global
(
std
::
vector
<
funct
>&
functions
,
const
std
::
vector
<
function_spec
>&
specs
,
const
max_function_calls
num
,
const
std
::
chrono
::
nanoseconds
max_runtime
=
FOREVER
,
double
solver_epsilon
=
0
);
/*!
This function is identical to the find_max_global() defined immediately above,
except that we perform minimization rather than maximization.
!*/
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template
<
template
<
...
@@ -204,9 +219,26 @@ namespace dlib
...
@@ -204,9 +219,26 @@ namespace dlib
optimizer.
optimizer.
!*/
!*/
template
<
typename
funct
>
function_evaluation
find_min_global
(
funct
f
,
const
matrix
<
double
,
0
,
1
>&
bound1
,
const
matrix
<
double
,
0
,
1
>&
bound2
,
const
std
::
vector
<
bool
>&
is_integer_variable
,
const
max_function_calls
num
,
const
std
::
chrono
::
nanoseconds
max_runtime
=
FOREVER
,
double
solver_epsilon
=
0
);
/*!
This function is identical to the find_max_global() defined immediately above,
except that we perform minimization rather than maximization.
!*/
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// The following functions are just convenient overloads for calling the above defined
// The following functions are just convenient overloads for calling the above defined
// find_max_global() routines.
// find_max_global()
and find_min_global()
routines.
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template
<
template
<
...
@@ -224,6 +256,21 @@ namespace dlib
...
@@ -224,6 +256,21 @@ namespace dlib
return
find_max_global
(
std
::
move
(
f
),
bound1
,
bound2
,
std
::
vector
<
bool
>
(
bound1
.
size
(),
false
),
num
,
FOREVER
,
solver_epsilon
);
return
find_max_global
(
std
::
move
(
f
),
bound1
,
bound2
,
std
::
vector
<
bool
>
(
bound1
.
size
(),
false
),
num
,
FOREVER
,
solver_epsilon
);
}
}
template
<
typename
funct
>
function_evaluation
find_min_global
(
funct
f
,
const
matrix
<
double
,
0
,
1
>&
bound1
,
const
matrix
<
double
,
0
,
1
>&
bound2
,
const
std
::
vector
<
bool
>&
is_integer_variable
,
const
max_function_calls
num
,
double
solver_epsilon
)
{
return
find_min_global
(
std
::
move
(
f
),
bound1
,
bound2
,
std
::
vector
<
bool
>
(
bound1
.
size
(),
false
),
num
,
FOREVER
,
solver_epsilon
);
}
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template
<
template
<
...
@@ -241,6 +288,21 @@ namespace dlib
...
@@ -241,6 +288,21 @@ namespace dlib
return
find_max_global
(
std
::
move
(
f
),
bound1
,
bound2
,
std
::
vector
<
bool
>
(
bound1
.
size
(),
false
),
num
,
max_runtime
,
solver_epsilon
);
return
find_max_global
(
std
::
move
(
f
),
bound1
,
bound2
,
std
::
vector
<
bool
>
(
bound1
.
size
(),
false
),
num
,
max_runtime
,
solver_epsilon
);
}
}
template
<
typename
funct
>
function_evaluation
find_min_global
(
funct
f
,
const
matrix
<
double
,
0
,
1
>&
bound1
,
const
matrix
<
double
,
0
,
1
>&
bound2
,
const
max_function_calls
num
,
const
std
::
chrono
::
nanoseconds
max_runtime
=
FOREVER
,
double
solver_epsilon
=
0
)
{
return
find_min_global
(
std
::
move
(
f
),
bound1
,
bound2
,
std
::
vector
<
bool
>
(
bound1
.
size
(),
false
),
num
,
max_runtime
,
solver_epsilon
);
}
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template
<
template
<
...
@@ -257,6 +319,20 @@ namespace dlib
...
@@ -257,6 +319,20 @@ namespace dlib
return
find_max_global
(
std
::
move
(
f
),
bound1
,
bound2
,
std
::
vector
<
bool
>
(
bound1
.
size
(),
false
),
num
,
FOREVER
,
solver_epsilon
);
return
find_max_global
(
std
::
move
(
f
),
bound1
,
bound2
,
std
::
vector
<
bool
>
(
bound1
.
size
(),
false
),
num
,
FOREVER
,
solver_epsilon
);
}
}
template
<
typename
funct
>
function_evaluation
find_min_global
(
funct
f
,
const
matrix
<
double
,
0
,
1
>&
bound1
,
const
matrix
<
double
,
0
,
1
>&
bound2
,
const
max_function_calls
num
,
double
solver_epsilon
)
{
return
find_min_global
(
std
::
move
(
f
),
bound1
,
bound2
,
std
::
vector
<
bool
>
(
bound1
.
size
(),
false
),
num
,
FOREVER
,
solver_epsilon
);
}
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template
<
template
<
...
@@ -274,6 +350,21 @@ namespace dlib
...
@@ -274,6 +350,21 @@ namespace dlib
return
find_max_global
(
std
::
move
(
f
),
matrix
<
double
,
0
,
1
>
({
bound1
}),
matrix
<
double
,
0
,
1
>
({
bound2
}),
num
,
max_runtime
,
solver_epsilon
);
return
find_max_global
(
std
::
move
(
f
),
matrix
<
double
,
0
,
1
>
({
bound1
}),
matrix
<
double
,
0
,
1
>
({
bound2
}),
num
,
max_runtime
,
solver_epsilon
);
}
}
template
<
typename
funct
>
function_evaluation
find_min_global
(
funct
f
,
const
double
bound1
,
const
double
bound2
,
const
max_function_calls
num
,
const
std
::
chrono
::
nanoseconds
max_runtime
=
FOREVER
,
double
solver_epsilon
=
0
)
{
return
find_min_global
(
std
::
move
(
f
),
matrix
<
double
,
0
,
1
>
({
bound1
}),
matrix
<
double
,
0
,
1
>
({
bound2
}),
num
,
max_runtime
,
solver_epsilon
);
}
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template
<
template
<
...
@@ -290,6 +381,20 @@ namespace dlib
...
@@ -290,6 +381,20 @@ namespace dlib
return
find_max_global
(
std
::
move
(
f
),
matrix
<
double
,
0
,
1
>
({
bound1
}),
matrix
<
double
,
0
,
1
>
({
bound2
}),
num
,
FOREVER
,
solver_epsilon
);
return
find_max_global
(
std
::
move
(
f
),
matrix
<
double
,
0
,
1
>
({
bound1
}),
matrix
<
double
,
0
,
1
>
({
bound2
}),
num
,
FOREVER
,
solver_epsilon
);
}
}
template
<
typename
funct
>
function_evaluation
find_min_global
(
funct
f
,
const
double
bound1
,
const
double
bound2
,
const
max_function_calls
num
,
double
solver_epsilon
)
{
return
find_min_global
(
std
::
move
(
f
),
matrix
<
double
,
0
,
1
>
({
bound1
}),
matrix
<
double
,
0
,
1
>
({
bound2
}),
num
,
FOREVER
,
solver_epsilon
);
}
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template
<
template
<
...
@@ -306,6 +411,20 @@ namespace dlib
...
@@ -306,6 +411,20 @@ namespace dlib
return
find_max_global
(
std
::
move
(
f
),
bound1
,
bound2
,
max_function_calls
(),
max_runtime
,
solver_epsilon
);
return
find_max_global
(
std
::
move
(
f
),
bound1
,
bound2
,
max_function_calls
(),
max_runtime
,
solver_epsilon
);
}
}
template
<
typename
funct
>
function_evaluation
find_min_global
(
funct
f
,
const
matrix
<
double
,
0
,
1
>&
bound1
,
const
matrix
<
double
,
0
,
1
>&
bound2
,
const
std
::
chrono
::
nanoseconds
max_runtime
,
double
solver_epsilon
=
0
)
{
return
find_min_global
(
std
::
move
(
f
),
bound1
,
bound2
,
max_function_calls
(),
max_runtime
,
solver_epsilon
);
}
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template
<
template
<
...
@@ -322,6 +441,20 @@ namespace dlib
...
@@ -322,6 +441,20 @@ namespace dlib
return
find_max_global
(
std
::
move
(
f
),
bound1
,
bound2
,
max_function_calls
(),
max_runtime
,
solver_epsilon
);
return
find_max_global
(
std
::
move
(
f
),
bound1
,
bound2
,
max_function_calls
(),
max_runtime
,
solver_epsilon
);
}
}
template
<
typename
funct
>
function_evaluation
find_min_global
(
funct
f
,
const
double
bound1
,
const
double
bound2
,
const
std
::
chrono
::
nanoseconds
max_runtime
,
double
solver_epsilon
=
0
)
{
return
find_min_global
(
std
::
move
(
f
),
bound1
,
bound2
,
max_function_calls
(),
max_runtime
,
solver_epsilon
);
}
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template
<
template
<
...
@@ -339,6 +472,21 @@ namespace dlib
...
@@ -339,6 +472,21 @@ namespace dlib
return
find_max_global
(
std
::
move
(
f
),
bound1
,
bound2
,
is_integer_variable
,
max_function_calls
(),
max_runtime
,
solver_epsilon
);
return
find_max_global
(
std
::
move
(
f
),
bound1
,
bound2
,
is_integer_variable
,
max_function_calls
(),
max_runtime
,
solver_epsilon
);
}
}
template
<
typename
funct
>
function_evaluation
find_min_global
(
funct
f
,
const
matrix
<
double
,
0
,
1
>&
bound1
,
const
matrix
<
double
,
0
,
1
>&
bound2
,
const
std
::
vector
<
bool
>&
is_integer_variable
,
const
std
::
chrono
::
nanoseconds
max_runtime
,
double
solver_epsilon
=
0
)
{
return
find_min_global
(
std
::
move
(
f
),
bound1
,
bound2
,
is_integer_variable
,
max_function_calls
(),
max_runtime
,
solver_epsilon
);
}
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
}
}
...
...
dlib/test/global_optimization.cpp
View file @
e273f515
...
@@ -213,6 +213,66 @@ namespace
...
@@ -213,6 +213,66 @@ namespace
DLIB_TEST_MSG
(
std
::
abs
(
result
.
y
-
21.9210397
)
<
0.0001
,
std
::
abs
(
result
.
y
-
21.9210397
));
DLIB_TEST_MSG
(
std
::
abs
(
result
.
y
-
21.9210397
)
<
0.0001
,
std
::
abs
(
result
.
y
-
21.9210397
));
}
}
// ----------------------------------------------------------------------------------------
void
test_find_min_global
(
)
{
print_spinner
();
auto
rosen
=
[](
const
matrix
<
double
,
0
,
1
>&
x
)
{
return
+
1
*
(
100
*
std
::
pow
(
x
(
1
)
-
x
(
0
)
*
x
(
0
),
2.0
)
+
std
::
pow
(
1
-
x
(
0
),
2
));
};
auto
result
=
find_min_global
(
rosen
,
{
0
,
0
},
{
2
,
2
},
max_function_calls
(
100
),
0
);
matrix
<
double
,
0
,
1
>
true_x
=
{
1
,
1
};
dlog
<<
LINFO
<<
"rosen: "
<<
trans
(
result
.
x
);
DLIB_TEST_MSG
(
min
(
abs
(
true_x
-
result
.
x
))
<
1e-5
,
min
(
abs
(
true_x
-
result
.
x
)));
print_spinner
();
result
=
find_min_global
(
rosen
,
{
0
,
0
},
{
2
,
2
},
max_function_calls
(
100
));
dlog
<<
LINFO
<<
"rosen: "
<<
trans
(
result
.
x
);
DLIB_TEST_MSG
(
min
(
abs
(
true_x
-
result
.
x
))
<
1e-5
,
min
(
abs
(
true_x
-
result
.
x
)));
print_spinner
();
result
=
find_min_global
(
rosen
,
{
0
,
0
},
{
2
,
2
},
std
::
chrono
::
seconds
(
5
));
dlog
<<
LINFO
<<
"rosen: "
<<
trans
(
result
.
x
);
DLIB_TEST_MSG
(
min
(
abs
(
true_x
-
result
.
x
))
<
1e-5
,
min
(
abs
(
true_x
-
result
.
x
)));
print_spinner
();
result
=
find_min_global
(
rosen
,
{
0
,
0
},
{
2
,
2
},
{
false
,
false
},
max_function_calls
(
100
));
dlog
<<
LINFO
<<
"rosen: "
<<
trans
(
result
.
x
);
DLIB_TEST_MSG
(
min
(
abs
(
true_x
-
result
.
x
))
<
1e-5
,
min
(
abs
(
true_x
-
result
.
x
)));
print_spinner
();
result
=
find_min_global
(
rosen
,
{
0
,
0
},
{
0.9
,
0.9
},
{
false
,
false
},
max_function_calls
(
100
));
true_x
=
{
0.9
,
0.81
};
dlog
<<
LINFO
<<
"rosen, bounded at 0.9: "
<<
trans
(
result
.
x
);
DLIB_TEST_MSG
(
min
(
abs
(
true_x
-
result
.
x
))
<
1e-5
,
min
(
abs
(
true_x
-
result
.
x
)));
print_spinner
();
result
=
find_min_global
([](
double
x
){
return
std
::
pow
(
x
-
2
,
2.0
);
},
-
10
,
10
,
max_function_calls
(
10
),
0
);
dlog
<<
LINFO
<<
"(x-2)^2: "
<<
trans
(
result
.
x
);
DLIB_TEST
(
result
.
x
.
size
()
==
1
);
DLIB_TEST
(
std
::
abs
(
result
.
x
-
2
)
<
1e-9
);
print_spinner
();
result
=
find_min_global
([](
double
x
){
return
std
::
pow
(
x
-
2
,
2.0
);
},
-
10
,
1
,
max_function_calls
(
10
));
dlog
<<
LINFO
<<
"(x-2)^2, bound at 1: "
<<
trans
(
result
.
x
);
DLIB_TEST
(
result
.
x
.
size
()
==
1
);
DLIB_TEST
(
std
::
abs
(
result
.
x
-
1
)
<
1e-9
);
print_spinner
();
result
=
find_min_global
([](
double
x
){
return
std
::
pow
(
x
-
2
,
2.0
);
},
-
10
,
1
,
std
::
chrono
::
seconds
(
2
));
dlog
<<
LINFO
<<
"(x-2)^2, bound at 1: "
<<
trans
(
result
.
x
);
DLIB_TEST
(
result
.
x
.
size
()
==
1
);
DLIB_TEST
(
std
::
abs
(
result
.
x
-
1
)
<
1e-9
);
print_spinner
();
result
=
find_min_global
([](
double
a
,
double
b
){
return
complex_holder_table
(
a
,
b
);},
{
-
10
,
-
10
},
{
10
,
10
},
max_function_calls
(
300
),
0
);
dlog
<<
LINFO
<<
"complex_holder_table y: "
<<
result
.
y
;
DLIB_TEST_MSG
(
std
::
abs
(
result
.
y
+
21.9210397
)
<
0.0001
,
std
::
abs
(
result
.
y
+
21.9210397
));
}
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
...
@@ -233,6 +293,7 @@ namespace
...
@@ -233,6 +293,7 @@ namespace
test_upper_bound_function
(
0.0
,
1e-1
);
test_upper_bound_function
(
0.0
,
1e-1
);
test_global_function_search
();
test_global_function_search
();
test_find_max_global
();
test_find_max_global
();
test_find_min_global
();
}
}
}
a
;
}
a
;
...
...
examples/optimization_ex.cpp
View file @
e273f515
...
@@ -263,14 +263,14 @@ int main() try
...
@@ -263,14 +263,14 @@ int main() try
// Finally, let's try the find_m
ax
_global() routine. Like find_min_bobyqa(),
// Finally, let's try the find_m
in
_global() routine. Like find_min_bobyqa(),
// this technique is specially designed to
opt
imize a function in the absence
// this technique is specially designed to
min
imize a function in the absence
// of derivative information. However, it is also designed to handle
// of derivative information. However, it is also designed to handle
// functions with many local optima. Where BOBYQA would get stuck at the
// functions with many local optima. Where BOBYQA would get stuck at the
// nearest local optima, find_m
ax
_global() won't. find_m
ax
_global() uses a
// nearest local optima, find_m
in
_global() won't. find_m
in
_global() uses a
// global optimization method based on a combination of non-parametric global
// global optimization method based on a combination of non-parametric global
// function modeling and BOBYQA style quadratic trust region modeling to
// function modeling and BOBYQA style quadratic trust region modeling to
// efficiently find a global m
ax
imizer. It usually does a good job with a
// efficiently find a global m
in
imizer. It usually does a good job with a
// relatively small number of calls to the function being optimized.
// relatively small number of calls to the function being optimized.
//
//
// You also don't have to give it a starting point or set any parameters,
// You also don't have to give it a starting point or set any parameters,
...
@@ -296,20 +296,20 @@ int main() try
...
@@ -296,20 +296,20 @@ int main() try
}
}
// Holder table function tilted towards 10,10 and with additional
// Holder table function tilted towards 10,10 and with additional
// high frequency terms to add more local optima.
// high frequency terms to add more local optima.
return
std
::
abs
(
sin
(
x0
)
*
cos
(
x1
)
*
exp
(
std
::
abs
(
1
-
std
::
sqrt
(
x0
*
x0
+
x1
*
x1
)
/
pi
)))
-
(
x0
+
x1
)
/
10
-
sin
(
x0
*
10
)
*
cos
(
x1
*
10
);
return
-
(
std
::
abs
(
sin
(
x0
)
*
cos
(
x1
)
*
exp
(
std
::
abs
(
1
-
std
::
sqrt
(
x0
*
x0
+
x1
*
x1
)
/
pi
)))
-
(
x0
+
x1
)
/
10
-
sin
(
x0
*
10
)
*
cos
(
x1
*
10
)
)
;
};
};
// To optimize this difficult function all we need to do is call
// To optimize this difficult function all we need to do is call
// find_m
ax
_global()
// find_m
in
_global()
auto
result
=
find_m
ax
_global
(
complex_holder_table
,
auto
result
=
find_m
in
_global
(
complex_holder_table
,
{
-
10
,
-
10
},
// lower bounds
{
-
10
,
-
10
},
// lower bounds
{
10
,
10
},
// upper bounds
{
10
,
10
},
// upper bounds
max_function_calls
(
300
));
max_function_calls
(
300
));
cout
.
precision
(
9
);
cout
.
precision
(
9
);
// These cout statements will show that find_m
ax
_global() found the
// These cout statements will show that find_m
in
_global() found the
// globally optimal solution to 9 digits of precision:
// globally optimal solution to 9 digits of precision:
cout
<<
"complex holder table function solution y (should be 21.9210397): "
<<
result
.
y
<<
endl
;
cout
<<
"complex holder table function solution y (should be
-
21.9210397): "
<<
result
.
y
<<
endl
;
cout
<<
"complex holder table function solution x:
\n
"
<<
result
.
x
<<
endl
;
cout
<<
"complex holder table function solution x:
\n
"
<<
result
.
x
<<
endl
;
}
}
catch
(
std
::
exception
&
e
)
catch
(
std
::
exception
&
e
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment