为 quadprog 生成代码
quadprog 代码生成的第一步
此示例说明如何为 quadprog 优化求解器生成代码。代码生成需要 MATLAB® Coder™ 许可证。有关代码生成要求的详细信息,请参阅 quadprog 背景下的代码生成。
问题可以表示为最小化二次表达式
其中
并且
需满足约束 、。
创建一个名为 test_quadp.m 的文件,其中包含创建问题和约束的代码。该文件必须设置使用 "active-set" 算法的选项。另外,请将 UseCodegenSolver 选项设置为 true,以便可以在 MATLAB 中使用生成的相同代码来验证结果。
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
为 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修改示例以提高效率
按照主题实时应用的优化代码生成中的一些建议,配置生成的代码以减少检查并使用静态内存分配。
cfg = coder.config("mex"); cfg.IntegrityChecks = false; cfg.SaturateOnIntegerOverflow = false; cfg.EnableDynamicMemoryAllocation = "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",UseCodegenSolver=true,... OptimalityTolerance=1e-5); [x,fval,eflag,output] = quadprog(H,f,[],[],Aeq,beq,lb,ub,x0,opts); end
为 test_quadp2 文件生成代码。
codegen -config cfg test_quadp2
Code generation successful.
运行生成的代码。
[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",UseCodegenSolver=true,... 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
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.'在本例中,求解器得到解所需的步数比默认情况下要少。但通常情况下,限制迭代次数并不能让求解器得到正确的解。
另请参阅
quadprog | codegen (MATLAB Coder) | optimoptions