2
0
mirror of https://github.com/boostorg/math.git synced 2026-02-24 04:02:18 +00:00

fixed argument container peeling for gcc

This commit is contained in:
mzhelyez
2025-10-18 10:46:19 +02:00
parent 49e74cf881
commit 9fcc79d006
5 changed files with 117 additions and 116 deletions

View File

@@ -37,33 +37,36 @@ using update_policy_real_type_t =
/** @brief> get realtype from argument container
* */
template<class Container>
struct argument_container_t;
struct argument_container_t
{
using type = typename argument_container_t<typename std::decay<Container>::type>::type;
};
template<template<typename, typename...> class Container,
typename ValueType,
typename... Args>
struct argument_container_t<Container<ValueType, Args...>>
{
using type = ValueType;
};
template<template<typename, typename...> class Container,
typename RealType,
int N,
typename... Args>
struct argument_container_t<Container<rdiff::rvar<RealType, N>, Args...>>
{
using type = RealType;
};
template<typename ValueType, std::size_t N>
struct argument_container_t<std::array<ValueType, N>>
{
using type = ValueType;
using type = ValueType;
};
template<typename RealType, int M, std::size_t N>
template<typename RealType, std::size_t M, std::size_t N>
struct argument_container_t<std::array<rdiff::rvar<RealType, M>, N>>
{
using type = RealType;
using type = RealType;
};
template<template<typename, typename...> class Container, typename ValueType, typename... Args>
struct argument_container_t<Container<ValueType, Args...>>
{
using type = ValueType;
};
template<template<typename, typename...> class Container,
typename RealType,
std::size_t N,
typename... Args>
struct argument_container_t<Container<rdiff::rvar<RealType, N>, Args...>>
{
using type = RealType;
};
/******************************************************************************/
/** @brief simple blas helpers

View File

@@ -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_;

View File

@@ -8,7 +8,7 @@
#include <boost/math/differentiation/autodiff_reverse.hpp>
#include <boost/random.hpp>
#include <random>
#include <type_traits>
namespace boost {
namespace math {
namespace optimization {
@@ -75,16 +75,15 @@ struct reverse_mode_gradient_evaluation_policy
template<typename RealType>
struct tape_initializer_rvar
{
template<class ArgumentContainer>
void operator()(ArgumentContainer&) const noexcept
{
static_assert(
std::is_same<typename ArgumentContainer::value_type,
rdiff::rvar<RealType, 1>>::value,
"ArgumentContainer::value_type must be rdiff::rvar<RealType,1>");
auto& tape = rdiff::get_active_tape<RealType, 1>();
tape.add_checkpoint();
}
template<class ArgumentContainer>
void operator()(ArgumentContainer& x) const noexcept
{
static_assert(std::is_same<typename ArgumentContainer::value_type,
rdiff::rvar<RealType, 1>>::value,
"ArgumentContainer::value_type must be rdiff::rvar<RealType,1>");
auto& tape = rdiff::get_active_tape<RealType, 1>();
tape.add_checkpoint();
}
};
template<typename RealType>

View File

@@ -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<typename ArgumentType,
typename std::enable_if<!boost::math::differentiation::reverse_mode::
@@ -270,22 +270,22 @@ template<class Objective, typename ArgumentContainer>
auto
make_lbfgs(Objective&& obj, ArgumentContainer& x, std::size_t m = 10)
{
using RealType = typename argument_container_t<ArgumentContainer>::type;
return lbfgs<ArgumentContainer,
RealType,
std::decay_t<Objective>,
tape_initializer_rvar<RealType>,
reverse_mode_function_eval_policy<RealType>,
reverse_mode_gradient_evaluation_policy<RealType>,
strong_wolfe_line_search_policy<RealType>>(
std::forward<Objective>(obj),
x,
m,
tape_initializer_rvar<RealType>{},
reverse_mode_function_eval_policy<RealType>{},
reverse_mode_gradient_evaluation_policy<RealType>{},
lbfgs_update_policy<RealType>{},
strong_wolfe_line_search_policy<RealType>{});
using RealType = typename argument_container_t<ArgumentContainer>::type;
return lbfgs<ArgumentContainer,
RealType,
std::decay_t<Objective>,
tape_initializer_rvar<RealType>,
reverse_mode_function_eval_policy<RealType>,
reverse_mode_gradient_evaluation_policy<RealType>,
strong_wolfe_line_search_policy<RealType>>(
std::forward<Objective>(obj),
x,
m,
tape_initializer_rvar<RealType>{},
reverse_mode_function_eval_policy<RealType>{},
reverse_mode_gradient_evaluation_policy<RealType>{},
lbfgs_update_policy<RealType>{},
strong_wolfe_line_search_policy<RealType>{});
}
template<class Objective,

View File

@@ -13,108 +13,107 @@ namespace bopt = boost::math::optimization;
BOOST_AUTO_TEST_SUITE(basic_lbfgs)
BOOST_AUTO_TEST_CASE_TEMPLATE(default_lbfgs_test, T, all_float_types)
BOOST_AUTO_TEST_CASE(default_lbfgs_test) //, T, all_float_types)
{
constexpr size_t NITER = 10;
constexpr size_t M = 10;
const T eps = T{ 1e-8 };
using T = double;
constexpr size_t NITER = 10;
constexpr size_t M = 10;
const T eps = T{1e-8};
RandomSample<T> rng{ T(-10), T(10) };
std::array<rdiff::rvar<T, 1>, 2> x;
x[0] = rng.next();
x[1] = rng.next();
RandomSample<T> rng{T(-10), T(10)};
std::array<rdiff::rvar<T, 1>, 2> x;
x[0] = rng.next();
x[1] = rng.next();
auto opt = bopt::make_lbfgs(&rosenbrock_saddle<rdiff::rvar<T, 1>>, x, M);
auto opt = bopt::make_lbfgs(&rosenbrock_saddle<rdiff::rvar<T, 1>>, 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<typename RealType>
struct zero_init_policy
{
void operator()(std::vector<RealType>& x) const noexcept
{
std::fill(x.begin(), x.end(), RealType{ 0 });
}
void operator()(std::vector<RealType>& x) const noexcept
{
std::fill(x.begin(), x.end(), RealType{0});
}
};
template<typename RealType>
struct analytic_objective_eval_pol
{
template<typename Objective, typename ArgumentContainer>
RealType operator()(Objective&& objective, ArgumentContainer& x)
{
return objective(x);
}
template<typename Objective, typename ArgumentContainer>
RealType operator()(Objective&& objective, ArgumentContainer& x)
{
return objective(x);
}
};
template<typename RealType>
struct analytic_gradient_eval_pol
{
template<class Objective,
class ArgumentContainer,
class FunctionEvaluationPolicy>
void operator()(Objective&& obj_f,
ArgumentContainer& x,
FunctionEvaluationPolicy&& f_eval_pol,
RealType& obj_v,
std::vector<RealType>& 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<class Objective, class ArgumentContainer, class FunctionEvaluationPolicy>
void operator()(Objective&& obj_f,
ArgumentContainer& x,
FunctionEvaluationPolicy&& f_eval_pol,
RealType& obj_v,
std::vector<RealType>& 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<T> rng{ T(-5), T(5) };
std::array<rdiff::rvar<T, 1>, 2> x;
x[0] = rng.next();
x[1] = rng.next();
RandomSample<T> rng{T(-5), T(5)};
std::array<rdiff::rvar<T, 1>, 2> x;
x[0] = rng.next();
x[1] = rng.next();
auto opt = bopt::make_lbfgs(&rosenbrock_saddle<rdiff::rvar<T, 1>>,
x,
M,
bopt::costant_initializer_rvar<T>(0.0));
auto result = minimize(opt);
auto opt = bopt::make_lbfgs(&rosenbrock_saddle<rdiff::rvar<T, 1>>,
x,
M,
bopt::costant_initializer_rvar<T>(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<T> rng{ T(-5), T(5) };
std::vector<T> x(3);
for (auto& xi : x)
xi = rng.next();
RandomSample<T> rng{T(-5), T(5)};
std::vector<T> x(3);
for (auto& xi : x)
xi = rng.next();
auto opt = bopt::make_lbfgs(&quadratic<T>, // Objective
x, // Arguments
M, // History size
zero_init_policy<T>{}, // Initialization
analytic_objective_eval_pol<T>{}, // Function eval
analytic_gradient_eval_pol<T>{}, // Gradient eval
bopt::armijo_line_search_policy<T>{});
auto opt = bopt::make_lbfgs(&quadratic<T>, // Objective
x, // Arguments
M, // History size
zero_init_policy<T>{}, // Initialization
analytic_objective_eval_pol<T>{}, // Function eval
analytic_gradient_eval_pol<T>{}, // Gradient eval
bopt::armijo_line_search_policy<T>{});
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()