minConf_BBST.m
function [x,f,funEvals,projects] = minConf_Sep(funObj1,funObj2,x,funProj,options)
if nargin < 5
options = [];
end
[verbose,optTol,progTol,maxIter,memory,testOpt,curvilinear] = myProcessOptions(options,'verbose',2,'optTol',1e-5,...
'progTol',1e-9,'maxIter',500,'memory',10,'testOpt',1,'curvilinear',0);
% Output Log
if verbose >= 2
if testOpt
fprintf('%10s %10s %10s %15s %15s %15s\n','Iteration','FunEvals','Projections','Step Length','Function Val','Opt Cond');
else
fprintf('%10s %10s %10s %15s %15s\n','Iteration','FunEvals','Projections','Step Length','Function Val');
end
end
% Evaluate Initial Objective
[f,g] = funObj1(x);
f = f+funObj2(x);
funEvals = 1;
projects = 0;
% Check optimality
if testOpt
optCond = max(abs(x-funProj(x-g,1)));
projects = projects+1;
if optCond < optTol
if verbose >= 1
fprintf('First-Order Optimality Conditions Below optTol at Initial Point\n');
end
return;
end
end
for i = 1:maxIter
% Compute direction
if i == 1
t = min(1,1/sum(abs(g)));
old_fvals = repmat(-inf,[memory 1]);
old_fvals(1) = f;
fr = f;
alpha = 1;
else
y = g-g_old;
s = x-x_old;
alpha = (y'*s)/(y'*y);
if alpha <= 1e-10 || alpha > 1e10
alpha = min(1,1/sum(abs(g)));
end
t = 1;
if i <= memory
old_fvals(i) = f;
else
old_fvals = [old_fvals(2:end);f];
end
fr = max(old_fvals);
end
x_old = x;
f_old = f;
g_old = g;
if curvilinear
x_new = funProj(x-t*alpha*g,t*alpha);
else
d = funProj(x-alpha*g,alpha)-x;
x_new = x + t*d;
end
projects = projects+1;
[f_new,g_new] = funObj1(x_new);
f_new = f_new + funObj2(x_new);
funEvals = funEvals+1;
while f_new > fr || ~isLegal(f_new)
if verbose
fprintf('Backtracking\n');
end
t = .5*t;
% Check whether step has become too small
if max(abs(x_new-x)) < progTol || t == 0
if verbose == 3
fprintf('Line Search failed\n');
end
t = 0;
f_new = f;
g_new = g;
break;
end
if curvilinear
x_new = funProj(x-t*alpha*g,t*alpha);
projects = projects+1;
else
x_new = x+t*d;
end
[f_new,g_new] = funObj1(x_new);
f_new = f_new + funObj2(x_new);
funEvals = funEvals+1;
end
x = x_new;
f = f_new;
g = g_new;
if testOpt
optCond = max(abs(x-funProj(x-g,1)));
projects = projects+1;
end
% Output Log
if verbose >= 2
if testOpt
fprintf('%10d %10d %10d %15.5e %15.5e %15.5e\n',i,funEvals,projects,t,f,optCond);
else
fprintf('%10d %10d %10d %15.5e %15.5e\n',i,funEvals,projects,t,f);
end
end
% Check Optimality
if testOpt
if optCond < optTol
if verbose
fprintf('First-order optimality below optTol\n');
end
break;
end
end
if max(abs(x-x_old)) < progTol
if verbose >= 1
fprintf('Step size below progTol\n');
end
break;
end
if abs(f-f_old) < progTol
if verbose >= 1
fprintf('Function value changing by less than progTol\n');
end
break;
end
if funEvals > maxIter
if verbose
fprintf('Exceeded maxIter funEvals\n');
end
break
end
end