174 lines
5.2 KiB
C++
174 lines
5.2 KiB
C++
// Copyright (C) 2008 Davis E. King (davis@dlib.net)
|
|
// License: Boost Software License See LICENSE.txt for the full license.
|
|
#ifndef DLIB_OPTIMIZATIOn_STOP_STRATEGIES_H_
|
|
#define DLIB_OPTIMIZATIOn_STOP_STRATEGIES_H_
|
|
|
|
#include <cmath>
|
|
#include <limits>
|
|
#include "../matrix.h"
|
|
#include "../algs.h"
|
|
#include "optimization_stop_strategies_abstract.h"
|
|
#include <iostream>
|
|
|
|
namespace dlib
|
|
{
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
class objective_delta_stop_strategy
|
|
{
|
|
public:
|
|
explicit objective_delta_stop_strategy (
|
|
double min_delta = 1e-7
|
|
) : _verbose(false), _been_used(false), _min_delta(min_delta), _max_iter(0), _cur_iter(0), _prev_funct_value(0)
|
|
{
|
|
DLIB_ASSERT (
|
|
min_delta >= 0,
|
|
"\t objective_delta_stop_strategy(min_delta)"
|
|
<< "\n\t min_delta can't be negative"
|
|
<< "\n\t min_delta: " << min_delta
|
|
);
|
|
}
|
|
|
|
objective_delta_stop_strategy (
|
|
double min_delta,
|
|
unsigned long max_iter
|
|
) : _verbose(false), _been_used(false), _min_delta(min_delta), _max_iter(max_iter), _cur_iter(0), _prev_funct_value(0)
|
|
{
|
|
DLIB_ASSERT (
|
|
min_delta >= 0 && max_iter > 0,
|
|
"\t objective_delta_stop_strategy(min_delta, max_iter)"
|
|
<< "\n\t min_delta can't be negative and max_iter can't be 0"
|
|
<< "\n\t min_delta: " << min_delta
|
|
<< "\n\t max_iter: " << max_iter
|
|
);
|
|
}
|
|
|
|
objective_delta_stop_strategy& be_verbose(
|
|
)
|
|
{
|
|
_verbose = true;
|
|
return *this;
|
|
}
|
|
|
|
template <typename T>
|
|
bool should_continue_search (
|
|
const T& ,
|
|
const double funct_value,
|
|
const T&
|
|
)
|
|
{
|
|
if (_verbose)
|
|
{
|
|
using namespace std;
|
|
cout << "iteration: " << _cur_iter << " objective: " << funct_value << endl;
|
|
}
|
|
|
|
++_cur_iter;
|
|
if (_been_used)
|
|
{
|
|
// Check if we have hit the max allowable number of iterations. (but only
|
|
// check if _max_iter is enabled (i.e. not 0)).
|
|
if (_max_iter != 0 && _cur_iter > _max_iter)
|
|
return false;
|
|
|
|
// check if the function change was too small
|
|
if (std::abs(funct_value - _prev_funct_value) < _min_delta)
|
|
return false;
|
|
}
|
|
|
|
_been_used = true;
|
|
_prev_funct_value = funct_value;
|
|
return true;
|
|
}
|
|
|
|
private:
|
|
bool _verbose;
|
|
|
|
bool _been_used;
|
|
double _min_delta;
|
|
unsigned long _max_iter;
|
|
unsigned long _cur_iter;
|
|
double _prev_funct_value;
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
class gradient_norm_stop_strategy
|
|
{
|
|
public:
|
|
explicit gradient_norm_stop_strategy (
|
|
double min_norm = 1e-7
|
|
) : _verbose(false), _min_norm(min_norm), _max_iter(0), _cur_iter(0)
|
|
{
|
|
DLIB_ASSERT (
|
|
min_norm >= 0,
|
|
"\t gradient_norm_stop_strategy(min_norm)"
|
|
<< "\n\t min_norm can't be negative"
|
|
<< "\n\t min_norm: " << min_norm
|
|
);
|
|
}
|
|
|
|
gradient_norm_stop_strategy (
|
|
double min_norm,
|
|
unsigned long max_iter
|
|
) : _verbose(false), _min_norm(min_norm), _max_iter(max_iter), _cur_iter(0)
|
|
{
|
|
DLIB_ASSERT (
|
|
min_norm >= 0 && max_iter > 0,
|
|
"\t gradient_norm_stop_strategy(min_norm, max_iter)"
|
|
<< "\n\t min_norm can't be negative and max_iter can't be 0"
|
|
<< "\n\t min_norm: " << min_norm
|
|
<< "\n\t max_iter: " << max_iter
|
|
);
|
|
}
|
|
|
|
gradient_norm_stop_strategy& be_verbose(
|
|
)
|
|
{
|
|
_verbose = true;
|
|
return *this;
|
|
}
|
|
|
|
template <typename T>
|
|
bool should_continue_search (
|
|
const T& ,
|
|
const double funct_value,
|
|
const T& funct_derivative
|
|
)
|
|
{
|
|
if (_verbose)
|
|
{
|
|
using namespace std;
|
|
cout << "iteration: " << _cur_iter << " objective: " << funct_value << " gradient norm: " << length(funct_derivative) << endl;
|
|
}
|
|
|
|
++_cur_iter;
|
|
|
|
// Check if we have hit the max allowable number of iterations. (but only
|
|
// check if _max_iter is enabled (i.e. not 0)).
|
|
if (_max_iter != 0 && _cur_iter > _max_iter)
|
|
return false;
|
|
|
|
// check if the gradient norm is too small
|
|
if (length(funct_derivative) < _min_norm)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
private:
|
|
bool _verbose;
|
|
|
|
double _min_norm;
|
|
unsigned long _max_iter;
|
|
unsigned long _cur_iter;
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
}
|
|
|
|
#endif // DLIB_OPTIMIZATIOn_STOP_STRATEGIES_H_
|
|
|