## Initialize Optimization Expressions

This topic describes an error that occurs when an optimization expression is not properly initialized, and provides examples of different ways to address the error.

### Error in Expression

Sometimes you receive this 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 results from an improper initialization of an optimization
expression. Typically, you initialize a 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);

This topic provides examples of proper 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 might get different answers depending on your initial point.

### Use `"like"`

Syntax to Initialize the Array

Rewrite the function to use the `"like"`

argument for
`zeros`

. You can then pass an optimization expression or a
numeric array as input.

This approach has several advantages:

The function signature is maintained.

The approach does not introduce extra code that runs during the solution process.

If applicable, automatic differentiation is enabled.

You can use the function in either the solver-based or problem-based workflow.

The approach enables static analysis when using

`fcn2optimexpr`

. For information about static analysis, see Static Analysis of Optimization Expressions.

function f = myFun1(x) out = zeros(size(x),"like",x); out(1) = x(1); for i = 2:10 out(i) = (x(i) - x(i-1))^3; end f = mean(out); end

Use `myFun1`

in a problem-based workflow.

x = optimvar("x",10,LowerBound=0,UpperBound=10); prob = optimproblem(Objective=myFun1(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 `myFun1`

in a solver-based workflow.

```
rng default
x0 = 10*rand(10,1);
lb = zeros(10,1);
ub = 10 + lb;
[sol,fval] = fmincon(@myFun1,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

### 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 an optimization
expression.

This approach has several advantages:

If applicable, automatic differentiation is enabled.

The approach does not introduce extra code that runs during the solution process.

You can use the function in either the solver-based or problem-based workflow.

The approach enables static analysis when using

`fcn2optimexpr`

. For information about static analysis, see Static Analysis of Optimization Expressions.

The disadvantage of this approach is that you must rewrite 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 workflow.

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 workflow.

```
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 several advantages:

If applicable, automatic differentiation is enabled.

You can use the function in either the solver-based or problem-based workflow.

The disadvantages of this approach are that you must rewrite the function, a small
amount of overhead is introduced while the solver runs, and, because of the
`if`

statement, static analysis is not supported when using
`fcn2optimexpr`

. For information about static analysis, see
Static Analysis of Optimization Expressions.

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)
```

### Use `fcn2optimexpr`

Conversion

For R2022b and later, you can convert the objective function to an optimization
expression using `fcn2optimexpr`

, and then initialize the
expression using a standard zero array.

This approach has several advantages:

The function signature is maintained.

If applicable, automatic differentiation is enabled.

You can use the function in either the solver-based or problem-based workflow.

This approach requires static analysis, so it might not run correctly in earlier
MATLAB^{®} versions, and might incur a bit of overhead. This example uses the
original function `myFun`

, which fails in the problem-based
workflow 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. sol = struct with fields: x: [10×1 double] fval = -262.9274