1 function [xnew, resnorm, residual, exitflag, output, tempsols] =
gplmm(funptr, x0, params)
2 %
function [vnew, resnorm, residual, output, exitflags] =
gplmm(funptr, vold, params)
3 % Global projected Levenberg-Marquard method
5 if ~isfield(params,
'beta')
8 if ~isfield(params, 'sigma')
11 if ~isfield(params, 'gamma')
12 params.gamma = 0.999995;
14 if ~isfield(params, 'mu')
17 if ~isfield(params, 'TolFun')
18 params.TolFun = 1e-10;
20 if ~isfield(params, 'TolLineSearch')
21 params.TolLineSearch = 1e-10;
23 if ~isfield(params, 'TolFuncCount')
24 params.TolFuncCount = 1000;
26 if ~isfield(params, 'TolRes')
29 if ~isfield(params, 'TolChange')
30 params.TolChange = 1e-13;
32 if ~isfield(params, 'maxIter')
35 if ~isfield(params, 'rho')
38 if ~isfield(params, 'armijo_p')
39 params.armijo_p = 2.1;
41 if isfield(params, 'HessFun')
42 compute_hess_matrix = 0;
44 compute_hess_matrix = 1;
47 if ~isfield(params, 'debug')
62 [F, J] = funptr(xold);
63 %J = computed_jacobian(J, xold, funptr);
71 % function converged to zero
72 [max_F, max_i] = max(abs(F));
73 imaxes = [imaxes, max_i];
74 resmaxes = [resmaxes, max_F];
75 disp(['i = ', num2str(imaxes(end)), ' max = ', num2str(resmaxes(end))]);
76 if resmaxes(end) < params.TolRes
82 disp('Found solution.');
88 % change in residual too small
89 if max(abs(F-Fold)) < params.TolChange
91 disp('Change in residual too small');
95 %one_rows = find(xold(1:400) > 1-100*eps);
96 % if ~isempty(one_rows)
99 % TI = repmat(one_rows', m, 1);
101 % TJ = repmat((1:m)', 1, length(one_rows));
103 % T = sparse(TI, TJ, ones(1, length(one_rows)*m), n, m);
105 %J(sub2ind([n, m], one_rows, one_rows)) = 0;
106 % J(:, one_rows) = 0; %= %J - (J & T);
111 setup.type = 'nofill';
113 setup.droptol = 1e-4;
115 if compute_hess_matrix
117 % [L,U] = ilu(Hess, setup);
118 % dkU = gmres(@(X) Hess * X, -gf, 3, 1e-10, min(2500, m), L, U);
119 % dkU = cgs(Hess, -gf, [], [], L, U);
122 % [HessTemp, precond] = params.HessFun(params, J, [], []);
123 HessFunWrap = @(X) params.HessFun(params, J, [], X);
124 dkU = bicgstab(HessFunWrap, -gf, 1e-12, 600);%,
125 % precond.L,precond.U);
126 % dkU = cgs(HessFunWrap, -gf, [], 300);
127 % dkU = gmres(HessFunWrap, -gf, [], 1e-12, min(2500, m));%, precond.L, precond.U);
129 if condest(Hess) > 1e-12
130 xnew = params.Px(xold + dkU);
136 muk = min(params.mu * (Fold'*Fold), 1) / (k+1);
138 % first order optimalities
139 foms = [foms, max(gf)];
141 if max(abs(Fold)) > params.TolRes
142 if compute_hess_matrix
143 Hess = J' * J + muk .* speye(m,m);
144 % [L,U] = ilu(Hess, setup);
145 % dkU = bicgstab(Hess, -gf, 1e-10, 600, L, U);
146 % dkU = gmres(Hess, -gf, 2, 1e-10, min(2500, m), L, U);
149 % [HessTemp, precond] = params.HessFun(params, J, [], []);
150 HessFunWrap = @(X) params.HessFun(params, J, [], X) + muk .* X;
151 dkU = gmres(HessFunWrap, -gf, 2, 1e-12, min(2500, m));%, precond.L, precond.U);
154 pxnext = params.Px(xold + dkU);
156 [Fcand, Jcand] = funptr(pxnext);
157 % Jcand = computed_jacobian(Jcand, pxnext, funptr);
159 [OK, ok_mat] = check_jacobian(pxnext, funptr, Jcand);
163 fcand = sum(Fcand.*Fcand);
164 nFcand = sqrt(fcand);
166 armijo_sk = pxnext - xold;
167 if nFcand <= params.gamma * nF
168 % found local iteration
177 if gf' * armijo_sk <= - params.rho * norm(armijo_sk)^params.armijo_p
178 % type line search direction
182 % projected gradient line search direction
189 % line search too small
190 if tkc < params.TolLineSearch
193 disp('Line search failed.');
197 xktkc = params.Px(xold + tkc*sdir);
199 [Fxktkc, J] = funptr(xktkc);
200 % J = computed_jacobian(J, xktkc, funptr);
203 if sum(Fxktkc.*Fxktkc) <= f + params.sigma * gf' * (xktkc - xold);
213 tkc = tkc * params.beta;
221 stepsizes = [stepsizes, norm(xnew - xold)];
223 if max(abs(xnew - xold)) < params.TolChange
225 disp('Step change too small.');
230 tempsols = [tempsols, xold];
232 % too many iterations
234 if k > params.maxIter
236 disp('Maximum number of iterations exceeded.');
240 if funcI > params.TolFuncCount
242 disp('Maximum number of function evaluations exceeded.');
250 output.iterations = k;
251 output.funcCount = funcI;
252 output.stepsize = stepsizes;
253 output.firstorderopt = foms;
254 output.resmax = resmaxes;
257 % tempsols = PCA_fixspace(tempsols, [], [], 2);
262 function jac_comp = computed_jacobian(jac_test, X, fun)
263 jac_comp = zeros(size(jac_test));
265 for j = 1:size(jac_test, 2);
266 addend = zeros(size(X));
268 jac_comp(:,j) = 1/(2e-10) .* (fun(X + addend) - fun(X - addend));
271 function [OK, ok_mat] = check_jacobian(Utest, fun, jac_test, epsilon)
277 jac_comp = computed_jacobian(jac_test, Utest, fun);
279 nz_elements = abs(jac_comp) > 1e6*eps;
280 ok_mat = zeros(size(jac_test));
281 ok_mat(nz_elements) = abs(jac_comp(nz_elements) - jac_test(nz_elements))./(abs(jac_comp(nz_elements))) > epsilon;
282 ok_mat = ok_mat + (nz_elements) - (abs(full(jac_test)) > 100*eps);
283 OK = all(~ok_mat(:));
286 disp('Jacobian incorrect: ');
function [ xnew , resnorm , residual , exitflag , output , tempsols ] = gplmm(funptr, x0, params)
Global projected Levenberg-Marquard method.