26 #include "nlp_builder.hpp"
38 stream <<
"#x=" << this->
x.size() <<
", #g=" << this->
g.size();
41 stream <<
"x = " << this->
x << std::endl;
42 stream <<
"f = " << this->
f << std::endl;
43 stream <<
"g = " << this->
g << std::endl;
53 for (
auto&& op : opts) {
54 if (op.first ==
"verbose") {
58 ss <<
"Unknown option \"" << op.first <<
"\"" << std::endl;
64 if (verbose_) casadi_message(
"Reading file \"" +
filename +
"\"");
67 const casadi_int header_sz = 10;
68 std::vector<std::string> header(header_sz);
69 for (casadi_int k=0; k<header_sz; ++k) {
70 getline(s_, header[k]);
74 if (header.at(0).at(0)==
'g') {
76 }
else if (header.at(0).at(0)==
'b') {
79 casadi_error(
"File could not be read");
83 std::stringstream ss(header[1]);
84 ss >> n_var_ >> n_con_ >> n_obj_ >> n_eq_ >> n_lcon_;
86 casadi_message(
"n_var=" +
str(n_var_) +
", n_con =" +
str(n_con_) +
", "
87 "n_obj=" +
str(n_obj_) +
", n_eq=" +
str(n_eq_) +
", "
88 "n_lcon=" +
str(n_lcon_));
92 std::stringstream ss4(header[4]);
93 ss4 >> nlvc_ >> nlvo_ >> nlvb_;
95 casadi_message(
"nlvc=" +
str(nlvc_) +
", nlvo=" +
str(nlvo_) +
", nlvb=" +
str(nlvb_));
99 std::stringstream ss6(header[6]);
100 ss6 >> nbv_ >> niv_ >> nlvbi_ >> nlvci_ >> nlvoi_;
102 casadi_message(
"nbv=" +
str(nbv_) +
", niv =" +
str(niv_) +
", "
103 "nlvbi=" +
str(nlvbi_) +
", nlvci=" +
str(nlvci_) +
", "
104 "nlvoi=" +
str(nlvoi_));
108 nlp_.
x =
MX::sym(
"x", 1, 1, n_var_);
112 nlp_.
g.resize(n_con_, 0);
115 nlp_.
x_lb.resize(n_var_, -
inf);
117 nlp_.
x_init.resize(n_var_, 0);
120 nlp_.
g_lb.resize(n_con_, -
inf);
129 for (casadi_int j=0; j<nlvb_-nlvbi_; ++j) nlp_.
discrete.push_back(
false);
132 for (casadi_int j=0; j<nlvbi_; ++j) nlp_.
discrete.push_back(
true);
135 for (casadi_int j=0; j<nlvc_ - (nlvb_ + nlvci_); ++j) nlp_.
discrete.push_back(
false);
138 for (casadi_int j=0; j<nlvci_; ++j) nlp_.
discrete.push_back(
true);
141 for (casadi_int j=0; j<nlvo_ - (nlvc_ + nlvoi_); ++j) nlp_.
discrete.push_back(
false);
144 for (casadi_int j=0; j < nlvoi_; ++j) nlp_.
discrete.push_back(
true);
147 casadi_int max_nlvc_nlvo = (nlvc_ < nlvo_) ? nlvo_ : nlvc_;
148 for (casadi_int j=0; j<n_var_-(max_nlvc_nlvo+niv_+nbv_); ++j) nlp_.
discrete.push_back(
false);
151 for (casadi_int j = 0; j<nbv_; ++j) nlp_.
discrete.push_back(
true);
154 for (casadi_int j = 0; j<niv_; ++j) nlp_.
discrete.push_back(
true);
156 casadi_assert(nlp_.
discrete.size()==n_var_,
157 "Number of variables in the header don't match");
163 std::streampos offset = s_.tellg();
165 s_.open(
filename.c_str(), std::ifstream::binary);
173 nlp_.
f = sign_*nlp_.
f;
181 void NlImporter::parse() {
191 case 'F': F_segment();
break;
192 case 'S': S_segment();
break;
193 case 'V': V_segment();
break;
194 case 'C': C_segment();
break;
195 case 'L': L_segment();
break;
196 case 'O': O_segment();
break;
197 case 'd': d_segment();
break;
198 case 'x': x_segment();
break;
199 case 'r': r_segment();
break;
200 case 'b': b_segment();
break;
201 case 'k': k_segment();
break;
202 case 'J': J_segment();
break;
203 case 'G': G_segment();
break;
204 default: casadi_error(
"Unknown .nl segment");
209 MX NlImporter::expr() {
211 char inst = read_char();
218 std::stringstream msg;
253 d =
static_cast<double>(read_long());
268 case 13:
case 14:
case 15:
case 16:
case 34:
case 37:
case 38:
case 39:
case 40:
269 case 41:
case 43:
case 42:
case 44:
case 45:
case 46:
case 47:
case 49:
case 50:
270 case 51:
case 52:
case 53:
277 case 13:
return floor(x);
278 case 14:
return ceil(x);
279 case 15:
return abs(x);
281 case 34:
return logic_not(x);
282 case 37:
return tanh(x);
283 case 38:
return tan(x);
284 case 39:
return sqrt(x);
285 case 40:
return sinh(x);
286 case 41:
return sin(x);
287 case 42:
return log10(x);
288 case 43:
return log(x);
289 case 44:
return exp(x);
290 case 45:
return cosh(x);
291 case 46:
return cos(x);
293 case 49:
return atan(x);
295 case 51:
return asin(x);
297 case 53:
return acos(x);
300 casadi_error(
"Unknown unary operation: " +
str(i));
306 case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 20:
case 21:
307 case 22:
case 23:
case 24:
case 28:
case 29:
case 30:
case 48:
case 55:
case 56:
308 case 57:
case 58:
case 73:
316 case 0:
return x + y;
317 case 1:
return x - y;
318 case 2:
return x * y;
319 case 3:
return x / y;
321 case 5:
return pow(x, y);
324 case 20:
return logic_or(x, y);
325 case 21:
return logic_and(x, y);
326 case 22:
return x < y;
327 case 23:
return x <= y;
328 case 24:
return x == y;
329 case 28:
return x >= y;
330 case 29:
return x > y;
331 case 30:
return x != y;
332 case 48:
return atan2(x, y);
340 casadi_error(
"Unknown binary operation: " +
str(i));
346 case 11:
case 12:
case 54:
case 59:
case 60:
case 61:
case 70:
case 71:
case 74:
352 std::vector<MX> args(n);
353 for (
int k=0; k<n; ++k) {
371 for (std::vector<MX>::const_iterator it=args.begin();
372 it!=args.end(); ++it) r += *it;
377 casadi_error(
"Unknown n-ary operation: " +
str(i));
384 casadi_error(
"Piecewise linear terms not supported");
388 case 35:
case 65:
case 72:
389 casadi_error(
"If-then-else expressions not supported");
393 casadi_error(
"Unknown operation: " +
str(i));
398 uout() << s_.tellg() << std::endl;
399 casadi_error(
"Unknown instruction: " +
str(inst));
403 casadi_error(
"Unknown error");
406 void NlImporter::F_segment() {
407 casadi_error(
"Imported function description unsupported.");
410 void NlImporter::S_segment() {
411 casadi_error(
"Suffix values unsupported");
414 void NlImporter::V_segment() {
421 if (i >= v_.size()) {
429 for (
int jj=0; jj<j; ++jj) {
432 double cl = read_double();
435 casadi_assert(!v_.at(pl).is_empty(),
"Circular dependencies not supported");
436 v_.at(i) += cl*v_.at(pl);
443 int NlImporter::read_int() {
446 s_.read(
reinterpret_cast<char *
>(&i),
sizeof(
int));
453 char NlImporter::read_char() {
463 double NlImporter::read_double() {
466 s_.read(
reinterpret_cast<char *
>(&d),
sizeof(
double));
473 short NlImporter::read_short() {
476 s_.read(
reinterpret_cast<char *
>(&d), 2);
483 long NlImporter::read_long() {
486 s_.read(
reinterpret_cast<char *
>(&d), 4);
493 void NlImporter::C_segment() {
498 nlp_.
g.at(i) = expr();
501 void NlImporter::L_segment() {
502 casadi_error(
"Logical constraint expression unsupported");
505 void NlImporter::O_segment() {
510 int sigma= read_int();
511 sign_ = sigma!=0 ? -1 : 1;
517 void NlImporter::d_segment() {
522 for (
int i=0; i<m; ++i) {
524 int offset = read_int();
525 double d = read_double();
532 void NlImporter::x_segment() {
537 for (
int i=0; i<m; ++i) {
539 int offset = read_int();
540 double d = read_double();
543 nlp_.
x_init.at(offset) = d;
547 void NlImporter::r_segment() {
549 for (
int i=0; i<n_con_; ++i) {
552 char c_type = read_char();
585 nlp_.
g_lb.at(i) = nlp_.
g_ub.at(i) = c;
594 casadi_error(
"Complementary constraints unsupported");
599 casadi_error(
"Illegal constraint type");
604 void NlImporter::b_segment() {
606 for (casadi_int i=0; i<n_var_; ++i) {
609 char c_type = read_char();
642 nlp_.
x_lb.at(i) = nlp_.
x_ub.at(i) = c;
646 casadi_error(
"Illegal variable bound type");
651 void NlImporter::k_segment() {
653 std::vector<casadi_int> rowind(n_var_+1);
657 casadi_assert_dev(k==n_var_-1);
661 for (
int i=0; i<k; ++i) {
662 rowind[i+1] = read_int();
666 void NlImporter::J_segment() {
672 for (
int kk=0; kk<k; ++kk) {
675 double c = read_double();
678 nlp_.
g.at(i) += c*v_.at(j);
682 void NlImporter::G_segment() {
688 for (
int kk=0; kk<k; ++kk) {
691 double c = read_double();
694 nlp_.
f += c*v_.at(j);
static MX sym(const std::string &name, casadi_int nrow=1, casadi_int ncol=1)
Create an nrow-by-ncol symbolic primitive.
NlImporter(NlpBuilder &nlp, const std::string &filename, const Dict &opts)
A symbolic NLP representation.
void disp(std::ostream &stream, bool more=false) const
Print a description of the object.
std::vector< double > x_lb
Bounds on x.
std::vector< double > g_ub
Variables.
std::vector< bool > discrete
Discrete variables.
std::vector< double > lambda_init
Dual initial guess.
std::vector< double > x_ub
Variables.
std::vector< MX > x
Variables.
std::vector< double > g_lb
Bounds on g.
std::vector< MX > g
Constraints.
void import_nl(const std::string &filename, const Dict &opts=Dict())
Import an .nl file.
std::vector< double > x_init
Primal initial guess.
std::string str(const T &v)
String representation, any type.
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.
std::string filename(const std::string &path)