The FORCES Pro text interface allows to configure the solver in more detail compared to the Simulink® Interface. For all the options to tune the solver please see the following sections:

- Solver Options: Description of the general options of the FORCES Pro solver.
- Solver name
- Printing level
- Maximum number of iterations
- Compiler optimization level
- Skipping certain steps of the build process
- Computation time measurement
- Data type
- Solver overwriting
- Simulink block ports
- Code generation server
- Branch-and-bound settings

- Solver Methods: Available optimization methods supported by the solver.

- Supported Platforms: List of platforms for which FORCES Pro can generate code.

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. Use

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

`>> codeoptions = getOptions('NameOfTheSolver')`

Options are passed to FORCES Pro through a struct in MATLAB or through a dictionary in Python, which we refer to as `codeoptions` (although it can have in principle an arbitrary name).

To control the amount of information the generated solver prints to the console, use the settings field `printlevel` as outlined in the following table. Note that for `printlevel=0`, the generated solver has no dependency on any system header library.

Print levels

Possible values for `codeoptions.printlevel`

Level |
Result | Dependency |
---|---|---|

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

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

2 | Summary after each iteration of solver | <stdio.h> |

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

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

The compiler optimization level can be varied by changing the field `optlevel` from 0 to 3. It is recommended to set `optlevel` to zero while evaluating the functionality of the solver to avoid long compilation times. Then set it back to 3 when generating code for deployment.

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

By default the execution time is measured. The execution time can be accessed in the field `solvetime` of the information returned by the solver. In addition, the execution time is printed in the console if the flag `printlevel` is greater than zero.

Note that 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.

The type of variables can be set by using

Data type | Decimation | Width (bits) | Supported Algorithms |
---|---|---|---|

double |
64 bit | Floating point | PDIP_NLP, PDIPM, ADMM, Gradient Projection |

float |
32 bit | Floating point | PDIP_NLP, PDIPM, ADMM, Gradient Projection |

int |
32 bit | Fixed point | ADMM, Gradient Projection |

short |
16 bit | Fixed point | ADMM, Gradient Projection |

The default value is `'double'`. Note that if a format other than `'double'` is selected, all data is converted and stored in the selected format. Loss of precision can occur during this operation.

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

Level |
Result |
---|---|

0 | never overwrite |

1 | always overwrite |

2 | ask to overwrite |

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

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

By default, code generation requests are routed to embotech's server. To send a code generation to a local server set the following field to an appropriate value:

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

**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:

This option is not available for the Python interface.

By default, after code generation, FORCES Pro deletes a couple of files that are not needed to just run the solver in Matlab. These files are typically automatically C files generated by CasADi (for function evaluations) that are used to build the MEX file. They are however needed if you want to link the generated solver into another software project, as the object file or the library in the obj or lib sub-folders contain only the nonlinear solver itself. You can deactivate the automatic cleanup by using the following option:

This option is not available for the Python interface.

**Branch-and-Bound Settings**

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

The setting of the FORCES mixed-integer branch-and-bound solver are accessed through the `codeoptions.mip` struct as follows (use `codeoptions = getOptions('solvername')` to obtain a default options struct):

Setting |
Description | Possible values | Default |
---|---|---|---|

mip.timeout |
Timeout in seconds, after which the search is stopped and the best solution found so far is returned. | Any value \(\geq 0\) | 31536000 (1 year) |

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. |
Any value \(\geq 0\) | 0 |

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). |
'mostAmbiguous''leastAmbiguous' |
'mostAmbiguous' |

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. |
0 (ON)1 (ON) |
1 (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. |
'bestFirst''depthFirst' |
'bestFirst' |

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. |
Any value \(>0\) | 1E-5 |

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 exitflag -2 (see below) and returns the best solution found so far. | Any integer value \(>0\) | 1000 |

The setting of the FORCES mixed-integer branch-and-bound solver are accessed through the `'mip'` entry of the `codeoptions` property of the `stages` object. Use `s = MultistageProblem(N)` to initialize such an object, which will carry all necessary information on the multistage problem.

Setting |
Description | Possible values | Default |
---|---|---|---|

s.codeoptions['mip']|'timeout'] |
Timeout in seconds, after which the search is stopped and the best solution found so far is returned. | Any value \(\geq 0\) | 31536000 (1 year) |

