26 #include "ampl_interface.hpp"
27 #include "casadi/core/casadi_misc.hpp"
34 int CASADI_NLPSOL_AMPL_EXPORT
37 plugin->name =
"ampl";
39 plugin->version = CASADI_VERSION;
62 "AMPL solver binary"}}
74 for (
auto&& op : opts) {
75 if (op.first==
"solver") {
76 solver_ = op.second.to_string();
82 "Only SX supported currently.");
84 std::vector<SX> fg =
oracle()(xp);
91 casadi_assert(p.
is_empty(),
"'p' currently not supported");
94 std::vector<std::string> x_name, g_name;
95 for (casadi_int i=0; i<
nx_; ++i) x_name.push_back(
"x[" +
str(i) +
"]");
96 for (casadi_int i=0; i<
ng_; ++i) g_name.push_back(
"g[" +
str(i) +
"]");
97 casadi_int max_x_name = x_name.back().size();
98 casadi_int max_g_name = g_name.empty() ? 0 : g_name.back().size();
105 std::vector<SX> ex = {f, g}, v, vdef;
148 << jac_f.
nnz() <<
"\n";
152 << max_g_name <<
"\n";
162 Function F(
"F", {vertcat(v), x}, {vertcat(vdef), f, g},
163 {
"v",
"x"}, {
"vdef",
"f",
"g"});
166 std::vector<std::string> work(F.sz_w());
169 for (casadi_int k=0; k<F.n_instructions(); ++k) {
171 casadi_int op = F.instruction_id(k);
173 std::vector<casadi_int> o = F.instruction_output(k);
174 casadi_int o0=-1, o1=-1, i0=-1, i1=-1;
175 if (!o.empty()) o0 = o[0];
176 if (o.size()>1) o1 = o[1];
177 std::vector<casadi_int> i = F.instruction_input(k);
178 if (!i.empty()) i0 = i[0];
179 if (i.size()>1) i1 = i[1];
182 work[o0] =
"n" +
str(F.instruction_constant(k)) +
"\n";
185 work[o0] =
"v" +
str(i0*v.size() + i1) +
"\n";
190 nl_init_ <<
"V" << (x.
nnz()+o1) <<
" 0 0\n" << work[i0];
193 nl_init_ <<
"O" << o1 <<
" 0\n" << work[i0];
196 nl_init_ <<
"C" << o1 <<
"\n" << work[i0];
199 case OP_ADD: work[o0] =
"o0\n" + work[i0] + work[i1];
break;
200 case OP_SUB: work[o0] =
"o1\n" + work[i0] + work[i1];
break;
201 case OP_MUL: work[o0] =
"o2\n" + work[i0] + work[i1];
break;
202 case OP_DIV: work[o0] =
"o3\n" + work[i0] + work[i1];
break;
203 case OP_SQ: work[o0] =
"o5\n" + work[i0] +
"n2\n";
break;
204 case OP_POW: work[o0] =
"o5\n" + work[i0] + work[i1];
break;
205 case OP_FLOOR: work[o0] =
"o13\n" + work[i0];
break;
206 case OP_CEIL: work[o0] =
"o14\n" + work[i0];
break;
207 case OP_FABS: work[o0] =
"o15\n" + work[i0];
break;
208 case OP_NEG: work[o0] =
"o16\n" + work[i0];
break;
209 case OP_TANH: work[o0] =
"o37\n" + work[i0];
break;
210 case OP_TAN: work[o0] =
"o38\n" + work[i0];
break;
211 case OP_SQRT: work[o0] =
"o39\n" + work[i0];
break;
212 case OP_SINH: work[o0] =
"o40\n" + work[i0];
break;
213 case OP_SIN: work[o0] =
"o41\n" + work[i0];
break;
214 case OP_LOG: work[o0] =
"o43\n" + work[i0];
break;
215 case OP_EXP: work[o0] =
"o44\n" + work[i0];
break;
216 case OP_COSH: work[o0] =
"o45\n" + work[i0];
break;
217 case OP_COS: work[o0] =
"o46\n" + work[i0];
break;
218 case OP_ATANH: work[o0] =
"o47\n" + work[i0];
break;
219 case OP_ATAN2: work[o0] =
"o48\n" + work[i0] + work[i1];
break;
220 case OP_ATAN: work[o0] =
"o49\n" + work[i0];
break;
221 case OP_ASINH: work[o0] =
"o50\n" + work[i0];
break;
222 case OP_ASIN: work[o0] =
"o51\n" + work[i0];
break;
223 case OP_ACOSH: work[o0] =
"o52\n" + work[i0];
break;
224 case OP_ACOS: work[o0] =
"o53\n" + work[i0];
break;
235 const casadi_int *colind = jac_g.
colind(), *row = jac_g.
row();
237 for (casadi_int i=1; i<
nx_; ++i)
nl_init_ << colind[i] <<
"\n";
242 for (casadi_int i=0; i<
ng_; ++i) {
243 nl_init_ <<
"J" << i <<
" " << (colind[i+1]-colind[i]) <<
"\n";
244 for (casadi_int k=colind[i]; k<colind[i+1]; ++k) {
253 nl_init_ <<
"G" << 0 <<
" " << (colind[0+1]-colind[0]) <<
"\n";
254 for (casadi_int k=colind[0]; k<colind[0+1]; ++k) {
268 casadi_int*& iw,
double*& w)
const {
278 auto d_nlp = &m->
d_nlp;
282 std::ofstream nl(nlname, std::ofstream::out);
283 if (
verbose_) casadi_message(
"Opened " + nlname);
287 nl <<
"x" <<
nx_ <<
"\n";
288 for (casadi_int i=0; i<
nx_; ++i) {
289 nl << i <<
" " << d_nlp->z[i] <<
"\n";
295 for (casadi_int i=0; i<
ng_; ++i) {
296 double lbg = d_nlp->lbz[i+
nx_];
297 double ubg = d_nlp->ubz[i+
nx_];
302 nl <<
"1 " << ubg <<
"\n";
306 nl <<
"2 " << lbg <<
"\n";
307 }
else if (ubg==lbg) {
308 nl <<
"4 " << lbg <<
"\n";
310 nl <<
"0 " << lbg <<
" " << ubg <<
"\n";
317 for (casadi_int i=0; i<
nx_; ++i) {
318 double lbx = d_nlp->lbz[i];
319 double ubx = d_nlp->ubz[i];
324 nl <<
"1 " << ubx <<
"\n";
328 nl <<
"2 " << lbx <<
"\n";
329 }
else if (ubx==lbx) {
330 nl <<
"4 " << lbx <<
"\n";
332 nl <<
"0 " << lbx <<
" " << ubx <<
"\n";
346 std::string system_cmd =
solver_ +
" -o" + solname +
" " + nlname +
" > " + outname;
347 int ret = system(system_cmd.c_str());
348 casadi_assert_dev(ret==0);
351 if (
remove(nlname.c_str())!=0) {
352 casadi_warning(
"Failed to remove " + nlname);
354 if (
verbose_) casadi_message(
"Removed " + nlname);
357 std::ifstream out(outname, std::ifstream::in);
358 casadi_assert(out.is_open(),
"Failed to open " + outname);
362 uout() << line <<
"\n";
367 if (
remove(outname.c_str())!=0) {
368 casadi_warning(
"Failed to remove " + outname);
370 if (
verbose_) casadi_message(
"Removed " + outname);
373 std::ifstream sol(solname, std::ifstream::in);
374 casadi_assert(sol.is_open(),
"Failed to open " + solname);
375 if (
verbose_) casadi_message(
"Opened " + solname);
378 std::vector<std::string> sol_lines;
381 sol_lines.push_back(line);
385 for (casadi_int i=0; i<
nx_; ++i) {
386 std::istringstream s(sol_lines.at(sol_lines.size() -
nx_ + i - 1));
391 for (casadi_int i=0; i<
nx_; ++i) {
396 for (casadi_int i=0; i<
ng_; ++i) {
397 std::istringstream s(sol_lines.at(sol_lines.size() -
ng_ -
nx_ + i - 1));
398 s >> d_nlp->lam[i +
nx_];
399 d_nlp->lam[i +
nx_] *= -1;
404 if (
remove(solname.c_str())!=0) {
405 casadi_warning(
"Failed to remove " + solname);
407 if (
verbose_) casadi_message(
"Removed " + solname);
AmplInterface(const std::string &name, const Function &nlp)
static const std::string meta_doc
A documentation string.
int solve(void *mem) const override
static const Options options_
Options.
static Nlpsol * creator(const std::string &name, const Function &nlp)
Create a new NLP Solver.
int init_mem(void *mem) const override
Initalize memory block.
void set_work(void *mem, const double **&arg, double **&res, casadi_int *&iw, double *&w) const override
Set the (persistent) work vectors.
~AmplInterface() override
std::stringstream nl_init_
void init(const Dict &opts) override
Initialize.
const SX sx_in(casadi_int iind) const
Get symbolic primitives equivalent to the input expressions.
bool is_empty(bool both=false) const
Check if the sparsity is empty, i.e. if one of the dimensions is zero.
casadi_int nnz() const
Get the number of (structural) non-zero elements.
Sparse matrix class. SX and DM are specializations.
static Matrix< Scalar > jacobian(const Matrix< Scalar > &f, const Matrix< Scalar > &x, const Dict &opts=Dict())
NLP solver storage class.
static const Options options_
Options.
void init(const Dict &opts) override
Initialize.
casadi_int ng_
Number of constraints.
int init_mem(void *mem) const override
Initalize memory block.
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.
bool is_a(const std::string &type, bool recursive) const override
Check if the function is of a particular type.
const Function & oracle() const override
Get oracle.
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)
Sparsity T() const
Transpose the matrix.
casadi_int nnz() const
Get the number of (structural) non-zeros.
const casadi_int * row() const
Get a reference to row-vector,.
const casadi_int * colind() const
Get a reference to the colindex of all column element (see class description)
int CASADI_NLPSOL_AMPL_EXPORT casadi_register_nlpsol_ampl(Nlpsol::Plugin *plugin)
@ NL_F
Objective function.
@ NL_G
Constraint function.
std::string temporary_file(const std::string &prefix, const std::string &suffix)
void CASADI_NLPSOL_AMPL_EXPORT casadi_load_nlpsol_ampl()
std::string str(const T &v)
String representation, any type.
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.
const double nan
Not a number.
bool remove(const std::string &path)
casadi_nlpsol_data< double > d_nlp
Options metadata for a class.
Easy access to all the functions for a particular type.