For my latest work, I heavily used CasADi to formulate the stochastic nonlinear optimization problem. Here, I'd like to illustrate several preliminaries and tips that hopefully may be useful for others.

CasADi is an open-source wrapper mainly for nonlinear programmings (NLPs), although you can use CasADi for other optimization algorithms, such as Mixed-Integer Nonlinear Programming (MINLP). These optimization problems can be solved utilizing SQP or interfaces to IPOPT, BlockSQP, WORHP, KNITRO, and SNOPT, which are solvers you can choose. Furthermore, CasADi can also deal with Quadratic programs with integer variables using a primal-dual active set method or interfaces to CPLEX, Gurobi, HPMPC, OOQP, or qpOASES.

What's more, CasADi can solve the problem such as:

\(\begin{array}{ll}\underset{x}{\operatorname{minimize}} & f(x, p) \\ \text { subject to: } &\quad x_{1 b} \leq x \leq x_{\mathrm{ub}} \\ &g_{1 b} \leq g(x, p) \leq g_{\mathrm{ub}}\end{array}\)

using in Matlab, Octave, Python, and C++!

For example, if you want to solve the following NLP,

\(\begin{array}{ll}\underset{x, y, z}{\operatorname{minimize}} & x^{2}+100 z^{2} \\ \text { subject to } & z+(1-x)^{2}-y=0\end{array}\)

you can then solve in C++ as follows:

// #include <casadi/casadi.hpp> using namespace casadi;

// Create scalar/matrix symbols MX x = MX::sym("x",5,1);

// Compose into expressions MX y = norm_2(x);

// Sensitivity of expression -> new expression MX grad_y = gradient(y,x);

// Create a Function to evaluate expression Function f = Function("f",{x},{grad_y});

// Evaluate numerically std::vector grad_y_num = f(DM({1,2,3,4,5}));

Especially, the best feature I love most in CasADi is the Opti stack, which dramatically enhance your NLP coding experience. Note that you can get explanations in detail here.

Say, you are solving the following problem in Matlab

\(\begin{array}{ll} \underset{x, y}{\operatorname{minimize}} & (1-x)^{2}+\left(y-x^{2}\right)^{2} \\ \text { subject to } & x^{2}+y^{2}=1 \\ & y \geq x \end{array}\)

You can easily formulate using CasADi as follows:

  • opti = casadi.Opti();
  • x = opti.variable();
  • y = opti.variable();
  • opti.minimize((1-x)^2+(y-x^2)^2);
  • opti.subject_to(x^2+y^2==1);
  • opti.subject_to(y>=x);
  • opti.solver('ipopt');
  • sol = opti.solve();

Sometimes, your optimization solver cannot find the solution or does not converge to the optimal solution due to various reasons. For example, your formulated function is not smooth so CasADi is not able to calculate Jacobian well, in which you will get NaN as your output of the solver. Or, you may have very tight constraints so the optimization problem itself is already infeasible. CadADi provides us with very powerful debug commands so that you can know which equations or codes are making your problems. For NaN problems, you can use "opti.debug.g_describe" that gives you which element in Jacobian has problems. For infeasible issue, you can use the command "opti.debug.show_infeasibilities" so that the wrapper shows which constraints are violating.

Reference:

J. A. E. Andersson, J. Gillis, G. Horn, J. B. Rawlings, and M. Diehl, “CasADi: a software framework for nonlinear optimization and optimal control,” Mathematical Programming Computation, vol. 11, no. 1, pp. 1–36, Jul. 2018.
@article{Andersson_2018,
    doi = {10.1007/s12532-018-0139-4},
    url = {https://doi.org/10.1007%2Fs12532-018-0139-4},
    year = 2018,
    month = {jul},
    publisher = {Springer Science and Business Media {LLC}},
    volume = {11},
    number = {1},
    pages = {1--36},
    author = {Joel A. E. Andersson and Joris Gillis and Greg Horn and James B. Rawlings and Moritz Diehl},
    title = {{CasADi}: a software framework for nonlinear optimization and optimal control},
    journal = {Mathematical Programming Computation}
}
< bib >

Next Post Previous Post