quadprog のコード生成
quadprog コード生成の最初のステップ
この例では、最適化ソルバー quadprog のコードを生成する方法を示します。コード生成には、MATLAB®Coder™ ライセンスが必要です。コード生成の要件の詳細については、quadprog 用のコード生成の背景を参照してください。
問題は、次の二次式を最小化することです。
ここで、
および以下となります。
これは制約 、 に従います。
問題と制約を作成するコードを含む test_quadp.m という名前のファイルを作成します。このファイルで、"active-set" アルゴリズムを使用するためのオプションを設定する必要があります。また、生成されるコードと同じコードを使用して MATLAB で結果を確認できるように、UseCodegenSolver オプションを true に設定します。
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 に制限する 3 番目のファイルを作成して、最適化プロセスに対する効果を確認します。
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