## Convert Nonlinear Constraints Between `surrogateopt`

Form and Other
Solver Forms

### Why Convert Constraint Forms?

To try various solvers including `surrogateopt`

on a problem that has
nonlinear inequality constraints, you must convert between the form required by
`surrogateopt`

and the form required by other solvers.

### Convert from `surrogateopt`

Structure Form to Other Solvers

The objective function `objconstr(x)`

for
`surrogateopt`

returns a structure. The `Fval`

field
contains the objective function value, a scalar. The `Ineq`

field contains
a vector of constraint function values. The solver attempts to make all values in the
`Ineq`

field be less than or equal to zero. Positive values indicate a
constraint violation.

Other solvers expect the objective function to return a scalar value, not a structure.
Other solvers also expect the nonlinear constraint function to return two outputs,
`c(x)`

and `ceq(x)`

, not a structure containing
`c(x)`

.

To convert the `surrogateopt`

function
`objconstr(x)`

for use in other solvers:

Set the objective function to

`@(x)objconstr(x).Fval`

.Set the nonlinear constraint function to

`@(x)deal(objconstr(x).Ineq,[])`

.

For example,

function ff = objconstr(x) ff.Fval = norm(x)^2; ff.Ineq = norm(x - [5,8])^2 - 25; end

To solve a constrained minimization problem using `objconstr`

, call
`surrogateopt`

.

lb = [-10,-20]; ub = [20,10]; sol = surrogateopt(@objconstr,lb,ub)

surrogateopt stopped because it exceeded the function evaluation limit set by 'options.MaxFunctionEvaluations'. sol = 2.3504 3.7598

To solve the same problem using `fmincon`

, split the objective and
constraint into separate functions. Include the nonlinear equality constraint as
`[]`

by using the `deal`

function.

objfcn = @(x)objconstr(x).Fval; nlcon = @(x)deal(objconstr(x).Ineq,[]);

Call `fmincon`

with the objective function `objfcn`

and nonlinear constraint function `nlcon`

.

```
[solf,fvalf,eflag,output] = ...
fmincon(objfcn,[0,0],[],[],[],[],lb,ub,nlcon)
```

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. solf = 2.3500 3.7600 fvalf = 19.6602 eflag = 1 output = struct with fields: iterations: 7 funcCount: 24 constrviolation: 0 stepsize: 2.0397e-05 algorithm: 'interior-point' firstorderopt: 4.8151e-06 cgiterations: 0 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.403047e-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.' bestfeasible: [1×1 struct]

You can also use `patternsearch`

or `ga`

to solve
the problem using the same conversion.

### Convert from Other Solvers to `surrogateopt`

Structure Form

If you have a problem written in the form for other solvers, use the `packfcn`

function to
convert the objective and nonlinear constraints to the structure form for
`surrogateopt`

. If the objective function is a function handle
`@obj`

and the nonlinear constraint function is
`@nlconst`

, then use the objective function `objconstr`

for `surrogateopt`

.

objconstr = packfcn(@obj,@nlconst);

In this example, the objective function is Rosenbrock's function.

ros = @(x)100*(x(2) - x(1)^2)^2 + (1 - x(1))^2;

Specify the constraint function to restrict the solution to lie inside a disk of radius 1/3 centered at the point [1/3,1/3].

```
function [c,ceq] = circlecon(x)
c = (x(1)-1/3)^2 + (x(2)-1/3)^2 - (1/3)^2;
ceq = [];
```

Set bounds of –2 and 2 on each component.

lb = [-2,-2]; ub = [2,2];

Solve the problem using `patternsearch`

starting from [0,0].

x0 = [0,0]; x = patternsearch(ros,x0,[],[],[],[],lb,ub,@circlecon)

Optimization finished: mesh size less than options.MeshTolerance and constraint violation is less than options.ConstraintTolerance. x = 0.6523 0.4258

Convert the problem for solution by `surrogateopt`

.

objconstr = packfcn(ros,@circlecon); xs = surrogateopt(objconstr,lb,ub)

surrogateopt stopped because it exceeded the function evaluation limit set by 'options.MaxFunctionEvaluations'. xs = 0.6543 0.4286