主要内容

本页采用了机器翻译。点击此处可查看最新英文版本。

优化表达式的静态分析

什么是静态分析?

静态分析是分析函数中可有效编码的规律的过程。具体来说,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

静态分析的局限性

静态分析不支持以下内容:

  • 元胞数组

  • 元胞索引

  • 点索引

  • 匿名函数

  • breakcontinuereturn 语句

  • 嵌套函数

  • 全局变量

  • 持久变量

  • 名称-值参量

  • 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 语句被忽略。

  • 不影响结果的全局变量可能被忽略。例如,如果您使用全局变量来计算函数运行的次数,则可能会获得误导性的计数。

  • 如果该函数包含对 randrng 的调用,则该函数可能只执行第一次调用,以后的调用不会设置随机数流。

  • plot 调用可能不会在所有迭代中都更新图窗。

  • 可能不会在每次迭代时都将数据保存到 mat 文件或文本文件中。

为了确保非计算函数按预期运行,请将 fcn2optimexprAnalysis 名称值参量设置为 "off"

另请参阅

主题