Generate Code for quadprog - MATLAB & Simulink (original) (raw)

Main Content

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

where

and

subject to the constraints 0≤x≤1, ∑x=1/2.

Create a file named test_quadp.m containing code that creates the problem and constraints. The file must set options to use the"active-set" algorithm. Also, set theUseCodegenSolver option to true so you can verify the results in MATLAB using the same code as is generated.

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",UseCodegenSolver=true); [x,fval] = quadprog(H,f,[],[],Aeq,beq,lb,ub,x0,opts); end

Generate code for the test_quadp file.

codegen -config:mex test_quadp

After some time, codegen creates a MEX file namedtest_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.EnableDynamicMemoryAllocation = "Off";

Create a file named test_quadp2.m containing the following code. This code sets a looser optimality tolerance than the default1e-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",UseCodegenSolver=true,... OptimalityTolerance=1e-5); [x,fval,eflag,output] = quadprog(H,f,[],[],Aeq,beq,lb,ub,x0,opts); end

Generate code for the test_quadp2 file.

codegen -config cfg test_quadp2

Code generation successful.

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",UseCodegenSolver=true,... 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, runtest_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
0.5000

-0.0000

fval =

-1.2500

exitflag =

 0

output =

struct with fields:

      algorithm: 'active-set'
  firstorderopt: 2.0000
constrviolation: 1.1102e-16
     iterations: 2
        message: 'Solver stopped prematurely.↵↵quadprog stopped because it exceeded the iteration limit,↵options.MaxIterations = 2.000000e+00.'

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.

See Also

quadprog | codegen (MATLAB Coder) | optimoptions

Topics