# 9. Solver Options¶

The default solver options can be loaded when giving a name to the solver with the following command

```
codeoptions = getOptions('solvername');
```

In the documentation below, we assume that you have created this struct and
named it `codeoptions`

.

## 9.1. General options¶

We will first discuss how to change several options that are valid for all the FORCES Pro interfaces.

### 9.1.1. Solver name¶

The name of the solver will be used to name variables, functions, but also the MEX file and associated help file. This helps you to use multiple solvers generated by FORCES within the same software project or Simulink model. To set the name of the solver use:

```
codeoptions.name = 'solvername';
```

Alternatively, you can directly name the solver when generating the options struct by calling:

```
codeoptions = getOptions('solvername');
```

### 9.1.2. Print level¶

To control the amount of information the generated solver prints to the console, set the field `printlevel`

as outlined in Table 9.1.

`printlevel` |
Result | Dependency |
---|---|---|

`0` |
No output will be written. | (None) |

`1` |
Summary line after each solve. | `<stdio.h>` |

`2` (default) |
Summary after each iteration of solver. | `<stdio.h>` |

Note

For `printlevel=0`

, the generated solver has no dependency on any system
library. Otherwise, there will be a dependency on `<stdio.h>`

.

Important

`printlevel`

should always be set to `0`

when recording performance
timings or when deploying the code on an autonomous embedded system.

### 9.1.3. Maximum number of iterations¶

To set the maximum number of iterations of the generated solver, use:

```
codeoptions.maxit = 200;
```

The default maximum number of iterations for all solvers provided by FORCES Pro
is set to `200`

.

### 9.1.4. Compiler optimization level¶

The compiler optimization level can be varied by changing the field `optlevel`

from `0`

to `3`

(default):

```
codeoptions.optlevel = 0;
```

Important

It is recommended to set `optlevel`

to `0`

during prototyping to evaluate
the functionality of the solver without long compilation times. Then set it
back to `3`

when generating code for deployment or timing measurements.

### 9.1.5. Running solvers in parallel¶

The generated solver can be run in parallel on different threads by changing
the field `threadSafeStorage`

from `false`

to `true`

:

```
codeoptions.threadSafeStorage = true;
```

### 9.1.6. Measure Computation time¶

You can measure the time used for executing the generated code by using:

```
codeoptions.timing = 1;
```

By default the execution time is measured. The execution time can be accessed in
the field `solvetime`

of the information structure returned by the solver. In
addition, the execution time is printed in the console if the flag
`printlevel`

is greater than `0`

.

Important

Setting timing on will introduce a dependency on libraries used for accessing the system clock. Timing should be turned off when deploying the code on an autonomous embedded system.

By default when choosing to generate solvers for target platforms, timing is disabled. You can manually enable timing on embedded platforms by using:

```
codeoptions.embedded_timing = 1;
```

### 9.1.7. Datatypes¶

The type of variables can be changed by setting the field `floattype`

as outlined in Table 9.2.

`floattype` |
Decimation | Width (bits) | Supported algorithms |
---|---|---|---|

`'double'` (default) |
64 bit | Floating point | PDIP, PDIP_NLP, ADMM, DFG, FG |

`'float'` |
32 bit | Floating point | PDIP, PDIP_NLP, ADMM, DFG, FG |

`'int'` |
32 bit | Fixed point | PDIP, PDIP_NLP, ADMM, DFG, FG |

`'short'` |
16 bit | Fixed point | PDIP, PDIP_NLP, ADMM, DFG, FG |

Important

Unless running on a resource-constrained platform, we recommend using double
precision floating point arithmetics to avoid problems in the solver. If
single precision floating point has to be used, reduce the required tolerances
on the solver accordingly by a power of two (i.e. from `1E-6`

to `1E-3`

).

### 9.1.8. Overwriting existing solvers¶

When a new solver is generated with the same name as an existing solver one can
control the overwriting behaviour by setting the field `overwrite`

as outlined
in Table 9.3.

`overwrite` |
Result |
---|---|

`0` |
Never overwrite. |

`1` |
Always overwrite. |

`2` (default) |
Ask to overwrite. |

### 9.1.9. Solver info in Simulink block¶

FORCES Pro always generates a Simulink block encapsulating the generated solver. You can add output ports to the Simulink block to obtain the solver exit flag and other solver information (number of iterations, solve time in seconds, value of the objective function) by setting:

```
codeoptions.showinfo = 1;
```

By default these ports are not present in the Simulink block.

### 9.1.10. Code generation server¶

