优化表达式的静态分析
什么是静态分析?
静态分析是分析函数中可有效编码的规律的过程。具体来说,fcn2optimexpr
执行静态分析,尝试有效地编码 for
循环。为此,fcn2optimexpr
要求循环驻留在单独的函数中。嵌套的 for
循环可以位于一个函数中。示例 创建 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
静态分析的局限性
静态分析不支持以下内容:
元胞数组
元胞索引
点索引
匿名函数
break
、continue
和return
语句类
嵌套函数
全局变量
持久变量
名称-值参量
parfor
switch
语句try
-catch
块while
语句if
语句字符串索引
非数值循环范围
多个左侧赋值 - 静态分析不支持具有多个左侧的赋值,例如:
[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
的调用,则该函数可能只执行第一次调用,以后的调用不会设置随机数流。plot
调用可能不会在所有迭代中都更新图窗。可能不会在每次迭代时都将数据保存到
mat
文件或文本文件中。
为了确保非计算函数按预期运行,请将 fcn2optimexpr
的 Analysis
名称值参量设置为 "off"
。