26 #include "alpaqa_interface.hpp"
28 #include <alpaqa/params/params.hpp>
33 int CASADI_NLPSOL_ALPAQA_EXPORT
36 plugin->name =
"alpaqa";
38 plugin->version = CASADI_VERSION;
61 "Options to be passed to Alpaqa"}}
72 for (
auto&& op : opts) {
73 if (op.first==
"alpaqa") {
89 std::vector<MX> ret =
oracle_(std::vector<MX>{x, p});
93 MX sL = s * f +
dot(y, g);
95 MX zeta = g + (y / sigma);
96 MX z_hat = fmax(zl, fmin(zeta, zu));
99 MX s_psi = s * f + 0.5 *
dot(y_hat, d);
100 MX psi = f + 0.5 *
dot(y_hat, d);
109 {
"x",
"p",
"y",
"sigma",
"zl",
"zu"}, {
"psi",
"y_hat"});
111 MX grad_psi = gradient(psi, x);
112 create_function(
"nlp_grad_psi", {x, p, y, sigma, zl, zu}, {psi, grad_psi},
113 {
"x",
"p",
"y",
"sigma",
"zl",
"zu"}, {
"psi",
"grad_psi"});
115 MX grad_L = gradient(L, x);
117 {
"x",
"p",
"y"}, {
"grad_L"});
119 MX hess_L = hessian(sL, x)(0);
120 if (!hess_L.is_dense()) hess_L = triu(hess_L);
122 {
"x",
"p",
"y",
"s"}, {
"hess_L"});
124 MX L_prod = gradient(jtimes(sL, x, v,
false), x);
126 {
"x",
"p",
"y",
"s",
"v"}, {
"L_prod"});
128 MX hess_psi = hessian(sL, x)(0);
129 if (!hess_psi.is_dense()) hess_psi = triu(hess_psi);
130 create_function(
"nlp_hess_psi", {x, p, y, sigma, s, zl, zu}, {hess_psi},
131 {
"x",
"p",
"y",
"sigma",
"s",
"zl",
"zu"}, {
"hess_psi"});
133 MX hess_psi_prod = gradient(jtimes(s_psi, x, v,
false), x);
134 create_function(
"nlp_hess_psi_prod", {x, p, y, sigma, s, zl, zu, v}, {hess_psi},
135 {
"x",
"p",
"y",
"sigma",
"s",
"zl",
"zu",
"v"}, {
"hess_psi_prod"});
148 void AlpaqaInterface::clear_mem_at(
AlpaqaMemory* m)
const {
171 casadi_int*& iw,
double*& w)
const {
191 auto d_nlp = &m->
d_nlp;
202 auto counted_problem = alpaqa::problem_with_counters_ref(problem);
205 using Direction = alpaqa::LBFGSDirection<alpaqa::DefaultConfig>;
206 using InnerSolver = alpaqa::PANOCSolver<Direction>;
207 using OuterSolver = alpaqa::ALMSolver<InnerSolver>;
210 OuterSolver::Params almparam;
213 InnerSolver::Params panocparam;
216 Direction::AcceleratorParams lbfgsparam;
218 for (
auto&& op :
opts_) {
219 if (op.first==
"alm") {
220 for (
auto&& kv : op.second.to_dict())
221 alpaqa::params::set_param(almparam, {.full_key = kv.first, .key = kv.first, .value =
str(kv.second)});
222 }
else if (op.first==
"panoc") {
223 for (
auto&& kv : op.second.to_dict())
224 alpaqa::params::set_param(panocparam, {.full_key = kv.first, .key = kv.first, .value =
str(kv.second)});
225 }
else if (op.first==
"lbfgs") {
226 for (
auto&& kv : op.second.to_dict())
227 alpaqa::params::set_param(lbfgsparam, {.full_key = kv.first, .key = kv.first, .value =
str(kv.second)});
229 casadi_error(
"Unknown option: " + op.first);
236 {panocparam, lbfgsparam},
241 alpaqa::DefaultConfig::vec x(
nx_);
242 alpaqa::DefaultConfig::vec y(
ng_);
247 auto stats = solver(counted_problem, x, y);
252 d_nlp->objective = problem.
eval_f(x);
253 alpaqa::DefaultConfig::vec g(
ng_);
257 if (stats.status == alpaqa::SolverStatus::Converged) {
259 }
else if (stats.status == alpaqa::SolverStatus::MaxTime || stats.status == alpaqa::SolverStatus::MaxIter) {
261 }
else if (stats.status == alpaqa::SolverStatus::NotFinite) {
263 }
else if (stats.status == alpaqa::SolverStatus::Interrupted) {
269 uout() <<
'\n' << *counted_problem.evaluations <<
'\n';
270 uout() <<
"status: " << stats.status <<
'\n'
271 <<
"f = " << problem.
eval_f(x) <<
'\n'
272 <<
"inner iterations: " << stats.inner.iterations <<
'\n'
273 <<
"outer iterations: " << stats.outer_iterations <<
'\n'
274 <<
"ε = " << stats.ε <<
'\n'
275 <<
"δ = " << stats.δ <<
'\n'
277 << std::chrono::duration<double>{stats.elapsed_time}.count()
279 <<
"x = " << x.transpose() <<
'\n'
280 <<
"y = " << y.transpose() <<
'\n'
281 <<
"avg τ = " << (stats.inner.sum_τ / stats.inner.count_τ) <<
'\n'
282 <<
"L-BFGS rejected = " << stats.inner.lbfgs_rejected <<
'\n'
283 <<
"L-BFGS failures = " << stats.inner.lbfgs_failures <<
'\n'
284 <<
"Line search failures = " << stats.inner.linesearch_failures
294 s.
version(
"AlpaqaInterface", 1);
301 s.
version(
"AlpaqaInterface", 1);
~AlpaqaInterface() override
AlpaqaInterface(const std::string &name, const Function &nlp)
int solve(void *mem) const override
static ProtoFunction * deserialize(DeserializingStream &s)
Deserialize into MX.
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
Dict get_stats(void *mem) const override
Get all statistics.
Dict opts_
All Alpaqa options.
static const Options options_
void free_mem(void *mem) const override
Free memory block.
int init_mem(void *mem) const override
Initalize memory block.
void init(const Dict &opts) override
Initialize.
void set_work(void *mem, const double **&arg, double **&res, casadi_int *&iw, double *&w) const override
Set the (persistent) work vectors.
static Nlpsol * creator(const std::string &name, const Function &nlp)
static const std::string meta_doc
void eval_g(crvec x, rvec g) const
real_t eval_f(crvec x) const
Helper class for Serialization.
void unpack(Sparsity &e)
Reconstruct an object from the input stream.
void version(const std::string &name, int v)
static MX sym(const std::string &name, casadi_int nrow=1, casadi_int ncol=1)
Create an nrow-by-ncol symbolic primitive.
NLP solver storage class.
Dict get_stats(void *mem) const override
Get all statistics.
static const Options options_
Options.
void init(const Dict &opts) override
Initialize.
casadi_int ng_
Number of constraints.
virtual void check_inputs(void *mem) const
Check if the inputs correspond to a well-posed problem.
int init_mem(void *mem) const override
Initalize memory block.
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
casadi_int np_
Number of parameters.
casadi_int nx_
Number of variables.
void set_work(void *mem, const double **&arg, double **&res, casadi_int *&iw, double *&w) const override
Set the (persistent) work vectors.
Function oracle_
Oracle: Used to generate other functions.
Function create_function(const Function &oracle, const std::string &fname, const std::vector< std::string > &s_in, const std::vector< std::string > &s_out, const Function::AuxOut &aux=Function::AuxOut(), const Dict &opts=Dict())
static void registerPlugin(const Plugin &plugin, bool needs_lock=true)
Register an integrator in the factory.
bool verbose_
Verbose printout.
void clear_mem()
Clear all memory (called from destructor)
Helper class for Serialization.
void version(const std::string &name, int v)
void pack(const Sparsity &e)
Serializes an object to the output stream.
void CASADI_NLPSOL_ALPAQA_EXPORT casadi_load_nlpsol_alpaqa()
void casadi_copy(const T1 *x, casadi_int n, T1 *y)
COPY: y <-x.
std::string str(const T &v)
String representation, any type.
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.
T dot(const std::vector< T > &a, const std::vector< T > &b)
int CASADI_NLPSOL_ALPAQA_EXPORT casadi_register_nlpsol_alpaqa(Nlpsol::Plugin *plugin)
alpaqa::ALMSolver< InnerSolver > * solver
UnifiedReturnStatus unified_return_status
casadi_nlpsol_data< double > d_nlp
Options metadata for a class.
static Dict sanitize(const Dict &opts, bool top_level=true)
Sanitize a options dictionary.