📄 常微分.txt
字号:
hmin = 16*eps*abs(t);
if isempty(htry)
% Compute an initial step size h using y'(t).
absh = min(hmax, abs(tspan(next) - t));
if normcontrol
rh = (norm(f0) / max(normy,threshold)) / (0.8 * rtol^pow);
else
rh = norm(f0 ./ max(abs(y),threshold),inf) / (0.8 * rtol^pow);
end
if absh * rh > 1
absh = 1 / rh;
end
absh = max(absh, hmin);
else
absh = min(hmax, max(hmin, htry));
end
f(:,1) = f0;
% Initialize the output function.
if haveoutfun
feval(outfun,[t tfinal],y(outputs),'init');
end
% THE MAIN LOOP
done = false;
while ~done
% By default, hmin is a small number such that t+hmin is only slightly
% different than t. It might be 0 if t is 0.
hmin = 16*eps*abs(t);
absh = min(hmax, max(hmin, absh)); % couldn't limit absh until new hmin
h = tdir * absh;
% Stretch the step if within 10% of tfinal-t.
if 1.1*absh >= abs(tfinal - t)
h = tfinal - t;
absh = abs(h);
done = true;
end
% LOOP FOR ADVANCING ONE STEP.
nofailed = true; % no failed attempts
while true
hA = h * A;
hB = h * B;
f(:,2) = feval(odefile, t + hA(1), y + f*hB(:,1), args{:});
f(:,3) = feval(odefile, t + hA(2), y + f*hB(:,2), args{:});
f(:,4) = feval(odefile, t + hA(3), y + f*hB(:,3), args{:});
f(:,5) = feval(odefile, t + hA(4), y + f*hB(:,4), args{:});
f(:,6) = feval(odefile, t + hA(5), y + f*hB(:,5), args{:});
tnew = t + hA(6);
ynew = y + f*hB(:,6);
f(:,7) = feval(odefile, tnew, ynew, args{:});
nfevals = nfevals + 6; % stats
% Estimate the error.
if normcontrol
normynew = norm(ynew);
err = absh * (norm(f * E) / max(max(normy,normynew),threshold));
else
err = absh * norm((f * E) ./ max(max(abs(y),abs(ynew)),threshold),inf);
end
% Accept the solution only if the weighted error is no more than the
% tolerance rtol. Estimate an h that will yield an error of rtol on
% the next step or the next try at taking this step, as the case may be,
% and use 0.8 of this value to avoid failures.
if err > rtol % Failed step
nfailed = nfailed + 1; % stats
if absh <= hmin
msg = sprintf(['Failure at t=%e. Unable to meet integration ' ...
'tolerances without reducing the step size below ' ...
'the smallest value allowed (%e) at time t.\n'],t,hmin);
warning(msg);
if haveoutfun
feval(outfun,[],[],'done');
end
if printstats % print cost statistics
fprintf('%g successful steps\n', nsteps);
fprintf('%g failed attempts\n', nfailed);
fprintf('%g function evaluations\n', nfevals);
fprintf('%g partial derivatives\n', npds);
fprintf('%g LU decompositions\n', ndecomps);
fprintf('%g solutions of linear systems\n', nsolves);
end
if nargout > 0
tout = tout(1:nout);
yout = yout(1:nout,:);
if haveeventfun
varargout{1} = teout;
varargout{2} = yeout;
varargout{3} = ieout;
varargout{4} = [nsteps; nfailed; nfevals; npds; ndecomps; nsolves];
else
varargout{1} = [nsteps; nfailed; nfevals; npds; ndecomps; nsolves];
end
end
return;
end
if nofailed
nofailed = false;
absh = max(hmin, absh * max(0.1, 0.8*(rtol/err)^pow));
else
absh = max(hmin, 0.5 * absh);
end
h = tdir * absh;
done = false;
else % Successful step
break;
end
end
nsteps = nsteps + 1; % stats
if haveeventfun
[te,ye,ie,valt,stop] = ...
odezero('ntrp45',odefile,valt,t,y,tnew,ynew,t0,varargin,h,f);
nte = length(te);
if nte > 0
if nargout > 2
teout = [teout; te];
yeout = [yeout; ye.'];
ieout = [ieout; ie];
end
if stop % stop on a terminal event
tnew = te(nte);
ynew = ye(:,nte);
done = true;
end
end
end
if nargout > 0
oldnout = nout;
if outflag == 3 % computed points, with refinement
nout = nout + refine;
if nout > length(tout)
tout = [tout; zeros(chunk,1)]; % requires chunk >= refine
yout = [yout; zeros(chunk,neq)];
end
i = oldnout+1:nout-1;
tout(i) = t + (tnew-t)*S;
yout(i,:) = ntrp45(tout(i),t,y,[],[],h,f).';
tout(nout) = tnew;
yout(nout,:) = ynew.';
elseif outflag == 2 % computed points, no refinement
nout = nout + 1;
if nout > length(tout)
tout = [tout; zeros(chunk,1)];
yout = [yout; zeros(chunk,neq)];
end
tout(nout) = tnew;
yout(nout,:) = ynew.';
elseif outflag == 1 % output only at tspan points
while next <= ntspan
if tdir * (tnew - tspan(next)) < 0
if haveeventfun & done
nout = nout + 1;
tout(nout) = tnew;
yout(nout,:) = ynew.';
end
break;
elseif tnew == tspan(next)
nout = nout + 1;
tout(nout) = tnew;
yout(nout,:) = ynew.';
next = next + 1;
break;
end
nout = nout + 1; % tout and yout are already allocated
tout(nout) = tspan(next);
yout(nout,:) = ntrp45(tspan(next),t,y,[],[],h,f).';
next = next + 1;
end
end
if haveoutfun
i = oldnout+1:nout;
if ~isempty(i) & (feval(outfun,tout(i),yout(i,outputs).') == 1)
tout = tout(1:nout);
yout = yout(1:nout,:);
if haveeventfun
varargout{1} = teout;
varargout{2} = yeout;
varargout{3} = ieout;
varargout{4} = [nsteps; nfailed; nfevals; npds; ndecomps; nsolves];
else
varargout{1} = [nsteps; nfailed; nfevals; npds; ndecomps; nsolves];
end
return;
end
end
elseif haveoutfun
if outflag == 3 % computed points, with refinement
tinterp = t + (tnew-t)*S;
yinterp = ntrp45(tinterp,t,y,[],[],h,f);
if feval(outfun,[tinterp; tnew],[yinterp(outputs,:), ynew(outputs)]) == 1
return;
end
elseif outflag == 2
if feval(outfun,tnew,ynew(outputs)) == 1
return;
end
elseif outflag == 1 % output only at tspan points
ninterp = 0;
while next <= ntspan
if tdir * (tnew - tspan(next)) < 0
if haveeventfun & done
ninterp = ninterp + 1;
tinterp(ninterp,1) = tnew;
yinterp(:,ninterp) = ynew;
end
break;
elseif tnew == tspan(next)
ninterp = ninterp + 1;
tinterp(ninterp,1) = tnew;
yinterp(:,ninterp) = ynew;
next = next + 1;
break;
end
ninterp = ninterp + 1;
tinterp(ninterp,1) = tspan(next);
yinterp(:,ninterp) = ntrp45(tspan(next),t,y,[],[],h,f);
next = next + 1;
end
if ninterp > 0
if feval(outfun,tinterp(1:ninterp),yinterp(outputs,1:ninterp)) == 1
return;
end
end
end
end
% If there were no failures compute a new h.
if nofailed
% Note that absh may shrink by 0.8, and that err may be 0.
temp = 1.25*(err/rtol)^pow;
if temp > 0.2
absh = absh / temp;
else
absh = 5.0*absh;
end
end
% Advance the integration one step.
t = tnew;
y = ynew;
if normcontrol
normy = normynew;
end
f(:,1) = f(:,7); % Already evaluated odefile(tnew,ynew)
end
if haveoutfun
feval(outfun,[],[],'done');
end
if printstats % print cost statistics
fprintf('%g successful steps\n', nsteps);
fprintf('%g failed attempts\n', nfailed);
fprintf('%g function evaluations\n', nfevals);
fprintf('%g partial derivatives\n', npds);
fprintf('%g LU decompositions\n', ndecomps);
fprintf('%g solutions of linear systems\n', nsolves);
end
if nargout > 0
tout = tout(1:nout);
yout = yout(1:nout,:);
if haveeventfun
varargout{1} = teout;
varargout{2} = yeout;
varargout{3} = ieout;
varargout{4} = [nsteps; nfailed; nfevals; npds; ndecomps; nsolves];
else
varargout{1} = [nsteps; nfailed; nfevals; npds; ndecomps; nsolves];
end
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -