This is machine translation

Translated by Microsoft
Mouseover text to see original. Click the button below to return to the English version of the page.

Note: This page has been translated by MathWorks. Click here to see
To view all translated materials including this page, select Country from the country navigator on the bottom of this page.

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-1/2.

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

View the problem.

showproblem(prob)
  OptimizationProblem : 

	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 = randn(3);
x0.u = x0.u + x0.u.';
x0.v = 2*randn(3,1);
[sol,fval,exitflag,output] = solve(prob,x0)
Solver stopped prematurely.

fmincon stopped because it exceeded the function evaluation limit,
options.MaxFunctionEvaluations = 3.000000e+03.
sol = struct with fields:
    u: [3x3 double]
    v: [3x1 double]

fval = -276.0978
exitflag = 
    SolverLimitExceeded

output = struct with fields:
         iterations: 176
          funcCount: 3000
    constrviolation: 0.0035
           stepsize: 0.3984
          algorithm: 'interior-point'
      firstorderopt: 347.7391
       cgiterations: 376
            message: '...'
             solver: 'fmincon'

View the solution.

disp(sol.u)
    0.9661    1.0000   -0.7093
    1.0000    0.2724   -0.4667
   -0.7093   -0.4667   -0.1584
disp(sol.v)
    2.0000
   -2.0000
    2.0000

The solution matrix u is symmetric. The solution vector v has all entries at bound constraints.

See Also

Related Topics