## Initialize Optimization Expressions

### Error in Expression

Sometimes you get this mysterious error from an objective or nonlinear constraint function or expression:

```Unable to perform assignment because value of type 'optim.problemdef.OptimizationExpression' is not convertible to 'double'.```

Often, this error comes from an improper initialization of an optimization expression. Typically, you initialize an variable `F` in a standard loop by declaring an array of zeros, such as

`F = zeros(N,1);`

However, if `F` is an optimization expression, then you must initialize it using `optimexpr`:

`F = optimexpr(N,1);`

The following topics provide examples of initialization techniques. All are based on the same example, a function that uses an internal loop.

```function f = myFun(x) out = zeros(size(x)); out(1) = x(1); for i = 2:10 out(i) = (x(i) - x(i-1))^3; end f = mean(out); end```

If you try to use `myFun(x)` as the objective function for an optimization variable `x`, you get an error

```x = optimvar('x',10,"LowerBound",0,"UpperBound",10); prob = optimproblem("Objective",myFun(x));```
```Unable to perform assignment because value of type 'optim.problemdef.OptimizationVariable' is not convertible to 'double'. Error in myFun (line 3) out(1) = x(1); Caused by: Error using double Conversion to double from optim.problemdef.OptimizationVariable is not possible.```

However, `myFun` works as the objective in a solver-based problem.

```rng default x0 = 10*rand(10,1); lb = zeros(10,1); ub = 10 + lb; [sol,fval] = fmincon(@myFun,x0,[],[],[],[],lb,ub)```
```Local minimum found that satisfies the constraints. Optimization completed because the objective function is non-decreasing in feasible directions, to within the value of the optimality tolerance, and constraints are satisfied to within the value of the constraint tolerance. sol = 9.4226 10.0000 0.0000 5.0000 10.0000 0.0000 3.3333 6.6667 10.0000 0.0000 fval = -262.9274```

This problem has several local solutions, so you can get different answers depending on your initial point.

### Modify Function To Accept an Initial Array

Rewrite the function to accept the initial value as an additional argument. You can then pass an optimization expression or a numeric array as the initial value. `myFun2` uses the input variable `out` as the output variable, and accepts either a zero array or optimization expression.

This method has the advantages of enabling automatic differentiation, if applicable, and of not introducing extra code that runs during the solution process. The method has the disadvantage of requiring a rewrite of the function with a different function signature.

```function f = myFun2(out,x) out(1) = x(1); for i = 2:10 out(i) = (x(i) - x(i-1))^3; end f = mean(out); end```

Use `myFun2` in a problem-based way.

```x = optimvar('x',10,"LowerBound",0,"UpperBound",10); out = optimexpr(size(x)); prob = optimproblem("Objective",myFun2(out,x)); rng default x0.x = 10*rand(10,1); [sol,fval] = solve(prob,x0)```
```Solving problem using fmincon. Local minimum found that satisfies the constraints. Optimization completed because the objective function is non-decreasing in feasible directions, to within the value of the optimality tolerance, and constraints are satisfied to within the value of the constraint tolerance. sol = struct with fields: x: [10×1 double] fval = -262.9274```

Use `myFun2` in a solver-based way.

```rng default x0 = 10*rand(10,1); lb = zeros(10,1); ub = 10 + lb; out = zeros(size(x0)); [sol,fval] = fmincon(@(x)myFun2(out,x),x0,[],[],[],[],lb,ub)```
```Local minimum found that satisfies the constraints. Optimization completed because the objective function is non-decreasing in feasible directions, to within the value of the optimality tolerance, and constraints are satisfied to within the value of the constraint tolerance. sol = 9.4226 10.0000 0.0000 5.0000 10.0000 0.0000 3.3333 6.6667 10.0000 0.0000 fval = -262.9274```

### Rewrite Function to Initialize Expressions Appropriately

You can explicitly check for the type of problem variables and initialize an expression appropriately. This method has the advantages of enabling automatic differentiation, if applicable, and keeping the same function signature. It has the disadvantages of requiring a rewrite of the function and of having a small amount of overhead while the solver runs.

```function f = myFun3(x) % Check for the data type of variable x if isa(x,'double') out = zeros(size(x)); else out = optimexpr(size(x)); end % No changes to the rest of the code out(1) = x(1); for i = 2:10 out(i) = (x(i) - x(i-1))^3; end f = mean(out); end```

Solve the problem using optimization variables with the objective function `myFun3`.

```x = optimvar('x',10,"LowerBound",0,"UpperBound",10); prob = optimproblem("Objective",myFun3(x)); rng default x0.x = 10*rand(10,1); [sol,fval] = solve(prob,x0)```
```Solving problem using fmincon. Local minimum found that satisfies the constraints. Optimization completed because the objective function is non-decreasing in feasible directions, to within the value of the optimality tolerance, and constraints are satisfied to within the value of the constraint tolerance. sol = struct with fields: x: [10×1 double] fval = -262.9274```

Solve the problem using `fmincon` with the objective function `myFun3`.

```rng default x0 = 10*rand(10,1); lb = zeros(10,1); ub = 10 + lb; out = zeros(size(x0)); [sol,fval] = fmincon(@myFun3,x0,[],[],[],[],lb,ub)```
```Local minimum found that satisfies the constraints. Optimization completed because the objective function is non-decreasing in feasible directions, to within the value of the optimality tolerance, and constraints are satisfied to within the value of the constraint tolerance. sol = 9.4226 10.0000 0.0000 5.0000 10.0000 0.0000 3.3333 6.6667 10.0000 0.0000 fval = -262.9274```

### Use `fcn2optimexpr` Conversion

For R2022b and later, you can convert the objective function to an optimization expression using `fcn2optimexpr` and initialize using a standard zero array. The initialization requires static analysis, so might not run correctly in earlier MATLAB® versions. This example uses the original function `myFun` that fails in the problem-based approach in Error in Expression.

```x = optimvar('x',10,"LowerBound",0,"UpperBound",10); obj = fcn2optimexpr(@myFun,x,Display="on"); prob = optimproblem("Objective",obj); rng default x0.x = 10*rand(10,1); [sol,fval] = solve(prob,x0)```
```The function uses only supported operators. The returned expressions use the operators on the problem variables. Solving problem using fmincon. Local minimum found that satisfies the constraints. Optimization completed because the objective function is non-decreasing in feasible directions, to within the value of the optimality tolerance, and constraints are satisfied to within the value of the constraint tolerance. <stopping criteria details> sol = struct with fields: x: [10×1 double] fval = -262.9274```