By default, code generation requests are routed to embotech’s server. To send a code generation request to a local server, for example when FORCES Pro is used in an enterprise setting, set the following field to an appropriate value:

```
codeoptions.server = 'http://embotech-server2.com:8114/v1.5.beta';
```

### 9.1.11. Skipping the Build of Simulink S-function¶

By default, after code generation, the Simulink block is compiled, which may take a very long time for large problems on Windows systems. If you will not use the Simulink block, or want to build it later yourself, you can disable automatic builds by using the following option:

```
codeoptions.BuildSimulinkBlock = 0;
```

### 9.1.12. Skipping automatic cleanup¶

FORCES Pro automatically cleans up some of the files that it generates during the code generation, but which are usually not needed any more after building the MEX file. In particular, some intermediate CasADi generated files are deleted. If you would like to prevent any cleanup by FORCES, set the option:

```
codeoptions.cleanup = 0;
```

The default value is `1`

(true).

Important

The library or object files generated by FORCES Pro contain only the solver itself. To retain the CasADi generated files for function evaluations, switch off automatic cleanup as shown above. This is needed if you want to use the solver within another software project, and need to link to it.

### 9.1.13. Target platform¶

As a default option, FORCES Pro generates code for simulation on the host
platform. To obtain code for deployment on a target embedded platform, set the
field `platform`

to the appropriate value The platforms currently supported by
FORCES Pro are given in Table 9.4.

`platform` |
Platform |
---|---|

`'Generic'` (default) |
For the architecture of the host platform. |

`'x86_64'` |
For x86_64 based 64-bit platforms (detected OS). |

`'x86'` |
For x86 based 32-bit platforms (detected OS). |

`'Win-x86_64'` |
For Windows x86_64 based 64-bit platforms (supports Microsoft/Intel compiler). |

`'Win-x86'` |
For Windows x86 based 32-bit platforms (supports Microsoft/Intel compiler). |

`'Win-MinGW-x86_64'` |
For Windows x86 based 32-bit platforms (supports MinGW compiler). |

`'Win-MinGW-x86'` |
For Windows x86_64 based 64-bit platforms (supports MinGW compiler). |

`'Mac-x86_64'` |
For Mac x86_64 based 64-bit platforms (supports GCC/Clang compiler). |

`'Gnu-x86_64'` |
For Linux x86_64 based 64-bit platforms (supports GCC compiler). |

`'Gnu-x86'` |
For Linux x86 based 32-bit platforms (supports GCC compiler). |

`'Docker-Gnu-x86_64'` |
For Linux x86_64 based 64-bit platforms on Docker (supports GCC compiler). |

`'Docker-Gnu-x86'` |
For Linux x86 based 32-bit platforms on Docker (supports GCC compiler). |

`'ARM-Generic'` |
For ARM Cortex 32-bit processors (Gnueabih machine type). |

`'ARM-Generic64'` |
For ARM Cortex 64-bit processors (Aarch machine type). |

`'Integrity-ARM-x86'` |
For ARM Cortex 32-bit processors using the Integrity toolchain. |

`'Integrity-ARM-x64'` |
For ARM Cortex 64-bit processors using the Integrity toolchain. |

`'ARM Cortex-M3'` |
For ARM Cortex M3 32-bit processors. |

`'ARM-Cortex-M4-NOFPU'` |
For the ARM Cortex M4 32-bit processors without a floating-point unit. |

`'ARM-Cortex-M4'` |
For the ARM Cortex M4 32-bit processors with a floating-point unit. |

`'ARM-Cortex-A7'` |
For the ARM Cortex A7 32-bit processors (Gnueabih machine type). |

`'ARM-Cortex-A8'` |
For the ARM Cortex A8 32-bit processors (Gnueabih machine type). |

`'ARM-Cortex-A9'` |
For the ARM Cortex A9 32-bit processors (Gnueabih machine type). |

`'ARM-Cortex-A53'` |
For the ARM Cortex A53 64-bit processors (Gnueabih machine type). |

`'ARM-Cortex-A72'` |
For the ARM Cortex A72 64-bit processors (Gnueabih machine type). |

`'TI-Cortex-A15'` |
For the ARM Cortex A15 32-bit processors (Gnueabih machine type). |

`'NVIDIA-Cortex-A57'` |
For the NVIDIA Cortex A57 64-bit processors (Aarch machine type). |

`'AARCH-Cortex-A57'` |
For the ARM Cortex A57 64-bit processors (Aarch machine type). |