s.codeoptions['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. |
Any value \(\geq 0\) | 0 |

s.codeoptions['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). |
'mostAmbiguous''leastAmbiguous' |
'mostAmbiguous' |

s.codeoptions['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. |
0 (ON)1 (ON) |
1 (ON) |

s.codeoptions['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. |
'bestFirst''depthFirst' |
'bestFirst' |

s.codeoptions['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. |
Any value \(>0\) | 1E-5 |

s.codeoptions['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 exitflag -2 (see below) and returns the best solution found so far. | Any integer value \(>0\) | 1000 |

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

Possible solve methods are:

ID |
Method | Description |
---|---|---|

'PDIP' | 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 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. |

The following section will describe the settings for each method.

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

**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

ID |
Method | Initialization method |
---|---|---|

0 |
Cold start | (default) 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\). Read below to learn how to set \(\mu_0\) to a different value at code generation time. |

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_{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\). |

**Initial Complementary Slackness**

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

**Accuracy Requirements**

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

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

stages.codeoptions['accuracy']['ineq'] = 1.e-6 # infinity norm of residual for equalities

stages.codeoptions['accuracy']['mu'] = 1.e-6 # absolute duality gap

stages.codeoptions['accuracy']['rdgap'] = 1.e-4 % relative duality gap := (pobj-dobj)/pobj

**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_cc = 0.95;

stages.codeoptions['linesearch']['factor_cc'] = 0.95

The remaining two parameters of the field `linesearch` determine the minimum (`minstep`) and maximum step size (`maxstep`). Choosing `min step` 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.maxstep = 0.995;

stages.codeoptions['linesearch']['maxstep'] = 0.995

**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.delta = 1e-8; % then set it to delta

stages.codeoptions['regularize']['delta'] = 1e-8; # then set it to delta

**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

By default multicore computation is switched off.

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`:

where possible options are as follows:

Initialization options

Variant | ADMM formulation |
---|---|

1 |
$$ \begin{align} \text{minimize} \ \ & \frac{1}{2} y^T H y + f^T y & &\\ \text{subject to} \ \ & D y = c && \\ & \underline{z} \leq z \leq \bar{z} && \\ & y = z && \\ \end{align}$$ |

2 |
$$ \begin{align} \text{minimize} \ \ & \frac{1}{2} y^T H y + f^T y & &\\ \text{subject to} \ \ & D y = c && \\ & A y = z && \\ & z \leq b && \\ \end{align}$$ |

**Accuracy Requirements**

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

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

stages.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.

**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 \). This parameter can be tuned using the following command. Its value should satisfy \( \rho > 0 \).

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

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. This step can be tuned by parameter alpha \( \alpha \) using the following command. Its value should satisfy \( 1 \leq \alpha \leq 2 \).

**Auto-tuner**

In some cases it may be hard to choose ADMM parameters that result in fast convergence for a set of problem. Click here for a procedure to determine the best ADMM parameters experimentally.

**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.

`stages.codeoptions['ADMMfactorize'] = 0`

**Custom Projection Functions**

First-order method perform Euclidean projection computations onto the constraint set. These methods can sometimes converge slowly when they have to handle general polytopic constraints. In addition, in some cases the constraint set cannot be described by a polytope. FORCES Pro provides an interface to provide user-coded custom projection functions. Click here for a detailed description of the procedure.

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.
`
codeoptions.accuracy.gmap= 1e-5; % infinity norm of the gradient map`

`stages.codeoptions['accuracy']['gmap'] = 1e-5 # infinity norm of the gradient map`

`codeoptions.FGstep = 1/1000;`
`stages.codeoptions['FGstep'] = 1/1000`
`codeoptions.FGautostep = 1;`
`stages.codeoptions['FGautostep'] = 1`
`codeoptions.warmstart = 1;`
`stages.codeoptions['warmstart'] = 1`

**Accuracy Requirements**

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

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.

**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:

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

**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

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.

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

If a solver for another platform is requested, FORCES Pro will also provide the simulation interfaces for MATLAB® and Simulink® for the 'Generic' host platform, although timing will be turned off. The following target platforms are supported:

ID |
Platform |
---|---|

'Generic' |
Using the default option 'Generic', code is provided for the architecture of the host platform. |

'x86_64' |
For x86 based 64-bit platforms. The same operating system as the host will be assumed when requesting compiled code. For more information on this architecture click here. Add codeoptions.sse = 1 to use SSE instructions to accelerate the execution of your solver. |

'x86' |
For x86 based 32-bit platforms. The same operating system as the host will be assumed when requesting compiled code. For more information on this architecture click here. |

'ARM Cortex-M3' |
The ARM Cortex M3 is the industry leading 32-bit processor for highly deterministic real-time applications. More information can be found here. |

'ARM Cortex-M4 (NO FPU)' |
The ARM Cortex M4 is the latest embedded processor developed by ARM. Choose this option when the target processor does not have a floating-point unit. More information can be found here. |

'ARM Cortex-M4 (FPU)' |
The ARM Cortex M4 is the latest embedded processor developed by ARM. Choose this option when the target processor has a floating-point unit. More information can be found here. |

'ARM Cortex-A' |
More information on the ARM Cortex A9 can be found here. |

'Tricore' |
TriCore™ is a 32-bit architecture supporting RISC-type and DSP-type instructions. For more information click here. |

'PowerPC' |
For 32-bit PowerPC based platforms. More information on the PowerPC architecture can be found here. |

'PowerPC64' |
For 64-bit PowerPC based platforms. More information on the PowerPC architecture can be found here. |

'MIPS' |
For 32-bit MIPS based platforms. More information on the MIPS architecture can be found here. |

'MIPS64' |
For 64-bit MIPS based platforms. More information on the MIPS architecture can be found here. |

'VHDL' |
For custom circuits described in a hardware description language. |

Note: Additional add-ons for FORCES Pro are required to generate code for different target platforms. An overview can be found here.

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

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