57template <concepts::
objective_function ObjectiveFunction>
71 using value_type =
typename objective_function_type::value_type;
103 "Lower and upper limits must have the same size.");
110 const auto half =
static_cast<value_type>(0.5);
135 for (
auto iter = std::rbegin(divided_rects);
136 iter != std::rend(divided_rects); ++iter) {
155 iteration_logger.template append<index_type>(
157 iteration_logger.template append<index_type>(
159 iteration_logger.template append<value_type>(
199 "Maximum number of function evaluations must be a positive "
215 "Minimum rate of improvement in the function value required "
216 "for potentially optimal rectangles must be a positive value.");
307 [](
bool elem) {
return elem; })) {
366 return left.value() > right.value();
401 std::vector<std::pair<std::size_t, value_type>> search_rects;
404 for (; ind <
rects_.size(); ++ind) {
405 if (!
rects_[ind].empty()) {
409 search_rects.emplace_back(ind, std::numeric_limits<value_type>::max());
412 for (; ind <
rects_.size(); ++ind) {
413 if (
rects_[ind].empty()) {
417 const auto& [last_ind, last_slope] = search_rects.back();
420 if (slope <= last_slope) {
421 search_rects.emplace_back(ind, slope);
424 search_rects.pop_back();
430 for (
auto iter = search_rects.begin(); iter != search_rects.end();) {
431 const auto& [ind, slope] = *iter;
432 if (
rects_[ind].top().value() - slope *
rects_[ind].top().dist() <=
436 iter = search_rects.erase(iter);
451 return (larger_rect.value() - smaller_rect.value()) /
452 (larger_rect.dist() - smaller_rect.dist());
461 if (index + 1 ==
rects_.size()) {
467 const auto [divided_dim, lower_value, upper_value] =
472 divided_lowest = origin.
lower()(divided_dim);
473 divided_highest = origin.
upper()(divided_dim);
475 divided_lowest = origin.
lower();
476 divided_highest = origin.
upper();
478 const auto [divided_lower, divided_upper] =
482 divided_dim, divided_lowest, divided_lower, lower_value));
484 divided_dim, divided_upper, divided_highest, upper_value));
486 divided_dim, divided_lower, divided_upper, origin.
value());
487 rects_[index + 1].push(std::move(origin));
498 -> std::tuple<index_type, value_type, value_type> {
499 value_type min_value = std::numeric_limits<value_type>::max();
510 width = rect.upper()[i] - rect.lower()[i];
512 width = rect.upper() - rect.lower();
514 static const auto one_third =
static_cast<value_type>(1.0 / 3.0);
517 static const auto half =
static_cast<value_type>(0.5);
521 origin_center = center[i];
523 origin_center = center;
529 center[i] = origin_center - diff;
531 center[i] = origin_center + diff;
538 if (lower_value < min_value) {
539 min_value = lower_value;
541 dim_lower_value = lower_value;
542 dim_upper_value = upper_value;
544 if (upper_value < min_value) {
545 min_value = upper_value;
547 dim_lower_value = lower_value;
548 dim_upper_value = upper_value;
552 return {dim, dim_lower_value, dim_upper_value};
563 value_type highest) -> std::pair<value_type, value_type> {
564 const auto width = highest - lowest;
565 static const auto one_third =
static_cast<value_type>(1.0 / 3.0);
566 static const auto two_thirds =
static_cast<value_type>(2.0 / 3.0);
567 return {lowest + one_third * width, lowest + two_thirds * width};
578 constexpr auto safe_limit =
579 std::numeric_limits<value_type>::max() * 1e-2;
580 if (!
isfinite(value) || value > safe_limit) {
594 std::vector<std::priority_queue<rectangle, std::vector<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.
auto divide(index_type dim, value_type lower, value_type upper, value_type value) const -> rectangle
Divide this object and return the divided rectangle.
rectangle(const variable_type &lower, const variable_type &upper, const value_type &value)
Constructor.
variable_type upper_
Element-wise upper limit.
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.
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.
std::vector< std::priority_queue< rectangle, std::vector< rectangle >, greater_rectangle > > rects_
Rectangles.
auto iterations() const noexcept -> index_type
Get the number of iterations.
dividing_rectangles< ObjectiveFunction > this_type
This class.
void change_objective_function(const objective_function_type &obj_fun)
Change the objective function.
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.
optimizer_base(logging::log_tag_view tag)
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.
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 rectangle &left, const rectangle &right) const -> bool
Compare rectangles.