Skip to main content
Version: v0.7.0 beta

Supported Problem Formulation

OPTIMake solves the following optimization problem:

min⁡v1,⋯ ,vN∑i=1Nl(vi,p)+le(vN,p)subject tofs(v1,p)=0,f(vi,vi+1,p)=0,i=1,⋯ ,N−1,fe(vN,p)=0,g(vi,p)≥0,i=1,⋯ ,N\begin{split} &\quad \quad \quad \min_{v_1,\cdots,v_N} \sum_{i=1}^{N} l(v_i, p) + l_e(v_N, p) \\ &\begin{split} \text{subject to} &\quad f_s(v_1, p) = 0,\\ &\quad f(v_{i}, v_{i+1}, p) = 0,\quad i=1,\cdots,N - 1,\\ &\quad f_e(v_N, p) = 0,\\ &\quad g(v_i, p) \geq 0,\quad i=1,\cdots,N \end{split} \end{split}

This optimization problem has NN stages and may be a nonlinear non-convex optimization problem. Where:

  • v1,⋯ ,vN∈Rnvv_1,\cdots,v_N \in \mathbb{R}^{n_{v}} are the optimization variables
  • p∈Rnpp\in \mathbb{R}^{n_{p}} are the parameters
  • l:Rnv×Rnp→Rl: \mathbb{R}^{n_{v}} \times \mathbb{R}^{n_{p}} \rightarrow \mathbb{R} is the stage objective
  • le:Rnv×Rnp→Rl_e: \mathbb{R}^{n_{v}} \times \mathbb{R}^{n_{p}} \rightarrow \mathbb{R} is the additional objective at the terminal point
  • fs:Rnv×Rnp→Rnfsf_s: \mathbb{R}^{n_{v}} \times \mathbb{R}^{n_{p}} \rightarrow \mathbb{R}^{n_{f_s}} is the initial equality constraint
  • f:Rnv×Rnv×Rnp→Rnff: \mathbb{R}^{n_{v}} \times \mathbb{R}^{n_{v}} \times \mathbb{R}^{n_{p}} \rightarrow \mathbb{R}^{n_{f}} is the transition equality constraint
  • fe:Rnv×Rnp→Rnfef_e: \mathbb{R}^{n_{v}} \times \mathbb{R}^{n_{p}} \rightarrow \mathbb{R}^{n_{f_e}} is the terminal equality constraint
  • g:Rnv×Rnp→Rngg: \mathbb{R}^{n_{v}} \times \mathbb{R}^{n_{p}} \rightarrow \mathbb{R}^{n_{g}} is the inequality constraint

Problem Definition​

Below is an example of defining a problem, which specifies the problem name as vehicle, a maximum of 10 stages, and the CasADi symbolic engine:

from optimake import multi_stage_problem

prob = multi_stage_problem(name='vehicle', N=10, symbolic_engine='casadi')

The function parameters are defined as follows:

  • name: str The name of the problem, which will be used in generated code file names, function names, etc.

  • N: int The maximum number of stages for the problem, must be greater than or equal to 1

  • symbolic_engine: str The engine used for symbolic modeling, differentiation, and code generation of the model functions. Valid values are 'sympy' and 'casadi', and the default value is 'sympy'. Derivatives such as the Jacobian and Hessian are generated automatically by the selected engine.

info
  • Since the above optimization problem is a multi-stage optimization problem, the equality and inequality constraint expressions are identical across all stages, so they only need to be defined once rather than separately for each stage (the same applies to parameters and optimization variables)
  • N is the maximum number of stages. OPTIMake supports dynamic stage counts, meaning the effective number of stages can be set to less than N at solve time, but cannot exceed N

Choosing and Using a Symbolic Engine​

Both engines can be used to define objectives, dynamics, and constraints. The main differences are as follows:

ItemSymPy ('sympy')CasADi ('casadi')
Use caseSimple symbolic expressions, e.g., vehicle kinematic modelsComplex symbolic expressions, e.g., robot kinematic/dynamic models
Expressions and differentiationSymPy expressions, symbolic differentiationCasADi SX computational graph, automatic differentiation
Return type of Matrixsympy.Matrixcasadi.SX
A * B for two matricesMatrix multiplicationElement-wise multiplication; use A @ B or casadi.mtimes(A, B) for matrix multiplication

To make the modeling code work with both engines, you can use the Matrix, sin, cos, and other interfaces provided by OPTIMake, and consistently use matmul(A, B) for matrix multiplication. These interfaces use the engine selected when the problem is created, so they must be called after the problem is created. For example, continuing with the prob above:

from optimake import Matrix, sin, matmul

theta = prob.variable('theta')
A = Matrix([[1, sin(theta)], [0, 1]])
b = Matrix([theta, 1])
y = matmul(A, b)
info
  • For simple symbolic expressions, SymPy usually generates more efficient code
  • For complex symbolic expressions, code generation with SymPy may take a very long time or even fail; CasADi is recommended in this case
  • Functions supported by CasADi, such as Pinocchio's CasADi interface, can be used directly in symbolic expressions
  • Only one symbolic engine can be used within a single Python process; SymPy and CasADi symbolic expressions cannot be mixed
  • The CasADi engine requires CasADi 3.7.2 or later, which can be installed with the full mode of the client installation

After defining the problem name and number of stages, the following sections describe how to define the parameters, optimization variables, and constraints in the optimization problem.