Main Content

最適化式の静的解析

静的解析とは

静的解析は、関数を解析し、効率的にコード化できる規則性の有無を探すプロセスです。特に、fcn2optimexpr は、for ループを効率的に符号化しようとするために静的解析を実行します。これを行うために、fcn2optimexpr ではループが別個の関数内になければなりません。入れ子形式の for ループは 1 つの関数内に入れることができます。例静的解析のための for ループの作成では、for ループを別個の関数に容易に変換する方法を示します。例静的解析のための for ループの制約の変換では、別個の関数の制約に for ループを作成する方法を示します。

静的解析の一環として、どの関数が数値データのみで動作するか、およびどれが最適化変数に依存するかを特定します。最適化変数に依存しない関数の場合、fcn2optimexpr はサポートされていない関数を自動的にラップし、関数の残りの部分が自動微分を利用できるようにします。このサポートされていない関数をラップしたものは、最適化変数に関してゼロ勾配をもつと仮定されます。たとえば、関数 ceil はサポートされていません (最適化変数および式でサポートされる演算を参照してください)。ただし、次の関数では、ceil が最適化変数ではなくループ変数のみで動作するため、fcn2optimexpr は自動微分をサポートする式を返します。

function [expr, val] = forloop(x, y)
N = numel(y);
expr = y + 2;
val = zeros(N,1);
for i = 1:N
    val(i) = ceil(sqrt(i+1));
    expr(i) = expr(i) + val(i)*x;
end
end

静的解析の制限

静的解析は次をサポートしていません。

  • cell 配列

  • セル インデックス付け

  • ドット インデックス付け

  • 無名関数

  • breakcontinue、および return ステートメント

  • クラス

  • 入れ子関数

  • グローバル変数

  • 永続変数

  • 名前と値の引数

  • parfor

  • switch ステートメント

  • try-catch ブロック

  • while ステートメント

  • if ステートメント

  • string インデックス付け

  • 非数値のループ範囲

  • 複数の左辺への代入 — 静的解析は、次のような複数の左辺を含む代入をサポートしていません。

    [a,b] = peaks(5);
  • ループ内で縮小または拡大する式 — 静的解析は、式の大きさを変化させる for ループをサポートしていません。すべての式を事前に割り当てることをお勧めします。たとえば、次のループは静的解析でサポートされていません。

    for i = 1:10
        x = [x fun(i)]; % x grows by concatenation
    end
    %%
    temp = x.^2;
    for i = 1:N
        temp(i+1) = temp(i) + x.*i; % temp grows by indexing
    end
    %%
    for i = 2:N
        expr(2:i) = expr(1:i-1) - i*x^2;
    % Vectors 2:i and 1:i-1 change size at each iteration
    end
    %%
    for i = N:-1:1
        expr(i) = []; % expr shrinks at each iteration
    end

また、静的解析では計算をしない関数を無視することができます。アルゴリズムにはこのような特徴があるため、次のような結果になります。

  • pause ステートメントは無視されます。

  • 結果に影響しないグローバル変数は無視される可能性があります。たとえば、グローバル変数を使用して関数の実行回数をカウントすると、誤った回数を得る場合があります。

  • rand または rng の呼び出しが関数に含まれている場合、関数は 1 回目のみ呼び出しを実行すると考えられますが、その後の呼び出しでは乱数ストリームが設定されません。

  • plot を呼び出しても、すべての反復で Figure が更新されない場合があります。

  • mat ファイルまたはテキスト ファイルへのデータの保存は、すべての反復で実行されない場合があります。

計算をしない関数が想定したとおりに動作するには、fcn2optimexprAnalysis 名前と値の引数を "off" に設定します。

参考

関連するトピック