`'AARCH-Cortex-A72'` |
For the ARM Cortex A72 64-bit processors (Aarch machine type). |

`'PowerPC'` |
For 32-bit PowerPC based platforms (supports GCC compiler). |

`'PowerPC64'` |
For 64-bit PowerPC based platforms (supports GCC compiler). |

`'MinGW32'` |
For Windows x86 based 32-bit platforms (supports MinGW compiler). |

`'MinGW64'` |
For Windows x86_64 based 64-bit platforms (supports MinGW compiler). |

`'dSPACE-MABII'` |
For the dSPACE MicroAutoBox II real-time system (supports Microtec compiler). |

`'Speedgoat-x86'` |
For Speedgoat 32-bit real-time platforms (supports Microsoft compiler). |

`'Speedgoat-x64'` |
For Speedgoat 64-bit real-time platforms (supports Microsoft compiler). |

`'IAtomE680_Bachmann'` |
For Bachmann PLC platforms (supports VxWorks compiler). |

Note

If a solver for another platform is requested, FORCES Pro will still
provide the simulation interfaces for the `'Generic'`

host platform to
enable users to run simulations.

#### 9.1.13.1. Cross compilation¶

To generate code for other operating systems different from the host platform, set the appropriate flag from the following list to `1`

:

```
codeoptions.win
codeoptions.mac
codeoptions.gnu
```

Note that this will only affect the target platform. Interfaces for the host platform will be automatically built.

#### 9.1.13.2. Mac compilation¶

When compiling for mac platforms it’s possible to select the compiler to be used for the web compilation. Select from the available
values `gcc`

(default) and `clang`

with the following codeoption:

```
codeoptions.maccompiler
```

#### 9.1.13.3. SIMD instructions¶

On x86-based platforms one can also add the following field to accelerate the execution of the solver:

```
codeoptions.sse = 1;
% or
codeoptions.avx = 1;
```

Depending on the platform AVX may be automatically enabled. If the machine running the solver does not support AVX and returns the message “Illegal Instruction” one can explicitly disable avx by setting:

```
codeoptions.avx = -1;
```

### 9.1.14. MISRA 2012 compliance¶

If your license allows it, add the following field to generate C code that is compliant with the MISRA 2012 rules:

```
codeoptions.misra2012_check = 1;
```

This option makes the generated solver code MISRA compliant. After compilation, the client also downloads a folder
whose name terminates with `_misra2012_analysis`

. The folder contains one summary of all MISRA violations for the solver source
and header files. Note that the option only produces MISRA compliant code when used with algorithms `PDIP`

and `PDIP_NLP`

.

### 9.1.15. Optimizing code size¶

The size of sparse linear algebra routines in the generated code can be reduced by changing the option `compactSparse`

from `0`

to `1`

:

```
codeoptions.compactSparse = 1;
```

### 9.1.16. Optimizing Linear Algebra Operations¶

Some linear algebra routines in the generated code have available optimizations that can be enabled by changing the options `optimize_<optimization>`

from `0`

to `1`

.
These optimizations change the code in order to make better use of some embedded architectures in which hardware is more limited compared to host PC architectures.
Therefore, these optimizations show better results in embedded platforms such as ARM targets rather than during simulations on host PCs.
The available optimizations are:

**Cholesky Division:**This option performs the divisions included in the Cholesky factorization more efficiently to reduce its computation time.**Registers:**This option attempts to use the architecture’s registers in order to reduce memory operations which can take significant time.**Use Locals:**These options (which are separated into`simple`

/`heavy`

/`all`

in ascending complexity) make better use of data locality in order to reduce memory jumps**Operations Rearrange:**This option rearranges operations in order to make more efficient use of data and reduce memory jumps**Loop Unrolling:**This option unrolls some of the included loops in order to remove their overhead.**Enable Offset:**This option allows the rest of the optimizations to take place in cases where the matrix contains offsets.

```
codeoptions.optimize_choleskydivision = 1;
codeoptions.optimize_registers = 1;
codeoptions.optimize_uselocalsall = 1;
codeoptions.optimize_uselocalsheavy = 1; % overriden if uselocalsall is enabled
codeoptions.optimize_uselocalssimple = 1; % overriden if uselocalsheavy is enabled
codeoptions.optimize_operationsrearrange = 1;
codeoptions.optimize_loopunrolling = 1;
codeoptions.optimize_enableoffset = 1;
```

## 9.2. High-level interface options¶

The FORCES Pro NLP solver of the high-level interface implements a nonlinear barrier interior-point method. We will now discuss how to change several parameters in the solver.

