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