LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
QBD_IS.m
1function [G,R,U]=QBD_IS(A0,A1,A2,varargin)
2%QBD_IS Invariant Subspace for Quasi-Birth-Death Markov Chains [Akar, Sohraby]
3%
4% DISCRETE TIME CASE:
5%
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
9%
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
12%
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
15%
16% CONTINUOUS TIME CASE:
17%
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
21%
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
24%
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
27%
28% Optional Parameters:
29%
30% MaxNumIt: Maximum number of iterations (default: 50)
31% Verbose: The residual error is printed at each step when set to 1,
32% (default:0)
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)
37
38OptionNames=['Mode ';
39 'Verbose ';
40 'MaxNumIt '];
41OptionTypes=['char ';
42 'numeric';
43 'numeric'];
44
45OptionValues{1}=['MSignStandard';
46 'MSignBalzer ';
47 'Schur '];
48
49options=[];
50for i=1:size(OptionNames,1)
51 options.(deblank(OptionNames(i,:)))=[];
52end
53
54% Default settings
55options.Mode='Schur';
56options.Verbose=0;
57options.MaxNumIt=50;
58
59% Convert to discrete time problem, if needed
60m=size(A1,1);
61continues=0;
62if (sum(diag(A1)<0)) % continues time
63 continues=1;
64 lamb=max(-diag(A1));
65 A0=A0/lamb;
66 A1=A1/lamb+eye(m);
67 A2=A2/lamb;
68end
69
70% Parse Parameters
71QBD_ParsePara(A0,A1,A2);
72
73% Parse Optional Parameters
74options=ParseOptPara(options,OptionNames,OptionTypes,OptionValues,varargin);
75
76% check whether G is known explicitly
77[G,R,U]=QBD_EG(A0,A1,A2,options.Verbose,nargout);
78if (~isempty(G))
79 return
80end
81
82epsilon=10^(-12);
83f=2;
84m=size(A1,1);
85
86
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);
91F{1}=-A0;
92F{2}=eye(m)-A1;
93F{3}=-A2;
94
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
96for i=0:f
97 H{i+1}=zeros(m,m);
98end
99for i=0:f
100 temp1=[1 -1];
101 temp2=[1 1];
102 con1=1;
103 con2=1;
104 for j=1:f-i
105 con1=conv(con1,temp1);
106 end
107 for j=1:i
108 con2=conv(con2,temp2);
109 end
110 contrib=conv(con1,con2);
111 for j=0:f
112 H{j+1}=H{j+1}+contrib(j+1)*F{i+1};
113 end
114end
115
116clear F;
117
118% Step 3, \hat{H}_i = H_f^-1*H_i
119H{f+1}=inv(H{f+1});
120for i=0:f-1
121 hatH{i+1}=H{f+1}*H{i+1};
122end
123
124% Step 4, y, xT
125y=[ones(m,1); zeros(m*(f-1),1)];
126x0T=[zeros(1,m) 1] / [hatH{1} ones(m,1)];
127for i=1:f-1
128 xT(1,(i-1)*m+1:i*m)=x0T*hatH{i+1};
129end
130xT(1,(f-1)*m+1:f*m)=x0T;
131
132% Step 5, E_m in Zold
133Zold=zeros(m*f,m*f);
134for i=1:f-1
135 Zold((i-1)*m+1:i*m,i*m+1:(i+1)*m)=eye(m);
136end
137for i=0:f-1
138 Zold(m*(f-1)+1:m*f,i*m+1:(i+1)*m)=-hatH{i+1};
139end
140y=y/(xT*y);
141Zold=Zold-sign(drift)*y*xT;
142
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');
148 drawnow;
149 end
150 numit=0;
151 check=1;
152 while (check > epsilon && numit < options.MaxNumIt)
153 numit=numit+1;
154 if (strcmp(options.Mode,'MSignStandard'))
155 determ=1/2;
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));
159 end
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);
164 drawnow;
165 end
166 Zold=Znew;
167 end
168 if (numit == options.MaxNumIt && check > epsilon)
169 warning('Maximum Number of Iterations %d reached: T may not have m columns',numit);
170 end
171 % Step 7,
172 T=orth(Znew-eye(m*f));
173else
174 % Theorem 7 (Akar, Oguz, Sohraby -- SM 2000)
175 [T,D]=schur(Zold);
176 [T,D]=ordschur(T,D,'lhp');
177 T=T(:,1:m);
178end
179
180% Step 8,
181G=(T(1:m,:)+T(m+1:2*m,:))*inv(T(1:m,:)-T(m+1:2*m,:));
182
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);
186end
187
188% Compute R
189if (nargout > 1)
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);
194 end
195end
196
197% Compute U
198if (nargout > 2)
199 U=A1+R*A0;
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);
203 end
204 if (continues)
205 U=lamb*(U-eye(m));
206 end
207end
208