Main Content

Static Analysis of Optimization Expressions

What Is Static Analysis?

Static analysis is the process of analyzing a function for regularities that can be coded efficiently. In particular, fcn2optimexpr performs static analysis in an attempt to encode for loops efficiently. To do so, fcn2optimexpr requires that the loop reside in a separate function. Nested for loops can reside in one function. The example Create for Loop for Static Analysis shows how to convert a for loop easily to a separate function. The example Convert Constraints in for Loops for Static Analysis shows how to create a for loop for constraints in a separate function.

Part of static analysis is determining which functions operate on purely numeric data and which depend on optimization variables. For functions that do not depend on optimization variables, fcn2optimexpr automatically wraps unsupported functions so that the remainder of the functions can use automatic differentiation. The wrapped, unsupported functions are assumed to have zero gradient with respect to the optimization variables. For example, the ceil function is not supported (see Supported Operations for Optimization Variables and Expressions). However, in the following function, ceil operates only on a loop variable, not on optimization variables, so fcn2optimexpr returns an expression that supports automatic differentiation.

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

Limitations of Static Analysis

Static analysis does not support the following:

  • Cell arrays

  • Cell indexing

  • Dot indexing

  • Anonymous functions

  • break, continue, and return statements

  • Classes

  • Nested functions

  • Global variables

  • Persistent variables

  • Name-value arguments

  • parfor

  • switch statements

  • try-catch blocks

  • while statements

  • if statements

  • String indexing

  • Non-numeric loop range

  • Multiple left-hand-side assignment — Static analysis does not support assignments with multiple left-hand sides, such as:

    [a,b] = peaks(5);
  • Expression shrinking or growing in the loop — Static analysis does not support for loops that change the size of an expression. The best practice is to preallocate all expressions. For example, the following loops are not supported for static analysis:

    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

In addition, static analysis can neglect noncomputational functions. This aspect of the algorithm can result in the following:

  • pause statements are ignored.

  • A global variable that does not affect the results can be ignored. For example, if you use a global variable to count how many times the function runs, you might obtain a misleading count.

  • If the function contains a call to rand or rng, the function might execute the first call only, and future calls do not set the random number stream.

  • A plot call might not update a figure at all iterations.

  • Saving data to a mat file or text file might not occur at every iteration.

To ensure that noncomputational functions operate as you expect, set the Analysis name-value argument of fcn2optimexpr to "off".

See Also

Related Topics