1 /*
2  *    This file is part of CasADi.
3  *
4  *    CasADi -- A symbolic framework for dynamic optimization.
5  *    Copyright (C) 2010-2014 Joel Andersson, Joris Gillis, Moritz Diehl,
6  *                            K.U. Leuven. All rights reserved.
7  *    Copyright (C) 2011-2014 Greg Horn
8  *
9  *    CasADi is free software; you can redistribute it and/or
10  *    modify it under the terms of the GNU Lesser General Public
11  *    License as published by the Free Software Foundation; either
12  *    version 3 of the License, or (at your option) any later version.
13  *
14  *    CasADi is distributed in the hope that it will be useful,
15  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  *    Lesser General Public License for more details.
18  *
19  *    You should have received a copy of the GNU Lesser General Public
20  *    License along with CasADi; if not, write to the Free Software
21  *    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22  *
23  */
24 
25 #include "optistack_internal.hpp"
26 #include "exception.hpp"
27 #include "global_options.hpp"
28 
29 using namespace std;
30 namespace casadi {
31 
32 // Throw informative error message
33 #define THROW_ERROR(FNAME, WHAT) \
34 throw CasadiException("Error in Opti::" FNAME " "\
35   "[" + this->class_name() + "] at " + CASADI_WHERE + ":\n"\
36   + string(WHAT));
37 
38 
operator ->()39 OptiNode* Opti::operator->() {
40   if (getCount()!=1) *this = copy();
41   return static_cast<OptiNode*>(SharedObject::operator->());
42 }
43 
operator ->() const44 const OptiNode* Opti::operator->() const {
45   return static_cast<const OptiNode*>(SharedObject::operator->());
46 }
47 
48 
Opti(const std::string & problem_type)49 Opti::Opti(const std::string& problem_type) {
50   own(OptiNode::create(problem_type));
51 }
52 
variable(casadi_int n,casadi_int m,const std::string & attribute)53 MX Opti::variable(casadi_int n, casadi_int m, const std::string& attribute) {
54   try {
55     return (*this)->variable(n, m, attribute);
56   } catch (exception& e) {
57     THROW_ERROR("variable", e.what());
58   }
59 }
60 
Opti(OptiNode * node)61 Opti::Opti(OptiNode* node) {
62   own(node);
63 }
64 
Opti(const Opti & rhs)65 Opti::Opti(const Opti& rhs) : SharedObject(rhs) {
66   callback_class();
67 }
68 
OptiAdvanced(const Opti & rhs)69 OptiAdvanced::OptiAdvanced(const Opti& rhs) : Opti(rhs) {
70 }
71 
create(OptiNode * node)72 Opti Opti::create(OptiNode* node) {
73   return Opti(node);
74 }
75 
parameter(casadi_int n,casadi_int m,const std::string & attribute)76 MX Opti::parameter(casadi_int n, casadi_int m, const std::string& attribute) {
77   try {
78     return (*this)->parameter(n, m, attribute);
79   } catch (exception& e) {
80     THROW_ERROR("parameter", e.what());
81   }
82 }
83 
minimize(const MX & f)84 void Opti::minimize(const MX& f) {
85   try {
86     (*this)->minimize(f);
87   } catch (exception& e) {
88     THROW_ERROR("minimize", e.what());
89   }
90 }
91 
subject_to(const MX & g)92 void Opti::subject_to(const MX& g) {
93   try {
94     (*this)->subject_to(g);
95   } catch (exception& e) {
96     THROW_ERROR("subject_to", e.what());
97   }
98 }
99 
subject_to(const std::vector<MX> & g)100 void Opti::subject_to(const std::vector<MX>& g) {
101   for (const auto& gs : g) subject_to(gs);
102 }
103 
subject_to()104 void Opti::subject_to() {
105   try {
106     (*this)->subject_to();
107   } catch (exception& e) {
108     THROW_ERROR("subject_to", e.what());
109   }
110 }
111 
112 
solver(const std::string & solver,const Dict & plugin_options,const Dict & solver_options)113 void Opti::solver(const std::string& solver,
114                        const Dict& plugin_options,
115                        const Dict& solver_options) {
116   try {
117     (*this)->solver(solver, plugin_options, solver_options);
118   } catch (exception& e) {
119     THROW_ERROR("solver", e.what());
120   }
121 }
122 
set_initial(const MX & x,const DM & v)123 void Opti::set_initial(const MX& x, const DM& v) {
124   try {
125     (*this)->set_initial(x, v);
126   } catch (exception& e) {
127     THROW_ERROR("set_initial", e.what());
128   }
129 }
set_initial(const std::vector<MX> & assignments)130 void Opti::set_initial(const std::vector<MX>& assignments) {
131   try {
132     (*this)->set_initial(assignments);
133   } catch (exception& e) {
134     THROW_ERROR("set_initial", e.what());
135   }
136 }
137 
138 
set_value(const MX & x,const DM & v)139 void Opti::set_value(const MX& x, const DM& v) {
140   try {
141     (*this)->set_value(x, v);
142   } catch (exception& e) {
143     THROW_ERROR("set_value", e.what());
144   }
145 }
146 
set_value(const std::vector<MX> & assignments)147 void Opti::set_value(const std::vector<MX>& assignments) {
148   try {
149     (*this)->set_value(assignments);
150   } catch (exception& e) {
151     THROW_ERROR("set_value", e.what());
152   }
153 }
154 
solve()155 OptiSol Opti::solve() {
156   try {
157     return (*this)->solve(false);
158   } catch (exception& e) {
159     THROW_ERROR("solve", e.what());
160   }
161 }
162 
solve_limited()163 OptiSol Opti::solve_limited() {
164   try {
165     return (*this)->solve(true);
166   } catch (exception& e) {
167     THROW_ERROR("solve", e.what());
168   }
169 }
170 
value(const MX & x,const std::vector<MX> & values) const171 DM Opti::value(const MX& x, const std::vector<MX>& values) const {
172   try {
173     return (*this)->value(x, values);
174   } catch (exception& e) {
175     THROW_ERROR("value", e.what());
176   }
177 }
178 
179 
value(const DM & x,const std::vector<MX> & values) const180 DM Opti::value(const DM& x, const std::vector<MX>& values) const {
181   try {
182     return (*this)->value(x, values);
183   } catch (exception& e) {
184     THROW_ERROR("value", e.what());
185   }
186 }
187 
value(const SX & x,const std::vector<MX> & values) const188 DM Opti::value(const SX& x, const std::vector<MX>& values) const {
189   try {
190     return (*this)->value(x, values);
191   } catch (exception& e) {
192     THROW_ERROR("value", e.what());
193   }
194 }
195 
stats() const196 Dict Opti::stats() const {
197   try {
198     return (*this)->stats();
199   } catch (exception& e) {
200     THROW_ERROR("stats", e.what());
201   }
202 }
203 
return_status() const204 std::string Opti::return_status() const {
205   try {
206     return (*this)->return_status();
207   } catch (exception& e) {
208     THROW_ERROR("return_status", e.what());
209   }
210 }
211 
initial() const212 std::vector<MX> Opti::initial() const {
213   try {
214     return (*this)->initial();
215   } catch (exception& e) {
216     THROW_ERROR("initial", e.what());
217   }
218 }
219 
value_variables() const220 std::vector<MX> Opti::value_variables() const {
221   try {
222     return (*this)->value_variables();
223   } catch (exception& e) {
224     THROW_ERROR("value_variables", e.what());
225   }
226 }
227 
value_parameters() const228 std::vector<MX> Opti::value_parameters() const {
229   try {
230     return (*this)->value_parameters();
231   } catch (exception& e) {
232     THROW_ERROR("value_parameters", e.what());
233   }
234 }
235 
dual(const MX & m) const236 MX Opti::dual(const MX& m) const {
237   try {
238     return (*this)->dual(m);
239   } catch (exception& e) {
240     THROW_ERROR("dual", e.what());
241   }
242 }
243 
nx() const244 casadi_int Opti::nx() const {
245   try {
246     return (*this)->nx();
247   } catch (exception& e) {
248     THROW_ERROR("nx", e.what());
249   }
250 }
251 
np() const252 casadi_int Opti::np() const {
253   try {
254     return (*this)->np();
255   } catch (exception& e) {
256     THROW_ERROR("nx", e.what());
257   }
258 }
259 
ng() const260 casadi_int Opti::ng() const {
261   try {
262     return (*this)->ng();
263   } catch (exception& e) {
264     THROW_ERROR("ng", e.what());
265   }
266 }
267 
x() const268 MX Opti::x() const {
269   try {
270     return (*this)->x();
271   } catch (exception& e) {
272     THROW_ERROR("x", e.what());
273   }
274 }
275 
p() const276 MX Opti::p() const {
277   try {
278     return (*this)->p();
279   } catch (exception& e) {
280     THROW_ERROR("p", e.what());
281   }
282 }
283 
g() const284 MX Opti::g() const {
285   try {
286     return (*this)->g();
287   } catch (exception& e) {
288     THROW_ERROR("g", e.what());
289   }
290 }
291 
f() const292 MX Opti::f() const {
293   try {
294     return (*this)->f();
295   } catch (exception& e) {
296     THROW_ERROR("f", e.what());
297   }
298 }
299 
lbg() const300 MX Opti::lbg() const {
301   try {
302     return (*this)->lbg();
303   } catch (exception& e) {
304     THROW_ERROR("lbg", e.what());
305   }
306 }
307 
ubg() const308 MX Opti::ubg() const {
309   try {
310     return (*this)->ubg();
311   } catch (exception& e) {
312     THROW_ERROR("ubg", e.what());
313   }
314 }
315 
316 
lam_g() const317 MX Opti::lam_g() const {
318   try {
319     return (*this)->lam_g();
320   } catch (exception& e) {
321     THROW_ERROR("lam_g", e.what());
322   }
323 }
324 
to_function(const std::string & name,const std::vector<MX> & args,const std::vector<MX> & res,const std::vector<std::string> & name_in,const std::vector<std::string> & name_out,const Dict & opts)325 Function Opti::to_function(const std::string& name,
326     const std::vector<MX>& args, const std::vector<MX>& res,
327     const std::vector<std::string>& name_in,
328     const std::vector<std::string>& name_out,
329     const Dict& opts) {
330   try {
331     return (*this)->to_function(name, args, res, name_in, name_out, opts);
332   } catch (exception& e) {
333     THROW_ERROR("to_function", e.what());
334   }
335 }
336 
to_function(const std::string & name,const std::vector<MX> & args,const std::vector<MX> & res,const Dict & opts)337 Function Opti::to_function(const std::string& name,
338     const std::vector<MX>& args, const std::vector<MX>& res,
339     const Dict& opts) {
340   return to_function(name, args, res, {}, {}, opts);
341 }
342 
to_function(const std::string & name,const std::map<std::string,MX> & dict,const std::vector<std::string> & name_in,const std::vector<std::string> & name_out,const Dict & opts)343 Function Opti::to_function(const std::string& name,
344     const std::map<std::string, MX>& dict,
345     const std::vector<std::string>& name_in,
346     const std::vector<std::string>& name_out,
347     const Dict& opts) {
348   std::vector<MX> ex_in(name_in.size()), ex_out(name_out.size());
349   for (auto&& i : dict) {
350     vector<string>::const_iterator it;
351     if ((it=find(name_in.begin(), name_in.end(), i.first))!=name_in.end()) {
352       // Input expression
353       ex_in[it-name_in.begin()] = i.second;
354     } else if ((it=find(name_out.begin(), name_out.end(), i.first))!=name_out.end()) {
355       // Output expression
356       ex_out[it-name_out.begin()] = i.second;
357     } else {
358       // Neither
359       casadi_error("Unknown dictionary entry: '" + i.first + "'");
360     }
361   }
362   return to_function(name, ex_in, ex_out, name_in, name_out, opts);
363 }
364 
callback_class(OptiCallback * callback)365 void Opti::callback_class(OptiCallback* callback) {
366   try {
367     (*this)->callback_class(callback);
368   } catch (exception& e) {
369     THROW_ERROR("callback_class", e.what());
370   }
371 }
372 
callback_class()373 void Opti::callback_class() {
374   try {
375     if ((*this)->has_callback_class() && getCount()!=1) {
376       Opti ret = copy();
377       ret.callback_class();
378       *this = ret;
379     } else {
380       (*this)->callback_class();
381     }
382   } catch (exception& e) {
383     THROW_ERROR("callback_class", e.what());
384   }
385 }
386 
update_user_dict(const MX & m,const Dict & meta)387 void Opti::update_user_dict(const MX& m, const Dict& meta) {
388   try {
389     (*this)->update_user_dict(m, meta);
390   } catch (exception& e) {
391     THROW_ERROR("update_user_dict", e.what());
392   }
393 }
394 
update_user_dict(const std::vector<MX> & ms,const Dict & meta)395 void Opti::update_user_dict(const std::vector<MX>& ms, const Dict& meta) {
396   for (const auto& m : ms)
397      update_user_dict(m, meta);
398 }
399 
user_dict(const MX & m) const400 Dict Opti::user_dict(const MX& m) const {
401   try {
402     return (*this)->user_dict(m);
403   } catch (exception& e) {
404     THROW_ERROR("user_dict", e.what());
405   }
406 }
407 
casadi_solver() const408 Function OptiAdvanced::casadi_solver() const {
409   try {
410     return (*this)->casadi_solver();
411   } catch (exception& e) {
412     THROW_ERROR("casadi_solver", e.what());
413   }
414 }
415 
is_parametric(const MX & expr) const416 bool OptiAdvanced::is_parametric(const MX& expr) const {
417   try {
418     return (*this)->is_parametric(expr);
419   } catch (exception& e) {
420     THROW_ERROR("is_parametric", e.what());
421   }
422 }
423 
symvar() const424 std::vector<MX> OptiAdvanced::symvar() const {
425   try {
426     return (*this)->symvar();
427   } catch (exception& e) {
428     THROW_ERROR("symvar", e.what());
429   }
430 }
431 
symvar(const MX & expr) const432 std::vector<MX> OptiAdvanced::symvar(const MX& expr) const {
433   try {
434     return (*this)->symvar(expr);
435   } catch (exception& e) {
436     THROW_ERROR("symvar", e.what());
437   }
438 }
439 
symvar(const MX & expr,VariableType type) const440 std::vector<MX> OptiAdvanced::symvar(const MX& expr, VariableType type) const {
441   try {
442     return (*this)->symvar(expr, type);
443   } catch (exception& e) {
444     THROW_ERROR("symvar", e.what());
445   }
446 }
447 
canon_expr(const MX & expr) const448 MetaCon OptiAdvanced::canon_expr(const MX& expr) const {
449   try {
450     return (*this)->canon_expr(expr);
451   } catch (exception& e) {
452     THROW_ERROR("canon_expr", e.what());
453   }
454 }
455 
get_meta(const MX & m) const456 MetaVar OptiAdvanced::get_meta(const MX& m) const {
457   try {
458     return (*this)->get_meta(m);
459   } catch (exception& e) {
460     THROW_ERROR("get_meta", e.what());
461   }
462 }
463 
get_meta_con(const MX & m) const464 MetaCon OptiAdvanced::get_meta_con(const MX& m) const {
465   try {
466     return (*this)->get_meta_con(m);
467   } catch (exception& e) {
468     THROW_ERROR("get_meta_con", e.what());
469   }
470 }
471 
set_meta(const MX & m,const MetaVar & meta)472 void OptiAdvanced::set_meta(const MX& m, const MetaVar& meta) {
473   try {
474     (*this)->set_meta(m, meta);
475   } catch (exception& e) {
476     THROW_ERROR("set_meta", e.what());
477   }
478 }
479 
set_meta_con(const MX & m,const MetaCon & meta)480 void OptiAdvanced::set_meta_con(const MX& m, const MetaCon& meta) {
481   try {
482     return (*this)->set_meta_con(m, meta);
483   } catch (exception& e) {
484     THROW_ERROR("set_meta_con", e.what());
485   }
486 }
487 
488 
assert_active_symbol(const MX & m) const489 void OptiAdvanced::assert_active_symbol(const MX& m) const {
490   try {
491     (*this)->assert_active_symbol(m);
492   } catch (exception& e) {
493     THROW_ERROR("assert_active_symbol", e.what());
494   }
495 }
496 
active_symvar(VariableType type) const497 std::vector<MX> OptiAdvanced::active_symvar(VariableType type) const {
498   try {
499     return (*this)->active_symvar(type);
500   } catch (exception& e) {
501     THROW_ERROR("active_symvar", e.what());
502   }
503 }
504 
active_values(VariableType type) const505 std::vector<DM> OptiAdvanced::active_values(VariableType type) const {
506   try {
507     return (*this)->active_values(type);
508   } catch (exception& e) {
509     THROW_ERROR("active_values", e.what());
510   }
511 }
512 
x_lookup(casadi_int i) const513 MX OptiAdvanced::x_lookup(casadi_int i) const {
514   try {
515     return (*this)->x_lookup(i);
516   } catch (exception& e) {
517     THROW_ERROR("x_lookup", e.what());
518   }
519 }
520 
g_lookup(casadi_int i) const521 MX OptiAdvanced::g_lookup(casadi_int i) const {
522   try {
523     return (*this)->g_lookup(i);
524   } catch (exception& e) {
525     THROW_ERROR("g_lookup", e.what());
526   }
527 }
528 
x_describe(casadi_int i) const529 std::string OptiAdvanced::x_describe(casadi_int i) const {
530   try {
531     return (*this)->x_describe(i);
532   } catch (exception& e) {
533     THROW_ERROR("x_describe", e.what());
534   }
535 }
g_describe(casadi_int i) const536 std::string OptiAdvanced::g_describe(casadi_int i) const {
537   try {
538     return (*this)->g_describe(i);
539   } catch (exception& e) {
540     THROW_ERROR("g_describe", e.what());
541   }
542 }
describe(const MX & x,casadi_int indent) const543 std::string OptiAdvanced::describe(const MX& x, casadi_int indent) const {
544   try {
545     return (*this)->describe(x, indent);
546   } catch (exception& e) {
547     THROW_ERROR("describe", e.what());
548   }
549 }
550 
show_infeasibilities(double tol) const551 void OptiAdvanced::show_infeasibilities(double tol) const {
552   std::vector<double> g_ = value(g()).get_elements();
553   std::vector<double> lbg_ = value(lbg()).get_elements();
554   std::vector<double> ubg_ = value(ubg()).get_elements();
555 
556   uout() << "Violated constraints (tol " << tol << "), in order of declaration:" << std::endl;
557   for (casadi_int i=0;i<g_.size();++i) {
558     double err = std::max(g_[i]-ubg_[i], lbg_[i]-g_[i]);
559     if (err>=tol) {
560       uout() << "------- i = " << i+GlobalOptions::start_index;
561       uout() << "/" << g_.size() << " ------ " << std::endl;
562       uout() << lbg_[i] << " <= " << g_[i] << " <= " << ubg_[i];
563       uout() << " (viol " << err << ")" << std::endl;
564       uout() << g_describe(i) << std::endl;
565     }
566   }
567 }
568 
solve_prepare()569 void OptiAdvanced::solve_prepare() {
570   try {
571     (*this)->solve_prepare();
572   } catch (exception& e) {
573     THROW_ERROR("solve_prepare", e.what());
574   }
575 }
solve_actual(const DMDict & args)576 DMDict OptiAdvanced::solve_actual(const DMDict& args) {
577   try {
578     return (*this)->solve_actual(args);
579   } catch (exception& e) {
580     THROW_ERROR("solve_actual", e.what());
581   }
582 }
583 
arg() const584 DMDict OptiAdvanced::arg() const {
585   try {
586     return (*this)->arg();
587   } catch (exception& e) {
588     THROW_ERROR("arg", e.what());
589   }
590 }
591 
592 
res(const DMDict & res)593 void OptiAdvanced::res(const DMDict& res) {
594   try {
595     return (*this)->res(res);
596   } catch (exception& e) {
597     THROW_ERROR("res", e.what());
598   }
599 }
600 
res() const601 DMDict OptiAdvanced::res() const {
602   try {
603     return (*this)->res();
604   } catch (exception& e) {
605     THROW_ERROR("res", e.what());
606   }
607 }
608 
constraints() const609 std::vector<MX> OptiAdvanced::constraints() const {
610   try {
611     return (*this)->constraints();
612   } catch (exception& e) {
613     THROW_ERROR("constraints", e.what());
614   }
615 }
objective() const616 MX OptiAdvanced::objective() const {
617   return f();
618 }
619 
baked_copy() const620 OptiAdvanced OptiAdvanced::baked_copy() const {
621   try {
622     return (*this)->baked_copy();
623   } catch (exception& e) {
624     THROW_ERROR("baked_copy", e.what());
625   }
626 }
627 
assert_empty() const628 void OptiAdvanced::assert_empty() const {
629   try {
630     return (*this)->assert_empty();
631   } catch (exception& e) {
632     THROW_ERROR("assert_empty", e.what());
633   }
634 }
635 
instance_number() const636 casadi_int OptiAdvanced::instance_number() const {
637   try {
638     return (*this)->instance_number();
639   } catch (exception& e) {
640     THROW_ERROR("instance_number", e.what());
641   }
642 }
643 
disp(std::ostream & stream,bool more) const644 void Opti::disp(std::ostream& stream, bool more) const {
645   stream << "Opti {" << std::endl;
646   OptiAdvanced mycopy = debug();
647   stream << "  instance #" << mycopy.instance_number() << std::endl;
648   if (mycopy.problem_dirty()) mycopy.bake();
649   stream << "  #variables: " << mycopy.active_symvar(OPTI_VAR).size()
650     << " (nx = " << mycopy.nx() << ")" <<  std::endl;
651   stream << "  #parameters: " << mycopy.active_symvar(OPTI_PAR).size()
652     << " (np = " << mycopy.np() << ")" << std::endl;
653   stream << "  #constraints: " << mycopy.active_symvar(OPTI_DUAL_G).size()
654     << " (ng = " << mycopy.ng() << ")" << std::endl;
655   if (mycopy.solver_dirty()) {
656     stream << "  CasADi solver needs updating." << std::endl;
657   } else {
658     stream << "  CasADi solver allocated." << std::endl;
659   }
660   if (mycopy.solved()) {
661     stream << "  CasADi solver was called: " << mycopy.return_status() << std::endl;
662   }
663   stream << "}";
664 }
665 
get_str(bool more) const666 std::string Opti::get_str(bool more) const {
667     std::stringstream ss;
668     disp(ss, more);
669     return ss.str();
670 }
671 
bake()672 void OptiAdvanced::bake() {
673   try {
674     (*this)->bake();
675   } catch (exception& e) {
676     THROW_ERROR("bake", e.what());
677   }
678 }
679 
mark_problem_dirty(bool flag)680 void OptiAdvanced::mark_problem_dirty(bool flag) {
681   try {
682     (*this)->mark_problem_dirty(flag);
683   } catch (exception& e) {
684     THROW_ERROR("mark_problem_dirty", e.what());
685   }
686 }
problem_dirty() const687 bool OptiAdvanced::problem_dirty() const {
688   try {
689     return (*this)->problem_dirty();
690   } catch (exception& e) {
691     THROW_ERROR("problem_dirty", e.what());
692   }
693 }
694 
mark_solver_dirty(bool flag)695 void OptiAdvanced::mark_solver_dirty(bool flag) {
696   try {
697     (*this)->mark_solver_dirty(flag);
698   } catch (exception& e) {
699     THROW_ERROR("mark_solver_dirty", e.what());
700   }
701 }
solver_dirty() const702 bool OptiAdvanced::solver_dirty() const {
703   try {
704     return (*this)->solver_dirty();
705   } catch (exception& e) {
706     THROW_ERROR("solver_dirty", e.what());
707   }
708 }
709 
mark_solved(bool flag)710 void OptiAdvanced::mark_solved(bool flag) {
711   try {
712     (*this)->mark_solved(flag);
713   } catch (exception& e) {
714     THROW_ERROR("mark_solved", e.what());
715   }
716 }
717 
solved() const718 bool OptiAdvanced::solved() const {
719   try {
720     return (*this)->solved();
721   } catch (exception& e) {
722     THROW_ERROR("solved", e.what());
723   }
724 }
725 
assert_solved() const726 void OptiAdvanced::assert_solved() const {
727   try {
728     (*this)->assert_solved();
729   } catch (exception& e) {
730     THROW_ERROR("assert_solved", e.what());
731   }
732 }
assert_baked() const733 void OptiAdvanced::assert_baked() const {
734   try {
735     (*this)->assert_baked();
736   } catch (exception& e) {
737     THROW_ERROR("assert_baked", e.what());
738   }
739 }
740 
debug() const741 OptiAdvanced Opti::debug() const {
742   return *this;
743 }
advanced() const744 OptiAdvanced Opti::advanced() const {
745   return *this;
746 }
copy() const747 Opti Opti::copy() const {
748   return (*this)->copy();
749 }
750 
OptiSol(const Opti & opti)751 OptiSol::OptiSol(const Opti& opti) : optistack_(opti) {
752 }
753 
disp(std::ostream & stream,bool more) const754 void OptiSol::disp(std::ostream& stream, bool more) const {
755   optistack_.disp(stream, more);
756 }
757 
get_str(bool more) const758 std::string OptiSol::get_str(bool more) const {
759   return optistack_.get_str(more);
760 }
761 
value(const MX & x,const std::vector<MX> & values) const762 DM OptiSol::value(const MX& x, const std::vector<MX>& values) const {
763   return optistack_.value(x, values);
764 }
value(const DM & x,const std::vector<MX> & values) const765 DM OptiSol::value(const DM& x, const std::vector<MX>& values) const {
766   return optistack_.value(x, values);
767 }
value(const SX & x,const std::vector<MX> & values) const768 DM OptiSol::value(const SX& x, const std::vector<MX>& values) const {
769   return optistack_.value(x, values);
770 }
771 
value_variables() const772 std::vector<MX> OptiSol::value_variables() const {
773   return optistack_.value_variables();
774 }
775 
value_parameters() const776 std::vector<MX> OptiSol::value_parameters() const {
777   return optistack_.value_parameters();
778 }
779 
stats() const780 Dict OptiSol::stats() const {
781   return optistack_.stats();
782 }
783 
784 
785 
786 
787 } // namespace casadi
788