# 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: 87
funcCount: 1448
constrviolation: 6.3860e-12
stepsize: 7.4093e-05
algorithm: 'interior-point'
firstorderopt: 0.0012
cgiterations: 172
message: '...'
solver: 'fmincon'

View the solution.

disp(sol.u)
0.8419    0.5748   -0.7670
0.5748    0.3745    0.2997
-0.7670    0.2997    0.5667
disp(sol.v)
2.0000
-2.0000
2.0000

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