Documentation

# fcn2optimexpr

Convert function to optimization expression

## Syntax

``[out1,out2,...,outN] = fcn2optimexpr(fcn,in1,in2,...,inK)``
``[out1,out2,...,outN] = fcn2optimexpr(fcn,in1,in2,...,inK,Name,Value)``

## Description

example

````[out1,out2,...,outN] = fcn2optimexpr(fcn,in1,in2,...,inK)` converts the function `fcn(in1,in2,...,inK)` to an optimization expression having `N` outputs.```

example

````[out1,out2,...,outN] = fcn2optimexpr(fcn,in1,in2,...,inK,Name,Value)` modifies the expression creation process according to name-value parameters.```

## Examples

collapse all

To use a MATLAB™ function in the problem-based approach, first convert it to an optimization expression.

For example, to use the objective function $-\mathrm{exp}\left(-{x}^{2}/2\right)$, create an optimization variable `x` and use it in a converted anonymous function:

```x = optimvar('x'); obj = fcn2optimexpr(@(t)-exp(-t^2/2),x); prob = optimproblem('Objective',obj); showproblem(prob)```
``` OptimizationProblem : Solve for: x minimize : anonymousFunction1(x) where: anonymousFunction1 = @(t)-exp(-t^2/2); ```

For more complex functions, convert a function file. For example, suppose that you have a function file named `expfn2.m` that computes an objective in two optimization variables.

`type expfn2`
```function f = expfn2(t,u) f = -exp(-t^2/2)*u/(1 + u^2); ```

Include this objective in a problem.

```x = optimvar('x'); y = optimvar('y','LowerBound',0); obj = fcn2optimexpr(@expfn2,x,y); prob = optimproblem('Objective',obj); showproblem(prob)```
``` OptimizationProblem : Solve for: x, y minimize : expfn2(x, y) variable bounds: 0 <= y ```

If your function has several outputs, you can use them as elements of the objective function. For example, suppose that `u` is a 2-by-2 variable and `v` is a 2-by-1 variable, and `expfn3` has three outputs:

`type expfn3`
```function [f,g,mineval] = expfn3(u,v) mineval = min(eig(u)); f = v'*u*v; f = -exp(-f); t = u*v; g = t'*t + sum(t) - 3; ```

Create appropriately sized optimization variables, and create an objective function from the first two outputs.

```u = optimvar('u',2,2); v = optimvar('v',2); [f,g,mineval] = fcn2optimexpr(@expfn3,u,v); prob = optimproblem; prob.Objective = f*g/(1 + f^2); showproblem(prob)```
``` OptimizationProblem : Solve for: u, v minimize : ((arg2 .* arg3) ./ (1 + arg1.^2)) where: [arg1,~,~] = expfn3(u, v); [arg2,~,~] = expfn3(u, v); [~,arg3,~] = expfn3(u, v); ```

You can use the `mineval` output in a subsequent constraint expression.

In problem-based optimization, constraints are two optimization expressions with a comparison operator (`==`, `<=`, or `>=`) between them. You can use `fcn2optimexpr` to create one or both optimization expressions.

Create the constraint that `expfn2` is less than or equal to –1/2. This function of two variables is in the `expfn2.m` file.

`type expfn2`
```function f = expfn2(t,u) f = -exp(-t^2/2)*u/(1 + u^2); ```

Create optimization variables, convert the function file to an optimization expression, then express the constraint as `confn`.

```x = optimvar('x'); y = optimvar('y','LowerBound',0); expr1 = fcn2optimexpr(@expfn2,x,y); confn = expr1 <= -1/2; showconstr(confn)```
``` expfn2(x, y) <= -0.5 ```

Create another constraint that `expfn2` is greater than `x + y`.

`confn2 = expr1 >= x + y;`

Create an optimization problem and place the constraints in the problem.

```prob = optimproblem; prob.Constraints.confn = confn; prob.Constraints.confn2 = confn2; showproblem(prob)```
``` OptimizationProblem : Solve for: x, y minimize : subject to confn: expfn2(x, y) <= -0.5 subject to confn2: expfn2(x, y) >= (x + y) variable bounds: 0 <= y ```

If the objective and nonlinear constraint come from a common, time-consuming function, save time by using the `'ReuseEvaluation'` name-value pair. For example, `rosenbrocknorm` computes both the Rosenbrock objective function, and the norm of the argument for use in the constraint $‖x{‖}^{2}\le 4$.

`type rosenbrocknorm`
```function [f,c] = rosenbrocknorm(x) pause(1) % Simulates time-consuming function c = dot(x,x); f = 100*(x(2) - x(1)^2)^2 + (1 - x(1))^2; ```

Create a 2-D optimization variable `x`. Then convert `rosenbrocknorm` to an optimization expression by using `fcn2optimexpr`, specifying `'ReuseEvaluation'`.

```x = optimvar('x',2); [f,c] = fcn2optimexpr(@rosenbrocknorm,x,'ReuseEvaluation',true);```

Create objective and constraint expressions from the returned expressions. Include these expressions in an optimization problem. Review the problem using `showproblem`.