### 9.2.1. Integrators¶

When providing the continuous dynamics the user must select a particular
integrator by setting `nlp.integrator.type`

as outlined in Table 9.5.

`nlp.integrator.type` |
Type | Order |
---|---|---|

`'ForwardEuler'` |
Explicit Euler Method | 1 |

`'ERK2'` |
Explicit Runge-Kutta | 2 |

`'ERK3'` |
Explicit Runge-Kutta | 3 |

`'ERK4'` (default) |
Explicit Runge-Kutta | 4 |

`'BackwardEuler'` |
Implicit Euler Method | 1 |

`'IRK2'` |
Implicit Euler Method | 2 |

`'IRK4'` |
Implicit Euler Method | 4 |

The user must also provide the discretization interval (in seconds) and the number of intermediate shooting nodes per interval. For instance:

```
codeoptions.nlp.integrator.type = 'ERK2';
codeoptions.nlp.integrator.Ts = 0.01;
codeoptions.nlp.integrator.nodes = 10;
```

Tip

Usually an explicit integrator such as RK4 should suffice for most applications. If you have stiff systems, or suspect inaccurate integration to be the cause of convergence failure of the NLP solver, consider using implicit integrators from the table above.

### 9.2.2. Accuracy requirements¶

One can modify the termination criteria by altering the KKT tolerance with respect to stationarity, equality constraints, inequality constraints and complementarity conditions, respectively, using the following fields:

```
% default tolerances
codeoptions.nlp.TolStat = 1E-5; % inf norm tol. on stationarity
codeoptions.nlp.TolEq = 1E-6; % tol. on equality constraints
codeoptions.nlp.TolIneq = 1E-6; % tol. on inequality constraints
codeoptions.nlp.TolComp = 1E-6; % tol. on complementarity
```

All tolerances are computed using the infinitiy norm \(\lVert \cdot \rVert_\infty\).

### 9.2.3. Barrier strategy¶

The strategy for updating the barrier parameter is set using the field:

```
codeoptions.nlp.BarrStrat = 'loqo';
```

It can be set to `'loqo'`

(default) or to `'monotone'`

. The default settings
often leads to faster convergence, while `'monotone'`

may help convergence for
difficult problems.

### 9.2.4. Hessian approximation¶

The way the Hessian of the Lagrangian function is computed can be set using the field:

```
codeoptions.nlp.hessian_approximation = 'bfgs';
```

FORCES Pro currently supports BFGS updates (`'bfgs'`

) (default) and
Gauss-Newton approximation (`'gauss-newton'`

). Exact Hessians will be
supported in a future version. Read the subsequent sections for the
corresponding Hessian approximation method of your choice.

#### 9.2.4.1. BFGS options¶

When the Hessian is approximated using BFGS updates, the initialization of the estimates can play a critical role in the convergence of the method. The default value is the identity matrix, but the user can modify it using e.g.:

```
codeoptions.nlp.bfgs_init = diag([0.1, 10, 4]);
```

Note that BFGS updates are carried out individually per stage in the FORCES NLP solver, so the size of this matrix is the size of the stage variable. Also note that this matrix must be positive definite. When the cost function is positive definite, it often helps to initialize BFGS with the Hessian of the cost function.

This matrix is also used to restart the BFGS estimates whenever the BFGS updates are skipped several times in a row. The maximum number of updates skipped before the approximation is re-initialized is set using:

```
codeoptions.nlp.max_update_skip = 2;
```

The default value for `max_update_skip`

is 2.

#### 9.2.4.2. Gauss-Newton options¶

For problems that have a least squares objective, i.e. the cost function can be expressed by a vector-valued function \(r_k : \mathbb{R}^n \rightarrow \mathbb{R}^m\) which implicitly defines the objective function as:

the Gauss-Newton approximation of the Hessian is given by:

and can lead to faster convergence and a more reliable method. When this option
is selected, the functions \(r_k\) have to be provided by the user in the
field `LSobjective`

. For example if \(r(z)=\sqrt{100} z_1^2 + \sqrt{6}
z_2^2\), i.e. \(f(z) = 50 z_1^2 + 3 z_2^2\), then the following code defines
the least-squares objective (note that \(r\) is a vector-valued function):

```
nlp.objective = @(z) 0.1* z(1)^2 + 0.01*z(2)^2;
nlp.LSobjective = @(z) [sqrt(0.2)*z(1); sqrt (0.02)*z(2)];
```

Important

The field `LSobjective`

will have precedence over `objective`

