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
, andreturn
statementsClasses
Nested functions
Global variables
Persistent variables
Name-value arguments
parfor
switch
statementstry
-catch
blockswhile
statementsif
statementsString 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
orrng
, 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"
.