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

📄 jdqz.m

📁 数据降维工具箱
💻 M
📖 第 1 页 / 共 5 页
字号:
global Precond_Form Precond_L Precond_U Precond_P Precond_Params Precond_Solves    switch Precond_Form      case 0,           case 1,     Precond_Params{1}=y;                   y=feval(Precond_L,Precond_Params{:});       case 2,     Precond_Params{1}=y; Precond_Params{2}='preconditioner';                  y=feval(Precond_L,Precond_Params{:});      case 3,     Precond_Params{1}=y;                   Precond_Params{1}=feval(Precond_L,Precond_Params{:});                   y=feval(Precond_U,Precond_Params{:});      case 4,     Precond_Params{1}=y; Precond_Params{2}='L';                   Precond_Params{1}=feval(Precond_L,Precond_Params{:});                   Precond_Params{2}='U';                  y=feval(Precond_L,Precond_Params{:});      case 5,     y=Precond_L\y;      case 6,     y=Precond_U\(Precond_L\y);      case 7,     y=Precond_U\(Precond_L\(Precond_P*y));    end    if Precond_Form      Precond_Solves = Precond_Solves +size(y,2);    end%% y(1:5,1), pausereturn%------------------------------------------------------------------------function [v,u]=PreMV(theta,Q,Z,M,v)% v=Atilde*vglobal Precond_Type  if Precond_Type    u=SkewProj(Q,Z,M,SolvePrecond(v));     [v,w]=MV(u); v=theta(2)*v-theta(1)*w;  else    [v,u]=MV(v); u=theta(2)*v-theta(1)*u;    v=SkewProj(Q,Z,M,SolvePrecond(u));  end  return%------------------------------------------------------------------------function  r=SkewProj(Q,Z,M,r);   if ~isempty(Q),       r=r-Z*(M\(Q'*r));   end return%------------------------------------------------------------------------function ppar=spar(par,nit)k=size(par,2)-2;ppar=par(1,k:k+2);if k>1   if nit>k      ppar(1,1)=par(1,k)*((par(1,k)/par(1,k-1))^(nit-k));   else      ppar(1,1)=par(1,max(nit,1));   endendppar(1,1)=max(ppar(1,1),1.0e-8);return%------------------------------------------------------------------------function u=ImagVector(u)% computes "essential" imaginary part of a vector  maxu=max(u); maxu=maxu/abs(maxu); u=imag(u/maxu);return%------------------------------------------------------------------------function Sigma=ScaleEig(Sigma)% %  n=sign(Sigma(:,2)); n=n+(n==0);  d=sqrt((Sigma.*conj(Sigma))*[1;1]).*n;  Sigma=diag(d)\Sigma;return%%%======== COMPUTE r AND z =============================================function [r,z,nrm,theta]=Comp_rz(E,kappa)%% [r,z,nrm,theta]=Comp_rz(E)%   computes the direction r of the minimal residual,%   the left projection vector z,%   the approximate eigenvalue theta%% [r,z,nrm,theta]=Comp_rz(E,kappa)%   kappa is a scaling factor.%% coded by Gerard Sleijpen, version Januari 7, 1998  if nargin == 1    kappa=norm(E(:,1))/norm(E(:,2)); kappa=2^(round(log2(kappa)));  end  if kappa ~=1, E(:,1)=E(:,1)/kappa; end  [Q,sigma,u]=svd(E,0);   %%% E*u=Q*sigma, sigma(1,1)>sigma(2,2)  r=Q(:,2); z=Q(:,1); nrm=sigma(2,2);   % nrm=nrm/sigma(1,1); nrmz=sigma(1,1)  u(1,:)=u(1,:)/kappa; theta=[-u(2,2),u(1,2)];  return%%%======== END computation r and z =====================================%%%======================================================================%%%======== Orthogonalisation ===========================================%%%======================================================================function [V,R]=RepGS(Z,V,gamma)%% Orthonormalisation using repeated Gram-Schmidt%   with the Daniel-Gragg-Kaufman-Stewart (DGKS) criterion%% Q=RepGS(V)%   The n by k matrix V is orthonormalized, that is,%   Q is an n by k orthonormal matrix and %   the columns of Q span the same space as the columns of V%   (in fact the first j columns of Q span the same space%   as the first j columns of V for all j <= k).%% Q=RepGS(Z,V)%  Assuming Z is n by l orthonormal, V is orthonormalized against Z:%  [Z,Q]=RepGS([Z,V])%% Q=RepGS(Z,V,gamma)%  With gamma=0, V is only orthogonalized against Z%  Default gamma=1 (the same as Q=RepGS(Z,V))%% [Q,R]=RepGS(Z,V,gamma)%  if gamma == 1, V=[Z,Q]*R; else, V=Z*R+Q; end % coded by Gerard Sleijpen, March, 2002% if nargin == 1, V=Z; Z=zeros(size(V,1),0); end   if nargin <3, gamma=1; end[n,dv]=size(V); [m,dz]=size(Z);if gamma, l0=min(dv+dz,n); else, l0=dz; endR=zeros(l0,dv); if dv==0, return, endif dz==0 & gamma==0, return, end% if m~=n%   if m<n, Z=[Z;zeros(n-m,dz)]; end%   if m>n, V=[V;zeros(m-n,dv)]; n=m; end% endif (dz==0 & gamma)   j=1; l=1; J=1;   q=V(:,1); nr=norm(q); R(1,1)=nr;   while nr==0, q=rand(n,1); nr=norm(q); end, V(:,1)=q/nr;   if dv==1, return, end    else   j=0; l=0; J=[];endwhile j<dv,   j=j+1; q=V(:,j); nr_o=norm(q); nr=eps*nr_o;   if dz>0, yz=Z'*q;     q=q-Z*yz;      end   if l>0,  y=V(:,J)'*q; q=q-V(:,J)*y;  end   nr_n=norm(q);     while (nr_n<0.5*nr_o & nr_n > nr)      if dz>0, sz=Z'*q;     q=q-Z*sz;     yz=yz+sz; end      if l>0,  s=V(:,J)'*q; q=q-V(:,J)*s; y=y+s;    end      nr_o=nr_n; nr_n=norm(q);                   end   if dz>0, R(1:dz,j)=yz; end   if l>0,  R(dz+J,j)=y;  end   if ~gamma     V(:,j)=q;   elseif l+dz<n, l=l+1;      if nr_n <= nr % expand with a random vector       % if nr_n==0       V(:,l)=RepGS([Z,V(:,J)],rand(n,1));       % else % which can be numerical noice       %   V(:,l)=q/nr_n;       % end     else       V(:,l)=q/nr_n; R(dz+l,j)=nr_n;      end     J=[1:l];   end end % while jif gamma & l<dv, V=V(:,J); endreturn%%%======== END  Orthogonalisation ======================================%%%======================================================================%%%======== Sorts Schur form ============================================%%%======================================================================function [Q,Z,S,T]=SortQZ(A,B,tau,kappa,gamma,u)%% [Q,Z,S,T]=SortQZ(A,B,tau)%   A and B are k by k matrices, tau is a complex pair [alpha,beta].%   SortQZ computes the qz-decomposition of (A,B) with prescribed%   ordering: A*Q=Z*S, B*Q=Z*T; %             Q and Z are unitary k by k matrices,%             S and T are upper triangular k by k matrices.%   The ordering is as follows:%   (diag(S),diag(T)) are the eigenpairs of (A,B) ordered%   with increasing "chordal distance" w.r.t. tau.%%   If tau is a scalar then [tau,1] is used.%   Default value for tau is tau=0, i.e., tau=[0,1].%% [Q,Z,S,T]=SortQZ(A,B,tau,kappa)%   kappa scales A first: A/kappa. Default kappa=1.%% [Q,Z,S,T]=SortQZ(A,B,tau,kappa,gamma)%   Sorts the first MAX(gamma,1) elements. Default: gamma=k%% [Q,Z,S,T]=SortQZ(A,B,tau,kappa,gamma,u)%   Now, with ordering such that angle u and Q(:,1) is less than 45o,%   and, except for the first pair, (diag(S),diag(T)) are %   with increasing "chordal distance" w.r.t. tau.%   If such an ordering does not exist, ordering is as without u.%% coded by Gerard Sleijpen, version April, 2002  k=size(A,1);   if k==1, Q=1; Z=1; S=A;T=B; return, end  kk=k-1;  if nargin < 3, tau=[0,1]; end   if nargin < 4, kappa=1;   end   if nargin > 4, kk=max(1,min(gamma,k-1)); end  %%    kappa=max(norm(A,inf)/max(norm(B,inf),1.e-12),1);  %%    kappa=2^(round(log2(kappa)));%%%------ compute the qz factorization -------  [S,T,Z,Q]=qz(A,B); Z=Z';                 % kkappa=max(norm(A,inf),norm(B,inf));                 % Str='norm(A*Q-Z*S)';texttest(Str,eval(Str))                 % Str='norm(B*Q-Z*T)';texttest(Str,eval(Str))%%%------ scale the eigenvalues --------------  t=diag(T); n=sign(t); n=n+(n==0); D=diag(n);    Q=Q/D; S=S/D; T=T/D; %%%------ sort the eigenvalues ---------------  I=SortEig(diag(S),real(diag(T)),tau,kappa);               %%%------ swap the qz form -------------------  [Q,Z,S,T]=SwapQZ(Q,Z,S,T,I(1:kk));                 % Str='norm(A*Q-Z*S)';texttest(Str,eval(Str))                % Str='norm(B*Q-Z*T)';texttest(Str,eval(Str))  if nargin < 6 | size(u,2) ~= 1     return  else%%% repeat SwapQZ if angle is too small     kk=min(size(u,1),k); J=1:kk; u=u(J,1)'*Q(J,:);      if abs(u(1,1))>0.7, return, end     for j=2:kk        J=1:j;        if norm(u(1,J))>0.7          J0=[j,1:j-1];            [Qq,Zz,Ss,Tt]=SwapQZ(eye(j),eye(j),S(J,J),T(J,J),J0);          if abs(u(1,J)*Qq(:,1))>0.71             Q(:,J)=Q(:,J)*Qq; Z(:,J)=Z(:,J)*Zz;              S(J,J)=Ss; S(J,j+1:k)=Zz'*S(J,j+1:k);             T(J,J)=Tt; T(J,j+1:k)=Zz'*T(J,j+1:k);                 % Str='norm(A*Q-Z*S)';texttest(Str,eval(Str))                 % Str='norm(B*Q-Z*T)';texttest(Str,eval(Str))                 fprintf('  Took %2i:%6.4g\n',j,S(1,1)./T(1,1))             return          end        end     end     disp(['  Selection problem:  took ',num2str(1)])     return  end%%%======================================================================function I=SortEig(s,t,sigma,kappa);%% I=SortEig(S,T,SIGMA) sorts the indices of [S,T] as prescribed by SIGMA%   S and T are K-vectors.%%   If SIGMA=[ALPHA,BETA] is a complex pair then %     if CHORDALDISTANCE%       sort [S,T] with increasing chordal distance w.r.t. SIGMA.%     else %       sort S./T with increasing distance w.r.t. SIGMA(1)/SIGMA(2)%%  The chordal distance D between a pair A and a pair B is %  defined as follows.%    Scale A by a scalar F such that NORM(F*A)=1.%    Scale B by a scalar G such that NORM(G*B)=1.%    Then D(A,B)=SQRT(1-ABS((F*A)*(G*B)')).%% I=SortEig(S,T,SIGMA,KAPPA). Kappa is a caling that effects the% chordal distance: [S,KAPPA*T] w.r.t. [SIGMA(1),KAPPA*SIGMA(2)].% coded by Gerard Sleijpen, version April 2002global CHORDALDISTANCEif ischar(sigma)  warning off, s=s./t; warning on  switch sigma    case 'LM'      [s,I]=sort(-abs(s));    case 'SM'      [s,I]=sort(abs(s));    case 'LR';      [s,I]=sort(-real(s));    case 'SR';      [s,I]=sort(real(s));    case 'BE';      [s,I]=sort(real(s)); I=twistdim(I,1);  endelseif CHORDALDISTANCE  if kappa~=1, t=kappa*t; sigma(2)=kappa*sigma(2); end  n=sqrt(s.*conj(s)+t.*t);  [s,I]=sort(-abs([s,t]*sigma')./n);else  warning off, s=s./t; warning on  if sigma(2)==0; [s,I]=sort(-abs(s));  else, [s,I]=sort(abs(s-sigma(1)/sigma(2)));  end endreturn%------------------------------------------------------------------------function t=twistdim(t,k)  d=size(t,k); J=1:d; J0=zeros(1,2*d);  J0(1,2*J)=J; J0(1,2*J-1)=flipdim(J,2); I=J0(1,J);  if k==1, t=t(I,:); else, t=t(:,I); endreturn%%%======================================================================function [Q,Z,S,T]=SwapQZ(Q,Z,S,T,I)% [Q,Z,S,T]=SwapQZ(QQ,ZZ,SS,TT,P)%    QQ and ZZ are K by K unitary,  SS and TT are K by K uper triangular.%    P is the first part of a permutation of (1:K)'.%%    Then Q and Z are K by K unitary, S and T are K by K upper triangular,%    such that, for A = ZZ*SS*QQ' and B = ZZ*T*QQ', we have %    A*Q = Z*S, B*Q = Z*T  and LAMBDA(1:LENGTH(P))=LLAMBDA(P) where %    LAMBDA=DIAG(S)./DIAGg(T) and LLAMBDA=DIAG(SS)./DIAG(TT).%%    Computation uses Givens rotations. %% coded by Gerard Sleijpen, version October 12, 1998    kk=min(length(I),size(S,1)-1);  j=1; while (j<=kk & j==I(j)), j=j+1; end  while j<=kk    i=I(j);    for k = i-1:-1:j,       %%% i>j, move ith eigenvalue to position j       J = [k,k+1];       q = T(k+1,k+1)*S(k,J) - S(k+1,k+1)*T(k,J);      if q(1) ~= 0         q = q/norm(q);        G = [[q(2);-q(1)],q'];        Q(:,J) = Q(:,J)*G;         S(:,J) = S(:,J)*G; T(:,J) = T(:,J)*G;      end       if abs(S(k+1,k))<abs(T(k+1,k)), q=T(J,k); else q=S(J,k); end      if q(2) ~= 0        q=q/norm(q);        G = [q';q(2),-q(1)];        Z(:,J) = Z(:,J)*G';         S(J,:) = G*S(J,:); T(J,:) = G*T(J,:);      end       T(k+1,k) = 0;      S(k+1,k) = 0;     end    I=I+(I<i);     j=j+1; while (j<=kk & j==I(j)), j=j+1; end  endreturn%------------------------------------------------------------------------function [Q,Z,S,T]=SwapQZ0(Q,Z,S,T,I)%% [Q,Z,S,T]=sortqz0(A,B,s,t,k)%    A and B are k by k matrices, t and s are k vectors such that%    (t(i),s(i)) eigenpair (A,B), i.e. t(i)*A-s(i)*B singular.%    Computes the Schur form with a ordering prescribed by (t,s):%       A*Q=Z*S, B*Q=Z*T such that diag(S)./diag(T)=s./t.%    Computation uses Householder reflections. %% coded by Gerard Sleijpen, version October 12, 1997    k=size(S,1); s=diag(S); t=diag(T); s=s(I,1); t=t(I,1);  for i=1:k-1    %%% compute q s.t. C*q=(t(i,1)*S-s(i,1)*T)*q=0    C=t(i,1)*S(i:k,i:k)-s(i,1)*T(i:k,i:k);    [q,r,p]=qr(C);          %% C*P=Q*R    %% check whether last but one diag. elt r nonzero    j=k-i; while abs(r(j,j))<eps*norm(r); j=j-1; end; j=j+1;    r(j,j)=1; e=zeros(j,1); e(j,1)=1;    q=p*([r(1:j,1:j)\e;zeros(k-i+1-j,1)]); q=q/norm(q);%% C*q    %%% end computation q    z=conj(s(i,1))*S(i:k,i:k)*q+conj(t(i,1))*T(i:k,i:k)*q; z=z/norm(z);    a=q(1,1); if a ~=0, a=abs(a)/a; q=a*q; end    a=z(1,1); if a ~=0, a=abs(a)/a; z=a*z; end

⌨️ 快捷键说明

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