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