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.