LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
QBD_NI.m
1function [G,R,U]=QBD_NI(A0,A1,A2,varargin)
2%QBD_NI Newton Iteration for Quasi-Birth-Death Markov Chains [Ramaswami,
3% Latouche,Bini,Meini]
4%
5% DISCRETE TIME CASE:
6%
7% G=QBD_NI(A0,A1,A2) computes the minimal nonnegative solution to the
8% matrix equation G = A0 + A1 G + A2 G^2, where A,B and C are square
9% nonnegative matrices, with (A0+A1+A2) irreducible and stochastic
10%
11% [G,R]=QBD_NI(A0,A1,A2) also provides the minimal nonnegative solution
12% to the matrix equation R = A2 + R A1 + R^2 A0
13%
14% [G,R,U]=QBD_NI(A0,A1,A2) also provides the minimal nonnegative solution
15% to the matrix equation U = A1 + A2 (I-U)^(-1) A0
16%
17% CONTINUOUS TIME CASE:
18%
19% G=QBD_NI(A0,A1,A2) computes the minimal nonnegative solution to the
20% matrix equation 0 = A0 + A1 G + A2 G^2, where A,B and C are square
21% nonnegative matrices, with (A0+A1+A2) having row sums equal to zero
22%
23% [G,R]=QBD_NI(A0,A1,A2) also provides the minimal nonnegative solution
24% to the matrix equation 0 = A2 + R A1 + R^2 A0
25%
26% [G,R,U]=QBD_NI(A0,A1,A2) also provides the minimal nonnegative solution
27% to the matrix equation U = A1 + A2 (-U)^(-1) A0
28%
29% Optional Parameters:
30%
31% MaxNumIt: Maximum number of iterations (default: 50)
32% Verbose: The residual error is printed at each step when set to 1,
33% (default:0)
34% Mode: 'Sylvest' solves a Sylvester matrix equation at each step
35% using an Hessenberg algorithm
36% 'Estimat' estimates the solution of the Sylvester equation
37% 'DirectSum' solves the Sylvester matrix equation at each
38% step by rewriting it as a (large) system of linear equations
39% (default: 'Sylvest')
40% RAPComp: set to 1 if the QBD has RAP components
41
42OptionNames=[
43% 'ProgressBar';
44 'Mode ';
45 'MaxNumIt ';
46 'Verbose ';
47 'RAPComp '];
48OptionTypes=[
49% 'numeric';
50 'char ';
51 'numeric';
52 'numeric';
53 'numeric'];
54OptionValues{1}=['Sylvest ';
55 'Estimat ';
56 'DirectSum'];
57
58options=[];
59for i=1:size(OptionNames,1)
60 options.(deblank(OptionNames(i,:)))=[];
61end
62
63% Default settings
64%options.ProgressBar=0;
65options.Mode='Sylvest';
66options.MaxNumIt=50;
67options.Verbose=0;
68options.RAPComp=0;
69
70% Parse Optional Parameters
71options=ParseOptPara(options,OptionNames,OptionTypes,OptionValues,varargin);
72
73if(~options.RAPComp)
74 % Convert to discrete time problem, if needed
75 m=size(A1,1);
76 continues=0;
77 if (sum(diag(A1)<0)) % continues time
78 continues=1;
79 lamb=max(-diag(A1));
80 A0=A0/lamb;
81 A1=A1/lamb+eye(m);
82 A2=A2/lamb;
83 end
84
85 % Parse Parameters
86 QBD_ParsePara(A0,A1,A2);
87else
88 % Parse Parameters
89 QBD_RAP_ParsePara(A0,A1,A2);
90
91 % Convert to discrete time problem - uniformization
92 m=size(A1,1);
93 continues=1;
94 lamb=max(-diag(A1));
95 A0=A0/lamb;
96 A1=A1/lamb+eye(m);
97 A2=A2/lamb;
98end
99
100% check whether G is known explicitly
101[G,R,U]=QBD_EG(A0,A1,A2,options.Verbose,nargout);
102if (~isempty(G))
103 return
104end
105
106% Start NI
107m=size(A1,1);
108
109R=zeros(m,m);
110check=1;
111numit=0;
112while (check > 10^(-12) && numit < options.MaxNumIt)
113 numit=numit+1;
114 if (numit==1)%R=0;
115 Yk=A2*(eye(m)-A1)^(-1);
116 else
117 if (strcmp(options.Mode,'Estimat'))
118 FRk=(A2+R*(A1-eye(m)+R*A0)); % FRk = (A2+RA1+R^2A0)-R
119 Zk=FRk*(eye(m)-A1)^(-1);
120 Yk=FRk+Zk*A1+(R*Zk+Zk*R)*A0;
121 else
122 D=-(A2+R*(A1-eye(m)+R*A0)); % D = R-(A2+RA1+R^2A0)
123 C=A1+R*A0-eye(m);
124 % Solve R*Yk*A0+Yk*C=D
125 if (strcmp(options.Mode,'Sylvest'))
126 Yk=QBD_NI_Sylvest(A0',R',C',D')';
127 else
128 Yk=(kron(A0',R)+kron(C',eye(m)))^(-1)*reshape(D,m^2,1);
129 Yk=reshape(Yk,m,m);
130 end
131 end
132 end
133 R=R+Yk;
134 check=norm(Yk,inf);
135 if (options.Verbose==1)
136 fprintf('Check after %d iterations: %d\n',numit,check);
137 drawnow;
138 end
139end
140clear C D Yk;
141if (numit == options.MaxNumIt && check > 10^(-12))
142 warning('Maximum Number of Iterations %d reached',numit);
143end
144
145% Compute G
146G=(eye(m)-(A1+R*A0))^(-1)*A0;
147
148if (options.Verbose==1)
149 res_norm=norm(G-A0-(A1+A2*G)*G,inf);
150 fprintf('Final Residual Error for G: %d\n',res_norm);
151end
152
153% R
154if (nargout > 1)
155 if (options.Verbose==1)
156 res_norm=norm(R-A2-R*(A1+R*A0),inf);
157 fprintf('Final Residual Error for R: %d\n',res_norm);
158 end
159end
160
161% Compute U
162if (nargout > 2)
163 U=A1+R*A0;
164 if (options.Verbose==1)
165 res_norm=norm(U-A1-A2*(eye(m)-U)^(-1)*A0,inf);
166 fprintf('Final Residual Error for U: %d\n',res_norm);
167 end
168 if (continues)
169 U=lamb*(U-eye(m));
170 end
171end