⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ode15s_old.m

📁 国外经典书籍MULTIVARIABLE FEEDBACK CONTROL-多变量反馈控制 的源码
💻 M
📖 第 1 页 / 共 2 页
字号:
function [tout,yout,stats] = ode15s(ydot,tspan,y0,options)%ODE15S	Solve stiff differential equations, variable order method.%	[T,Y] = ODE15S('ydot',TSPAN,Y0) with TSPAN = [T0 TFINAL] integrates%	the system of first order differential equations y' = ydot(t,y) from%	time T0 to TFINAL with initial conditions Y0.  Function ydot(t,y)%	must return a column vector.  Each row in solution matrix Y%	corresponds to a time returned in column vector T.  To obtain%	solutions at the specific times T0, T1, ..., TFINAL (all increasing%	or all decreasing), use TSPAN = [T0 T1 ... TFINAL].%	%	[T,Y] = ODE15S('ydot',TSPAN,Y0,OPTIONS) solves as above with default%	integration parameters replaced by values in OPTIONS, an argument%	created with the ODESET function.  See ODESET for details.  Commonly%	used options are scalar relative error tolerance 'rtol' (1e-3 by%	default) and vector of absolute error tolerances 'atol' (all%	components 1e-6 by default).%	%	It is possible to specify tspan, y0 and options in ydot.  If TSPAN%	or YO is empty, or if ODE15S is invoked as ODE15S('ydot'), ODE15S%	calls [tspan,y0,options] = ydot([],[]) to obtain any values not%	supplied at the command line.  TYPE CHM6EX to see how this is coded.%	%	The Jacobian matrix J(t,y) is critical to the reliability and%	efficiency of the integration.  If J(t,y) is constant and/or sparse,%	use the 'constantJ' and/or 'sparseJ' options (see B5EX, BRUSSEX).%	If ydot is coded so that ydot([t1 t2 ...],[y1 y2 ...]) returns%	[ydot(t1,y1) ydot(t2,y2) ...], setting 'vectorized' true may speed%	up the computation of J (see VDPEX).  If an M-file function that%	evaluates analytically J(t,y) is available, use the 'analyticJ'%	option (see VDPJAC, BRUSSJAC).%	%	As an example, the command%	%	    ode15s('vdpex',[0 3000],[2 0]);%	%	solves the system y' = vdpex(t,y) with the default relative error%	tolerance 1e-3 and the default absolute tolerance of 1e-6 for each%	component.  When called with no output arguments, as in this%	example, ODE15S calls the default output function ODEPLOT to plot%	the solution as it is computed.%	%	ODE15S also solves problems M(t)*y' = ydot(t,y) with a mass matrix%	M(t) that is nonsingular and (usually) sparse.  Use the 'mass'%	option to supply the name of a function of t that returns M(t) (see%	FEM1EX).  If M(t) is a constant matrix M, use the 'constantM'%	option, or supply M as the value of 'mass' (see FEM2EX).%	%	See also%	    other ODE solvers:   ODE23S, ODE45, ODE23, ODE113%	    options handling:    ODESET, ODEGET%	    output functions:    ODEPLOT, ODEPHAS2, ODEPHAS3%	    ydot examples:       VDPEX, BRUSSEX, B5EX, CHM6EX%	    ydot Jacobians:      VDPJAC, BRUSSJAC%	    Jacobian functions:  NUMJAC, COLGROUP%	    mass matrices:	 FEM1EX, FEM1MASS, FEM2EX, FEM2MASS%	ODE15S is a quasi-constant step size implementation in terms of%	backward differences of the Klopfenstein-Shampine family of%	Numerical Differentiation Formulas of orders 1-5.  The natural%	"free" interpolants are used.  Local extrapolation is not done.  By%	default, Jacobians are generated numerically.  Details are to be%	found in The MATLAB ODE Suite, L. F. Shampine and M. W. Reichelt,%	Rept. 94-6, Math. Dept., SMU, Dallas, TX, 1994.%	Mark W. Reichelt and Lawrence F. Shampine, 6-13-94%	Copyright (c) 1984-95 by The MathWorks, Inc.false = 0;true = ~false;nsteps = 0; 				% statsnfailed = 0; 				% statsnfevals = 0; 				% statsnpds = 0; 				% statsndecomps = 0; 				% statsnsolves = 0; 				% statsif nargin == 1  tspan = []; y0 = []; options = [];elseif nargin == 2  y0 = []; options = [];elseif nargin == 3  options = [];end% Get default tspan and y0 from ydot if none are specified.if (length(tspan) == 0) | (length(y0) == 0)  [ydot_tspan,ydot_y0,ydot_options] = feval(ydot,[],[]);  if length(tspan) == 0    tspan = ydot_tspan;  end  if length(y0) == 0    y0 = ydot_y0;  end  if length(options) == 0    options = ydot_options;  else    options = odeset(ydot_options,options);  endend% Test that tspan is internally consistent.tspan = tspan(:);ntspan = length(tspan);if ntspan == 1  t = 0;  next = 1;else  t = tspan(1);  next = 2;endtfinal = tspan(ntspan);if t == tfinal  error('The last entry in tspan must be different from the first entry.');endtdir = sign(tfinal - t);if any(tdir * (tspan(2:ntspan) - tspan(1:ntspan-1)) <= 0)  error('The entries in tspan must strictly increase or decrease.');endy = y0(:);neq = length(y);zerosneq = zeros(neq,1);% Get options, and set defaults.rtol = odeget(options,'rtol',1e-3);atol = odeget(options,'atol',1e-6);atol = atol(:);if (rtol <= 0) | any(atol <= 0)    error('Tolerance rtol and all entries of atol must be positive.');endif rtol < 100 * eps   rtol = 100 * eps;  fprintf('Warning: rtol has been increased to %e\n',rtol);endif length(atol) == 1  atol = atol + zerosneq;elseif length(atol) ~= neq  error(['Vector atol must be same length as y0 vector (' num2str(neq) ').']);endthreshold = atol ./ rtol;userhmax = abs(odeget(options,'hmax',0.1*abs(tfinal-t)));hmax = min(userhmax, abs(tfinal-t));hmin = 4 * eps * abs(t);userhmin = abs(odeget(options,'hmin',hmin));hmin = min(max(hmin, userhmin), hmax);stopfun = odeget(options,'stopfun');if nargout ~= 0  outfun = odeget(options,'outfun');else  outfun = odeget(options,'outfun','odeplot');endrefine = odeget(options,'refine',1);printstats = odeget(options,'printstats',false);vectorized = odeget(options,'vectorized',false);constantJ = odeget(options,'constantJ',false);Js = odeget(options,'sparseJ');analyticJ = odeget(options,'analyticJ');if length(analyticJ) == 0  notanalyticJ = true;else  notanalyticJ = false;endmass = odeget(options,'mass');if length(mass) ~= 0  if isstr(mass)    Mt = feval(mass,t);    constantM = odeget(options,'constantM',false);  else    Mt = mass;    constantM = odeget(options,'constantM',true);    if ~constantM      error('Mass matrix has constant value, and yet constantM is set false.');    end  end  [L,U] = lu(Mt);else  Mt = sparse((1:neq)',(1:neq)',1,neq,neq);  L = Mt;  U = Mt;  constantM = true;endif constantM  Mtnew = Mt;endmaxk = odeget(options,'maxorder',5);bdf = odeget(options,'bdf',false);% Initialize the output function.if length(outfun) == 0  haveoutfun = false;else  haveoutfun = true;  feval(outfun,[t tfinal],y,'init');end% Allocate memory if we're generating output.if nargout ~= 0  if (ntspan == 1) & (refine == 0) 	% only 1 output at tfinal    nout = 0;  else    if ntspan > 2 			% output only at tspan points      tout = zeros(ntspan,1);      yout = zeros(ntspan,neq);    else 				% alloc in chunks      chunk = max(ceil(128 / neq),refine);      tout = zeros(chunk,1);      yout = zeros(chunk,neq);    end    nout = 1;    tout(nout) = t;    yout(nout,:) = y.';  endend% Initialize method parameters.G = [1; 3/2; 11/6; 25/12; 137/60];if bdf  alpha = [0; 0; 0; 0; 0];else  alpha = [-37/200; -1/9; -0.0823; -0.0415; 0];endinvGa = 1 ./ (G .* (1 - alpha));erconst = alpha .* G + (1 ./ (2:6)');difU = [ -1, -2, -3, -4,  -5; 		% difU is its own inverse!          0,  1,  3,  6,  10;          0,  0, -1, -4, -10;          0,  0,  0,  1,   5;          0,  0,  0,  0,  -1 ];maxK = 1:maxk;[kJ,kI] = meshgrid(maxK,maxK);difU = difU(maxK,maxK);maxit = 4;% Set the output flag.if (ntspan > 2) | (refine == 0)  outflag = 1; 				% output only at tspan pointselseif refine == 1  outflag = 2; 				% computed points, no refinementelse  outflag = 3; 				% computed points, with refinement  ones1r = ones(1,refine-1);  S = 1 / refine;  S = cumsum(S(ones1r)) - 1;  p = cumprod((S(ones(maxk,1),:)+kI(:,1:refine-1)-1) ./ kI(:,1:refine-1));end% Compute the partial derivatives dfdt and dfdy.  The error of% BDF1 is 0.5*h^2*y''(t).  Use this to determine the optimal h.f0 = feval(ydot,t,y);[m,n] = size(f0);if n > 1  error(['Function ' ydot '(t,y) must return a column vector.'])elseif m ~= neq  error(['Vector ' ydot '(t,y) must be same length as initial conditions.']);endF0 = U \ (L \ f0);wt = abs(y) + threshold;absh = min(hmax, abs(tspan(next) - t));rh = norm(F0 ./ wt,inf) / (0.8 * sqrt(rtol));if absh * rh > 1  absh = 1 / rh;endabsh = max(absh, hmin);h = tdir * absh;tdel = (t + tdir*min(sqrt(eps)*max(abs(t),abs(t+h)),absh)) - t;f1 = feval(ydot,t+tdel,y);nfevals = nfevals + 2; 			% statsdfdt = (f1 - f0) ./ tdel;if notanalyticJ  [dfdy,fac,g,nF] = numjac(ydot,t,y,f0,atol,[],vectorized,Js,[]);  nfevals = nfevals + nF; 		% statselse  dfdy = feval(analyticJ,t,y);endnpds = npds + 1; 			% statsJMcurrent = true;absh = min(hmax, abs(tspan(next) - t));rh = 1.25 * sqrt(0.5*norm((U \ (L \ (dfdt + dfdy*F0))) ./ wt,inf) / rtol);if absh * rh > 1  absh = 1 / rh;endabsh = max(absh, hmin);h = tdir * absh;% Initialize.hnew = absh;k = 1; 					% start at order 1 with BDF1K = 1; 					% K = 1:knewhk = false;dif = zeros(neq,maxk+2);dif(:,1) = h * F0;hinvGak = h * invGa(k);nconhk = 0; 				% steps taken with current h and k[L,U] = lu(Mt - hinvGak * dfdy);ndecomps = ndecomps + 1; 		% statshavrate = false;% THE MAIN LOOPlast = false; 				% is it the last step?while ~last    hmin = max(userhmin, 4 * eps * abs(t));  if 1.1*hnew >= abs(tfinal - t)    hnew = abs(tfinal - t);    newhk = true;    last = true;  end  if newhk    newhk = false;        difRU = cumprod((kI - 1 - kJ*(hnew/absh)) ./ kI) * difU;    dif(:,K) = dif(:,K) * difRU(K,K);    absh = hnew;    h = tdir * absh;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -