1function [G,R,U]=QBD_IS(A0,A1,A2,varargin)
2%QBD_IS Invariant Subspace
for Quasi-Birth-Death Markov Chains [Akar, Sohraby]
6% G=QBD_IS(A0,A1,A2) computes the minimal nonnegative solution to the
7% matrix equation G = A0 + A1 G + A2 G^2, where A,B and C are square
8% nonnegative matrices, with (A0+A1+A2) irreducible and stochastic
10% [G,R]=QBD_IS(A0,A1,A2) also provides the minimal nonnegative solution
11% to the matrix equation R = A2 + R A1 + R^2 A0
13% [G,R,U]=QBD_IS(A0,A1,A2) also provides the minimal nonnegative solution
14% to the matrix equation U = A1 + A2 (I-U)^(-1) A0
16% CONTINUOUS TIME CASE:
18% G=QBD_IS(A0,A1,A2) computes the minimal nonnegative solution to the
19% matrix equation 0 = A0 + A1 G + A2 G^2, where A,B and C are square
20% nonnegative matrices, with (A0+A1+A2) having row sums equal to zero
22% [G,R]=QBD_IS(A0,A1,A2) also provides the minimal nonnegative solution
23% to the matrix equation 0 = A2 + R A1 + R^2 A0
25% [G,R,U]=QBD_IS(A0,A1,A2) also provides the minimal nonnegative solution
26% to the matrix equation U = A1 + A2 (-U)^(-1) A0
30% MaxNumIt: Maximum number of iterations (default: 50)
31% Verbose: The residual error
is printed at each step when set to 1,
33% Mode:
'MSignStandard' uses the matrix sign approach
34%
'MSignBalzer' uses the matrix sign approach with Balzer acceleration
35%
'Schur' relies on an ordered Schur decomposition to find the
36% invariant subspace (default: Schur)
45OptionValues{1}=[
'MSignStandard';
50for i=1:size(OptionNames,1)
51 options.(deblank(OptionNames(i,:)))=[];
59% Convert to discrete time problem, if needed
62if (sum(diag(A1)<0)) % continues time
71QBD_ParsePara(A0,A1,A2);
73% Parse Optional Parameters
74options=ParseOptPara(options,OptionNames,OptionTypes,OptionValues,varargin);
76% check whether G
is known explicitly
77[G,R,U]=QBD_EG(A0,A1,A2,options.Verbose,nargout);
87% Step 1, F(z)=zD(z)-N(z), with A(z) = D^(-1)(z)N(z)
88% For QBD: A(z)
is a polynomial matrix in z with degree f. Thus, D(z)=I.
89theta=statvec(A0+A1+A2);
90drift=theta*sum(A0,2)-theta*sum(A2,2);
95% Step 2, H(s)=sum_{i=0}^f F_i (1-s)^(f-i) (1+s)^i = sum_{i=0}^f H_i s^i
105 con1=conv(con1,temp1);
108 con2=conv(con2,temp2);
110 contrib=conv(con1,con2);
112 H{j+1}=H{j+1}+contrib(j+1)*F{i+1};
118% Step 3, \hat{H}_i = H_f^-1*H_i
121 hatH{i+1}=H{f+1}*H{i+1};
125y=[ones(m,1); zeros(m*(f-1),1)];
126x0T=[zeros(1,m) 1] / [hatH{1} ones(m,1)];
128 xT(1,(i-1)*m+1:i*m)=x0T*hatH{i+1};
130xT(1,(f-1)*m+1:f*m)=x0T;
135 Zold((i-1)*m+1:i*m,i*m+1:(i+1)*m)=eye(m);
138 Zold(m*(f-1)+1:m*f,i*m+1:(i+1)*m)=-hatH{i+1};
141Zold=Zold-sign(drift)*y*xT;
143if ( exist(
'ordschur') ~= 5 || ~strcmp(options.Mode,
'Schur'))
144 % Step 6, classic matrix sign function algorithm
145 if (strcmp(
'Schur',options.Mode))
146 fprintf(
'Ordschur not supported by current MATLAB version\n');
147 fprintf(
'An automatic switch is performed to the MSignBalzer Mode\n');
152 while (check > epsilon && numit < options.MaxNumIt)
154 if (strcmp(options.Mode,
'MSignStandard'))
156 else % options.Mode =
'MSignBalzer' or switched from
'Schur' Mode
157 determ=(1+abs(det(Zold))^(1/(m*f)))^(-1);
158 determ=min(determ,1-10^(-3));
160 Znew=determ*Zold+(1-determ)*inv(Zold);
161 check=norm(Znew-Zold,1)/norm(Zold,1);
162 if (options.Verbose==1)
163 fprintf(
'Check after %d iterations: %d\n',numit,check);
168 if (numit == options.MaxNumIt && check > epsilon)
169 warning(
'Maximum Number of Iterations %d reached: T may not have m columns',numit);
172 T=orth(Znew-eye(m*f));
174 % Theorem 7 (Akar, Oguz, Sohraby -- SM 2000)
176 [T,D]=ordschur(T,D,
'lhp');
181G=(T(1:m,:)+T(m+1:2*m,:))*inv(T(1:m,:)-T(m+1:2*m,:));
183if (options.Verbose==1)
184 res_norm=norm(G-A0-(A1+A2*G)*G,inf);
185 fprintf(
'Final Residual Error for G: %d\n',res_norm);
190 R=A2*(eye(m)-(A1+A2*G))^(-1);
191 if (options.Verbose==1)
192 res_norm=norm(R-A2-R*(A1+R*A0),inf);
193 fprintf(
'Final Residual Error for R: %d\n',res_norm);
200 if (options.Verbose==1)
201 res_norm=norm(U-A1-A2*(eye(m)-U)^(-1)*A0,inf);
202 fprintf(
'Final Residual Error for U: %d\n',res_norm);