17#include <Eigen/Cholesky>
18#include <Eigen/Eigenvalues>
48template <Config Conf = DefaultConfig>
69 [[maybe_unused]]
real_t γ_0, [[maybe_unused]]
crvec x_0,
70 [[maybe_unused]]
crvec x̂_0, [[maybe_unused]]
crvec p_0,
71 [[maybe_unused]]
crvec grad_ψx_0) {
72 if (!(
problem.provides_get_variable_bounds() &&
73 problem.provides_get_general_bounds()))
74 throw std::invalid_argument(
75 "Structured Newton only supports box-constrained problems");
77 if (!
problem.supports_eval_augmented_lagrangian_hessian())
78 throw std::invalid_argument(
"Structured Newton requires hess_ψ");
84 const auto n =
problem.get_num_variables();
88 if (!is_dense(
problem.get_augmented_lagrangian_hessian_sparsity()))
89 throw std::logic_error(
"Sparse hessians not yet implemented");
97 [[maybe_unused]]
crvec xₖ, [[maybe_unused]]
crvec xₙₑₓₜ,
98 [[maybe_unused]]
crvec pₖ, [[maybe_unused]]
crvec pₙₑₓₜ,
99 [[maybe_unused]]
crvec grad_ψxₖ,
100 [[maybe_unused]]
crvec grad_ψxₙₑₓₜ) {
108 const auto n =
problem->get_num_variables();
109 const auto &C =
problem->get_variable_bounds();
113 for (
index_t i = 0; i < n; ++i) {
114 real_t gd = xₖ(i) - γₖ * grad_ψxₖ(i);
115 if (gd <= C.lower(i)) {
117 }
else if (C.upper(i) <= gd) {
121 qₖ(i) = -grad_ψxₖ(i);
132 problem->eval_augmented_lagrangian_hessian(xₖ, *
y, *
Σ, 1,
H.reshaped());
142 Eigen::SelfAdjointEigenSolver<mat> eig{
H,
143 Eigen::ComputeEigenvectors};
145 auto λ_min = eig.eigenvalues().minCoeff(),
146 λ_max = eig.eigenvalues().maxCoeff();
149 std::cout <<
"λ(H): " << float_to_str(λ_min, 3) <<
", "
150 << float_to_str(λ_max, 3) << std::endl;
154 qₖ = eig.eigenvectors().transpose() * qₖ;
155 qₖ = eig.eigenvalues().cwiseMax(ε).asDiagonal().inverse() * qₖ;
156 qₖ = eig.eigenvectors() * qₖ;
175 HJ.template triangularView<Eigen::Lower>() =
176 H(J, J).template triangularView<Eigen::Lower>();
181 Eigen::SelfAdjointEigenSolver<mat> eig{HJ, Eigen::ComputeEigenvectors};
183 auto λ_min = eig.eigenvalues().minCoeff(),
184 λ_max = eig.eigenvalues().maxCoeff();
187 std::cout <<
"λ(H_JJ): " << float_to_str(λ_min, 3) <<
", "
188 << float_to_str(λ_max, 3) << std::endl;
192 auto qJ =
H.col(0).topRows(nJ);
194 qJ = eig.eigenvectors().transpose() * qJ;
195 qJ = eig.eigenvalues().cwiseMax(ε).asDiagonal().inverse() * qJ;
196 qₖ(J) = eig.eigenvectors() * qJ;
209 return "StructuredNewtonDirection<" +
210 std::string(config_t::get_name()) +
'>';
218 std::optional<crvec>
y = std::nullopt;
219 std::optional<crvec>
Σ = std::nullopt;
221 std::optional<vec>
y = std::nullopt;
222 std::optional<vec>
Σ = std::nullopt;
The main polymorphic minimization problem interface.
#define USING_ALPAQA_CONFIG(Conf)
#define ALPAQA_IF_QUADF(...)
#define ALPAQA_IF_LONGD(...)
#define ALPAQA_IF_FLOAT(...)
#define ALPAQA_EXPORT_EXTERN_TEMPLATE(...)
real_t hessian_vec_factor
Parameters for the StructuredNewtonDirection class.
Parameters for the StructuredNewtonDirection class.
typename Conf::indexvec indexvec
typename Conf::real_t real_t
typename Conf::rindexvec rindexvec
typename Conf::index_t index_t
typename Conf::crvec crvec
typename Conf::crindexvec crindexvec
Double-precision double configuration.
Single-precision float configuration.
long double configuration.
std::string get_name() const
void changed_γ(real_t γₖ, real_t old_γₖ)
StructuredNewtonDirection()=default
const auto & get_params() const
DirectionParams direction_params
DirectionParams direction
StructuredNewtonDirection(const AcceleratorParams ¶ms, const DirectionParams &directionparams={})
bool update(real_t γₖ, real_t γₙₑₓₜ, crvec xₖ, crvec xₙₑₓₜ, crvec pₖ, crvec pₙₑₓₜ, crvec grad_ψxₖ, crvec grad_ψxₙₑₓₜ)
StructuredNewtonDirectionParams< config_t > DirectionParams
StructuredNewtonDirection(const Params ¶ms)
AcceleratorParams reg_params
StructuredNewtonRegularizationParams< config_t > AcceleratorParams
void initialize(const Problem &problem, crvec y, crvec Σ, real_t γ_0, crvec x_0, crvec x̂_0, crvec p_0, crvec grad_ψx_0)
bool apply(real_t γₖ, crvec xₖ, crvec x̂ₖ, crvec pₖ, crvec grad_ψxₖ, rvec qₖ) const
bool has_initial_direction() const
AcceleratorParams accelerator
TypeErasedProblem< config_t > Problem
static void compute_complement(std::span< const index_t > in, std::span< index_t > out)