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

📄 stiff0.m

📁 matlab算法集 matlab算法集
💻 M
字号:
function [x,e,s] = stiff0 (x,t0,t1,tol,q,f,fx,ft,dm)
%------------------------------------------------------------------
% Usage:       [x,e,s] = stiff0 (x,t0,t1,tol,q,f,fx,ft,dm);
% 
% Description: Use the semi-implicit Bulirsch-Stoer variable order
%              extrapolation method to solve a stiff n-dimensional
%              system of ordinary differential equations:
%
%                 dx(t)/dt = f(t,x(t))   
%
%              over the time interval [t0,t1].
%                   
% Inputs:       x   = n by 1 initial conditon vector, x = x(t0)
%               t0  = initial time
%               t1  = final time
%               tol = upper bound on local truncation error (tol >= 0)
%               q   = maximum number of scalar function evaluations (q >= 1) 
%               f   = string containing name of function which defines the
%                     system of equations to be solved.
%               fx  = string containing name of optional function that
%                     defines the Jacobian matrix J = df(t,x)/dx
%               ft  = string containing name of optional function that
%                     defines df(t,x)/dt.  The forms of user-supplied
%                     functions are as follows:
%
%                        function dx   = f (t,x)
%                        function dfdx = fx(t,x)
%                        function dfdt = ft(t,x)
%
%                     When f is called, it should evaluate the right-hand
%                     side of the system of differential equations and
%                     return the result in the n by 1 vector dx. When fx
%                     is called, it should evaluate the n by n matrix of
%                     partial derivatives of f(t,x) with respect to x. That
%                     is, dfdx(k,j) = df(k)/dx(j) for 1 <= k,j <= n. When
%                     ft is called, it should evaluate the n by 1 vector of
%                     partial derivatives of f(t,x) with respect to t. That
%                     is, dfdt(k) = df(k)/dt for 1 <= k <= n. The functions
%                     fx and ft are optional in the sense that stiff0 can be
%                     called with the arguments fx and/or ft set to the
%                     empty string, ''. When this is done, the partial 
%                     derivatives are approximated numerically by stiff0
%                     using using central differences. Thus the user does
%                     not have to supply the functions in this case. 
%              dm   = optional display mode.  If present, intermediate
%                     results are displayed.   
%
% Outputs:     x  = n by 1 vector containing estimate of solution:
%                   x = x(t1)
%              e = maximum local truncation error over [t0,t1]     
%              s = number of scalar function evaluations.  If it is less
%                  than the user-specified maximum, q, then the following
%                  error criterion was satisfied by adjusting the
%                  extrapolation level.  Here ||E|| denotes theinfinity
%                  norm of the estimated local truncation error:
%
%                      ||E|| < max(||x||,1)*tol  
%------------------------------------------------------------------

% Initialize 

   chkvec (x,1,'stiff0');
   tol = args(tol,0,tol,4,'stiff0');
   q = args(q,0,q,5,'stiff0');
   chkfun (feval(f,t0,x),6,'stiff0');

   display = nargin > 8;
   s = 0;
   k = 0;			% starting level 
   levels = 8;		        % maximum level 
   r = 2^levels+1;  	        % maximum steps 
   n = length(x);
   I = eye(n,n);
   Ak  = zeros (n,levels);		% row k of A 
   Ak1 = zeros (n,levels);		% row k-1 of A 
   Q = zeros (r,n);			% midpoint estimates 	
   dx = zeros (n,1);			% derivative vector 
   ev = zeros (n,1);			% error vector 
   v = zeros (n,1);			% linear system solution  
   b = zeros (n,1);			% right-hand side 
   J = zeros (n,n);			% Jacobian matrix  
   Q(1,:) = x';
   e = max(norm(x,inf),1)*tol + 1;
   funfx = getfun (fx);
   funft = getfun (ft);
   if funft
      chkfun (feval(ft,t0,x),8,'stiff0');
   end

   while (k == 1) | ((e > max(norm(x,inf),1)*tol) & ...
         (k < levels) & (s < q)); 

% Apply semi-implicit midpoint method 
      
      k = k + 1;
      m = 2^k;
      h = (t1 - t0)/m;

% First step 

      dx = feval(f,t0,Q(1,:));
      s = s + n;
      if ~funfx
         J = fxstiff (t0,Q(1,:)',f);
         s = s + 2*n*n; 
      else 
         J = feval(fx,t0,Q(1,:)');
         s = s + n*n;
      end
      if ~funft
         b = ftstiff (t0,Q(1,:)',f);
         s = s + 2*n; 
      else 
         b = feval(ft,t0,Q(1,:)');
         s = s + n; 
      end 
      for i = 1 : n
         b(i) = h*(h*b(i) + dx(i));
      end
      J = I - h*J; 
      v = ludec (J,b); 
      for i = 1 : n
         Q(2,i) = Q(1,i) + v(i);
      end
      
% Midpoint steps 

      for j = 1 : m-1
         t = t0 + j*h;   
         b = feval(f,t,Q(j+1,:)');
         s = s + n;
         if ~funfx' 
            J = fxstiff (t,Q(j+1,:)',f);
            s = s + 2*n*n; 
         else  	
            J = feval(fx,t,Q(j+1,:)');
            s = s + n*n; 
         end
         for i = 1 : n
            for p = 1 : n
              b(i) = b(i) - J(i,p)*(Q(j+1,p) - Q(j,p));
            end
            b(i) = b(i)*2*h; 
         end
         J = I - h*J;
         v = ludec (J,b); 
         for i = 1 : n
            Q(j+2,i) = Q(j,i) + v(i); 
         end
      end
      
% Last step 

      dx = feval(f,t1,Q(m+1,:));
      if ~funfx
         J = fxstiff (t1,Q(m+1,:)',f);
         s = s + 2*n*n; 
      else 	
         J = feval(fx,t1,Q(m+1,:)');
         s = s + n*n; 
      end
      if ~funft 
         b = ftstiff (t0,Q(1,:)',f);
         s = s + 2*n; 
      else 
         b = feval(ft,t0,Q(1,:)');
         s = s + n; 
      end 
      for i = 1 : n
         b(i) = h*(h*b(i) + dx(i));
      end
      J = I - h*J;
      v = ludec (J,b);
      Ak1 = Ak;
      for i = 1 : n
         Ak(i,1) = (Q(m,i) + Q(m+1,i) + v(i))/2;
      end
         
% Update row k of matrix of extrapolated estimates 

      for j = 2 : k
         r0 = 4^(j-1);
         for i = 1 : n
            Ak(i,j) = (r0*Ak(i,j-1) - Ak1(i,j-1))/(r0 - 1);
            ev(i) = (Ak(i,j-1) - Ak1(i,j-1))/(r0 - 1); 
         end
         if display
            if j == 2
               fprintf ('\nInterval: [%.7g, %.7g]',t0,t1);
            end   
            fprintf ('\n %g %g',k,j);
            for i = 1 : n
               fprintf (' %10.3e',ev(i));
            end
            if j == k 
               fprintf ('\n');
               wait;
            end    
         end
      end
      e = norm (ev,inf);
      for i = 1 : n
         x(i) = Ak(i,k);
      end

   end
   s = min(s,q);

⌨️ 快捷键说明

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