最適化式の静的解析
静的解析とは
静的解析は、関数を解析し、効率的にコード化できる規則性の有無を探すプロセスです。特に、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 配列
セル インデックス付け
ドット インデックス付け
無名関数
break
、continue
、および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
ファイルまたはテキスト ファイルへのデータの保存は、すべての反復で実行されない場合があります。
計算をしない関数が想定したとおりに動作するには、fcn2optimexpr
の Analysis
名前と値の引数を "off"
に設定します。