Generate Code for `quadprog`

First Steps in `quadprog` Code Generation

This example shows how to generate code for the `quadprog` optimization solver. Code generation requires a MATLAB® Coder™ license. For details about code generation requirements, see Code Generation for quadprog Background.

The problem is to minimize the quadratic expression

`$\frac{1}{2}{x}^{T}Hx+{f}^{T}x$`

where

`$H=\left[\begin{array}{ccc}1& -1& 1\\ -1& 2& -2\\ 1& -2& 4\end{array}\right]$`

and

`$f=\left[\begin{array}{c}2\\ -3\\ 1\end{array}\right]$`

subject to the constraints $0\le x\le 1$, $\sum x=1/2$.

Create a file named `test_quadp.m` containing the following code.

```function [x,fval] = test_quadp H = [1,-1,1 -1,2,-2 1,-2,4]; f = [2;-3;1]; lb = zeros(3,1); ub = ones(size(lb)); Aeq = ones(1,3); beq = 1/2; x0 = zeros(3,1); opts = optimoptions('quadprog','Algorithm','active-set'); [x,fval] = quadprog(H,f,[],[],Aeq,beq,lb,ub,x0,opts)```

Generate code for the `test_quadp` file.

`codegen -config:mex test_quadp`

After some time, `codegen` creates a MEX file named `test_quadp_mex.mexw64` (the file extension varies, depending on your system). Run the resulting C code.

`[x,fval] = test_quadp_mex`
```x = 0 0.5000 0 fval = -1.2500```

Modify Example for Efficiency

Following some of the suggestions in the topic Optimization Code Generation for Real-Time Applications, configure the generated code to have fewer checks and to use static memory allocation.

```cfg = coder.config('mex'); cfg.IntegrityChecks = false; cfg.SaturateOnIntegerOverflow = false; cfg.DynamicMemoryAllocation = 'Off';```

Create a file named `test_quadp2.m` containing the following code. This code sets a looser optimality tolerance than the default `1e-8`.

```function [x,fval,eflag,output] = test_quadp2 H = [1,-1,1 -1,2,-2 1,-2,4]; f = [2;-3;1]; lb = zeros(3,1); ub = ones(size(lb)); Aeq = ones(1,3); beq = 1/2; x0 = zeros(3,1); opts = optimoptions('quadprog','Algorithm','active-set',... 'OptimalityTolerance',1e-5); [x,fval,eflag,output] = quadprog(H,f,[],[],Aeq,beq,lb,ub,x0,opts)```

Generate code for the `test_quadp2` file.

`codegen -config cfg test_quadp2`

Run the resulting code.

`[x,fval,eflag,output] = test_quadp2_mex`
```x = 0 0.5000 0 fval = -1.2500 eflag = 1 output = struct with fields: algorithm: 'active-set' firstorderopt: 8.8818e-16 constrviolation: 0 iterations: 3 ```

Changing the optimality tolerance does not affect the optimization process, because the `'active-set'` algorithm does not check this tolerance until it reaches a point where it stops.

Create a third file that limits the number of allowed iterations to 2 to see the effect on the optimization process.

```function [x,fval,exitflag,output] = test_quadp3 H = [1,-1,1 -1,2,-2 1,-2,4]; f = [2;-3;1]; lb = zeros(3,1); ub = ones(size(lb)); Aeq = ones(1,3); beq = 1/2; x0 = zeros(3,1); opts = optimoptions('quadprog','Algorithm','active-set','MaxIterations',2); [x,fval,exitflag,output] = quadprog(H,f,[],[],Aeq,beq,lb,ub,x0,opts)```

To see the effect of these settings on the solver, run `test_quadp3` in MATLAB without generating code.

`[x,fval,exitflag,output] = test_quadp3`
```Solver stopped prematurely. quadprog stopped because it exceeded the iteration limit, options.MaxIterations = 2.000000e+00. x = -0.0000 0.5000 0 fval = -1.2500 exitflag = 0 output = struct with fields: algorithm: 'active-set' iterations: 2 constrviolation: 1.6441e-18 firstorderopt: 2 message: '↵Solver stopped prematurely.↵↵quadprog stopped because it exceeded the iteration limit,↵options.MaxIterations = 2.000000e+00.↵↵' linearsolver: [] cgiterations: [] ```

In this case, the solver reached the solution in fewer steps than the default. Usually, though, limiting the number of iterations does not allow the solver to reach a correct solution.