numerical-collection-cpp 0.10.0
A collection of algorithms in numerical analysis implemented in C++
Loading...
Searching...
No Matches
adaptive_diagonal_curves.h
Go to the documentation of this file.
1/*
2 * Copyright 2021 MusicScience37 (Kenta Kabashima)
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
20#pragma once
21
22#include <algorithm>
23#include <cmath>
24#include <cstddef>
25#include <cstdint>
26#include <iterator>
27#include <limits>
28#include <memory>
29#include <queue>
30#include <string_view>
31#include <utility>
32#include <vector>
33
34#include <hash_tables/maps/multi_open_address_map_st.h>
35
49
51
54 logging::log_tag_view("num_collect::opt::adaptive_diagonal_curves");
55
56namespace impl {
57
64template <concepts::objective_function ObjectiveFunction>
66
73template <concepts::multi_variate_objective_function ObjectiveFunction>
74class adc_sample_dict<ObjectiveFunction> {
75public:
77 using objective_function_type = ObjectiveFunction;
78
80 using variable_type = typename objective_function_type::variable_type;
81
83 using value_type = typename objective_function_type::value_type;
84
92 : obj_fun_(obj_fun) {
93 constexpr std::size_t initial_space = 10000;
94 value_dict_.reserve_approx(initial_space);
95 }
96
103 obj_fun_ = obj_fun;
104 }
105
112 void init(const variable_type& lower, const variable_type& upper) {
113 NUM_COLLECT_PRECONDITION(lower.size() == upper.size(),
114 "Element-wise limits must have the same size.");
115 NUM_COLLECT_PRECONDITION((lower.array() < upper.array()).all(),
116 "Element-wise limits must satisfy lower < upper for each element.");
117
118 lower_ = lower;
119 width_ = upper - lower;
120 dim_ = lower.size();
121 value_dict_.clear();
122 }
123
132 [[nodiscard]] auto operator()(const ternary_vector& point) -> value_type {
133 return value_dict_.get_or_create_with_factory(
134 point, [this, &point] { return evaluate_on(point); });
135 }
136
142 [[nodiscard]] auto dim() const -> index_type { return dim_; }
143
147 [[nodiscard]] auto opt_variable() const -> const variable_type& {
148 return opt_variable_;
149 }
150
157 [[nodiscard]] auto opt_point() const -> const ternary_vector& {
158 return opt_point_;
159 }
160
164 [[nodiscard]] auto opt_value() const -> const value_type& {
165 return opt_value_;
166 }
167
171 [[nodiscard]] auto evaluations() const noexcept -> index_type {
172 return static_cast<index_type>(value_dict_.size());
173 }
174
175private:
184 [[nodiscard]] auto evaluate_on(const ternary_vector& point) -> value_type {
185 NUM_COLLECT_DEBUG_ASSERT(point.dim() == dim_);
186 auto var = variable_type(dim_);
187 for (index_type i = 0; i < dim_; ++i) {
188 var(i) = lower_(i) +
189 width_(i) * point.elem_as<typename variable_type::Scalar>(i);
190 }
191 obj_fun_.evaluate_on(var);
192
193 if (value_dict_.empty() || obj_fun_.value() < opt_value_) {
194 opt_point_ = point;
195 opt_variable_ = var;
196 opt_value_ = obj_fun_.value();
197 }
198
199 return obj_fun_.value();
200 }
201
204
207
210
212 index_type dim_{0};
213
215 hash_tables::maps::multi_open_address_map_st<impl::ternary_vector,
216 value_type>
217 value_dict_{};
218
220 ternary_vector opt_point_{};
221
223 variable_type opt_variable_{};
224
226 value_type opt_value_{};
227};
228
235template <base::concepts::real_scalar Value>
237public:
239 using value_type = Value;
240
250
256 [[nodiscard]] auto vertex() const -> const impl::ternary_vector& {
257 return vertex_;
258 }
259
265 [[nodiscard]] auto ave_value() const -> const value_type& {
266 return ave_value_;
267 }
268
274 [[nodiscard]] auto sample_points() const
277 }
278
284 [[nodiscard]] auto dist() const -> value_type {
285 auto squared_sum = static_cast<value_type>(0);
286 for (index_type i = 0; i < vertex_.dim(); ++i) {
287 using std::pow;
288 squared_sum +=
289 pow(static_cast<value_type>(3), -2 * (vertex_.digits(i) - 1));
290 }
291 using std::sqrt;
292 const auto half = static_cast<value_type>(0.5);
293 return half * sqrt(squared_sum);
294 }
295
302 [[nodiscard]] static auto determine_sample_points(
303 const ternary_vector& lowest_vertex)
304 -> std::pair<ternary_vector, ternary_vector> {
305 auto res = std::make_pair(lowest_vertex, lowest_vertex);
306 const auto dim = lowest_vertex.dim();
307 for (index_type i = 0; i < dim; ++i) {
308 const auto digits = lowest_vertex.digits(i);
309 NUM_COLLECT_DEBUG_ASSERT(digits > 0);
310 std::uint_fast32_t one_count = 0;
311 for (index_type j = 0; j < digits; ++j) {
312 if (lowest_vertex(i, j) == ternary_vector::digit_type{1}) {
313 ++one_count;
314 }
315 }
316
317 auto last_digit = // NOLINTNEXTLINE: false positive
318 static_cast<std::int_fast32_t>(lowest_vertex(i, digits - 1));
319 ++last_digit;
320 constexpr std::uint_fast32_t odd_mask = 1;
321 if ((one_count & odd_mask) == odd_mask) {
322 res.first(i, digits - 1) =
323 static_cast<ternary_vector::digit_type>(last_digit);
324 } else {
325 res.second(i, digits - 1) =
326 static_cast<ternary_vector::digit_type>(last_digit);
327 }
328 }
329 normalize_point(res.first);
330 normalize_point(res.second);
331 return res;
332 }
333
334private:
340 static void normalize_point(ternary_vector& point) {
341 for (index_type i = 0; i < point.dim(); ++i) {
342 for (index_type j = point.digits(i) - 1; j > 0; --j) {
343 if (point(i, j) == ternary_vector::digit_type{3}) {
344 point(i, j) = 0;
345 std::int_fast32_t temp =
346 point(i, j - 1); // NOLINT: false positive
347 ++temp;
348 point(i, j - 1) =
349 static_cast<ternary_vector::digit_type>(temp);
350 }
351 }
352 }
353 }
354
357
360};
361
368template <base::concepts::real_scalar Value>
370public:
372 using value_type = Value;
373
376
378 using rectangle_pointer_type = std::shared_ptr<rectangle_type>;
379
386
394 rects_.push(std::move(rect));
395 }
396
403 [[nodiscard]] auto min_rect() const -> const rectangle_pointer_type& {
405 return rects_.top();
406 }
407
413 [[nodiscard]] auto empty() const -> bool { return rects_.empty(); }
414
421 [[nodiscard]] auto pop() -> rectangle_pointer_type {
423 auto rect = rects_.top();
424 rects_.pop();
425 return rect;
426 }
427
433 [[nodiscard]] auto dist() const -> const value_type& { return dist_; }
434
435private:
439 struct greater {
447 [[nodiscard]] auto operator()(const rectangle_pointer_type& left,
448 const rectangle_pointer_type& right) const -> bool {
449 return left->ave_value() > right->ave_value();
450 }
451 };
452
454 using queue_type = std::priority_queue<rectangle_pointer_type,
455 std::vector<rectangle_pointer_type>, greater>;
456
459
462};
463
464} // namespace impl
465
472template <concepts::objective_function ObjectiveFunction>
474 : public optimizer_base<adaptive_diagonal_curves<ObjectiveFunction>> {
475public:
478
480 using objective_function_type = ObjectiveFunction;
481
483 using variable_type = typename objective_function_type::variable_type;
484
486 using value_type = typename objective_function_type::value_type;
487
491 enum class state_type : std::uint8_t {
492 none,
493 local,
494 local_last,
495 global,
497 };
498
505 [[nodiscard]] static auto state_name(state_type state) -> std::string_view {
506 switch (state) {
507 case state_type::none:
508 return "none";
510 return "local";
512 return "local (last)";
514 return "global";
516 return "global (last)";
517 default:
518 return "invalid process";
519 }
520 }
521
532
539 value_dict_.change_objective_function(obj_fun);
540 }
541
548 void init(const variable_type& lower, const variable_type& upper) {
549 value_dict_.init(lower, upper);
550 groups_.clear();
551 iterations_ = 0;
553
554 // Initialize groups_, optimal_value_, optimal_group_index_.
556
557 // prec_optimal_value_, prec_optimal_group_index, and
558 // iterations_in_current_phase_ are initialized in switch_state().
559 }
560
564 void iterate() {
565 switch_state();
566
567 switch (state_) {
570 break;
573 break;
576 break;
579 break;
580 default:
582 "invalid state (bug in adaptive_diagonal_curve class)");
583 }
584
585 ++iterations_;
586 }
587
591 [[nodiscard]] auto is_stop_criteria_satisfied() const -> bool {
592 return evaluations() >= max_evaluations_;
593 }
594
600 const {
601 iteration_logger.template append<index_type>(
602 "Iter.", &this_type::iterations);
603 iteration_logger.template append<index_type>(
604 "Eval.", &this_type::evaluations);
605 iteration_logger.template append<value_type>(
606 "Value", &this_type::opt_value);
607 constexpr index_type state_width = 15;
608 iteration_logger
609 .template append<std::string_view>(
611 ->width(state_width);
612 }
613
617 [[nodiscard]] auto opt_variable() const -> const variable_type& {
618 return value_dict_.opt_variable();
619 }
620
624 [[nodiscard]] auto opt_value() const -> const value_type& {
625 return value_dict_.opt_value();
626 }
627
631 [[nodiscard]] auto iterations() const noexcept -> index_type {
632 return iterations_;
633 }
634
638 [[nodiscard]] auto evaluations() const noexcept -> index_type {
639 return value_dict_.evaluations();
640 }
641
647 [[nodiscard]] auto last_state() const noexcept -> state_type {
648 return state_;
649 }
650
656 [[nodiscard]] auto last_state_name() const noexcept -> std::string_view {
657 return state_name(last_state());
658 }
659
667 NUM_COLLECT_PRECONDITION(value > 0, this->logger(),
668 "Maximum number of function evaluations must be a positive "
669 "integer.");
670
671 max_evaluations_ = value;
672 return *this;
673 }
674
683 NUM_COLLECT_PRECONDITION(value > static_cast<value_type>(0),
684 this->logger(),
685 "Minimum rate of improvement in the function value required for "
686 "potentially optimal rectangles must be a positive value.");
687 min_rate_imp_ = value;
688 return *this;
689 }
690
699 NUM_COLLECT_PRECONDITION(value > static_cast<value_type>(0),
700 this->logger(),
701 "Rate of function value used to check whether the function value "
702 "decreased in the current phase must be a positive value.");
703 decrease_rate_bound_ = value;
704 return *this;
705 }
706
707private:
710
713
716
721 const index_type dim = value_dict_.dim();
722 auto point = impl::ternary_vector{dim};
723 for (index_type i = 0; i < dim; ++i) {
724 point.push_back(i, 0);
725 }
726
727 const auto [lower_vertex, upper_vertex] =
728 rectangle_type::determine_sample_points(point);
729 const auto lower_vertex_value = value_dict_(lower_vertex);
730 const auto upper_vertex_value = value_dict_(upper_vertex);
731 const auto ave_value = half * (lower_vertex_value + upper_vertex_value);
732 const auto rect = std::make_shared<rectangle_type>(point, ave_value);
733
734 groups_.emplace_back(rect->dist());
735 groups_.front().push(rect);
736 using std::min;
737 optimal_value_ = min(lower_vertex_value, upper_vertex_value);
739 }
740
747 using std::abs;
748 switch (state_) {
753 }
754 return;
757 return;
765 return;
766 }
769 util::safe_cast<index_type>((static_cast<std::size_t>(2)
772 return;
773 }
774 return;
782 return;
783 }
787 return;
788 default:
793 }
794 }
795
800 using std::abs;
807 return;
808 }
809
810 const bool is_optimal_smallest =
811 (optimal_group_index_ == groups_.size() - 1);
812 const bool is_all_smallest =
813 std::all_of(std::begin(groups_), std::end(groups_) - 1,
814 [](const group_type& group) { return group.empty(); });
815 if ((!is_optimal_smallest) || is_all_smallest) {
819 return;
820 }
821
826 }
827
832 const std::size_t max_group_index = std::max<std::size_t>(
833 std::max<std::size_t>(prec_optimal_group_index_, 1) - 1,
836 min_nonempty_group_index(), max_group_index);
837 }
838
843 const std::size_t max_group_index = std::max<std::size_t>(
846 min_nonempty_group_index(), max_group_index);
847 }
848
853 const std::size_t max_group_index =
854 (std::max<std::size_t>(
857 2;
859 min_nonempty_group_index(), max_group_index);
860 }
861
866
872 [[nodiscard]] auto min_nonempty_group_index() const -> std::size_t {
873 for (std::size_t i = 0; i < groups_.size(); ++i) {
874 if (!groups_[i].empty()) {
875 return i;
876 }
877 }
879 "adaptive_diagonal_curves::init is not called.");
880 }
881
889 std::size_t min_group, std::size_t max_group) {
890 const auto search_rect =
891 determine_nondominated_rectangles(min_group, max_group);
892 for (auto iter = std::rbegin(search_rect);
893 iter != std::rend(search_rect); ++iter) {
894 divide_rectangle(iter->first);
895 }
896 }
897
906 std::size_t min_group, std::size_t max_group) const
907 -> std::vector<std::pair<std::size_t, value_type>> {
908 NUM_COLLECT_DEBUG_ASSERT(min_group <= max_group);
909 NUM_COLLECT_DEBUG_ASSERT(max_group < groups_.size());
910 NUM_COLLECT_DEBUG_ASSERT(!groups_[min_group].empty());
911
912 std::vector<std::pair<std::size_t, value_type>> search_rects;
913 search_rects.emplace_back(
914 min_group, std::numeric_limits<value_type>::max());
915
916 // convex full scan
917 for (std::size_t i = min_group + 1; i <= max_group; ++i) {
918 if (groups_[i].empty()) {
919 continue;
920 }
921 while (true) {
922 const auto& [last_i, last_slope] = search_rects.back();
923 const auto slope = calculate_slope(last_i, i);
924 if (slope <= last_slope) {
925 search_rects.emplace_back(i, slope);
926 break;
927 }
928 search_rects.pop_back();
929 }
930 }
931
932 // remove rectangles which won't update optimal value
933 using std::abs;
934 const auto value_bound =
936 for (auto iter = search_rects.begin(); iter != search_rects.end();) {
937 const auto& [ind, slope] = *iter;
938 if (groups_[ind].min_rect()->ave_value() -
939 slope * groups_[ind].dist() <=
940 value_bound) {
941 ++iter;
942 } else {
943 iter = search_rects.erase(iter);
944 }
945 }
946
947 return search_rects;
948 }
949
957 [[nodiscard]] auto calculate_slope(
958 std::size_t group_ind1, std::size_t group_ind2) const -> value_type {
959 return (groups_[group_ind1].min_rect()->ave_value() -
960 groups_[group_ind2].min_rect()->ave_value()) /
961 (groups_[group_ind1].dist() - groups_[group_ind2].dist());
962 }
963
969 void divide_rectangle(std::size_t group_ind) {
970 impl::ternary_vector vertex = groups_[group_ind].pop()->vertex();
971 index_type divided_dim = 1;
972 for (; divided_dim < vertex.dim(); ++divided_dim) {
973 if (vertex.digits(divided_dim) < vertex.digits(0)) {
974 break;
975 }
976 }
977 if (divided_dim == vertex.dim()) {
978 divided_dim = 0;
979 }
980
981 vertex.push_back(divided_dim, 0);
982 const auto rect0 = create_rect(vertex, group_ind + 1);
983 vertex(divided_dim, vertex.digits(divided_dim) - 1) = 1;
984 const auto rect1 = create_rect(vertex, group_ind + 1);
985 vertex(divided_dim, vertex.digits(divided_dim) - 1) = 2;
986 const auto rect2 = create_rect(vertex, group_ind + 1);
987
988 if (groups_.size() == group_ind + 1) {
989 groups_.emplace_back(rect0->dist());
990 }
991 groups_[group_ind + 1].push(rect0);
992 groups_[group_ind + 1].push(rect1);
993 groups_[group_ind + 1].push(rect2);
994 }
995
1003 [[nodiscard]] auto create_rect(const impl::ternary_vector& vertex,
1004 std::size_t group_ind) -> std::shared_ptr<rectangle_type> {
1005 const auto [vertex1, vertex2] =
1006 rectangle_type::determine_sample_points(vertex);
1007 const auto value1 = value_dict_(vertex1);
1008 const auto value2 = value_dict_(vertex2);
1009 const auto ave_value = half * (value1 + value2);
1010 if (value1 < optimal_value_) {
1011 optimal_value_ = value1;
1012 optimal_group_index_ = group_ind;
1013 } else if (value1 <= optimal_value_ &&
1014 group_ind > optimal_group_index_) {
1015 optimal_group_index_ = group_ind;
1016 }
1017 if (value2 < optimal_value_) {
1018 optimal_value_ = value2;
1019 optimal_group_index_ = group_ind;
1020 } else if (value2 <= optimal_value_ &&
1021 group_ind > optimal_group_index_) {
1022 optimal_group_index_ = group_ind;
1023 }
1024 return std::make_shared<rectangle_type>(vertex, ave_value);
1025 }
1026
1028 static inline const auto half = static_cast<value_type>(0.5);
1029
1032
1034 std::vector<group_type> groups_{};
1035
1038
1041
1048
1050 std::size_t optimal_group_index_{0};
1051
1054
1060
1067
1069 static constexpr index_type default_max_evaluations = 10000;
1070
1073
1078 static inline const auto default_min_rate_imp =
1079 static_cast<value_type>(1e-4);
1080
1086
1091 static inline const auto default_decrease_rate_bound =
1092 static_cast<value_type>(0.01);
1093
1099};
1100
1101} // namespace num_collect::opt
Definition of assertion macros.
#define NUM_COLLECT_DEBUG_ASSERT(CONDITION)
Macro to check whether a condition is satisfied in debug build only.
Definition assert.h:75
Class of exception on failure in algorithm.
Definition exception.h:93
Class of exception on not satisfying a precondition.
Definition exception.h:77
Class of tags of logs without memory management.
auto logger() const noexcept -> const num_collect::logging::logger &
Access to the logger.
Class of adaptive diagonal curves (ADC) method sergeyev2006 for optimization.
auto calculate_slope(std::size_t group_ind1, std::size_t group_ind2) const -> value_type
Calculate slope.
value_type decrease_rate_bound_
Rate of function value used to check whether the function value decreased in the current phase.
std::size_t optimal_group_index_
Index of the group in which the optimal solution exists.
std::size_t prec_optimal_group_index_
Index of the group in which the old optimal solution at the start of the current phase exists.
void iterate_locally()
Iterate once in the local phase (not last iteration).
void create_first_rectangle()
Create the first hyper-rectangle.
std::vector< group_type > groups_
Groups of hyper-rectangles.
value_type min_rate_imp_
Minimum rate of improvement in the function value required for potentially optimal rectangles.
index_type max_evaluations_
Maximum number of function evaluations.
auto max_evaluations(index_type value) -> adaptive_diagonal_curves &
Set the maximum number of function evaluations.
auto min_rate_imp(value_type value) -> adaptive_diagonal_curves &
Set the minimum rate of improvement in the function value required for potentially optimal rectangles...
void divide_rectangle(std::size_t group_ind)
Divide a hyper-rectangle.
dict_type value_dict_
Dictionary of sampled points.
void init(const variable_type &lower, const variable_type &upper)
Initialize the algorithm.
auto last_state() const noexcept -> state_type
Get the last state.
static const auto default_min_rate_imp
Default minimum rate of improvement in the function value required for potentially optimal rectangles...
auto is_stop_criteria_satisfied() const -> bool
Determine if stopping criteria of the algorithm are satisfied.
void configure_iteration_logger(logging::iterations::iteration_logger< this_type > &iteration_logger) const
Configure an iteration logger.
void switch_state()
Switch to the next state if necessary.
auto iterations() const noexcept -> index_type
Get the number of iterations.
void switch_state_on_local_last()
Switch to the next state if necessary in local_last state.
typename objective_function_type::variable_type variable_type
Type of variables.
auto evaluations() const noexcept -> index_type
Get the number of function evaluations.
adaptive_diagonal_curves(const objective_function_type &obj_fun=objective_function_type())
Constructor.
auto opt_value() const -> const value_type &
Get current optimal value.
void change_objective_function(const objective_function_type &obj_fun)
Change the objective function.
void iterate_globally()
Iterate once in the global phase (not last iteration).
static const auto default_decrease_rate_bound
Default rate of function value used to check whether the function value decreased in the current phas...
static auto state_name(state_type state) -> std::string_view
Convert a state to string.
static constexpr index_type default_max_evaluations
Default maximum number of function evaluations.
auto determine_nondominated_rectangles(std::size_t min_group, std::size_t max_group) const -> std::vector< std::pair< std::size_t, value_type > >
Determine nondominated hyper-rectangles.
auto create_rect(const impl::ternary_vector &vertex, std::size_t group_ind) -> std::shared_ptr< rectangle_type >
Create a hyper-rectangle.
void divide_nondominated_rectangles(std::size_t min_group, std::size_t max_group)
Divide nondominated hyper-rectangles.
typename group_type::rectangle_type rectangle_type
Type of hyper-rectangles.
auto decrease_rate_bound(value_type value) -> adaptive_diagonal_curves &
Set the rate of function value used to check whether the function value decreased in the current phas...
auto opt_variable() const -> const variable_type &
Get current optimal variable.
void iterate_globally_last()
Iterate once at teh last of the global phase.
value_type prec_optimal_value_
Old optimal value at the start of the current phase.
void iterate_locally_last()
Iterate once at the last of the local phase.
index_type iterations_in_current_phase_
Number of iterations in the current phase.
ObjectiveFunction objective_function_type
Type of the objective function.
auto min_nonempty_group_index() const -> std::size_t
Get the minimum index of non-empty groups.
state_type
Enumeration of states in ADC method.
@ global
Global phase (not last iteration).
typename objective_function_type::value_type value_type
Type of function values.
auto last_state_name() const noexcept -> std::string_view
Get the name of the last state.
Class of groups in sergeyev2006 for num_collect::opt::adaptive_diagonal_curves.
auto dist() const -> const value_type &
Get the distance between center point and vertex.
value_type dist_
Distance between center point and vertex.
auto pop() -> rectangle_pointer_type
Pick out the hyper-rectangle with the smallest average of function values at diagonal vertices.
Value value_type
Type of function values.
std::shared_ptr< rectangle_type > rectangle_pointer_type
Type of pointers of hyper-rectangles.
adc_rectangle< value_type > rectangle_type
Type of hyper-rectangles.
void push(rectangle_pointer_type rect)
Add a hyper-rectangle to this group.
auto empty() const -> bool
Check whether this group is empty.
auto min_rect() const -> const rectangle_pointer_type &
Access the hyper-rectangle with the smallest average of function values at diagonal vertices.
std::priority_queue< rectangle_pointer_type, std::vector< rectangle_pointer_type >, greater > queue_type
Type of queues of rectangles.
Class of rectangles as proposed in sergeyev2000 for num_collect::opt::adaptive_diagonal_curves.
auto ave_value() const -> const value_type &
Get the average function value.
auto sample_points() const -> std::pair< ternary_vector, ternary_vector >
Determine sampling points.
auto dist() const -> value_type
Get the distance between center point and vertex.
adc_rectangle(const impl::ternary_vector &vertex, const value_type &ave_value)
Constructor.
static void normalize_point(ternary_vector &point)
Normalize point.
impl::ternary_vector vertex_
A vertex with lower first component.
auto vertex() const -> const impl::ternary_vector &
Get the vertex with lower first component.
value_type ave_value_
Average function value.
static auto determine_sample_points(const ternary_vector &lowest_vertex) -> std::pair< ternary_vector, ternary_vector >
Determine sampling points.
auto opt_variable() const -> const variable_type &
Get current optimal variable.
auto evaluate_on(const ternary_vector &point) -> value_type
Evaluate function value.
ObjectiveFunction objective_function_type
Type of the objective function.
auto opt_value() const -> const value_type &
Get current optimal value.
typename objective_function_type::variable_type variable_type
Type of variables.
auto evaluations() const noexcept -> index_type
Get the number of function evaluations.
adc_sample_dict(const objective_function_type &obj_fun=objective_function_type())
Constructor.
void change_objective_function(const objective_function_type &obj_fun)
Change the objective function.
void init(const variable_type &lower, const variable_type &upper)
Initialize this object.
auto opt_point() const -> const ternary_vector &
Get the point in the unit hyper-cube for the current optimal variable.
auto operator()(const ternary_vector &point) -> value_type
Evaluate or get function value.
auto dim() const -> index_type
Get the number of dimension.
typename objective_function_type::value_type value_type
Type of function values.
Class of dictionaries of sampling points in num_collect::opt::adaptive_diagonal_curves.
Class of vectors of ternary floating-point numbers.
auto digits(index_type dim) const -> index_type
Get the number of digits of a dimension.
std::int8_t digit_type
Type of a digit.
void push_back(index_type dim, digit_type digit)
Add a digit to a dimension.
auto dim() const -> index_type
Get the number of dimensions.
Base class of implementations of optimization algorithms.
Definition of exceptions.
Definition of index_type type.
Definition of iteration_logger class.
Definition of log_tag_view class.
Definition of macros for logging.
#define NUM_COLLECT_LOG_AND_THROW(EXCEPTION_TYPE,...)
Write an error log and throw an exception for an error.
Definition of multi_variate_objective_function concept.
std::ptrdiff_t index_type
Type of indices in this library.
Definition index_type.h:33
Namespace of optimization algorithms.
constexpr auto adaptive_diagonal_curves_tag
Tag of adaptive_diagonal_curves.
auto safe_cast(const From &value) -> To
Cast safely.
Definition safe_cast.h:54
STL namespace.
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 real_scalar concept.
Definition of safe_cast function.
auto operator()(const rectangle_pointer_type &left, const rectangle_pointer_type &right) const -> bool
Compare rectangles.
Definition of ternary_vector class.