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
41OptionNames=[
42% 'ProgressBar';
43 'Mode ';
44 'MaxNumIt ';
45 'Verbose '];
46OptionTypes=[
47% 'numeric';
48 'char ';
49 'numeric';
50 'numeric'];
51OptionValues{1}=['Sylvest ';
52 'Estimat ';
53 'DirectSum'];
54
55options=[];
56for i=1:size(OptionNames,1)
57 options.(deblank(OptionNames(i,:)))=[];
58end
59
60% Default settings
61%options.ProgressBar=0;
62options.Mode='Sylvest';
63options.MaxNumIt=50;
64options.Verbose=0;
65
66% Convert to discrete time problem, if needed
67m=size(A1,1);
68continues=0;
69if (sum(diag(A1)<0)) % continues time
70 continues=1;
71 lamb=max(-diag(A1));
72 A0=A0/lamb;
73 A1=A1/lamb+eye(m);
74 A2=A2/lamb;
75end
76
77% Parse Parameters
78QBD_ParsePara(A0,A1,A2);
79
80% Parse Optional Parameters
81options=ParseOptPara(options,OptionNames,OptionTypes,OptionValues,varargin);
82
83% check whether G is known explicitly
84[G,R,U]=QBD_EG(A0,A1,A2,options.Verbose,nargout);
85if (~isempty(G))
86 return
87end
88
89% Start NI
90m=size(A1,1);
91
92R=zeros(m,m);
93check=1;
94numit=0;
95while (check > 10^(-12) && numit < options.MaxNumIt)
96 numit=numit+1;
97 if (numit==1)%R=0;
98 Yk=A2*(eye(m)-A1)^(-1);
99 else
100 if (strcmp(options.Mode,'Estimat'))
101 FRk=(A2+R*(A1-eye(m)+R*A0)); % FRk = (A2+RA1+R^2A0)-R
102 Zk=FRk*(eye(m)-A1)^(-1);
103 Yk=FRk+Zk*A1+(R*Zk+Zk*R)*A0;
104 else
105 D=-(A2+R*(A1-eye(m)+R*A0)); % D = R-(A2+RA1+R^2A0)
106 C=A1+R*A0-eye(m);
107 % Solve R*Yk*A0+Yk*C=D
108 if (strcmp(options.Mode,'Sylvest'))
109 Yk=QBD_NI_Sylvest(A0',R',C',D')';
110 else
111 Yk=(kron(A0',R)+kron(C',eye(m)))^(-1)*reshape(D,m^2,1);
112 Yk=reshape(Yk,m,m);
113 end
114 end
115 end
116 R=R+Yk;
117 check=norm(Yk,inf);
118 if (options.Verbose==1)
119 fprintf('Check after %d iterations: %d\n',numit,check);
120 drawnow;
121 end
122end
123clear C D Yk;
124if (numit == options.MaxNumIt && check > 10^(-12))
125 warning('Maximum Number of Iterations %d reached',numit);
126end
127
128% Compute G
129G=(eye(m)-(A1+R*A0))^(-1)*A0;
130
131if (options.Verbose==1)
132 res_norm=norm(G-A0-(A1+A2*G)*G,inf);
133 fprintf('Final Residual Error for G: %d\n',res_norm);
134end
135
136% R
137if (nargout > 1)
138 if (options.Verbose==1)
139 res_norm=norm(R-A2-R*(A1+R*A0),inf);
140 fprintf('Final Residual Error for R: %d\n',res_norm);
141 end
142end
143
144% Compute U
145if (nargout > 2)
146 U=A1+R*A0;
147 if (options.Verbose==1)
148 res_norm=norm(U-A1-A2*(eye(m)-U)^(-1)*A0,inf);
149 fprintf('Final Residual Error for U: %d\n',res_norm);
150 end
151 if (continues)
152 U=lamb*(U-eye(m));
153 end
154end