9#include <casadi/core/external.hpp>
22namespace fs = std::filesystem;
24namespace casadi_loader {
39 std::optional<ConstrFun>
constr = std::nullopt;
40 std::optional<CasADiFunctionEvaluator<Conf, 5, 1>>
hess_L_prod =
42 std::optional<CasADiFunctionEvaluator<Conf, 4, 1>>
hess_L = std::nullopt;
43 std::optional<CasADiFunctionEvaluator<Conf, 8, 1>>
hess_ψ_prod =
45 std::optional<CasADiFunctionEvaluator<Conf, 7, 1>>
hess_ψ = std::nullopt;
46 std::optional<CasADiFunctionEvaluator<Conf, 2, 1>>
jac_g = std::nullopt;
48 template <
class Loader>
50 {
loader(name) } -> std::same_as<casadi::Function>;
51 {
loader.format_name(name) } -> std::same_as<std::string>;
58 using namespace std::literals::string_literals;
61 "Invalid number of input arguments: got "s +
62 std::to_string(
gfun.n_in()) +
", should be 2.");
65 "Invalid number of output arguments: got "s +
66 std::to_string(
gfun.n_in()) +
", should be 0 or 1.");
67 if (
gfun.size2_in(0) != 1)
69 "First input argument should be a column vector.");
70 if (
gfun.size2_in(1) != 1)
72 "Second input argument should be a column vector.");
73 if (
gfun.n_out() == 1 &&
gfun.size2_out(0) != 1)
75 "First output argument should be a column vector.");
77 if (
gfun.n_out() == 1)
80 if (
gfun.n_out() == 0) {
83 "Function g has no outputs but m != 0");
88 return std::make_optional(std::move(g));
105 loader,
"psi_grad_psi",
dims(
n,
p,
m,
m,
m,
m),
dims(1,
n)),
114 loader,
"psi",
dims(
n,
p,
m,
m,
m,
m),
dims(1,
m)),
122 loader,
"hess_psi_prod",
dims(
n,
p,
m,
m, 1,
m,
m,
n),
dims(
n));
124 loader,
"hess_psi",
dims(
n,
p,
m,
m, 1,
m,
m),
dims(
dim(
n,
n)));
135template <Config Conf>
141template <Config Conf>
147 auto operator()(
const std::string &name)
const {
148 return casadi::external(name,
filename);
159 this->C = Box<config_t>{impl->n};
160 this->D = Box<config_t>{impl->m};
167template <Config Conf>
173 auto operator()(
const std::string &name)
const {
174 return casadi::Function::deserialize(functions.
functions.at(name));
177 return "SerializedCasADiFunctions['" + name +
"']";
185 this->C = Box<config_t>{impl->n};
186 this->D = Box<config_t>{impl->m};
189template <Config Conf>
195 throw std::runtime_error(
"Unable to open data file \"" +
204 return static_cast<void>(
data_file.get());
208 auto s = csv::read_row_std_vector<real_t>(
data_file,
sep);
213 throw std::runtime_error(
"Unable to read " + std::string(name) +
214 " from data file \"" +
filepath.string() +
215 ':' + std::to_string(
line) +
220 auto read_single = [&](std::string_view name,
auto &
v) {
223 throw std::runtime_error(
"Unable to read " + std::string(name) +
224 " from data file \"" +
filepath.string() +
225 ':' + std::to_string(
line) +
'"');
235 read_single(
"penalty_alm_split", this->penalty_alm_split);
238template <Config Conf>
240template <Config Conf>
243template <Config Conf>
255 impl->f({x.data(), param.data()}, {&f});
259template <Config Conf>
262 impl->f_grad_f({x.data(), param.data()}, {&f,
grad_fx.data()});
265template <Config Conf>
268 impl->f_grad_f({x.data(), param.data()}, {&f,
grad_fx.data()});
272template <Config Conf>
275 impl->constr->g({x.data(), param.data()}, {g.data()});
278template <Config Conf>
283template <Config Conf>
287 impl->grad_ψ({x.data(), param.data(), y.data(), Σ.data(),
288 this->D.lowerbound.data(),
this->D.upperbound.data()},
294 impl->ψ_grad_ψ({x.data(), param.data(), y.data(), Σ.data(),
295 this->D.lowerbound.data(),
this->D.upperbound.data()},
296 {&ψ, grad_ψ.data()});
300template <Config Conf>
305 impl->ψ_grad_ψ({x.data(), param.data(), y.data(), Σ.data(),
306 this->D.lowerbound.data(),
this->D.upperbound.data()},
307 {&ψ, grad_ψ.data()});
311template <Config Conf>
315 impl->constr->grad_L({x.data(), param.data(), y.data()},
318 eval_f_grad_f(x, grad_L);
321template <Config Conf>
326 impl->constr->ψ({x.data(), param.data(), y.data(), Σ.data(),
327 this->D.lowerbound.data(),
this->D.upperbound.data()},
330 impl->f({x.data(), param.data()}, {&ψ});
334template <Config Conf>
339template <Config Conf>
343 using map_t =
typename SparseCSC::index_vector_map_t;
346 .cols =
static_cast<index_t>(
sp.size2()),
347 .symmetry = symmetry,
350 .order = SparseCSC::SortedRows,
354template <Config Conf>
361 if (!impl->jac_g.has_value())
363 auto &&
sp = impl->jac_g->fun.sparsity_out(0);
369template <Config Conf>
371 assert(impl->jac_g.has_value());
372 (*impl->jac_g)({x.data(), param.data()}, {
J_values.data()});
375template <Config Conf>
378 assert(impl->hess_L_prod.has_value());
379 (*impl->hess_L_prod)({x.data(), param.data(), y.data(), &
scale,
v.data()},
383template <Config Conf>
390 if (!impl->hess_L.has_value())
392 auto &&
sp = impl->hess_L->fun.sparsity_out(0);
397template <Config Conf>
400 assert(impl->hess_L.has_value());
401 (*impl->hess_L)({x.data(), param.data(), y.data(), &
scale},
405template <Config Conf>
409 assert(impl->hess_ψ_prod.has_value());
410 (*impl->hess_ψ_prod)({x.data(), param.data(), y.data(), Σ.data(), &
scale,
411 this->D.lowerbound.data(), this->D.upperbound.data(),
416template <Config Conf>
423 if (!impl->hess_ψ.has_value())
425 auto &&
sp = impl->hess_ψ->fun.sparsity_out(0);
430template <Config Conf>
433 assert(impl->hess_ψ.has_value());
434 (*impl->hess_ψ)({x.data(), param.data(), y.data(), Σ.data(), &
scale,
435 this->D.lowerbound.data(), this->D.upperbound.data()},
439template <Config Conf>
443template <Config Conf>
445 return impl->jac_g.has_value();
447template <Config Conf>
449 return impl->hess_L_prod.has_value();
451template <Config Conf>
453 return impl->hess_L.has_value();
455template <Config Conf>
457 return impl->hess_ψ_prod.has_value();
459template <Config Conf>
461 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...
void validate_dimensions(const std::array< casadi_dim, N_in > &dim_in={}, const std::array< casadi_dim, N_out > &dim_out={})
#define USING_ALPAQA_CONFIG(Conf)
auto wrapped_load(Loader &&loader, const char *name, Args &&...args)
constexpr auto dims(auto... a)
std::pair< casadi_int, casadi_int > dim
auto wrap_load(Loader &&loader, const char *name, F f)
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
std::map< std::string, std::string > functions
CasADiFunctionEvaluator< Conf, 3, 1 > grad_L
std::optional< CasADiFunctionEvaluator< Conf, 5, 1 > > hess_L_prod
std::optional< CasADiFunctionEvaluator< Conf, 7, 1 > > hess_ψ
static std::unique_ptr< CasADiFunctionsWithParam > load(Loader &&loader)
std::optional< CasADiFunctionEvaluator< Conf, 4, 1 > > hess_L
CasADiFunctionEvaluator< Conf, 2, 1 > 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
Sparse compressed-column structure (CCS or CSC).
Stores any of the supported sparsity patterns.