Ordinarily, minimization routines use numerical gradients calculated by finite-difference approximation. This procedure systematically perturbs each of the variables in order to calculate function and constraint partial derivatives. Alternatively, you can provide a function to compute partial derivatives analytically. Typically, the problem is solved more accurately and efficiently if such a function is provided.
Consider how to solve
subject to the constraints
x1x2 – x1 – x2 ≤
–1.5,
x1x2 ≥
–10.
To solve the problem using analytically determined gradients, do the following.
function [f,gradf] = objfungrad(x)
f = exp(x(1))*(4*x(1)^2+2*x(2)^2+4*x(1)*x(2)+2*x(2)+1);
% Gradient of the objective function:
if nargout > 1
gradf = [ f + exp(x(1)) * (8*x(1) + 4*x(2)),
exp(x(1))*(4*x(1)+4*x(2)+2)];
endfunction [c,ceq,DC,DCeq] = confungrad(x)
c(1) = 1.5 + x(1) * x(2) - x(1) - x(2); % Inequality constraints
c(2) = -x(1) * x(2)-10;
% No nonlinear equality constraints
ceq=[];
% Gradient of the constraints:
if nargout > 2
DC= [x(2)-1, -x(2);
x(1)-1, -x(1)];
DCeq = [];
endgradf contains the partial derivatives of
the objective function, f, returned by objfungrad(x),
with respect to each of the elements in x:
| (6-58) |
The columns of DC contain the partial derivatives
for each respective constraint (i.e., the ith column
of DC is the partial derivative of the ith
constraint with respect to x). So in the above
example, DC is
| (6-59) |
Since you are providing the gradient of the objective in objfungrad.m and
the gradient of the constraints in confungrad.m,
you must tell fmincon that
these files contain this additional information. Use optimoptions to turn the options SpecifyObjectiveGradient and SpecifyConstraintGradient to true in
the example's existing options:
options = optimoptions(options,'SpecifyObjectiveGradient',true,'SpecifyConstraintGradient',true);
If you do not set these options to 'on', fmincon does not use the analytic gradients.
The arguments lb and ub place
lower and upper bounds on the independent variables in x.
In this example, there are no bound constraints, so set both to [].
x0 = [-1,1]; % Starting guess options = optimoptions(@fmincon,'Algorithm','sqp'); options = optimoptions(options,'SpecifyObjectiveGradient',true,'SpecifyConstraintGradient',true); lb = [ ]; ub = [ ]; % No upper or lower bounds [x,fval] = fmincon(@objfungrad,x0,[],[],[],[],lb,ub,... @confungrad,options);
The results:
x,fval
x =
-9.5474 1.0474
fval =
0.0236
[c,ceq] = confungrad(x) % Check the constraint values at x
c =
1.0e-13 *
-0.1066
0.1066
ceq =
[]