numerical-collection-cpp 0.10.0
A collection of algorithms in numerical analysis implemented in C++
Loading...
Searching...
No Matches
backtracking_line_searcher.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 <type_traits> // IWYU pragma: keep
23
30
31namespace num_collect::opt {
32
38template <concepts::differentiable_objective_function ObjectiveFunction>
40
46template <
48class backtracking_line_searcher<ObjectiveFunction> {
49public:
51 using objective_function_type = ObjectiveFunction;
52
54 using variable_type = typename objective_function_type::variable_type;
55
57 using value_type = typename objective_function_type::value_type;
58
59 static_assert(std::is_same_v<typename variable_type::Scalar, value_type>,
60 "This class assumes that scalars in Eigen::Matrix class is same as "
61 "value_type");
62
70 : obj_fun_(obj_fun) {}
71
77 void init(const variable_type& init_variable) {
78 variable_ = init_variable;
79 obj_fun_.evaluate_on(variable_);
80 evaluations_ = 1;
81 }
82
88 void search(const variable_type& direction) {
89 step_ = init_step;
90
91 const variable_type prev_var = variable_;
92 const value_type prev_value = obj_fun_.value();
93 const value_type step_coeff =
94 armijo_coeff_ * obj_fun_.gradient().dot(direction);
95
96 // prevent infinite loops
97 constexpr index_type max_loops = 1000;
98 for (index_type i = 0; i < max_loops; ++i) {
99 variable_ = prev_var + step_ * direction;
100 obj_fun_.evaluate_on(variable_);
101 ++evaluations_;
102 if (obj_fun_.value() <= prev_value + step_ * step_coeff) {
103 return;
104 }
105 step_ *= step_scale_;
106 }
107
109 algorithm_failure, "failed to search step size");
110 }
111
117 [[nodiscard]] auto obj_fun() -> objective_function_type& {
118 return obj_fun_;
119 }
120
126 [[nodiscard]] auto obj_fun() const -> const objective_function_type& {
127 return obj_fun_;
128 }
129
135 [[nodiscard]] auto opt_variable() const -> const variable_type& {
136 return variable_;
137 }
138
144 [[nodiscard]] auto opt_value() const -> const value_type& {
145 return obj_fun_.value();
146 }
147
153 [[nodiscard]] auto gradient() const -> const variable_type& {
154 return obj_fun_.gradient();
155 }
156
162 [[nodiscard]] auto evaluations() const -> index_type {
163 return evaluations_;
164 }
165
171 [[nodiscard]] auto last_step() const -> value_type { return step_; }
172
180 NUM_COLLECT_PRECONDITION(static_cast<value_type>(0) < value &&
181 value < static_cast<value_type>(1),
182 "Coefficient in Armijo rule must be in the range (0, 1).");
183 armijo_coeff_ = value;
184 return *this;
185 }
186
194 NUM_COLLECT_PRECONDITION(static_cast<value_type>(0) < value &&
195 value < static_cast<value_type>(1),
196 "Ratio to scale step sizes must be in the range (0, 1).");
197 step_scale_ = value;
198 return *this;
199 }
200
201private:
204
206 variable_type variable_{};
207
209 static inline const auto init_step = static_cast<value_type>(1.0);
210
212 value_type step_{init_step};
213
215 static inline const auto default_armijo_coeff =
216 static_cast<value_type>(0.1);
217
219 value_type armijo_coeff_{default_armijo_coeff};
220
222 static inline const auto default_step_scale = static_cast<value_type>(0.5);
223
225 value_type step_scale_{default_step_scale};
226
228 index_type evaluations_{0};
229};
230
231} // namespace num_collect::opt
Class of exception on failure in algorithm.
Definition exception.h:93
auto armijo_coeff(value_type value) -> backtracking_line_searcher &
Set the coefficient in Armijo rule.
auto obj_fun() const -> const objective_function_type &
Access objective function.
auto gradient() const -> const variable_type &
Get gradient for current optimal variable.
typename objective_function_type::variable_type variable_type
Type of variables.
auto step_scale(value_type value) -> backtracking_line_searcher &
Set the ratio to scale step sizes.
auto obj_fun() -> objective_function_type &
Access objective function.
void search(const variable_type &direction)
Search step size.
auto opt_value() const -> const value_type &
Get current optimal value.
auto evaluations() const -> index_type
Get the number of function evaluations.
backtracking_line_searcher(const objective_function_type &obj_fun=objective_function_type())
Constructor.
typename objective_function_type::value_type value_type
Type of function values.
auto opt_variable() const -> const variable_type &
Get current optimal variable.
ObjectiveFunction objective_function_type
Type of the objective function.
Class to perform backtracking line search.
Concept of multi-variate first-order differentiable objective functions in optimization.
Definition of differentiable_objective_function concept.
Definition of exceptions.
Definition of index_type type.
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_differentiable_objective_function concept.
std::ptrdiff_t index_type
Type of indices in this library.
Definition index_type.h:33
Namespace of optimization algorithms.
Definition of NUM_COLLECT_PRECONDITION macro.
#define NUM_COLLECT_PRECONDITION(CONDITION,...)
Check whether a precondition is satisfied and throw an exception if not.