https://github.com/kul-forbes/ForBES
Revision dc65c2366e10a76b7166228adb65acb9a20d68a0 authored by Pantelis Sopasakis on 05 March 2018, 20:56:03 UTC, committed by GitHub on 05 March 2018, 20:56:03 UTC
crash of Forbes on Matlab 2017a
Tip revision: dc65c2366e10a76b7166228adb65acb9a20d68a0 authored by Pantelis Sopasakis on 05 March 2018, 20:56:03 UTC
Merge pull request #3 from Zilleplus/master
Merge pull request #3 from Zilleplus/master
Tip revision: dc65c23
nama.m
function out = nama(prob, opt, varargin)
% initialize output stuff
if opt.report
residual = zeros(1, opt.maxit);
objective = zeros(1, opt.maxit);
ts = zeros(1, opt.maxit);
end
% initialize operations counter
ops = FBOperations();
% get Lipschitz constant & adaptiveness
[Lf, adaptive] = prob.Get_Lipschitz(opt);
% initialize gamma and sigma
gam = (1-opt.beta)/Lf;
% display header
if opt.display >= 2
fprintf('\n%s', opt.name);
fprintf('\n%6s%11s%11s%11s%11s%11s\n', 'iter', 'gamma', 'optim.', 'object.', '||d||', 'tau');
end
cacheDir.cntSkip = 0;
msgTerm = 'exceeded maximum iterations';
flagTerm = 1;
restart1 = 0;
restart2 = 0;
cache_x = FBCache(prob, prob.x0, gam, ops);
t0 = tic();
for it = 1:opt.maxit
% backtracking on gamma
if adaptive
[restart1, ~] = cache_x.Backtrack_Gamma(opt.beta);
gam = cache_x.Get_Gamma();
end
% trace stuff
if it == 1
cache_0 = cache_x;
end
if opt.report
objective(1, it) = cache_x.Get_FBE();
residual(1, it) = norm(cache_x.Get_FPR(), 'inf')/cache_x.Get_Gamma();
ts(1, it) = toc(t0);
end
if opt.toRecord
record(:, it) = opt.record(prob, it, cache_0, cache_x);
end
% check for termination
if ~(restart1 || restart2)
if ~opt.customTerm
if cache_x.Check_StoppingCriterion(opt.tol)
msgTerm = 'reached optimum (up to tolerance)';
flagTerm = 0;
break;
end
else
flagStop = opt.term(prob, it, cache_0, cache_x);
if (adaptive == 0 || it > 1) && flagStop
msgTerm = 'reached optimum (custom criterion)';
flagTerm = 0;
break;
end
end
end
% compute search direction and slope
if it == 1 || restart1 || restart2
sk = [];
yk = [];
end
[dir_QN, ~, cacheDir] = ...
opt.methodfun(prob, opt, it, restart1 || restart2, sk, yk, cache_x.Get_FPR(), cacheDir);
dir_FB = -cache_x.Get_FPR();
% perform line search
tau = 1.0; % this *must* be 1.0 for this line-search to work
cache_x.Set_Directions(dir_QN);
cache_w = cache_x.Get_CacheLine(tau, 1);
if adaptive
[restart2, cache_wbar] = cache_w.Backtrack_Gamma(opt.beta);
gam = cache_w.Get_Gamma();
else
cache_wbar = [];
end
if restart2
cache_x.Set_Gamma(gam);
continue;
end
if cache_w.Get_FBE() > cache_x.Get_FBE()
cache_x.Set_Directions([], dir_FB);
end
while cache_w.Get_FBE() > cache_x.Get_FBE()
if tau <= 1e-3
% simply do forward-backward step if line-search fails
cache_w = FBCache(prob, cache_x.Get_ProxGradStep(), gam, ops);
% next line is for debugging purposes in case the code reaches this
% cache_xbar = FBCache(prob, cache_x.Get_ProxGradStep(), gam, []);
break;
end
tau = tau/2;
cache_w = cache_x.Get_CacheSegment(tau);
if adaptive
[restart2, cache_wbar] = cache_w.Backtrack_Gamma(opt.beta);
gam = cache_w.Get_Gamma();
if restart2, break; end
end
end
if restart2
cache_x.Set_Gamma(gam);
continue;
end
restart2 = 0;
% store pair (s, y) to compute next direction
sk = cache_w.Get_Point() - cache_x.Get_Point();
yk = cache_w.Get_FPR() - cache_x.Get_FPR();
% update iterate
if ~isempty(cache_wbar)
cache_x = cache_wbar;
else
cache_x = FBCache(prob, cache_w.Get_ProxGradStep(), gam, ops);
end
% display stuff
if opt.display == 1
Util_PrintProgress(it);
elseif (opt.display == 2 && mod(it,10) == 0) || opt.display >= 3
res_curr = norm(cache_x.Get_FPR(), 'inf')/cache_x.Get_Gamma();
obj_curr = cache_x.Get_FBE();
fprintf('%6d %7.4e %7.4e %7.4e %7.4e %7.4e\n', it, gam, res_curr, obj_curr, norm(dir_QN), tau);
end
end
time = toc(t0);
if opt.display == 1
Util_PrintProgress(it, flagTerm);
elseif opt.display >= 2
res_curr = norm(cache_x.Get_FPR(), 'inf')/cache_x.Get_Gamma();
obj_curr = cache_x.Get_FBE();
fprintf('%6d %7.4e %7.4e %7.4e\n', it, gam, res_curr, obj_curr);
end
% pack up results
out.name = opt.name;
out.message = msgTerm;
out.flag = flagTerm;
if it == opt.maxit
out.x = cache_x.Get_Point();
else
out.x = cache_x.Get_ProxGradStep();
end
out.iterations = it;
out.operations = ops;
if opt.report
out.residual = residual(1, 1:it);
out.objective = objective(1, 1:it);
out.ts = ts(1, 1:it);
end
if opt.toRecord, out.record = record; end
out.gam = gam;
out.time = time;
out.cacheDir = cacheDir;
end
![swh spinner](/static/img/swh-spinner.gif)
Computing file changes ...