9#include <casadi/core/external.hpp>
22namespace fs = std::filesystem;
24namespace casadi_loader {
38 std::optional<ConstrFun>
constr = std::nullopt;
39 std::optional<CasADiFunctionEvaluator<Conf, 5, 1>>
hess_L_prod =
41 std::optional<CasADiFunctionEvaluator<Conf, 4, 1>>
hess_L = std::nullopt;
42 std::optional<CasADiFunctionEvaluator<Conf, 8, 1>>
hess_ψ_prod =
44 std::optional<CasADiFunctionEvaluator<Conf, 7, 1>>
hess_ψ = std::nullopt;
45 std::optional<CasADiFunctionEvaluator<Conf, 2, 1>>
jac_g = std::nullopt;
61 using namespace casadi_loader;
64 [&]() -> std::optional<CasADiFunctionEvaluator<Conf, 2, 1>> {
65 casadi::Function
gfun = casadi::external(
"g",
so_name);
66 using namespace std::literals::string_literals;
68 throw std::invalid_argument(
69 "Invalid number of input arguments: got "s +
70 std::to_string(
gfun.n_in()) +
", should be 2.");
72 throw std::invalid_argument(
73 "Invalid number of output arguments: got "s +
74 std::to_string(
gfun.n_in()) +
", should be 0 or 1.");
75 if (
gfun.size2_in(0) != 1)
76 throw std::invalid_argument(
77 "First input argument should be a column vector.");
78 if (
gfun.size2_in(1) != 1)
79 throw std::invalid_argument(
80 "Second input argument should be a column vector.");
81 if (
gfun.n_out() == 1 &&
gfun.size2_out(0) != 1)
82 throw std::invalid_argument(
83 "First output argument should be a column vector.");
85 if (
gfun.n_out() == 1)
88 if (
gfun.n_out() == 0) {
90 throw std::invalid_argument(
91 "Function g has no outputs but m != 0");
94 CasADiFunctionEvaluator<Conf, 2, 1> g{std::move(
gfun)};
95 g.validate_dimensions({
dim(n, 1),
dim(p, 1)}, {
dim(m, 1)});
96 return std::make_optional(std::move(g));
104 this->C = Box<config_t>{n};
105 this->D = Box<config_t>{m};
107 impl = std::make_unique<CasADiFunctionsWithParam<Conf>>(
111 .f_grad_f = wrapped_load<CasADiFunctionEvaluator<Conf, 2, 2>>(
115 .ψ_grad_ψ = wrapped_load<CasADiFunctionEvaluator<Conf, 6, 2>>(
116 so_name,
"psi_grad_psi",
dims(n, p, m, m, m, m),
dims(1, n)),
124 wrapped_load<CasADiFunctionEvaluator<Conf, 6, 2>>(
125 so_name,
"psi",
dims(n, p, m, m, m, m),
dims(1, m)),
133 so_name,
"hess_psi_prod",
dims(n, p, m, m, 1, m, m, n),
dims(n));
135 so_name,
"hess_psi",
dims(n, p, m, m, 1, m, m),
dims(
dim(n, n)));
144template <Config Conf>
150 throw std::runtime_error(
"Unable to open data file \"" +
159 return static_cast<void>(
data_file.get());
163 auto s = csv::read_row_std_vector<real_t>(
data_file,
sep);
168 throw std::runtime_error(
"Unable to read " + std::string(name) +
169 " from data file \"" +
filepath.string() +
170 ':' + std::to_string(
line) +
175 auto read_single = [&](std::string_view name,
auto &
v) {
178 throw std::runtime_error(
"Unable to read " + std::string(name) +
179 " from data file \"" +
filepath.string() +
180 ':' + std::to_string(
line) +
'"');
190 read_single(
"penalty_alm_split", this->penalty_alm_split);
193template <Config Conf>
195template <Config Conf>
198template <Config Conf>
210 impl->f({x.data(), param.data()}, {&f});
214template <Config Conf>
217 impl->f_grad_f({x.data(), param.data()}, {&f,
grad_fx.data()});
220template <Config Conf>
223 impl->f_grad_f({x.data(), param.data()}, {&f,
grad_fx.data()});
227template <Config Conf>
230 impl->constr->g({x.data(), param.data()}, {g.data()});
233template <Config Conf>
238template <Config Conf>
242 impl->grad_ψ({x.data(), param.data(), y.data(), Σ.data(),
243 this->D.lowerbound.data(),
this->D.upperbound.data()},
249 impl->ψ_grad_ψ({x.data(), param.data(), y.data(), Σ.data(),
250 this->D.lowerbound.data(),
this->D.upperbound.data()},
251 {&ψ, grad_ψ.data()});
255template <Config Conf>
260 impl->ψ_grad_ψ({x.data(), param.data(), y.data(), Σ.data(),
261 this->D.lowerbound.data(),
this->D.upperbound.data()},
262 {&ψ, grad_ψ.data()});
266template <Config Conf>
270 impl->constr->grad_L({x.data(), param.data(), y.data()},
273 eval_f_grad_f(x, grad_L);
276template <Config Conf>
281 impl->constr->ψ({x.data(), param.data(), y.data(), Σ.data(),
282 this->D.lowerbound.data(),
this->D.upperbound.data()},
285 impl->f({x.data(), param.data()}, {&ψ});
289template <Config Conf>
294template <Config Conf>
297 using index_vector_map_t =
typename SparseCSC::index_vector_map_t;
301 .symmetry = symmetry,
302 .inner_idx = index_vector_map_t{
sp.row(),
sp.nnz()},
303 .outer_ptr = index_vector_map_t{
sp.colind(),
sp.size2() + 1},
304 .order = SparseCSC::SortedRows,
308template <Config Conf>
315 if (!impl->jac_g.has_value())
317 auto &&
sp = impl->jac_g->fun.sparsity_out(0);
323template <Config Conf>
325 assert(impl->jac_g.has_value());
326 (*impl->jac_g)({x.data(), param.data()}, {
J_values.data()});
329template <Config Conf>
332 assert(impl->hess_L_prod.has_value());
333 (*impl->hess_L_prod)({x.data(), param.data(), y.data(), &
scale,
v.data()},
337template <Config Conf>
344 if (!impl->hess_L.has_value())
346 auto &&
sp = impl->hess_L->fun.sparsity_out(0);
351template <Config Conf>
354 assert(impl->hess_L.has_value());
355 (*impl->hess_L)({x.data(), param.data(), y.data(), &
scale},
359template <Config Conf>
363 assert(impl->hess_ψ_prod.has_value());
364 (*impl->hess_ψ_prod)({x.data(), param.data(), y.data(), Σ.data(), &
scale,
365 this->D.lowerbound.data(), this->D.upperbound.data(),
370template <Config Conf>
377 if (!impl->hess_ψ.has_value())
379 auto &&
sp = impl->hess_ψ->fun.sparsity_out(0);
384template <Config Conf>
387 assert(impl->hess_ψ.has_value());
388 (*impl->hess_ψ)({x.data(), param.data(), y.data(), Σ.data(), &
scale,
389 this->D.lowerbound.data(), this->D.upperbound.data()},
393template <Config Conf>
397template <Config Conf>
399 return impl->jac_g.has_value();
401template <Config Conf>
403 return impl->hess_L_prod.has_value();
405template <Config Conf>
407 return impl->hess_L.has_value();
409template <Config Conf>
411 return impl->hess_ψ_prod.has_value();
413template <Config Conf>
415 return impl->hess_ψ.has_value();
Implements common problem functions for minimization problems with box constraints.
Problem definition for a CasADi problem, loaded from a DLL.
bool provides_eval_hess_L() const
void eval_g(crvec x, rvec g) const
bool provides_eval_hess_ψ_prod() const
void eval_jac_g(crvec x, rvec J_values) const
Sparsity get_jac_g_sparsity() const
Sparsity get_hess_ψ_sparsity() const
bool provides_eval_jac_g() const
void eval_hess_ψ(crvec x, crvec y, crvec Σ, real_t scale, rvec H_values) const
Sparsity get_hess_L_sparsity() const
void load_numerical_data(const std::filesystem::path &filepath, char sep=',')
Load the numerical problem data (bounds and parameters) from a CSV file.
CasADiProblem & operator=(const CasADiProblem &)
void eval_grad_L(crvec x, crvec y, rvec grad_L, rvec work_n) const
real_t eval_ψ(crvec x, crvec y, crvec Σ, rvec ŷ) const
CasADiProblem(const std::string &filename)
Load a problem generated by CasADi (with parameters).
bool provides_eval_hess_L_prod() const
real_t eval_f_grad_f(crvec x, rvec grad_fx) const
void eval_grad_g_prod(crvec x, crvec y, rvec grad_gxy) const
void eval_hess_L_prod(crvec x, crvec y, real_t scale, crvec v, rvec Hv) const
bool provides_eval_grad_gi() const
void eval_grad_f(crvec x, rvec grad_fx) const
real_t eval_ψ_grad_ψ(crvec x, crvec y, crvec Σ, rvec grad_ψ, rvec work_n, rvec work_m) const
void eval_grad_gi(crvec x, index_t i, rvec grad_i) const
void eval_hess_L(crvec x, crvec y, real_t scale, rvec H_values) const
bool provides_eval_hess_ψ() const
void eval_grad_ψ(crvec x, crvec y, crvec Σ, rvec grad_ψ, rvec work_n, rvec work_m) const
void eval_hess_ψ_prod(crvec x, crvec y, crvec Σ, real_t scale, crvec v, rvec Hv) const
Class for evaluating CasADi functions, allocating the necessary workspace storage in advance for allo...
#define USING_ALPAQA_CONFIG(Conf)
CasADiFunctionEvaluator< Conf, 3, 1 > grad_L
std::optional< CasADiFunctionEvaluator< Conf, 5, 1 > > hess_L_prod
std::optional< CasADiFunctionEvaluator< Conf, 7, 1 > > hess_ψ
constexpr auto dims(auto... a)
std::optional< CasADiFunctionEvaluator< Conf, 4, 1 > > hess_L
std::pair< casadi_int, casadi_int > dim
CasADiFunctionEvaluator< Conf, 2, 1 > f
auto wrap_load(const std::string &so_name, const char *name, F f)
std::optional< ConstrFun > constr
std::optional< CasADiFunctionEvaluator< Conf, 8, 1 > > hess_ψ_prod
CasADiFunctionEvaluator< Conf, 6, 2 > ψ_grad_ψ
CasADiFunctionEvaluator< Conf, 6, 2 > ψ
std::optional< CasADiFunctionEvaluator< Conf, 2, 1 > > jac_g
CasADiFunctionEvaluator< Conf, 2, 2 > f_grad_f
CasADiFunctionEvaluator< Conf, 2, 1 > g
void read_row(std::istream &is, Eigen::Ref< Eigen::VectorX< float > > v, char sep)
auto casadi_to_index(casadi_int i) -> index_t< Conf >
Symmetry
Describes the symmetry of matrices.
@ Unsymmetric
No symmetry.
@ Upper
Symmetric, upper-triangular part is stored.
typename Conf::real_t real_t
typename Conf::index_t index_t
Sparsity< Conf > convert_csc(const auto &sp, sparsity::Symmetry symmetry)
typename Conf::length_t length_t
typename Conf::cmvec cmvec
typename Conf::crvec crvec
Sparse compressed-column structure (CCS or CSC).
Stores any of the supported sparsity patterns.