#pragma once #include #include "autoopt/optimization_problem.hpp" namespace autoopt { template struct btls_parameters { T step_decrease = T{0.5}; T step_increase = T{1.2}; T sufficient_decrease = T{1e-2}; T tolerance = T{1e-10}; size_t max_iters = 2000; }; template void btls(optimization_problem& problem, const btls_parameters& params = btls_parameters()) { Eigen::VectorX& x = problem.x(); T step_size = T{1.0}; for (size_t iter = 0; iter < params.max_iters; ++iter) { T obj_value = problem.objective(x); Eigen::VectorX grad = problem.gradient(x); Eigen::MatrixX hess = problem.hessian(x); Eigen::VectorX step_dir = -hess.ldlt().solve(grad).normalized(); // Eigen::VectorX step_dir = -grad.normalized(); auto decrease_condition = [&] { T new_obj = problem.objective(x + step_size * step_dir); return std::isnan(new_obj) || (new_obj > obj_value - std::abs(params.sufficient_decrease * step_size * grad.dot(step_dir))); }; while (decrease_condition()) { step_size *= params.step_decrease; } x += step_size * step_dir; step_size = step_size * params.step_increase; if (step_size < params.tolerance) { break; } } problem.x() = x; } } // namespace autoopt