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

📄 expv.m

📁 统计分析的软件包
💻 M
字号:
%  w = expv( t, A, v ) %  EXPV computes an approximation of w = exp(t*A)*v for a%  general matrix A using Krylov subspace  projection techniques.%  It does not compute the matrix exponential in isolation but instead,%  it computes directly the action of the exponential operator on the %  operand vector. This way of doing so allows for addressing large%  sparse problems. The matrix under consideration interacts only%  via matrix-vector products (matrix-free method).%%  [w, err] = expv( t, A, v )%  renders an estimate of the error on the approximation.%%  [w, err] = expv( t, A, v, tol )%  overrides default tolerance.%%  [w, err, hump] = expv( t, A, v, tol, m )%  overrides default tolerance and dimension of the Krylov subspace,%  and renders an approximation of the `hump'.%%  The hump is defined as:%          hump = max||exp(sA)||_2, s in [0,t]  (or s in [t,0] if t < 0).%  It is used as a measure of the conditioning of the matrix exponential%  problem. The matrix exponential is well-conditioned if hump = 1,%  whereas it is poorly-conditioned if hump >> 1. However the solution%  can still be relatively fairly accurate even when the hump is large%  (the hump is an upper bound), especially when the hump and %  ||w(t)||_2/||v||_2 are of the same order of magnitude (further%  details in reference below).%%  Example 1:%  ----------%    n = 100;%    A = rand(n);%    v = eye(n,1);%    w = expv(1,A,v);%%  Example 2:%  ----------%    % generate a random sparse matrix%    n = 100;%    A = rand(n);%    for j = 1:n%        for i = 1:n%            if rand < 0.5, A(i,j) = 0; end;%        end;%    end;%    v = eye(n,1);%    A = sparse(A); % invaluable for a large and sparse matrix.%%    tic%    [w,err] = expv(1,A,v);%    toc%%    disp('w(1:10) ='); disp(w(1:10));%    disp('err =');     disp(err);%%    tic%    w_matlab = expm(full(A))*v;%    toc%%    disp('w_matlab(1:10) ='); disp(w_matlab(1:10));%    gap = norm(w-w_matlab)/norm(w_matlab);%    disp('||w-w_matlab|| / ||w_matlab|| ='); disp(gap);%%  In the above example, n could have been set to a larger value,%  but the computation of w_matlab will be too long (feel free to%  discard this computation).%%  See also MEXPV.%  Roger B. Sidje (rbs@maths.uq.oz.au)%  EXPOKIT: Software Package for Computing Matrix Exponentials. %  Department of Mathematics, University of Queensland.%  Brisbane QLD 4072, Australia. 1996.function [w, err, hump] = expv( t, A, v, tol, m )[n,n] = size(A);if nargin == 3,  tol = 1.0e-7;  m = min(n,30);end;if nargin == 4,  m = min(n,30);end;anorm = norm(A,'inf'); mxrej = 10;  btol  = 1.0e-7; gamma = 0.9; delta = 1.2; mb    = m; t_out   = abs(t);istep = 0; t_new   = 0;t_now = 0; s_error = 0;rndoff= anorm*eps;k1 = 2; xm = 1/m; beta = norm(v); normv = beta;fact = (((m+1)/exp(1))^(m+1))*sqrt(2*pi*(m+1));t_new = (1/anorm)*((fact*tol)/(4*beta*anorm))^xm;s = 10^(floor(log10(t_new))-1); t_new = ceil(t_new/s)*s; sgn = sign(t); istep = 0;w = v;hump = beta;while t_now < t_out  istep = istep + 1;  t_step = min( t_out-t_now,t_new );  V = zeros(n,m+1);   H = zeros(m+2,m+2);  V(:,1) = (1/beta)*w;  for j = 1:m     p = A*V(:,j);     for i = 1:j        H(i,j) = V(:,i)'*p;        p = p-H(i,j)*V(:,i);     end;     s = norm(p);      if s < btol,        k1 = 0;        mb = j;        t_step = t_out-t_now;        break;     end;     H(j+1,j) = s;     V(:,j+1) = (1/s)*p;  end;   if k1 ~= 0,      H(m+2,m+1) = 1;     avnorm = norm(A*V(:,m+1));   end;  ireject = 0;  while ireject <= mxrej,     mx = mb + k1;     F = expm(sgn*t_step*H(1:mx,1:mx));     if k1 == 0,	err_loc = btol;         break;     else        phi1 = abs( beta*F(m+1,1) );        phi2 = abs( beta*F(m+2,1) * avnorm );        if phi1 > 10*phi2,           err_loc = phi2;           xm = 1/m;        elseif phi1 > phi2,           err_loc = (phi1*phi2)/(phi1-phi2);           xm = 1/m;        else           err_loc = phi1;           xm = 1/(m-1);        end;     end;     if err_loc <= delta * t_step*tol,        break;     else        t_step = gamma * t_step * (t_step*tol/err_loc)^xm;        s = 10^(floor(log10(t_step))-1);        t_step = ceil(t_step/s) * s;        if ireject == mxrej,           error('The requested tolerance is too high.');        end;        ireject = ireject + 1;     end;  end;  mx = mb + max( 0,k1-1 );  w = V(:,1:mx)*(beta*F(1:mx,1));  beta = norm( w );  hump = max(hump,beta);  t_now = t_now + t_step;  t_new = gamma * t_step * (t_step*tol/err_loc)^xm;  s = 10^(floor(log10(t_new))-1);   t_new = ceil(t_new/s) * s;  err_loc = max(err_loc,rndoff);  s_error = s_error + err_loc;end;err = s_error;hump = hump / normv;

⌨️ 快捷键说明

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