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, andreturnstatementsClasses
Nested functions
Global variables
Persistent variables
Name-value arguments
parforswitchstatementstry-catchblockswhilestatementsifstatementsString 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
forloops 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:
pausestatements 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
randorrng, the function might execute the first call only, and future calls do not set the random number stream.A
plotcall might not update a figure at all iterations.Saving data to a
matfile 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".