LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
QBD_CR.m
1function [G,R,U]=QBD_CR(A0,A1,A2,varargin)
2%QBD_CR Cyclic reduction for Quasi-Birth-Death Markov Chains [Bini,Meini]
3%
4% DISCRETE TIME CASE:
5%
6% G=QBD_CR(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_CR(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_CR(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_CR(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_CR(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_CR(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: 'Basic' uses the Basic Cyclic Reduction
34% 'Shift' uses the shift technique to accelarate convergence
35% (default: 'Shift')
36% RAPComp: set to 1 if the QBD has RAP components
37
38OptionNames=[
39% 'ProgressBar';
40 'Mode ';
41 'MaxNumIt ';
42 'Verbose ';
43 'RAPComp '];
44OptionTypes=[
45% 'numeric';
46 'char ';
47 'numeric';
48 'numeric';
49 'numeric'];
50OptionValues{1}=['Basic';
51 'Shift'];
52
53options=[];
54for i=1:size(OptionNames,1)
55 options.(deblank(OptionNames(i,:)))=[];
56end
57
58% Default settings
59%options.ProgressBar=0;
60options.Mode='Shift';
61options.MaxNumIt=50;
62options.Verbose=0;
63options.RAPComp=0;
64
65% Parse Optional Parameters
66options=ParseOptPara(options,OptionNames,OptionTypes,OptionValues,varargin);
67
68if(~options.RAPComp)
69 % Convert to discrete time problem, if needed
70 m=size(A1,1);
71 continues=0;
72 if (sum(diag(A1)<0)) % continues time
73 continues=1;
74 lamb=max(-diag(A1));
75 A0=A0/lamb;
76 A1=A1/lamb+eye(m);
77 A2=A2/lamb;
78 end
79
80 % Parse Parameters
81 QBD_ParsePara(A0,A1,A2);
82else
83 % Parse Parameters
84 QBD_RAP_ParsePara(A0,A1,A2);
85
86 % Convert to discrete time problem - uniformization
87 m=size(A1,1);
88 continues=1;
89 lamb=max(-diag(A1));
90 A0=A0/lamb;
91 A1=A1/lamb+eye(m);
92 A2=A2/lamb;
93end
94
95% check whether G is known explicitly
96[G,R,U]=QBD_EG(A0,A1,A2,options.Verbose,nargout);
97if (~isempty(G))
98 return
99end
100
101% Start CR
102
103% Shift technique
104if (options.Mode=='Shift')
105 theta=stat(A0+A1+A2);
106 drift=theta*sum(A0,2)-theta*sum(A2,2);
107 if (drift < 0) % MC is transient -> use the dual MC
108 if (nargout > 1 | options.Verbose==1)
109 A2old=A2;
110 end
111 A2=A2-ones(m,1)*(theta*A2);
112 A1=A1+ones(m,1)*(theta*A0);
113 else
114 uT=ones(1,m)/m;
115 if (nargout > 2 | options.Verbose==1) % store A0old to compute U
116 A0old=A0;
117 end
118 A0=A0-sum(A0,2)*uT;
119 A1=A1+sum(A2,2)*uT;
120 end
121end
122
123% Start of Cyclic Reduction (Basic)
124A=A1;
125B=A2;
126C=A0;
127if (nargout <= 1 & options.Verbose ~= 1) % A1 and A2 only needed to compute R
128 clear A1 A2;
129end
130Ahat=A;
131%if (options.ProgressBar==1)
132% progressBar2(0,'Quasi-Birth-Death','Computing R via Cyclic Reduction (CR) ...');
133%end
134check=1;
135numit=0;
136while (check > 10^(-14) & numit < options.MaxNumIt)
137 Atemp=(eye(m)-A)^(-1);
138 BAtemp=B*Atemp;
139 Atemp=C*Atemp;
140 Ahat=Ahat+BAtemp*C;
141 A=A+BAtemp*C+Atemp*B;
142 B=BAtemp*B;
143 C=Atemp*C;
144 numit=numit+1;
145 check=min(norm(B,inf),norm(C,inf));
146 %if (options.ProgressBar==1)
147 % est_numit=ceil(log2(log(10^(-50))/log(check/checkold)));
148 % checkold=check;
149 % progressBar2(min([1 numit/(numit+est_numit)]),'Quasi-Birth-Death');
150 %end
151 if (options.Verbose==1)
152 fprintf('Check after %d iterations: %d\n',numit,check);
153 drawnow;
154 end
155end
156if (numit == options.MaxNumIt && check > 10^(-14))
157 warning('Maximum Number of Iterations %d reached',numit);
158end
159clear Atemp BAtemp A B C;
160G=(eye(m)-Ahat)^(-1)*A0;
161clear Ahat;
162
163% Shift Technique
164if (options.Mode=='Shift')
165 if (drift < 0) % transient
166 if (nargout > 1 | options.Verbose==1)
167 A1=A1-ones(m,1)*theta*A0; % restore original A1
168 A2=A2old; % restore original A2
169 end
170 else % pos recurrent
171 G=G+ones(m,1)*uT;
172 if (nargout > 1 | options.Verbose==1)
173 A1=A1-sum(A2,2)*uT; % restore original A1
174 end
175 if (nargout > 2 | options.Verbose==1)
176 A0=A0old; % restore original A0
177 end
178 end
179end
180
181if (options.Verbose==1)
182 res_norm=norm(G-A0-(A1+A2*G)*G,inf);
183 fprintf('Final Residual Error for G: %d\n',res_norm);
184end
185
186% Compute R
187if (nargout > 1)
188 R=A2*(eye(m)-(A1+A2*G))^(-1);
189 if (options.Verbose==1)
190 res_norm=norm(R-A2-R*(A1+R*A0),inf);
191 fprintf('Final Residual Error for R: %d\n',res_norm);
192 end
193end
194
195% Compute U
196if (nargout > 2)
197 U=A1+R*A0;
198 if (options.Verbose==1)
199 res_norm=norm(U-A1-A2*(eye(m)-U)^(-1)*A0,inf);
200 fprintf('Final Residual Error for U: %d\n',res_norm);
201 end
202 if (continues)
203 U=lamb*(U-eye(m));
204 end
205end
206
207
208%if (options.ProgressBar==1)
209% progressBar2(1,'Quasi-Birth-Death');
210%end