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)]; end
function [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 = []; end
gradf
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 i
th column
of DC
is the partial derivative of the i
th
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 GradObj
and GradConstr
to 'on'
in
the example's existing options
:
options = optimoptions(options,'GradObj','on','GradConstr','on');
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,'GradObj','on','GradConstr','on'); 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 = []