Documentation

## Convert Nonlinear Function to Optimization Expression

To use a nonlinear function as an objective or nonlinear constraint function in the problem-based approach, convert the function to an optimization expression using `fcn2optimexpr`. This example shows how to convert the function using both a function file and an anonymous function.

### Function File

To use a function file in the problem-based approach, you need to convert the file to an expression using `fcn2optimexpr`.

For example, the `expfn3.m` file contains the following code:

`type expfn3.m`
```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; ```

To use this function file as an optimization expression, first create optimization variables of the appropriate sizes.

```u = optimvar('u',3,3,'LowerBound',-1,'UpperBound',1); % 3-by-3 variable v = optimvar('v',3,'LowerBound',-2,'UpperBound',2); % 3-by-1 variable```

Convert the function file to an optimization expressions using `fcn2optimexpr`.

`[f,g,mineval] = fcn2optimexpr(@expfn3,u,v);`

Because all returned expressions are scalar, you can save computing time by specifying the expression sizes using the `'OutputSize'` name-value pair argument. Also, because `expfn3` computes all of the outputs, you can save more computing time by using the `ReuseEvaluation` name-value pair.

`[f,g,mineval] = fcn2optimexpr(@expfn3,u,v,'OutputSize',[1,1],'ReuseEvaluation',true)`
```f = Nonlinear OptimizationExpression [argout,~,~] = expfn3(u, v) ```
```g = Nonlinear OptimizationExpression [~,argout,~] = expfn3(u, v) ```
```mineval = Nonlinear OptimizationExpression [~,~,argout] = expfn3(u, v) ```

### Anonymous Function

To use a general nonlinear function handle in the problem-based approach, convert the handle to an optimization expression using `fcn2optimexpr`. For example, write a function handle equivalent to `f` and convert it.

```fun = @(x,y)-exp(-y'*x*y); funexpr = fcn2optimexpr(fun,u,v,'OutputSize',[1,1])```
```funexpr = Nonlinear OptimizationExpression anonymousFunction1(u, v) where: anonymousFunction1 = @(x,y)-exp(-y'*x*y); ```

### Create Objective

To use either expression as an objective function, create an optimization problem.

```prob = optimproblem; prob.Objective = f; % Or, equivalently, prob.Objective = funexpr;```

### Define Constraints

Define the constraint `g <= 0` in the optimization problem.

`prob.Constraints.nlcons1 = g <= 0;`

Also define the constraints that `u` is symmetric and that $mineval\ge -1/2$.

```prob.Constraints.sym = u == u.'; prob.Constraints.mineval = mineval >= -1/2;```

View the problem.

`show(prob)`
``` OptimizationProblem : Solve for: u, v minimize : [argout,~,~] = expfn3(u, v) subject to nlcons1: arg_LHS <= 0 where: [~,arg_LHS,~] = expfn3(u, v); subject to sym: u(2, 1) - u(1, 2) == 0 u(3, 1) - u(1, 3) == 0 -u(2, 1) + u(1, 2) == 0 u(3, 2) - u(2, 3) == 0 -u(3, 1) + u(1, 3) == 0 -u(3, 2) + u(2, 3) == 0 subject to mineval: arg_LHS >= (-0.5) where: [~,~,arg_LHS] = expfn3(u, v); variable bounds: -1 <= u(1, 1) <= 1 -1 <= u(2, 1) <= 1 -1 <= u(3, 1) <= 1 -1 <= u(1, 2) <= 1 -1 <= u(2, 2) <= 1 -1 <= u(3, 2) <= 1 -1 <= u(1, 3) <= 1 -1 <= u(2, 3) <= 1 -1 <= u(3, 3) <= 1 -2 <= v(1) <= 2 -2 <= v(2) <= 2 -2 <= v(3) <= 2 ```

### Solve Problem

To solve the problem, call `solve`. Set an initial point `x0`.

```rng default % For reproducibility x0.u = 0.25*randn(3); x0.u = x0.u + x0.u.'; x0.v = 2*randn(3,1); [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. ```
```sol = struct with fields: u: [3x3 double] v: [3x1 double] ```
```fval = -403.4288 ```
```exitflag = OptimalSolution ```
```output = struct with fields: iterations: 70 funcCount: 1070 constrviolation: 1.3317e-12 stepsize: 6.1260e-06 algorithm: 'interior-point' firstorderopt: 5.6090e-04 cgiterations: 126 message: '...' solver: 'fmincon' ```

View the solution.

`disp(sol.u)`
``` 0.9167 0.4393 -0.9774 0.4393 0.1531 0.2139 -0.9774 0.2139 0.6913 ```
`disp(sol.v)`
``` 2.0000 -2.0000 2.0000 ```

The solution matrix `u` is symmetric. All values of `v` are at the bounds.