, which need
not be defined in this case.

When providing your own function evaluations in C, you must populate the Hessian argument with a positive definite Hessian.

### 9.2.5. Line search settings¶

The line search first computes the maximum step that can be taken while maintaining the iterates inside the feasible region (with respect to the inequality constraints). The maximum distance is then scaled back using the following setting:

```
% default fraction-to-boundary scaling
codeoptions.nlp.ftbr_scaling = 0.9900;
```

### 9.2.6. Regularization¶

To avoid ill-conditioned saddle point systems, FORCES employs two different types of regularization, static and dynamic regularization.

#### 9.2.6.1. Static regularization¶

Static regularization of the augmented Hessian by \(\delta_w I\), and of the multipliers corresponding to the equality constraints by \(-\delta_c I\) helps avoid problems with rank deficiency. The constants \(\delta_w\) and \(\delta_c\) vary at each iteration according to the following heuristic rule:

where \(\mu\) is the barrier parameter and \(i\) is the number of iterations.

This rule has been chosen to accommodate two goals: First, make the regularization dependent on the progress of the algorithm - the closer we are to the optimum, the smaller the regularization should be in order not to affect the search directions generated close to the solution, promoting superlinear convergence properties. Second, the amount of regularization employed should decrease with the number of iterations to a certain minimum level, at a certain sublinear rate, in order to prevent stalling due to too large regularization. FORCES NLP does not employ an inertia-correcting linear system solver, and so relies heavily on the parameters of this regularization to be chosen carefully.

You can change these parameters by using the following settings:

```
% default static regularization parameters
codeoptions.nlp.reg_eta_dw = 1E-4;
codeoptions.nlp.reg_beta_dw = 0.8;
codeoptions.nlp.reg_min_dw = 1E-9;
codeoptions.nlp.reg_gamma_dw = 1.0/3.0;
codeoptions.nlp.reg_eta_dc = 1E-4;
codeoptions.nlp.reg_beta_dc = 0.8;
codeoptions.nlp.reg_min_dc = 1E-9;
codeoptions.nlp.reg_gamma_dc = 1.0/3.0;
```

Note that by choosing \(\delta_w=0\) and \(\delta_c=0\), you can turn off the progress and iteration dependent regularization, and rely on a completely static regularization by \(\delta_{w,\min}\) and \(\delta_{c,\min}\), respectively.

#### 9.2.6.2. Dynamic regularization¶

Dynamic regularization regularizes the matrix on-the-fly to avoid instabilities due to numerical errors. During the factorization of the saddle point matrix, whenever it encounters a pivot smaller than \(\epsilon\), it is replaced by \(\delta\). There are two parameter pairs: \((\epsilon,\delta)\) affects the augmented Hessian and \((\epsilon_2,\delta_2)\) affects the search direction computation. You can set these parameters by:

```
% default dynamic regularization parameters
codeoptions.regularize.epsilon = 1E-12; % (for Hessian approx.)
codeoptions.regularize.delta = 4E-6; % (for Hessian approx.)
codeoptions.regularize.epsilon2 = 1E-14; % (for Normal eqs.)
codeoptions.regularize.delta2 = 1E-14; % (for Normal eqs.)
```

### 9.2.7. Linear system solver¶

The interior-point method solves a linear system to find a search direction at every iteration. FORCES NLP offers the following three linear solvers:

`'normal_eqs'`

(default): Solving the KKT system in normal equations form.`'symm_indefinite_fast'`

: Solving the KKT system in augmented / symmetric indefinite form, using regularization and positive definite Cholesky factorizations only.`'symm_indefinite'`

: Solving the KKT system in augmented / symmetric indefinite form, using block-indefinite factorizations.

The linear system solver can be selected by setting the following field:

```
codeoptions.nlp.linear_solver = 'symm_indefinite';
```

It is recommended to try different linear solvers when experiencing convergence
problems. The most stable method is `'symm_indefinite'`

, while the fastest
solver (and also very reliable) is `'symm_indefinite_fast'`

.

Note

Independent of the linear system solver choice, the generated code is always library-free and statically allocated, i.e. it can be embedded anywhere.

The `'normal_eqs'`

solver is the standard FORCES linear system solver based on
a full reduction of the KKT system (the so-called normal equations form). It
works well for standard problems, especially convex problems or nonlinear
problems where the BFGS or Gauss-Newton approximations of the Hessian are
numerically sufficiently well conditioned.

The `'symm_indefinite_fast'`

