📄 nsola.m
字号:
function [sol, it_hist, ierr] = nsola(x,f,tol, parms)% Newton-Krylov solver, globally convergent % solver for f(x) = 0%% Inexact-Newton-Armijo iteration%% Eisenstat-Walker forcing term%% Parabolic line search via three point interpolation.%% C. T. Kelley, June 29, 1994% parms made truly optional, Feb 12, 1996%% This code comes with no guarantee or warranty of any kind.%% function [sol, it_hist, ierr] = nsola(x,f,tol,parms)%% inputs:% initial iterate = x% function = f% tol = [atol, rtol] relative/absolute% error tolerances for the nonlinear iteration% parms = [maxit, maxitl, etamax, lmeth, restart_limit]% maxit = maxmium number of nonlinear iterations% default = 40% maxitl = maximum number of inner iterations before restart% in GMRES(m), m=maxitl % default = 40% % For iterative methods other than GMRES(m) maxitl% is the upper bound on linear iterations.%% |etamax| = Maximum error tolerance for residual in inner% iteration. The inner iteration terminates% when the relative linear residual is% smaller than eta*| F(x_c) |. eta is determined% by the modified Eisenstat-Walker formula if etamax > 0.% If etamax < 0, then eta = |etamax| for the entire% iteration.% default: etamax=.9%% lmeth = choice of linear iterative method% 1 (GMRES), 2 GMRES(m), % 3 (BICGSTAB), 4 (TFQMR)% default = 1 (GMRES, no restarts)%% restart_limit = max number of restarts for GMRES if% lmeth = 2% default=20%% output:% sol = solution% it_hist(maxit,3) = scaled l2 norms of nonlinear residuals% for the iteration, of number function evaluations,% and number of steplength reductions% ierr = 0 upon successful termination% ierr = 1 if either after maxit iterations% the termination criterion is not satsified% or the ratio of successive nonlinear residuals% exceeds 1. In this latter case, the iteration% is terminted.% ierr = 2 failure in the line search. The iteration% is terminated if too many steplength reductions% are taken.%%% internal parameters:% debug = turns on/off iteration statistics display as% the iteration progresses%% alpha = 1.d-4, parameter to measure sufficient decrease%% sigma0 = .1, sigma1=.5, safeguarding bounds for the linesearch%% maxarm = 50, maximum number of steplength reductions before% failure is reported%%% Requires dirder.m, fdkrylov.m, parab3p.m, fdgmres.m, % fdcgstab.m, fdtfqmr.m, givapp.m% %%%% set the debug parameter, 1 turns display on, otherwise off%debug=1;%% set alpha, sigma0, sigma1, maxarm, and restart_limit%alpha = 1.d-4; sigma0=.1; sigma1=.5; maxarm = 50; %% initialize it_hist, ierr, and set the iteration parameters%gamma=.9;ierr = 0; maxit=40; lmaxit=40; etamax=.9; it_histx=zeros(maxit,3);lmeth=1; restart_limit=20;%% initialize parameters for the iterative methods%gmparms=[abs(etamax), lmaxit];if nargin == 4 maxit=parms(1); lmaxit=parms(2); etamax=parms(3); gmparms=[abs(etamax), lmaxit]; if length(parms)>=4 lmeth=parms(4); end if length(parms)==5 gmparms=[abs(etamax), lmaxit, parms(5), 1]; endend%rtol=tol(2); atol=tol(1); n = length(x); fnrm=1; itc=0;%% evaluate f at the initial iterate% compute the stop tolerance%f0=feval(f,x);fnrm=norm(f0)/sqrt(n);it_histx(itc+1,1)=fnrm; it_histx(itc+1,2)=0; it_histx(itc+1,3)=0;fnrmo=1;stop_tol=atol + rtol*fnrm;outstat(itc+1, :) = [itc fnrm 0 0 0];%% main iteration loop%while(fnrm > stop_tol & itc < maxit)%% keep track of the ratio (rat = fnrm/frnmo)% of successive residual norms and % the iteration counter (itc)% rat=fnrm/fnrmo; fnrmo=fnrm; itc=itc+1; [step, errstep, inner_it_count,inner_f_evals]=... fdkrylov(f0, f, x, gmparms, lmeth);%% The line search starts here.% xold=x; lambda=1; lamm=1; lamc=lambda; iarm=0; xt = x + lambda*step; ft=feval(f,xt); nft=norm(ft); nf0=norm(f0); ff0=nf0*nf0; ffc=nft*nft; ffm=nft*nft; while nft >= (1 - alpha*lambda) * nf0;%% apply the three point parabolic model% if iarm == 0 lambda=sigma1*lambda; else lambda=parab3p(lamc, lamm, ff0, ffc, ffm); end%% update x; keep the books on lambda% xt=x+lambda*step; lamm=lamc; lamc=lambda;%% keep the books on the function norms% ft=feval(f,xt); nft=norm(ft); ffm=ffc; ffc=nft*nft; iarm=iarm+1; if iarm > maxarm disp(' Armijo failure, too many reductions '); ierr=2; disp(outstat) it_hist=it_histx(1:itc+1,:); sol=xold; return; end end x=xt; f0=ft;%% end of line search% fnrm=norm(f0)/sqrt(n); it_histx(itc+1,1)=fnrm; %% How many function evaluations did this iteration require?% it_histx(itc+1,2)=it_histx(itc,2)+inner_f_evals+iarm+1; if(itc == 1) it_histx(itc+1,2) = it_histx(itc+1,2)+1; end; it_histx(itc+1,3)=iarm;% rat=fnrm/fnrmo;%% adjust eta as per Eisenstat-Walker% if etamax > 0 etaold=gmparms(1); etanew=gamma*rat*rat; if gamma*etaold*etaold > .1 etanew=max(etanew,gamma*etaold*etaold); end gmparms(1)=min([etanew,etamax]); gmparms(1)=max(gmparms(1),.5*stop_tol/fnrm); end% outstat(itc+1, :) = [itc fnrm inner_it_count rat iarm];% if debug==1 disp(outstat(itc+1,:)) end% end whileendsol=x;it_hist=it_histx(1:itc+1,:);if debug==1 disp(outstat) it_hist=it_histx(1:itc+1,:);end%% on failure, set the error flag%if fnrm > stop_tol ierr = 1;end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -