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:

- General Solver Options: Description of the general options of the FORCES Pro solver.

- Barrier Interior-Point Options: Description of the tuning options for the nonlinear interior-point method.

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

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

codeoptions.nlp.TolEq = 1E-6; % infinity norm of residual for equalities

codeoptions.nlp.TolIneq = 1E-6; % infinity norm of residual for inequalities

codeoptions.nlp.TolComp = 1E-6; % tolerance on complementarity conditions

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

stages.codeoptions['nlp']['TolIneq'] = 1.e-6 # infinity norm of residual for inequalities

stages.codeoptions['nlp']['TolComp'] = 1.e-4 # tolerance on complementarity conditions

The strategy for updating the barrier parameter is set using the field `codeoptions.nlp.BarrStrat`. It can be set to `'loqo'` or to `'monotone'`. The default settings often leads to faster convergence.

FORCES supports currently the following Hessian approximation methods:

- quasi-Newton BFGS updates
- Gauss-Newton Hessian approximations (for least-squares objectives)

**BFGS Settings**

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

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

**Gauss-Newton Hessian Approximation**

In order to be able to use the Gauss-Newton Hessian approximation, your objective function must be a sum of squares of a (potentially nonlinear) function
\[
r: R^n \rightarrow R^m
\] which implicitly defines the objective function as
\[
f(x) := 0.5 \| r(x) \|_2^2
\]
The function \(r(x)\) is expected to be defined by the function handle `model.LSobjective`. For example, if \(r(x) := 100 x_1^2 + 6 x_2^2 \), then the following code defines the least-squares objective (note that \( r \) is a vector-valued function):

Currently not available in Python

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:

To avoid ill-conditioned saddle point systems or systems with wrong inertia, FORCES NLP regularizes the (augmented) Hessian of the KKT system by a factor \(\delta_w\) times the identity matrix. Similarly, to avoid problems due to rank-deficient equality constraint jacobians, a regularization term \(-\delta_c\) times the identity matrix is employed. These two regularizations are determined through the following heuristic rule:
\[
\delta_w = \eta_w \min(\mu, \| c(x) \|)^{\beta_w} \cdot (i+1)^{-\gamma_c} + \delta_{c,\min} \\
\delta_c = \eta_c \min(\mu, \| c(x) \|)^{\beta_w} \cdot (i+1)^{-\gamma_c} + \delta_{c,\min} \\
\]
where \(\mu\) is the barrier parameter and \(i\) the iteration counter.

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.

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.

codeoptions.nlp.reg_beta = 0.8;

codeoptions.nlp.reg_min_dw = 1E-9;

codeoptions.nlp.reg_gamma_dw = 1/3;

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/3;

stages.codeoptions['nlp']['nlp.reg_beta_dw'] = 0.8

stages.codeoptions['nlp']['reg_min_dw'] = 1.e-9

stages.codeoptions['nlp']['reg_gamma_dw'] = 1.0/3.0

stages.codeoptions['nlp']['nlp.reg_beta_dc'] = 0.8

stages.codeoptions['nlp']['reg_min_dc'] = 1.e-9

stages.codeoptions['nlp']['reg_gamma_dc'] = 1.0/3.0

FORCES can currently generate three different linear system solvers. As always, they are embeddable everywhere, as they feature static memory allocation and are library-free. You can select the linear solver by the following setting:

This option is not available for the Python interface.

ID |
Description | Limitations |
---|---|---|

normal_eqs |
Default: This is the standard FORCES linear system solver based on a full reduction of the KKT system (the so-called normal equations form). | 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. |

symm_indefinite |
Most robust solver, still high-speed: 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). |
(None) |

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

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.