solver is the most robust solver, but still
high-speed. It is based on block-wise factorization of the symmetric indefinite
form of the KKT system (the so-called augmented form). Each block is handled by
symmetric indefinite LDL factorization, with (modified) on-the-fly
Bunch-Kaufmann permutations leading to boundedness of lower triangular factors
for highest numerical stability. This is our most robust linear system solver,
with only a modest performance penalty (about 30% compared to
`'symm_indefinite_fast'`

).

The `'symm_indefinite'`

solver is robust, but even faster. It is based on
block-wise factorization of the symmetric indefinite KKT matrix, where each
block is handled by a Cholesky factorization. It uses regularization to
increase numerical stability. Currently only used for receding-horizon/MPC-like
problems where dimensions of all stages are equal (minus the first and last
stage, those are handled separately). It is more robust and faster than the
normal equations form. This solver is likely to become the default option in
the future.

### 9.2.8. Safety checks¶

By default, the output of the function evaluations is checked for the presence
of `NaN`

s or `INF`

s in order to diagnose potential initialization
problems. In order to speed up the solver one can remove these checks by
setting:

```
codeoptions.nlp.checkFunctions = 0;
```

## 9.3. Convex branch-and-bound options¶

The settings of the FORCES Pro mixed-integer branch-and-bound convex solver are accessed
through the `codeoptions.mip`

struct. It is worthwhile to explore different
values for the settings in Table 9.6, as they might have a
severe impact on the performance of the branch-and-bound procedure.

Note

All the options described below are currently not available with the FORCES Pro nonlinear solver. For mixed-integer nonlinear programs and the available options, please have a look at paragraph Mixed-integer nonlinear solver.

Setting | Values | Default |
---|---|---|

`mip.timeout` |
Any value \(\geq 0\) | `31536000` (1 year) |

`mip.mipgap` |
Any value \(\geq 0\) | `0` |

`mip.branchon` |
`'mostAmbiguous'` , `'leastAmbiguous'` |
`'mostAmbiguous'` |

`mip.stageinorder` |
`0` (OFF), `1` (ON) |
`1` (ON) |

`mip.explore` |
`'bestFirst'` , `'depthFirst'` |
`'bestFirst'` |

`mip.inttol` |
Any value \(> 0\) | `1E-5` |

`mip.queuesize` |
Any integer value \(\geq 0\) | `1000` |

A description of each setting is given below:

`mip.timeout`

: Timeout in seconds, after which the search is stopped and the best solution found so far is returned.`mip.mipgap`

: Relative sub-optimality after which the search shall be terminated. For example, a value of`0.01`

will search for a feasible solution that is at most 1%-suboptimal. Set to zero if the optimal solution is required.`mip.branchon`

: Determines which variable to branch on after having solved the relaxed problem. Options are`'mostAmbiguous'`

(i.e. the variable closest to 0.5) or`'leastAmbiguous'`

(i.e. the variable closest to 0 or 1).`mip.stageinorder`

: Stage-in-order heuristic: For the branching, determines whether to fix variables in order of the stage number, i.e. first all variables of stage \(i\) will be fixed before fixing any of the variables of stage \(i+1\). This is often helpful in multistage problems, where a timeout is expected to occur, and where it is important to fix the early stages first (for example MPC problems). Options are`0`

for OFF and`1`

for ON.`mip.explore`

: Determines the exploration strategy when selecting pending nodes. Options are`'bestFirst'`

, which chooses the node with the lowest lower bound from all pending nodes, or`'depthFirst'`

, which prioritizes nodes with the most number of fixed binaries first to quickly reach a node.`mip.inttol`

: Integer tolerance for identifying binary solutions of relaxed problems. A solution of a relaxed problem with variable values that are below`inttol`

away from binary will be declared to be binary.`mip.queuesize`

: Maximum number of pending nodes that the branch and bound solver can store. If that number is exceeded during the search, the solver quits with an`exitflag`

value of`-2`

and returns the best solution found so far.

## 9.4. Solve methods¶

As a default optimization method the primal-dual interior-point method is used.
Several other methods are available. To change the solve method set the
`solvemethod`

field as outlined in Table 9.7.

`solvemethod` |
Method | Description |
---|---|---|

`'PDIP'` (default) |
Primal-Dual Interior-Point Method | The Primal-Dual Interior-Point Method is a stable and robust method for most problems. |

`'ADMM'` |
Alternating Direction Methods of Multipliers | For some problems, ADMM may be faster. The method variant and several algorithm parameters can be tuned in order to improve performance. |

`'DFG'` |
Dual Fast Gradient Method | For some problems with simple constraints, our implementation of the dual fast gradient method can be the fastest option. No parameters need to be tuned in this method. |

`'FG'` |
Fast Gradient Method | For problems with no equality constraints (only one stage) and simple constraints, the primal fast gradient method can give medium accuracy solutions extremely quickly. The method has several tuning parameters that can significantly affect the performance. |

### 9.4.1. Primal-Dual Interior-Point Method¶

The Primal-Dual Interior-Point Method is the default optimization method. It is a stable and robust method for most of the problems.

#### 9.4.1.1. Solver Initialization¶

The performance of the solver can be influenced by the way the variables are
initialized. The default method (cold start) should work in most cases extremely
reliably, so there should be no need in general to try other methods, unless you
are experiencing problems with the default initialization scheme. To change the
method of initialization in FORCES Pro set the field `init`

to one of the
values in Table 9.8.

`init` |
Method | Initialization method |
---|---|---|

`0` (default) |
Cold start | Set all primal variables to \(0\), and all dual variables to the square root of the initial complementarity gap \(\mu_0: z_i=0, s_i=\sqrt{\mu_0}, \lambda_i=\sqrt{\mu_0}\). The default value is \(\mu_0=10^6\). |

`1` |
Centered start | Set all primal variables to zero, the slacks to the RHS of the corresponding inequality, and the Lagrange multipliers associated with the inequalities such that the pairwise product between slacks and multipliers is equal to the parameter \(\mu_0: z_i=0, s_i=b_{\mathrm{ineq}}\) and \(s_i \lambda_i = \mu_0\). |

`2` |
Primal warm start | Set all primal variables as provided by the user. Calculate the residuals and set the slacks to the residuals if they are sufficiently positive (larger than \(10^{-4}\)), or to one otherwise. Compute the associated Lagrange multipliers such that \(s_i \lambda_i = \mu_0\). |

#### 9.4.1.2. Initial Complementary Slackness¶

The default value for \(\mu_0\) is \(10^6\). To use a different value, use:

```
codeoptions.mu0 = 10;
```

#### 9.4.1.3. Accuracy Requirements¶

The accuracy for which FORCES Pro returns the OPTIMAL flag can be set as follows:

```
codeoptions.accuracy.ineq = 1e-6; % infinity norm of residual for inequalities
codeoptions.accuracy.eq = 1e-6; % infinity norm of residual for equalities
codeoptions.accuracy.mu = 1e-6; % absolute duality gap
codeoptions.accuracy.rdgap = 1e-4; % relative duality gap := (pobj-dobj)/pobj
```

#### 9.4.1.4. Line Search Settings¶

If FORCES Pro experiences convergence difficulties, you can try selecting
different line search parameters. The first two parameters of
`codeoptions.linesearch`

, `factor_aff`

and `factor_cc`

are the backtracking factors
for the line search (if the current step length is infeasible, then it is
reduced by multiplication with these factors) for the affine and combined search
direction, respectively.

```
codeoptions.linesearch.factor_aff = 0.9;
codeoptions.linesearch.factor_cc = 0.95;
```

The remaining two parameters of the field `linesearch`

determine the minimum
(`minstep`

) and maximum step size (`maxstep`

). Choosing `minstep`

too high will cause
the generated solver to quit with an exitcode saying that the line search has
failed, i.e. no progress could be made along the computed search direction.
Choosing `maxstep`

too close to 1 is likely to cause numerical issues, but
choosing it too conservatively (too low) is likely to increase the number of
iterations needed to solve a problem.

```
codeoptions.linesearch.minstep = 1e-8;
codeoptions.linesearch.maxstep = 0.995;
```

#### 9.4.1.5. Regularization¶

During factorization of supposedly positive definite matrices, FORCES Pro applies a regularization to the \(i\)-th pivot element if it is smaller than \(\epsilon\). In this case, it is set to \(\delta\), which is the lower bound on the pivot element that FORCES Pro allows to occur.

```
codeoptions.regularize.epsilon = 1e-13; % if pivot element < epsilon …
codeoptions.regularize.delta = 1e-8; % then set it to delta
```

#### 9.4.1.6. Multicore parallelization¶

FORCES Pro supports the computation on multiple cores, which is particularly useful for large problems and long horizons (the workload is split along the horizon to multiple cores). This is implemented by the use of OpenMP and can be switched on by using

```
codeoptions.parallel = 1;
```

By default multicore computation is switched off.

### 9.4.2. Alternating Directions Method of Multipliers¶

