Main Content

quadprog 生成代码

quadprog 代码生成的第一步

此示例说明如何为 quadprog 优化求解器生成代码。代码生成需要 MATLAB® Coder™ 许可证。有关代码生成要求的详细信息,请参阅 quadprog 背景下的代码生成

问题可以表示为最小化二次表达式

12xTHx+fTx

其中

H=[111122124]

并且

f=[231]

需满足约束 0x1x=1/2

创建一个名为 test_quadp.m 的文件,其中包含以下代码。

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)

test_quadp 文件生成代码。

codegen -config:mex test_quadp

一段时间后,codegen 会创建一个名为 test_quadp_mex.mexw64 的 MEX 文件(文件扩展名因系统而异)。运行生成的 C 代码。

[x,fval] = test_quadp_mex
x =

         0
    0.5000
         0


fval =

   -1.2500

修改示例以提高效率

按照主题Optimization Code Generation for Real-Time Applications中的一些建议,配置生成的代码以减少检查并使用静态内存分配。

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

创建一个名为 test_quadp2.m 的文件,其中包含以下代码。此代码会设置比默认 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)

test_quadp2 文件生成代码。

codegen -config cfg test_quadp2

运行生成的代码。

[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

更改最优性容差不会影响优化过程,因为 'active-set' 算法在到达停止点之前不会检查此容差。

创建第三个文件,将允许的迭代次数限制为 2,以查看对优化过程的影响。

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)

要查看这些设置对求解器的影响,请在不生成代码的情况下运行 MATLAB 中的 test_quadp3

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

在本例中,求解器得到解所需的步数比默认情况下要少。但通常情况下,限制迭代次数并不能让求解器得到正确的解。

另请参阅

| (MATLAB Coder) |

相关主题