26 #include "ampl_interface.hpp"
27 #include "casadi/core/casadi_misc.hpp"
28 #include "casadi/core/filesystem_impl.hpp"
35 int CASADI_NLPSOL_AMPL_EXPORT
38 plugin->name =
"ampl";
40 plugin->version = CASADI_VERSION;
63 "AMPL solver binary"}}
75 for (
auto&& op : opts) {
76 if (op.first==
"solver") {
77 solver_ = op.second.to_string();
83 "Only SX supported currently.");
85 std::vector<SX> fg =
oracle()(xp);
92 casadi_assert(p.
is_empty(),
"'p' currently not supported");
95 std::vector<std::string> x_name, g_name;
96 for (casadi_int i=0; i<
nx_; ++i) x_name.push_back(
"x[" +
str(i) +
"]");
97 for (casadi_int i=0; i<
ng_; ++i) g_name.push_back(
"g[" +
str(i) +
"]");
98 casadi_int max_x_name = x_name.back().size();
99 casadi_int max_g_name = g_name.empty() ? 0 : g_name.back().size();
106 std::vector<SX> ex = {f, g}, v, vdef;
149 << jac_f.
nnz() <<
"\n";
153 << max_g_name <<
"\n";
163 Function F(
"F", {vertcat(v), x}, {vertcat(vdef), f, g},
164 {
"v",
"x"}, {
"vdef",
"f",
"g"});
167 std::vector<std::string> work(F.sz_w());
170 for (casadi_int k=0; k<F.n_instructions(); ++k) {
172 casadi_int op = F.instruction_id(k);
174 std::vector<casadi_int> o = F.instruction_output(k);
175 casadi_int o0=-1, o1=-1, i0=-1, i1=-1;
176 if (!o.empty()) o0 = o[0];
177 if (o.size()>1) o1 = o[1];
178 std::vector<casadi_int> i = F.instruction_input(k);
179 if (!i.empty()) i0 = i[0];
180 if (i.size()>1) i1 = i[1];
183 work[o0] =
"n" +
str(F.instruction_constant(k)) +
"\n";
186 work[o0] =
"v" +
str(i0*v.size() + i1) +
"\n";
191 nl_init_ <<
"V" << (x.
nnz()+o1) <<
" 0 0\n" << work[i0];
194 nl_init_ <<
"O" << o1 <<
" 0\n" << work[i0];
197 nl_init_ <<
"C" << o1 <<
"\n" << work[i0];
200 case OP_ADD: work[o0] =
"o0\n" + work[i0] + work[i1];
break;
201 case OP_SUB: work[o0] =
"o1\n" + work[i0] + work[i1];
break;
202 case OP_MUL: work[o0] =
"o2\n" + work[i0] + work[i1];
break;
203 case OP_DIV: work[o0] =
"o3\n" + work[i0] + work[i1];
break;
204 case OP_SQ: work[o0] =
"o5\n" + work[i0] +
"n2\n";
break;
205 case OP_POW: work[o0] =
"o5\n" + work[i0] + work[i1];
break;
206 case OP_FLOOR: work[o0] =
"o13\n" + work[i0];
break;
207 case OP_CEIL: work[o0] =
"o14\n" + work[i0];
break;
208 case OP_FABS: work[o0] =
"o15\n" + work[i0];
break;
209 case OP_NEG: work[o0] =
"o16\n" + work[i0];
break;
210 case OP_TANH: work[o0] =
"o37\n" + work[i0];
break;
211 case OP_TAN: work[o0] =
"o38\n" + work[i0];
break;
212 case OP_SQRT: work[o0] =
"o39\n" + work[i0];
break;
213 case OP_SINH: work[o0] =
"o40\n" + work[i0];
break;
214 case OP_SIN: work[o0] =
"o41\n" + work[i0];
break;
215 case OP_LOG: work[o0] =
"o43\n" + work[i0];
break;
216 case OP_EXP: work[o0] =
"o44\n" + work[i0];
break;
217 case OP_COSH: work[o0] =
"o45\n" + work[i0];
break;
218 case OP_COS: work[o0] =
"o46\n" + work[i0];
break;
219 case OP_ATANH: work[o0] =
"o47\n" + work[i0];
break;
220 case OP_ATAN2: work[o0] =
"o48\n" + work[i0] + work[i1];
break;
221 case OP_ATAN: work[o0] =
"o49\n" + work[i0];
break;
222 case OP_ASINH: work[o0] =
"o50\n" + work[i0];
break;
223 case OP_ASIN: work[o0] =
"o51\n" + work[i0];
break;
224 case OP_ACOSH: work[o0] =
"o52\n" + work[i0];
break;
225 case OP_ACOS: work[o0] =
"o53\n" + work[i0];
break;
236 const casadi_int *colind = jac_g.
colind(), *row = jac_g.
row();
238 for (casadi_int i=1; i<
nx_; ++i)
nl_init_ << colind[i] <<
"\n";
243 for (casadi_int i=0; i<
ng_; ++i) {
244 nl_init_ <<
"J" << i <<
" " << (colind[i+1]-colind[i]) <<
"\n";
245 for (casadi_int k=colind[i]; k<colind[i+1]; ++k) {
254 nl_init_ <<
"G" << 0 <<
" " << (colind[0+1]-colind[0]) <<
"\n";
255 for (casadi_int k=colind[0]; k<colind[0+1]; ++k) {
269 casadi_int*& iw,
double*& w)
const {
279 auto d_nlp = &m->
d_nlp;
284 std::ostream& nl = *nl_ptr;
286 if (
verbose_) casadi_message(
"Opened " + nlname);
290 nl <<
"x" <<
nx_ <<
"\n";
291 for (casadi_int i=0; i<
nx_; ++i) {
292 nl << i <<
" " << d_nlp->z[i] <<
"\n";
298 for (casadi_int i=0; i<
ng_; ++i) {
299 double lbg = d_nlp->lbz[i+
nx_];
300 double ubg = d_nlp->ubz[i+
nx_];
305 nl <<
"1 " << ubg <<
"\n";
309 nl <<
"2 " << lbg <<
"\n";
310 }
else if (ubg==lbg) {
311 nl <<
"4 " << lbg <<
"\n";
313 nl <<
"0 " << lbg <<
" " << ubg <<
"\n";
320 for (casadi_int i=0; i<
nx_; ++i) {
321 double lbx = d_nlp->lbz[i];
322 double ubx = d_nlp->ubz[i];
327 nl <<
"1 " << ubx <<
"\n";
331 nl <<
"2 " << lbx <<
"\n";
332 }
else if (ubx==lbx) {
333 nl <<
"4 " << lbx <<
"\n";
335 nl <<
"0 " << lbx <<
" " << ubx <<
"\n";
349 std::string system_cmd =
solver_ +
" -o" + solname +
" " + nlname +
" > " + outname;
350 int ret = system(system_cmd.c_str());
351 casadi_assert_dev(ret==0);
354 if (
remove(nlname.c_str())!=0) {
355 casadi_warning(
"Failed to remove " + nlname);
357 if (
verbose_) casadi_message(
"Removed " + nlname);
361 std::istream& out = *out_ptr;
365 uout() << line <<
"\n";
370 if (
remove(outname.c_str())!=0) {
371 casadi_warning(
"Failed to remove " + outname);
373 if (
verbose_) casadi_message(
"Removed " + outname);
377 std::istream& sol = *sol_ptr;
378 if (
verbose_) casadi_message(
"Opened " + solname);
381 std::vector<std::string> sol_lines;
384 sol_lines.push_back(line);
388 for (casadi_int i=0; i<
nx_; ++i) {
389 std::istringstream s(sol_lines.at(sol_lines.size() -
nx_ + i - 1));
394 for (casadi_int i=0; i<
nx_; ++i) {
399 for (casadi_int i=0; i<
ng_; ++i) {
400 std::istringstream s(sol_lines.at(sol_lines.size() -
ng_ -
nx_ + i - 1));
401 s >> d_nlp->lam[i +
nx_];
402 d_nlp->lam[i +
nx_] *= -1;
407 if (
remove(solname.c_str())!=0) {
408 casadi_warning(
"Failed to remove " + solname);
410 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.
static std::unique_ptr< std::ostream > ofstream_ptr(const std::string &path, std::ios_base::openmode mode=std::ios_base::out)
static std::unique_ptr< std::istream > ifstream_ptr(const std::string &path, std::ios_base::openmode mode=std::ios_base::in, bool fail=true)
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.