## 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"`.