```prob = optimproblem('Objective',f); prob.Constraints.cineq = c <= 4; showproblem(prob)```
``` OptimizationProblem : Solve for: x minimize : [argout,~] = rosenbrocknorm(x) subject to cineq: arg_LHS <= 4 where: [~,arg_LHS] = rosenbrocknorm(x); ```

Solve the problem starting from the initial point `x0.x = [-1;1]`, timing the result.

```x0.x = [-1;1]; tic [sol,fval,exitflag,output] = 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. <stopping criteria details> ```
```sol = struct with fields: x: [2×1 double] ```
```fval = 3.6222e-11 ```
```exitflag = OptimalSolution ```
```output = struct with fields: iterations: 43 funcCount: 161 constrviolation: 0 stepsize: 9.1067e-08 algorithm: 'interior-point' firstorderopt: 6.3912e-07 cgiterations: 10 message: '↵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>↵↵Optimization completed: The relative first-order optimality measure, 6.391223e-07,↵is less than options.OptimalityTolerance = 1.000000e-06, and the relative maximum constraint↵violation, 0.000000e+00, is less than options.ConstraintTolerance = 1.000000e-06.↵↵' solver: 'fmincon' ```
`toc`
```Elapsed time is 161.656507 seconds. ```

The solution time in seconds is nearly the same as the number of function evaluations. This result indicates that the solver reused function values, and did not waste time by reevaluating the same point twice.

For a more extensive example, see Objective and Constraints Having a Common Function in Serial or Parallel, Problem-Based.

## Input Arguments

collapse all

Function to convert, specified as a function handle.

Example: `@sin` specifies the sine function

Data Types: `function_handle`

Input argument, specified as a MATLAB variable. The input can have any data type and any size.

Data Types: `single` | `double` | `int8` | `int16` | `int32` | `int64` | `uint8` | `uint16` | `uint32` | `uint64` | `logical` | `char` | `string` | `struct` | `table` | `cell` | `function_handle` | `categorical` | `datetime` | `duration` | `calendarDuration` | `fi`
Complex Number Support: Yes

### Name-Value Pair Arguments

Specify optional comma-separated pairs of `Name,Value` arguments. `Name` is the argument name and `Value` is the corresponding value. `Name` must appear inside quotes. You can specify several name and value pair arguments in any order as `Name1,Value1,...,NameN,ValueN`.

Example: ```[out1,out2] = fcn2optimexpr(@fun,x,y,'OutputSize',[1,1],'Reuse',true)``` specifies that `out1` and `out2` are scalars and that these variables will be reused between objective and constraint functions without recalculation.

Sizes of output expressions, specified as:

• An integer vector — If there is one output `out`1, `OutputSize` specifies the size of `out`1. If there are multiple outputs `out`1,…,`out`N, `OutputSize` specifies that all outputs have the same size.

### Note

A scalar has size `[1,1]`.

• A cell array of integer vectors — The size of output `out`j is the jth element of `OutputSize`.

If you do not pass an `OutputSize` name-value pair, then `fcn2optimexpr` passes data to `fcn` in order to determine the sizes of the outputs (see Algorithms). By passing `OutputSize`, you enable `fcn2optimexpr` to skip this step. Skipping this evaluation saves time. Additionally, if you do not pass an `OutputSize` name-value pair, and if the evaluation of `fcn` fails for any reason, then `fcn2optimexpr` fails as well.

Example: ```[out1,out2,out3] = fcn2optimexpr(@fun,x,'OutputSize',[1,1])``` specifies that the three outputs `[out1,out2,out3]` are scalars

Example: ```[out1,out2] = fcn2optimexpr(@fun,x,'OutputSize',{[4,4],[3,5]})``` specifies that `out1` has size 4-by-4 and `out2` has size 3-by-5.

Data Types: `double` | `cell`

Enable reusable values, specified as `false` (do not enable) or `true` (enable).

`ReuseEvaluation` can make your problem run faster when, for example, the objective and some nonlinear constraints rely on a common calculation. In this case, the solver stores the value for reuse wherever needed, so avoids recalculating the value.

There is a small overhead in enabling reusable values, so it is best to enable reusable values only for expressions that share a value.

Example: ```[out1,out2,out3] = fcn2optimexpr(@fun,x,'ReuseEvaluation',true)``` allows `out1`, `out2`, and `out3` to be used in multiple computations, with the outputs being calculated only once per evaluation point

Data Types: `logical`

## Output Arguments

collapse all

Output argument, returned as an `OptimizationExpression`. The size of the expression depends on the input function.

## Algorithms

To find the output size of each returned expression when you do not provide an `OutputSize`, `fcn2optimexpr` evaluates your function at the following point for each element of the problem variables.

• If there is a finite upper bound `ub` and a finite lower bound `lb`, the evaluation point is ```(lb + ub)/2 + ((ub - lb)/2)*eps```.

• If there is a finite lower bound and no upper bound, the evaluation point is `lb + max(1,abs(lb))*eps`.

• If there is a finite upper bound and no lower bound, the evaluation point is `ub - max(1,abs(ub))*eps`.

• If there are no bounds, the evaluation point is `1 + eps`.

• In addition, if the variable is specified as an integer, the evaluation point is `floor` of the point given previously.

It is possible that this evaluation point leads to an error in function evaluation. To avoid this error, specify `OutputSize`.