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