26 #include "nlp_builder.hpp"
28 #include "filesystem_impl.hpp"
39 stream <<
"#x=" << this->
x.size() <<
", #g=" << this->
g.size();
42 stream <<
"x = " << this->
x << std::endl;
43 stream <<
"f = " << this->
f << std::endl;
44 stream <<
"g = " << this->
g << std::endl;
52 std::istream& s = *s_ptr_;
55 for (
auto&& op : opts) {
56 if (op.first ==
"verbose") {
60 ss <<
"Unknown option \"" << op.first <<
"\"" << std::endl;
65 if (verbose_) casadi_message(
"Reading file \"" +
filename +
"\"");
68 const casadi_int header_sz = 10;
69 std::vector<std::string> header(header_sz);
70 for (casadi_int k=0; k<header_sz; ++k) {
71 getline(s, header[k]);
75 if (header.at(0).at(0)==
'g') {
77 }
else if (header.at(0).at(0)==
'b') {
80 casadi_error(
"File could not be read");
84 std::stringstream ss(header[1]);
85 ss >> n_var_ >> n_con_ >> n_obj_ >> n_eq_ >> n_lcon_;
87 casadi_message(
"n_var=" +
str(n_var_) +
", n_con =" +
str(n_con_) +
", "
88 "n_obj=" +
str(n_obj_) +
", n_eq=" +
str(n_eq_) +
", "
89 "n_lcon=" +
str(n_lcon_));
93 std::stringstream ss4(header[4]);
94 ss4 >> nlvc_ >> nlvo_ >> nlvb_;
96 casadi_message(
"nlvc=" +
str(nlvc_) +
", nlvo=" +
str(nlvo_) +
", nlvb=" +
str(nlvb_));
100 std::stringstream ss6(header[6]);
101 ss6 >> nbv_ >> niv_ >> nlvbi_ >> nlvci_ >> nlvoi_;
103 casadi_message(
"nbv=" +
str(nbv_) +
", niv =" +
str(niv_) +
", "
104 "nlvbi=" +
str(nlvbi_) +
", nlvci=" +
str(nlvci_) +
", "
105 "nlvoi=" +
str(nlvoi_));
109 nlp_.
x =
MX::sym(
"x", 1, 1, n_var_);
113 nlp_.
g.resize(n_con_, 0);
116 nlp_.
x_lb.resize(n_var_, -
inf);
118 nlp_.
x_init.resize(n_var_, 0);
121 nlp_.
g_lb.resize(n_con_, -
inf);
130 for (casadi_int j=0; j<nlvb_-nlvbi_; ++j) nlp_.
discrete.push_back(
false);
133 for (casadi_int j=0; j<nlvbi_; ++j) nlp_.
discrete.push_back(
true);
136 for (casadi_int j=0; j<nlvc_ - (nlvb_ + nlvci_); ++j) nlp_.
discrete.push_back(
false);
139 for (casadi_int j=0; j<nlvci_; ++j) nlp_.
discrete.push_back(
true);
142 for (casadi_int j=0; j<nlvo_ - (nlvc_ + nlvoi_); ++j) nlp_.
discrete.push_back(
false);
145 for (casadi_int j=0; j < nlvoi_; ++j) nlp_.
discrete.push_back(
true);
148 casadi_int max_nlvc_nlvo = (nlvc_ < nlvo_) ? nlvo_ : nlvc_;
149 for (casadi_int j=0; j<n_var_-(max_nlvc_nlvo+niv_+nbv_); ++j) nlp_.
discrete.push_back(
false);
152 for (casadi_int j = 0; j<nbv_; ++j) nlp_.
discrete.push_back(
true);
155 for (casadi_int j = 0; j<niv_; ++j) nlp_.
discrete.push_back(
true);
157 casadi_assert(nlp_.
discrete.size()==n_var_,
158 "Number of variables in the header don't match");
164 std::streampos offset = s.tellg();
167 s_ptr_->seekg(offset);
174 nlp_.
f = sign_*nlp_.
f;
182 void NlImporter::parse() {
190 if (s_ptr_->eof())
break;
192 case 'F': F_segment();
break;
193 case 'S': S_segment();
break;
194 case 'V': V_segment();
break;
195 case 'C': C_segment();
break;
196 case 'L': L_segment();
break;
197 case 'O': O_segment();
break;
198 case 'd': d_segment();
break;
199 case 'x': x_segment();
break;
200 case 'r': r_segment();
break;
201 case 'b': b_segment();
break;
202 case 'k': k_segment();
break;
203 case 'J': J_segment();
break;
204 case 'G': G_segment();
break;
205 default: casadi_error(
"Unknown .nl segment");
210 MX NlImporter::expr() {
212 char inst = read_char();
219 std::stringstream msg;
254 d =
static_cast<double>(read_long());
269 case 13:
case 14:
case 15:
case 16:
case 34:
case 37:
case 38:
case 39:
case 40:
270 case 41:
case 43:
case 42:
case 44:
case 45:
case 46:
case 47:
case 49:
case 50:
271 case 51:
case 52:
case 53:
278 case 13:
return floor(x);
279 case 14:
return ceil(x);
280 case 15:
return abs(x);
282 case 34:
return logic_not(x);
283 case 37:
return tanh(x);
284 case 38:
return tan(x);
285 case 39:
return sqrt(x);
286 case 40:
return sinh(x);
287 case 41:
return sin(x);
288 case 42:
return log10(x);
289 case 43:
return log(x);
290 case 44:
return exp(x);
291 case 45:
return cosh(x);
292 case 46:
return cos(x);
294 case 49:
return atan(x);
296 case 51:
return asin(x);
298 case 53:
return acos(x);
301 casadi_error(
"Unknown unary operation: " +
str(i));
307 case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 20:
case 21:
308 case 22:
case 23:
case 24:
case 28:
case 29:
case 30:
case 48:
case 55:
case 56:
309 case 57:
case 58:
case 73:
317 case 0:
return x + y;
318 case 1:
return x - y;
319 case 2:
return x * y;
320 case 3:
return x / y;
322 case 5:
return pow(x, y);
325 case 20:
return logic_or(x, y);
326 case 21:
return logic_and(x, y);
327 case 22:
return x < y;
328 case 23:
return x <= y;
329 case 24:
return x == y;
330 case 28:
return x >= y;
331 case 29:
return x > y;
332 case 30:
return x != y;
333 case 48:
return atan2(x, y);
341 casadi_error(
"Unknown binary operation: " +
str(i));
347 case 11:
case 12:
case 54:
case 59:
case 60:
case 61:
case 70:
case 71:
case 74:
353 std::vector<MX> args(n);
354 for (
int k=0; k<n; ++k) {
372 for (std::vector<MX>::const_iterator it=args.begin();
373 it!=args.end(); ++it) r += *it;
378 casadi_error(
"Unknown n-ary operation: " +
str(i));
385 casadi_error(
"Piecewise linear terms not supported");
389 case 35:
case 65:
case 72:
390 casadi_error(
"If-then-else expressions not supported");
394 casadi_error(
"Unknown operation: " +
str(i));
399 uout() << s_ptr_->tellg() << std::endl;
400 casadi_error(
"Unknown instruction: " +
str(inst));
404 casadi_error(
"Unknown error");
407 void NlImporter::F_segment() {
408 casadi_error(
"Imported function description unsupported.");
411 void NlImporter::S_segment() {
412 casadi_error(
"Suffix values unsupported");
415 void NlImporter::V_segment() {
422 if (i >= v_.size()) {
430 for (
int jj=0; jj<j; ++jj) {
433 double cl = read_double();
436 casadi_assert(!v_.at(pl).is_empty(),
"Circular dependencies not supported");
437 v_.at(i) += cl*v_.at(pl);
444 int NlImporter::read_int() {
445 std::istream& s = *s_ptr_;
448 s.read(
reinterpret_cast<char *
>(&i),
sizeof(
int));
455 char NlImporter::read_char() {
456 std::istream& s = *s_ptr_;
466 double NlImporter::read_double() {
467 std::istream& s = *s_ptr_;
470 s.read(
reinterpret_cast<char *
>(&d),
sizeof(
double));
477 short NlImporter::read_short() {
478 std::istream& s = *s_ptr_;
481 s.read(
reinterpret_cast<char *
>(&d), 2);
488 long NlImporter::read_long() {
489 std::istream& s = *s_ptr_;
492 s.read(
reinterpret_cast<char *
>(&d), 4);
499 void NlImporter::C_segment() {
504 nlp_.
g.at(i) = expr();
507 void NlImporter::L_segment() {
508 casadi_error(
"Logical constraint expression unsupported");
511 void NlImporter::O_segment() {
516 int sigma= read_int();
517 sign_ = sigma!=0 ? -1 : 1;
523 void NlImporter::d_segment() {
528 for (
int i=0; i<m; ++i) {
530 int offset = read_int();
531 double d = read_double();
538 void NlImporter::x_segment() {
543 for (
int i=0; i<m; ++i) {
545 int offset = read_int();
546 double d = read_double();
549 nlp_.
x_init.at(offset) = d;
553 void NlImporter::r_segment() {
555 for (
int i=0; i<n_con_; ++i) {
558 char c_type = read_char();
591 nlp_.
g_lb.at(i) = nlp_.
g_ub.at(i) = c;
600 casadi_error(
"Complementary constraints unsupported");
605 casadi_error(
"Illegal constraint type");
610 void NlImporter::b_segment() {
612 for (casadi_int i=0; i<n_var_; ++i) {
615 char c_type = read_char();
648 nlp_.
x_lb.at(i) = nlp_.
x_ub.at(i) = c;
652 casadi_error(
"Illegal variable bound type");
657 void NlImporter::k_segment() {
659 std::vector<casadi_int> rowind(n_var_+1);
663 casadi_assert_dev(k==n_var_-1);
667 for (
int i=0; i<k; ++i) {
668 rowind[i+1] = read_int();
672 void NlImporter::J_segment() {
678 for (
int kk=0; kk<k; ++kk) {
681 double c = read_double();
684 nlp_.
g.at(i) += c*v_.at(j);
688 void NlImporter::G_segment() {
694 for (
int kk=0; kk<k; ++kk) {
697 double c = read_double();
700 nlp_.
f += c*v_.at(j);
static std::unique_ptr< std::istream > ifstream_ptr(const std::string &path, std::ios_base::openmode mode=std::ios_base::in, bool fail=true)
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)