numerical-collection-cpp 0.10.0
A collection of algorithms in numerical analysis implemented in C++
Loading...
Searching...
No Matches
sampling_optimizer.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 <cstddef>
23#include <limits>
24#include <vector>
25
36
37namespace num_collect::opt {
38
40constexpr auto sampling_optimizer_tag =
41 logging::log_tag_view("num_collect::opt::sampling_optimizer");
42
48template <concepts::objective_function ObjectiveFunction>
50
56template <concepts::single_variate_objective_function ObjectiveFunction>
57class sampling_optimizer<ObjectiveFunction>
58 : public optimizer_base<sampling_optimizer<ObjectiveFunction>> {
59public:
62
64 using objective_function_type = ObjectiveFunction;
65
67 using variable_type = typename objective_function_type::variable_type;
68
70 using value_type = typename objective_function_type::value_type;
71
79 : optimizer_base<sampling_optimizer<ObjectiveFunction>>(
81 obj_fun_(obj_fun) {}
82
89 obj_fun_ = obj_fun;
90 }
91
98 void init(const variable_type& lower, const variable_type& upper) {
99 lower_ = lower;
100 upper_ = upper;
101 iterations_ = 0;
102 evaluations_ = 0;
103
104 // Without this, solve() causes segmentation fault.
105 iterate();
106 }
107
111 void iterate() {
112 const auto num_samples_size_t =
113 util::safe_cast<std::size_t>(num_samples_);
114 samples_.resize(num_samples_size_t);
115 values_.resize(num_samples_size_t);
116
117 value_type min_val = std::numeric_limits<value_type>::max();
118
119 for (std::size_t i = 0; i < num_samples_size_t; ++i) {
120 const variable_type rate = static_cast<variable_type>(i) /
121 static_cast<variable_type>(num_samples_ - 1);
122 const variable_type variable = lower_ + (upper_ - lower_) * rate;
123
124 obj_fun_.evaluate_on(variable);
125 const value_type value = obj_fun_.value();
126
127 samples_[i] = variable;
128 values_[i] = value;
129
130 if (value < min_val) {
131 min_val = value;
132 ind_opt_sample_ = i;
133 }
134
135 ++evaluations_;
136 }
137
138 if (ind_opt_sample_ > 0) {
139 lower_ = samples_[ind_opt_sample_ - 1];
140 }
141 if (ind_opt_sample_ < num_samples_size_t - 1) {
142 upper_ = samples_[ind_opt_sample_ + 1];
143 }
144
145 ++iterations_;
146 }
147
151 [[nodiscard]] auto is_stop_criteria_satisfied() const -> bool {
152 return iterations_ >= max_iterations_;
153 }
154
159 sampling_optimizer<ObjectiveFunction>>& iteration_logger) const {
160 iteration_logger.template append<index_type>(
161 "Iter.", &this_type::iterations);
162 iteration_logger.template append<index_type>(
163 "Eval.", &this_type::evaluations);
164 iteration_logger.template append<value_type>(
165 "Value", &this_type::opt_value);
166 }
167
171 [[nodiscard]] auto opt_variable() const -> const variable_type& {
172 return samples_[ind_opt_sample_];
173 }
174
178 [[nodiscard]] auto opt_value() const -> const value_type& {
179 return values_[ind_opt_sample_];
180 }
181
187 [[nodiscard]] auto upper() const -> const variable_type& { return upper_; }
188
194 [[nodiscard]] auto lower() const -> const variable_type& { return lower_; }
195
199 [[nodiscard]] auto iterations() const noexcept -> index_type {
200 return iterations_;
201 }
202
206 [[nodiscard]] auto evaluations() const noexcept -> index_type {
207 return evaluations_;
208 }
209
217 NUM_COLLECT_PRECONDITION(value >= 2, this->logger(),
218 "Number of samples must be at least two.");
219 num_samples_ = value;
220 return *this;
221 }
222
230 NUM_COLLECT_PRECONDITION(value > 0, this->logger(),
231 "Maximum number of iterations must be a positive integer.");
232 max_iterations_ = value;
233 return *this;
234 }
235
236private:
239
241 variable_type lower_{static_cast<variable_type>(0)};
242
244 variable_type upper_{static_cast<variable_type>(1)};
245
247 std::vector<variable_type> samples_{};
248
250 std::vector<value_type> values_{};
251
253 std::size_t ind_opt_sample_{0};
254
256 static constexpr index_type default_num_samples = 21;
257
259 index_type num_samples_{default_num_samples};
260
262 static constexpr index_type default_max_iterations = 3;
263
265 index_type max_iterations_{default_max_iterations};
266
268 index_type iterations_{0};
269
271 index_type evaluations_{0};
272};
273
274} // namespace num_collect::opt
Class of tags of logs without memory management.
Base class of implementations of optimization algorithms.
Class to perform optimization using samples of objective functions.
void configure_iteration_logger(logging::iterations::iteration_logger< sampling_optimizer< ObjectiveFunction > > &iteration_logger) const
Configure an iteration logger.
objective_function_type obj_fun_
Objective function.
auto upper() const -> const variable_type &
Get the current upper limit.
sampling_optimizer(const objective_function_type &obj_fun=objective_function_type())
Constructor.
auto iterations() const noexcept -> index_type
Get the number of iterations.
auto opt_value() const -> const value_type &
Get current optimal value.
auto evaluations() const noexcept -> index_type
Get the number of function evaluations.
void change_objective_function(const objective_function_type &obj_fun)
Change the objective function.
auto lower() const -> const variable_type &
Get the current lower limit.
typename objective_function_type::variable_type variable_type
Type of variables.
auto max_iterations(index_type value) -> sampling_optimizer &
Set the maximum number of iterations.
auto num_samples(index_type value) -> sampling_optimizer &
Set the number of samples.
auto is_stop_criteria_satisfied() const -> bool
Determine if stopping criteria of the algorithm are satisfied.
typename objective_function_type::value_type value_type
Type of function values.
ObjectiveFunction objective_function_type
Type of the objective function.
auto opt_variable() const -> const variable_type &
Get current optimal variable.
void init(const variable_type &lower, const variable_type &upper)
Initialize the algorithm.
Class to perform optimization using samples of objective functions.
Definition of exceptions.
Definition of index_type type.
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.
Definition index_type.h:33
Namespace of optimization algorithms.
constexpr auto sampling_optimizer_tag
Tag of golden_section_search.
auto safe_cast(const From &value) -> To
Cast safely.
Definition safe_cast.h:54
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.
Definition of single_variate_objective_function concept.