From 9fcc79d006c2c7091afaf72aaf8cf6de7c46a7b8 Mon Sep 17 00:00:00 2001 From: mzhelyez Date: Sat, 18 Oct 2025 10:46:19 +0200 Subject: [PATCH] fixed argument container peeling for gcc --- .../detail/differentiable_opt_utilties.hpp | 41 +++--- .../detail/line_search_policies.hpp | 2 +- .../detail/rdiff_optimization_policies.hpp | 21 ++- include/boost/math/optimization/lbfgs.hpp | 34 ++--- test/test_lbfgs.cpp | 135 +++++++++--------- 5 files changed, 117 insertions(+), 116 deletions(-) diff --git a/include/boost/math/optimization/detail/differentiable_opt_utilties.hpp b/include/boost/math/optimization/detail/differentiable_opt_utilties.hpp index bd245164a..9e7e989ef 100644 --- a/include/boost/math/optimization/detail/differentiable_opt_utilties.hpp +++ b/include/boost/math/optimization/detail/differentiable_opt_utilties.hpp @@ -37,33 +37,36 @@ using update_policy_real_type_t = /** @brief> get realtype from argument container * */ template -struct argument_container_t; +struct argument_container_t +{ + using type = typename argument_container_t::type>::type; +}; -template class Container, - typename ValueType, - typename... Args> -struct argument_container_t> -{ - using type = ValueType; -}; -template class Container, - typename RealType, - int N, - typename... Args> -struct argument_container_t, Args...>> -{ - using type = RealType; -}; template struct argument_container_t> { - using type = ValueType; + using type = ValueType; }; -template +template struct argument_container_t, N>> { - using type = RealType; + using type = RealType; +}; + +template class Container, typename ValueType, typename... Args> +struct argument_container_t> +{ + using type = ValueType; +}; + +template class Container, + typename RealType, + std::size_t N, + typename... Args> +struct argument_container_t, Args...>> +{ + using type = RealType; }; /******************************************************************************/ /** @brief simple blas helpers diff --git a/include/boost/math/optimization/detail/line_search_policies.hpp b/include/boost/math/optimization/detail/line_search_policies.hpp index d1bb457ab..0dd85867b 100644 --- a/include/boost/math/optimization/detail/line_search_policies.hpp +++ b/include/boost/math/optimization/detail/line_search_policies.hpp @@ -123,7 +123,7 @@ public: RealType f_x) const { RealType gTp0 = dot(g, p); - RealType alpha_prev = 0; + RealType alpha_prev{0}; RealType f_prev = f_x; RealType alpha = alpha0_; diff --git a/include/boost/math/optimization/detail/rdiff_optimization_policies.hpp b/include/boost/math/optimization/detail/rdiff_optimization_policies.hpp index e1860db6b..5258728bd 100644 --- a/include/boost/math/optimization/detail/rdiff_optimization_policies.hpp +++ b/include/boost/math/optimization/detail/rdiff_optimization_policies.hpp @@ -8,7 +8,7 @@ #include #include #include - +#include namespace boost { namespace math { namespace optimization { @@ -75,16 +75,15 @@ struct reverse_mode_gradient_evaluation_policy template struct tape_initializer_rvar { - template - void operator()(ArgumentContainer&) const noexcept - { - static_assert( - std::is_same>::value, - "ArgumentContainer::value_type must be rdiff::rvar"); - auto& tape = rdiff::get_active_tape(); - tape.add_checkpoint(); - } + template + void operator()(ArgumentContainer& x) const noexcept + { + static_assert(std::is_same>::value, + "ArgumentContainer::value_type must be rdiff::rvar"); + auto& tape = rdiff::get_active_tape(); + tape.add_checkpoint(); + } }; template diff --git a/include/boost/math/optimization/lbfgs.hpp b/include/boost/math/optimization/lbfgs.hpp index 73a8f56f8..57b70d21a 100644 --- a/include/boost/math/optimization/lbfgs.hpp +++ b/include/boost/math/optimization/lbfgs.hpp @@ -107,7 +107,7 @@ struct lbfgs_update_policy ArgumentType>::value>::type> void operator()(ArgumentType& x, RealType pk, RealType alpha) { - x.get_value() += alpha * pk; + x.get_value() += alpha * pk; } template auto make_lbfgs(Objective&& obj, ArgumentContainer& x, std::size_t m = 10) { - using RealType = typename argument_container_t::type; - return lbfgs, - tape_initializer_rvar, - reverse_mode_function_eval_policy, - reverse_mode_gradient_evaluation_policy, - strong_wolfe_line_search_policy>( - std::forward(obj), - x, - m, - tape_initializer_rvar{}, - reverse_mode_function_eval_policy{}, - reverse_mode_gradient_evaluation_policy{}, - lbfgs_update_policy{}, - strong_wolfe_line_search_policy{}); + using RealType = typename argument_container_t::type; + return lbfgs, + tape_initializer_rvar, + reverse_mode_function_eval_policy, + reverse_mode_gradient_evaluation_policy, + strong_wolfe_line_search_policy>( + std::forward(obj), + x, + m, + tape_initializer_rvar{}, + reverse_mode_function_eval_policy{}, + reverse_mode_gradient_evaluation_policy{}, + lbfgs_update_policy{}, + strong_wolfe_line_search_policy{}); } template rng{ T(-10), T(10) }; - std::array, 2> x; - x[0] = rng.next(); - x[1] = rng.next(); + RandomSample rng{T(-10), T(10)}; + std::array, 2> x; + x[0] = rng.next(); + x[1] = rng.next(); - auto opt = bopt::make_lbfgs(&rosenbrock_saddle>, x, M); + auto opt = bopt::make_lbfgs(&rosenbrock_saddle>, x, M); - auto result = minimize(opt); - for (auto& xi : x) { - BOOST_REQUIRE_CLOSE(xi, T{ 1.0 }, eps); - } + auto result = minimize(opt); + for (auto& xi : x) { + BOOST_REQUIRE_CLOSE(xi, T{1.0}, eps); + } } // Custom initialization policy that zeros out the parameters template struct zero_init_policy { - void operator()(std::vector& x) const noexcept - { - std::fill(x.begin(), x.end(), RealType{ 0 }); - } + void operator()(std::vector& x) const noexcept + { + std::fill(x.begin(), x.end(), RealType{0}); + } }; template struct analytic_objective_eval_pol { - template - RealType operator()(Objective&& objective, ArgumentContainer& x) - { - return objective(x); - } + template + RealType operator()(Objective&& objective, ArgumentContainer& x) + { + return objective(x); + } }; template struct analytic_gradient_eval_pol { - template - void operator()(Objective&& obj_f, - ArgumentContainer& x, - FunctionEvaluationPolicy&& f_eval_pol, - RealType& obj_v, - std::vector& grad_container) - { - RealType v = f_eval_pol(obj_f, x); - obj_v = v; - grad_container.resize(x.size()); - for (size_t i = 0; i < x.size(); ++i) { - grad_container[i] = 2 * x[i]; + template + void operator()(Objective&& obj_f, + ArgumentContainer& x, + FunctionEvaluationPolicy&& f_eval_pol, + RealType& obj_v, + std::vector& grad_container) + { + RealType v = f_eval_pol(obj_f, x); + obj_v = v; + grad_container.resize(x.size()); + for (size_t i = 0; i < x.size(); ++i) { + grad_container[i] = 2 * x[i]; + } } - } }; BOOST_AUTO_TEST_CASE_TEMPLATE(custom_init_lbfgs_test, T, all_float_types) { - constexpr size_t M = 8; - const T eps = T{ 1e-6 }; + constexpr size_t M = 8; + const T eps = T{1e-6}; - RandomSample rng{ T(-5), T(5) }; - std::array, 2> x; - x[0] = rng.next(); - x[1] = rng.next(); + RandomSample rng{T(-5), T(5)}; + std::array, 2> x; + x[0] = rng.next(); + x[1] = rng.next(); - auto opt = bopt::make_lbfgs(&rosenbrock_saddle>, - x, - M, - bopt::costant_initializer_rvar(0.0)); - auto result = minimize(opt); + auto opt = bopt::make_lbfgs(&rosenbrock_saddle>, + x, + M, + bopt::costant_initializer_rvar(0.0)); + auto result = minimize(opt); - for (auto& xi : x) { - BOOST_REQUIRE_CLOSE(xi, T{ 1.0 }, eps); - } + for (auto& xi : x) { + BOOST_REQUIRE_CLOSE(xi, T{1.0}, eps); + } } BOOST_AUTO_TEST_CASE_TEMPLATE(analytic_lbfgs_test, T, all_float_types) { - constexpr size_t M = 10; - const T eps = T{ 1e-3 }; + constexpr size_t M = 10; + const T eps = T{1e-3}; - RandomSample rng{ T(-5), T(5) }; - std::vector x(3); - for (auto& xi : x) - xi = rng.next(); + RandomSample rng{T(-5), T(5)}; + std::vector x(3); + for (auto& xi : x) + xi = rng.next(); - auto opt = bopt::make_lbfgs(&quadratic, // Objective - x, // Arguments - M, // History size - zero_init_policy{}, // Initialization - analytic_objective_eval_pol{}, // Function eval - analytic_gradient_eval_pol{}, // Gradient eval - bopt::armijo_line_search_policy{}); + auto opt = bopt::make_lbfgs(&quadratic, // Objective + x, // Arguments + M, // History size + zero_init_policy{}, // Initialization + analytic_objective_eval_pol{}, // Function eval + analytic_gradient_eval_pol{}, // Gradient eval + bopt::armijo_line_search_policy{}); - auto result = minimize(opt); + auto result = minimize(opt); - for (auto& xi : x) { - BOOST_REQUIRE_SMALL(xi, eps); - } + for (auto& xi : x) { + BOOST_REQUIRE_SMALL(xi, eps); + } } BOOST_AUTO_TEST_SUITE_END()