Clear Filters
Clear Filters

Exchanging information between function, gradient, and Hessian

2 views (last 30 days)
Hello there
I have a constrained nonlinear optimzation problem. Denote the objective, constraints, and their respective gradient vectors and Hessian matricies as
.
The Hessian of the Lagrangian function is .
The gradient vectors of the objective and constraints functions are given in the (conditionalized) output as
function [f,df] = myObj(x)
f; %compute f
if nargout > 1
df; %compute df
end
end
function [g,dg] = myConst(x)
g(k); % compute g_k
if nargout > 1
dg(k); % compute dg_k
end
end
NOTE: The gradient vectors are only calculated when fmincon needs to evaluate them
Fmicon requests that the Hessian is supplied via a seperate function,
function [H] = myHess(x,lam)
H; %compute H
end
However, in the case of my problem, the computation of H requires the gradient vectors Obviously, I don't want to recompute them inside myHess. Instead, I want to pass the information to myHess as
function [H] = myHess(x,lam,df,dg)
H; %compute H using df and dg
end
My Question: How can I efficiently use the results of df and dg inside myHess?
I have seen the page on using nested functions: https://ch.mathworks.com/help/optim/ug/objective-and-nonlinear-constraints-in-the-same-function.html. However, here they did not show what to do when I have conditionalized outputs.
Thanks a lot!

Accepted Answer

Marty
Marty on 8 Mar 2023
See my reply to Sai

More Answers (1)

Sai Kiran
Sai Kiran on 8 Mar 2023
Hi,
As per my understanding you dont want to recompute the df,dg. You can directly pass the functions myObj & myConst in the myHess function to get the df, dg .
Please follow the below example for better understanding.
myHess function uses the func1 and func2 outputs.
function [H] = myHess(a,b)
H=func1(a)+func2(b);
end
function [a]=func1(x)
a=x*x;
end
function [b]=func2(y)
b=y*y;
end
Name the matlab file as myHess.m and use the myHess function.
I hope it helps!
Thanks.
  1 Comment
Marty
Marty on 8 Mar 2023
Edited: Marty on 8 Mar 2023
Hi Sai
Thanks for your reply!
Mmm, this is not exactly what I was looking for---unless I am not understanding your code correctly. The computations of a and b may already be done, so it would be redudant to do them inside of myHess. The Hessian is not called at every iteration.
However, I did solve this problem using nested functions. I expanded the example shown here: https://ch.mathworks.com/help/optim/ug/objective-and-nonlinear-constraints-in-the-same-function.html. Below, you can find an example of what I did. NOTE: I had to remove and re-write some parts, since it contained confidential material, so code may be incomplete.
function [x,f_out,flag,output] = solve_problem(x0)
%% nested variables (shared between functions)
x_last_obj = []; % last iteration used to compute objective
x_last_nonlincons = []; % last iteration used to compute nonlinear constraints
f_obj = []; % value of objective
df_obj = []; % gradient of objective
c_nonlin_ineq = []; % values of inequality constraints
dc_nonlin_ineq = []; % gradient ofinequality constraints
%% handles for fmincon
obj = @(x) my_obj(x)
nonlin = @(x) my_constr(x)
HessFcn = @(x,lam) my_hessian(x,lam)
%% options for fmincon
options = optimoptions('fmincon','Algorithm','interior-point',...
"SpecifyConstraintGradient",true,"SpecifyObjectiveGradient",true,...
'HessianFcn',@HessFcn);
%% solve problem
[x,f_out,flag,output] = fmincon(obj,x0,[],[],[],[],[],[],nonlin,options);
%% Nested functions
function [f,df] = my_obj(x)
if nargout > 1 % need gradient
[f,df] = objective_function(x);
f_obj = f;
df_obj = df;
else % need only value
f = objective_function(x);
f_obj = f;
df_obj = [];
end
x_last_obj = x;
end
function [c,ceq,dc,deq] = my_constr(x)
if nargout > 2 % need gradient
[c,~,dc,~] = nonlinear_constraints(x);
c_nonlin_ineq = c;
dc_nonlin_ineq = dc;
else % need only value
c = nonlinear_constraints(x);
c_nonlin_ineq = c;
dc_nonlin_ineq = [];
end
ceq = [];
deq = [];
x_last_nonlincons = x;
end
function H = my_hessian(x,lam)
% check if gradients have been calculated and if the values are up
% to date; if false, calculate them
if isempty(dc_nonlin_ineq) || isempty(df_obj) || ~isequal(x_last_obj,x) || ~isequal(x_last_nonlincons,x)
[c_nonlin_ineq,~,dc_nonlin_ineq,~] = nonlinear_constraints(x);
[f_obj,df_obj] = objective_function(x);
end
H = hessian(x,lam,f_obj,df_obj,c_nonlin_ineq,dc_nonlin_ineq);
end
end

Sign in to comment.

Products


Release

R2020b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!