60template <concepts::
objective_function ObjectiveFunction>
74 using value_type =
typename objective_function_type::value_type;
106 "Lower and upper limits must have the same size.");
113 const auto half =
static_cast<value_type>(0.5);
126 std::make_shared<rectangle>(variable_type::Zero(
dim_),
140 for (
auto iter = std::rbegin(divided_rects);
141 iter != std::rend(divided_rects); ++iter) {
160 iteration_logger.template append<index_type>(
162 iteration_logger.template append<index_type>(
164 iteration_logger.template append<value_type>(
204 "Maximum number of function evaluations must be a positive "
220 "Minimum rate of improvement in the function value required "
221 "for potentially optimal rectangles must be a positive value.");
312 [](
bool elem) {
return elem; })) {
329 -> std::shared_ptr<rectangle> {
330 auto ptr = std::make_shared<rectangle>(*
this);
370 [[nodiscard]]
auto operator()(
const std::shared_ptr<rectangle>& left,
371 const std::shared_ptr<rectangle>& right)
const ->
bool {
372 return left->value() > right->value();
407 std::vector<std::pair<std::size_t, value_type>> search_rects;
410 for (; ind <
rects_.size(); ++ind) {
411 if (!
rects_[ind].empty()) {
415 search_rects.emplace_back(ind, std::numeric_limits<value_type>::max());
418 for (; ind <
rects_.size(); ++ind) {
419 if (
rects_[ind].empty()) {
423 const auto& [last_ind, last_slope] = search_rects.back();
426 if (slope <= last_slope) {
427 search_rects.emplace_back(ind, slope);
430 search_rects.pop_back();
436 for (
auto iter = search_rects.begin(); iter != search_rects.end();) {
437 const auto& [ind, slope] = *iter;
438 if (
rects_[ind].top()->value() -
439 slope *
rects_[ind].top()->dist() <=
443 iter = search_rects.erase(iter);
458 return (larger_rect.value() - smaller_rect.value()) /
459 (larger_rect.dist() - smaller_rect.dist());
468 if (index + 1 ==
rects_.size()) {
471 const auto origin =
rects_[index].top();
474 const auto [divided_dim, lower_value, upper_value] =
479 divided_lowest = origin->lower()(divided_dim);
480 divided_highest = origin->upper()(divided_dim);
482 divided_lowest = origin->lower();
483 divided_highest = origin->upper();
485 const auto [divided_lower, divided_upper] =
488 rects_[index + 1].push(origin->divide(
489 divided_dim, divided_lowest, divided_lower, lower_value));
490 rects_[index + 1].push(origin->divide(
491 divided_dim, divided_upper, divided_highest, upper_value));
492 origin->divide_in_place(
493 divided_dim, divided_lower, divided_upper, origin->value());
494 rects_[index + 1].push(origin);
505 -> std::tuple<index_type, value_type, value_type> {
506 value_type min_value = std::numeric_limits<value_type>::max();
517 width = rect.upper()[i] - rect.lower()[i];
519 width = rect.upper() - rect.lower();
521 static const auto one_third =
static_cast<value_type>(1.0 / 3.0);
524 static const auto half =
static_cast<value_type>(0.5);
528 origin_center = center[i];
530 origin_center = center;
536 center[i] = origin_center - diff;
538 center[i] = origin_center + diff;
545 if (lower_value < min_value) {
546 min_value = lower_value;
548 dim_lower_value = lower_value;
549 dim_upper_value = upper_value;
551 if (upper_value < min_value) {
552 min_value = upper_value;
554 dim_lower_value = lower_value;
555 dim_upper_value = upper_value;
559 return {dim, dim_lower_value, dim_upper_value};
570 value_type highest) -> std::pair<value_type, value_type> {
571 const auto width = highest - lowest;
572 static const auto one_third =
static_cast<value_type>(1.0 / 3.0);
573 static const auto two_thirds =
static_cast<value_type>(2.0 / 3.0);
574 return {lowest + one_third * width, lowest + two_thirds * width};
585 constexpr auto safe_limit =
586 std::numeric_limits<value_type>::max() * 1e-2;
587 if (!
isfinite(value) || value > safe_limit) {
601 std::vector<std::priority_queue<std::shared_ptr<rectangle>,
Definition of assertion macros.
#define NUM_COLLECT_DEBUG_ASSERT(CONDITION)
Macro to check whether a condition is satisfied in debug build only.
Class to write logs of iterations.
Class of tags of logs without memory management.
auto logger() const noexcept -> const num_collect::logging::logger &
Access to the logger.
Class of hyper rectangle in DIRECT method.
std::vector< bool > is_divided_
Whether each dimension is divided.
rectangle(const variable_type &lower, const variable_type &upper, const value_type &value)
Constructor.
variable_type upper_
Element-wise upper limit.
auto divide(index_type dim, value_type lower, value_type upper, value_type value) const -> std::shared_ptr< rectangle >
Divide this object and return the divided rectangle.
value_type dist_
Distance between center point and end point.
void divide_in_place(index_type dim, value_type lower, value_type upper, value_type value)
Divide this object in place.
auto value() const -> const value_type &
Get function value at the center.
value_type value_
Function value at the center.
auto dist() const -> const value_type &
Get distance between center point and end point.
static const auto half
Half.
variable_type lower_
Element-wise lower limit.
auto upper() const -> const variable_type &
Get element-wise upper limit.
auto lower() const -> const variable_type &
Get element-wise lower limit.
auto is_divided() const -> const std::vector< bool > &
Get whether each dimension is divided.
Class of dividing rectangles (DIRECT) method jones1993 for optimization.
typename objective_function_type::variable_type variable_type
Type of variables.
value_type opt_value_
Current optimal value.
static auto separate_section(value_type lowest, value_type highest) -> std::pair< value_type, value_type >
Separate a section.
variable_type lower_
Element-wise lower limit.
variable_type width_
Element-wise width.
static auto calculate_slope(const rectangle &larger_rect, const rectangle &smaller_rect) -> value_type
Calculate slope.
auto evaluate_on(const variable_type &variable) -> value_type
Evaluate function value.
void configure_iteration_logger(logging::iterations::iteration_logger< this_type > &iteration_logger) const
Configure an iteration logger.
static auto correct_value_if_needed(value_type value) noexcept -> value_type
Correct function values if needed.
auto determine_rects() const -> std::vector< std::pair< std::size_t, value_type > >
Search rectangles to divide.
auto iterations() const noexcept -> index_type
Get the number of iterations.
void change_objective_function(const objective_function_type &obj_fun)
Change the objective function.
std::vector< std::priority_queue< std::shared_ptr< rectangle >, std::vector< std::shared_ptr< rectangle > >, greater_rectangle > > rects_
Rectangles.
objective_function_type obj_fun_
Objective function.
auto determine_divided_dimension(const rectangle &rect) -> std::tuple< index_type, value_type, value_type >
Determine the divided dimension of a rectangle.
variable_type upper_
Element-wise upper limit.
dividing_rectangles(const objective_function_type &obj_fun=objective_function_type())
Constructor.
void iterate()
Iterate the algorithm once.
value_type min_rate_imp_
Minimum rate of improvement in the function value required for potentially optimal rectangles.
index_type iterations_
Number of iterations.
ObjectiveFunction objective_function_type
Type of the objective function.
static const auto default_min_rate_imp
Default minimum rate of improvement in the function value required for potentially optimal rectangles...
void init(const variable_type &lower, const variable_type &upper)
Initialize the algorithm.
auto max_evaluations(index_type value) -> dividing_rectangles &
Set the maximum number of function evaluations.
void divide_rect(std::size_t index)
Divide a rectangle.
typename objective_function_type::value_type value_type
Type of function values.
variable_type opt_variable_
Current optimal variable.
index_type max_evaluations_
Maximum number of function evaluations.
auto is_stop_criteria_satisfied() const -> bool
Determine if stopping criteria of the algorithm are satisfied.
static constexpr index_type default_max_evaluations
Default maximum number of function evaluations.
index_type evaluations_
Number of function evaluations.
index_type dim_
Number of dimension.
auto opt_variable() const -> const variable_type &
Get current optimal variable.
auto evaluations() const noexcept -> index_type
Get the number of function evaluations.
auto min_rate_imp(value_type value) -> dividing_rectangles &
Set the minimum rate of improvement in the function value required for potentially optimal rectangles...
auto opt_value() const -> const value_type &
Get current optimal value.
Base class of implementations of optimization algorithms.
Definition of exceptions.
Definition of get_size class.
Definition of index_type type.
Definition of is_eigen_vector class.
Definition of isfinite function.
Definition of iteration_logger class.
Definition of log_tag_view class.
Definition of macros for logging.
std::ptrdiff_t index_type
Type of indices in this library.
auto norm(const Matrix &matrix)
Calculate norm of a matrix.
auto get_size(const Matrix &matrix) -> index_type
Get the size.
auto isfinite(const T &val) -> bool
Check whether a number is finite.
Namespace of optimization algorithms.
constexpr auto dividing_rectangles_tag
Tag of dividing_rectangles.
auto safe_cast(const From &value) -> To
Cast safely.
constexpr bool is_eigen_vector_v
Get whether a type is a Eigen's vector.
Definition of norm class.
Definition of objective_function concept.
Definition of optimizer_base class.
Definition of NUM_COLLECT_PRECONDITION macro.
#define NUM_COLLECT_PRECONDITION(CONDITION,...)
Check whether a precondition is satisfied and throw an exception if not.
Definition of safe_cast function.
Class to compare rectangles.
auto operator()(const std::shared_ptr< rectangle > &left, const std::shared_ptr< rectangle > &right) const -> bool
Compare rectangles.