https://github.com/ruqihuang/AdjointFmaps
Tip revision: d41efaa1636fb8cc0da8f09d89f4a1cae0172320 authored by ruqihuang on 24 August 2017, 07:39:27 UTC
Update readme
Update readme
Tip revision: d41efaa
minConf_QNST.m
function [x,f,funEvals] = minConf_QNST(funObj1,funObj2,x,funProj,options)
nVars = length(x);
if nargin < 5
options = [];
end
[verbose,numDiff,optTol,progTol,maxIter,maxProject,suffDec,corrections,adjustStep,bbInit,...
BBSToptTol,BBSTprogTol,BBSTiters,BBSTtestOpt] = ...
myProcessOptions(...
options,'verbose',2,'numDiff',0,'optTol',1e-5,'progTol',1e-9,'maxIter',500,'maxProject',100000,'suffDec',1e-4,...
'corrections',10,'adjustStep',0,'bbInit',0,'BBSToptTol',1e-6,'BBSTprogTol',1e-10,'BBSTiters',10,'BBSTtestOpt',0);
% Output Parameter Settings
if verbose >= 3
fprintf('Running QNST...\n');
fprintf('Number of L-BFGS Corrections to store: %d\n',corrections);
fprintf('Spectral initialization of BBST: %d\n',bbInit);
fprintf('Maximum number of BBST iterations: %d\n',BBSTiters);
fprintf('BBST optimality tolerance: %.2e\n',BBSToptTol);
fprintf('BBST progress tolerance: %.2e\n',BBSTprogTol);
fprintf('PQN optimality tolerance: %.2e\n',optTol);
fprintf('PQN progress tolerance: %.2e\n',progTol);
fprintf('Quadratic initialization of line search: %d\n',adjustStep);
fprintf('Maximum number of function evaluations: %d\n',maxIter);
fprintf('Maximum number of projections: %d\n',maxProject);
end
if verbose
fprintf('%10s %10s %10s %15s %15s\n','Iteration','FunEvals','Projections','Step Length','Function Val');
end
% Evaluate Initial Objective
[f1,g] = funObj1(x);
f = f1+funObj2(x);
funEvals = 1;
projects = 0;
% Check optimality
optCond = max(abs(x-funProj(x-g,1)));
projects = 1;
if optCond < optTol
if verbose >= 1
fprintf('First-Order Optimality Conditions Below optTol at Initial Point\n');
end
return;
end
i = 1;
while 1
if 0 % BBST
if i == 1
alpha = 1;
else
y = g-g_old;
s = x-x_old;
alpha = (s'*s)/(s'*y);
if alpha <= 1e-10 || alpha > 1e10
alpha = min(1,1/sum(abs(g)));
end
end
p = funProj(x-alpha*g,alpha);
projects = projects+1;
else % QNST
if i == 1
p = funProj(x-g,1);
projects = projects+1;
S = zeros(nVars,0);
Y = zeros(nVars,0);
Hdiag = 1;
else
y = g-g_old;
s = x-x_old;
[S,Y,Hdiag] = lbfgsUpdate(y,s,corrections,verbose==3,S,Y,Hdiag);
% Make Compact Representation
k = size(Y,2);
L = zeros(k);
for j = 1:k
L(j+1:k,j) = S(:,j+1:k)'*Y(:,j);
end
N = [S/Hdiag Y];
M = [S'*S/Hdiag L;L' -diag(diag(S'*Y))];
HvFunc = @(v)lbfgsHvFunc2(v,Hdiag,N,M);
if bbInit
% Use Barzilai-Borwein step to initialize sub-problem
alpha = (s'*s)/(s'*y);
if alpha <= 1e-10 || alpha > 1e10
alpha = 1/norm(g);
end
% Solve Sub-problem
xSubInit = funProj(x-alpha*g,alpha);
projects = projects+1;
else
xSubInit = x;
end
% Solve Sub-problem
[p,subProjects] = solveSubProblem(x,g,HvFunc,funObj2,funProj,BBSToptTol,BBSTprogTol,BBSTiters,BBSTtestOpt,xSubInit);
projects = projects+subProjects;
end
end
d = p-x;
g_old = g;
x_old = x;
% Bound Step length on first iteration
t = 1;
if i == 1
t = min(1,1/sum(abs(g)));
end
if t == 1
x_new = p;
else
x_new = x+t*d;
end
[f1_new,g_new] = funObj1(x_new);
f_new = f1_new + funObj2(x_new);
funEvals = funEvals+1;
f_old = f;
while f_new > f
if verbose
fprintf('Backtracking\n');
end
t = t/2;
x_new = x+t*d;
[f1_new,g_new] = funObj1(x_new);
f_new = f1_new + funObj2(x_new);
funEvals = funEvals+1;
end
x = x_new;
f = f_new;
g = g_new;
% Check Optimality
optCond = max(abs(x-funProj(x-g,1)));
projects = projects+1;
if verbose
fprintf('%10d %10d %10d %15.5e %15.5e %15.5e\n',i,funEvals,projects,t,f,optCond);
end
if optCond < optTol
if verbose
fprintf('First-order optimality below optTol\n');
end
break;
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
i = i + 1;
end
end
function [p,subProjects] = solveSubProblem(x,g,H,funObj2,funProj,optTol,progTol,maxIter,testOpt,x_init)
% Uses BBST to solve for quasi-Newton soft-threshold direction
options.verbose = 0;
options.optTol = optTol;
options.progTol = progTol;
options.maxIter = maxIter;
options.testOpt = testOpt;
funObj = @(p)subHv(p,x,g,H);
[p,f,funEvals,subProjects] = minConf_BBST(funObj,funObj2,x_init,funProj,options);
end
function [f,g] = subHv(p,x,g,HvFunc)
d = p-x;
Hd = HvFunc(d);
f = g'*d + (1/2)*d'*Hd;
g = g + Hd;
end