Main Content

Coding and Minimizing an Objective Function Using Pattern Search

This example shows how to create and minimize an objective function using pattern search.

Objective Function

For this problem, the objective function to minimize is a simple function of a 2-D variable x.

simple_objective(x) = (4 - 2.1*x(1)^2 + x(1)^4/3)*x(1)^2 + x(1)*x(2) + (-4 + 4*x(2)^2)*x(2)^2;

This function is known as "cam," as described in L.C.W. Dixon and G.P. Szego [1].

Code the Objective Function

Create a MATLAB® file named simple_objective.m containing the following code:

type simple_objective
function y = simple_objective(x)
%SIMPLE_OBJECTIVE Objective function for PATTERNSEARCH solver

%   Copyright 2004 The MathWorks, Inc.  

x1 = x(1);
x2 = x(2);
y = (4-2.1.*x1.^2+x1.^4./3).*x1.^2+x1.*x2+(-4+4.*x2.^2).*x2.^2;

Solvers such as patternsearch accept a single input x, where x has as many elements as the number of variables in the problem. The objective function computes the scalar value of the objective function and returns it in its single output argument y.

Minimize Using patternsearch

Specify the objective function as a function handle.

ObjectiveFunction = @simple_objective;

Specify an initial point for the solver.

x0 = [0.5 0.5];   % Starting point

Call the solver, requesting the optimal point x and the function value at the optimal point fval.

[x,fval] = patternsearch(ObjectiveFunction,x0)
Optimization terminated: mesh size less than options.MeshTolerance.
x = 1×2

   -0.0898    0.7127

fval = -1.0316

Minimize Using Additional Arguments

Sometimes your objective function has extra arguments that act as constants during the optimization. For example, in simple_objective, you might want to specify the constants 4, 2.1, and 4 as variable parameters to create a family of objective functions.

Rewrite simple_objective to take three additional parameters (p1, p2, and p3) that act as constants during the optimization (they are not varied as part of the minimization). To implement the objective function calculation, the MATLAB file parameterized_objective.m contains the following code:

type parameterized_objective
function y = parameterized_objective(x,p1,p2,p3)
%PARAMETERIZED_OBJECTIVE Objective function for PATTERNSEARCH solver

%   Copyright 2004 The MathWorks, Inc.
  
x1 = x(1);
x2 = x(2);
y = (p1-p2.*x1.^2+x1.^4./3).*x1.^2+x1.*x2+(-p3+p3.*x2.^2).*x2.^2;

patternsearch calls the objective function with just one argument x, but the parameterized objective function has four arguments: x, p1, p2, and p3. Use an anonymous function to capture the values of the additional arguments p1, p2, and p3. Create a function handle ObjectiveFunction to an anonymous function that takes one input x, but calls parameterized_objective with x, p1, p2, and p3. When you create the function handle ObjectiveFunction, the variables p1, p2, and p3 have values that are stored in the anonymous function. For details, see Passing Extra Parameters.

p1 = 4; p2 = 2.1; p3 = 4;    % Define constant values
ObjectiveFunction = @(x) parameterized_objective(x,p1,p2,p3);
[x,fval] = patternsearch(ObjectiveFunction,x0)
Optimization terminated: mesh size less than options.MeshTolerance.
x = 1×2

   -0.0898    0.7127

fval = -1.0316

Vectorize the Objective Function

By default, patternsearch passes in one point at a time to the objective function. Sometimes, you can speed the solver by vectorizing the objective function to take a set of points and return a set of function values.

For the solver to evaluate a set of five points in one call to the objective function, for example, the solver calls the objective on a matrix of size 5-by-2 (where 2 is the number of variables). For details, see Vectorize the Objective and Constraint Functions.

To vectorize parameterized_objective, use the following code:

type vectorized_objective
function y = vectorized_objective(x,p1,p2,p3)
%VECTORIZED_OBJECTIVE Objective function for PATTERNSEARCH solver

%   Copyright 2004-2018 The MathWorks, Inc.

x1 = x(:,1); % First column of x
x2 = x(:,2);
y = (p1 - p2.*x1.^2 + x1.^4./3).*x1.^2 + x1.*x2 + (-p3 + p3.*x2.^2).*x2.^2;

This vectorized version of the objective function takes a matrix x with an arbitrary number of points (the rows of x) and returns a column vector y whose length is the number of rows of x.

To take advantage of the vectorized objective function, set the UseVectorized option to true and the UseCompletePoll option to true. patternsearch requires both of these options to compute in a vectorized manner.

options = optimoptions(@patternsearch,'UseVectorized',true,'UseCompletePoll',true);

Specify the objective function and call patternsearch, including the options argument. Use tic/toc to evaluate the solution time.

ObjectiveFunction = @(x) vectorized_objective(x,4,2.1,4);
tic
[x,fval] = patternsearch(ObjectiveFunction,x0,[],[],[],[],[],[],[],options)
Optimization terminated: mesh size less than options.MeshTolerance.
x = 1×2

   -0.0898    0.7127

fval = -1.0316
toc
Elapsed time is 0.027503 seconds.

Evaluate the nonvectorized solution time for comparison.

tic
[x,fval] = patternsearch(ObjectiveFunction,x0)
Optimization terminated: mesh size less than options.MeshTolerance.
x = 1×2

   -0.0898    0.7127

fval = -1.0316
toc
Elapsed time is 0.027502 seconds.

In this case, the vectorization does not have a significant impact on the solution time.

References

[1] Dixon, L. C. W., and G .P. Szego (eds.). Towards Global Optimisation 2. North-Holland: Elsevier Science Ltd., Amsterdam, 1978.

Related Topics