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

効率を高める変更例

トピックリアルタイム アプリケーションの最適化コード生成のいくつかのヒントに従って、行われるチェックを減らし、静的なメモリ割り当てを使用するよう、生成コードを構成します。

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 に制限する 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','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) |

関連するトピック