FORCES Pro implements several optimization methods based on the ADMM framework.
Different variants can handle different types of constraints and FORCES Pro will
automatically choose an ADMM variant that can handle the constraints in a given
problem. To manually choose a specific method in FORCES Pro, use the `ADMMvariant`

field of `codeoptions`

:

```
codeoptions.ADMMvariant = 1; % can be 1 or 2
```

where variant `1`

is as follows:

and variant `2`

is as follows:

#### 9.4.2.1. Accuracy requirements¶

The accuracy for which FORCES Pro returns the OPTIMAL flag can be set as follows:

```
codeoptions.accuracy.consensus = 1e-3; % infinity norm of the consensus equality
codeoptions.accuracy.dres = 1e-3; % infinity norm of the dual residual
```

Note that, in contrast to primal-dual interior-point methods, the required number of ADMM iterations varies very significantly depending on the requested accuracy. ADMM typically requires few iterations to compute medium accuracy solutions, but many more iterations to achive the same accuracy as interior-point methods. For feedback applications, medium accuracy solutions are typically sufficient. Also note that the ADMM accuracy requirements have to be changed depending on the problem scaling.

#### 9.4.2.2. Method parameters¶

ADMM uses a regularization parameter \(\rho\), which also acts as the step size in the gradient step. The convergence speed of ADMM is highly variable in the parameter \(\rho\). Its value should satisfy \(\rho > 0\). This parameter can be tuned using the following command:

```
codeoptions.ADMMrho = 1;
```

In some cases it may be possible to let FORCES Pro choose the value \(\rho\) automatically. To enable this feature set:

```
codeoptions.ADMMautorho = 1;
```

Please note that this does not guarantee that the choice of \(\rho\) will be optimal.

ADMM can also include an ‘over-relaxation’ step that can improve the convergence speed. This step is typically useful for problems where ADMM exhibits very slow convergence and can be tuned using the parameter \(\alpha\). Its value should satisfy \(1 \leq \alpha \leq 2\). This step using the following command:

```
codeoptions.ADMMalpha = 1;
```

#### 9.4.2.3. Precomputations¶

For problems with time-invariant data, FORCES Pro can compute full matrix
inverses at code generation time and then implement matrix solves online by
dense matrix-vector multiplication. In some cases, especially when the
prediction horizon is long, it may be better to factorize the matrix and
implement matrix solves using forward and backward solves with the pre-computed
factors. To manually switch on this option, use the `ADMMfactorize`

field of
`codeoptions`

.

When the data is time-varying, or when the prediction horizon is larger than 15 steps, FORCES Pro automatically switches to a factorization-based method.

```
codeoptions.ADMMfactorize = 0;
```

### 9.4.3. Dual Fast Gradient Method¶

For some problems with simple constraints, our implementation of the dual fast gradient method can be the fastest option. No parameters need to be tuned in this method.

### 9.4.4. Primal Fast Gradient Method¶

For problems with no equality constraints (only one stage) and simple constraints, the primal fast gradient method can give medium accuracy solutions extremely quickly. The method has several tuning parameters that can significantly affect the performance.

#### 9.4.4.1. Accuracy requirements¶

The accuracy for which FORCES Pro returns the OPTIMAL flag can be set as follows:

```
codeoptions.accuracy.gmap= 1e-5; % infinity norm of the gradient map
```

The gradient map is related to the difference with respect to the optimal objective value. Just like with other first-order methods, the required number of FG iterations varies very significantly depending on the requested accuracy. Medium accuracy solutions can typically be computed very quickly, but many iterations are needed to achieve the same accuracy as with interior-point methods.

#### 9.4.4.2. Method parameters¶

The user has to determine the step size in the fast gradient method. The convergence speed of FG is highly variable in this parameter, which should typically be set to be one over the maximum eigenvalue of the quadratic cost function. This parameter can be tuned using the following command:

```
codeoptions.FGstep = 1/1000;
```

In some cases it may be possible to let FORCES Pro choose the step size automatically. To enable this feature set:

```
codeoptions.FGautostep = 1;
```

#### 9.4.4.3. Warm starting¶

The performance of the fast gradient method can be greatly influenced by the way the variables are initialized. Unlike with interior-point methods, fast gradient methods can be very efficiently warm started with a good guess for the optimal solution. To enable this feature set:

```
codeoptions.warmstart = 1;
```

When the user turns warm start on, a new parameter `z_init_0`

is automatically
added. The user should set it to be a good guess for the solution, which is
typically available when solving a sequence of problems.