1function G=MG1_RR(D,varargin)
2%MG1_RR Ramaswami Reduction based Algorithm
for M/G/1-Type Markov Chains
3% [Bini,Meini,Ramaswami]
5% G=MG1_RR(A) computes the minimal nonnegative solution to the
6% matrix equation G = A0 + A1 G + A2 G^2 + A3 G^3 + ... + A_max G^max,
7% where A = [A0 A1 A2 A3 ... A_max] has m rows and m*max columns and
is
8% a nonnegative matrix, with (A0+A1+A2+...+A_max) irreducible and
13% MaxNumIt: Maximum number of iterations (
default: 50)
14% Verbose: The residual error
is printed at each step when set to 1,
16% Mode:
'Direct' does not rely on the displacement structure,
17% Requirements: memory O(m^2N^2), time O(m^3N^3)
18%
'DispStruct' makes use of the displacement structure,
19% Requirements: memory O(m^2N), time O(m^3N^2)
20%
'DispStructFFT' uses the displacement structure and FFTs
21% Requirements: memory O(m^2N), time O(m^2NlogN+m^3N)
22% (default:
'DispStruct')
30OptionValues{1}=[
'Direct ';
35for i=1:size(OptionNames,1)
36 options.(deblank(OptionNames(i,:)))=[];
40%options.ProgressBar=0;
45% Parse Optional Parameters
46options=ParseOptPara(options,OptionNames,OptionTypes,OptionValues,varargin);
48% check whether G
is known explicitly
49G=MG1_EG(D,options.Verbose);
62if (strcmp(options.Mode,'Direct'))
63 B=[zeros(m,N*m); eye((N-1)*m) zeros((N-1)*m,m)];
64 check=min(norm(B,inf),norm(D0,inf));
68 while (check > 10^(-15) && numit < options.MaxNumIt)
72 S=inv(eye(m)-vT*uhat);
73 ZZTuhat=[zeros(m,m) ; uhat(m+1:N*m,:)];
78 newD0=D0*(S*vT(:,1:m)+T+eye(m))*D0;
81 % Use (7) of Theorem 3, Section 3.1
87 % we continue with updating uhat and vT
88 temp=uhat*(S*vT(:,1:m)+T+eye(m))*D0;
93 % update other variables
99 check=min(norm(B,inf),norm(D0,inf));
100 if (options.Verbose==1)
101 fprintf('Check value of iteration %d equals %d \n',numit,check);
107 b(m+1:2*m,1:m)=eye(m);
114 check=min(sum(sum(b)),norm(D0,inf));
117 while ((check > 10^(-15) || first == 1) && numit < options.MaxNumIt)
122 S=inv(eye(m)-vT*uhat);
123 temp=[zeros(m,m) ; uhat(m+1:N*m,:)]; %% ZZTuhat
128 newD0=D0*(S*vT(:,1:m)+T+eye(m))*D0;
131 temp=uhat*(S*vT(:,1:m)+T+eye(m))*D0;
132 if (strcmp(options.Mode,'DispStruct'))
140 if (strcmp(options.Mode,'DispStruct'))
148 % we start by calculating (I-A)^(-1) b using the structure of (I-A)^-1
149 temp=[vT*b; b(1:m,1:m)];
150 temp=[S T; S eye(m)+T]*temp;
151 newb(1:m,1:m)=b(1:m,1:m)+temp(1:m,:);
152 newb(m+1:N*m,1:m)=b(m+1:end,1:m)+uhat(m+1:end,:)*temp(m+1:end,:);
154 if (strcmp(options.Mode,'DispStruct'))
163 e1pZu=[eye(m); uhat(m+1:end,:)];
164 Z2u=[zeros(2*m,m); uhat(m+1:(N-1)*m,:)];
165 e2pZ2u=[zeros(m,m); eye(m); uhat(m+1:(N-1)*m,:)];
166 H=[e1pZu e2pZ2u*S e2pZ2u*T+Z2u];
173 temp=[vT(:,m+1:end) zeros(m,m)];
174 KT=[S*temp; -vT; [-eye(m) zeros(m,(N-1)*m)]];
178 if (strcmp(options.Mode,'DispStruct'))
181 W(1:N*m,2*m+1:5*m)=temp;
184 temp=H(:,colp*m+1:(colp+1)*m);
186 W(1:N*m,(2+colp)*m+1:(3+colp)*m)=temp;
190 temp=[vT*[c1 c2]; [c1(1:m,1:m) c2(1:m,1:m)]];
191 temp=[S T; S eye(m)+T]*temp;
192 temp2(1:m,1:2*m)=[c1(1:m,1:m) c2(1:m,1:m)]+temp(1:m,:);
193 temp2(m+1:N*m,1:2*m)=[c1(m+1:end,1:m) c2(m+1:end,1:m)]+...
194 uhat(m+1:end,:)*temp(m+1:end,:);
195 if (strcmp(options.Mode,'DispStruct'))
199 W(1:N*m,5*m+1:7*m)=temp;
204 temp=supertemp2(:,colp*m+1:(1+colp)*m);
206 W(1:N*m,(5+colp)*m+1:(6+colp)*m)=temp;
212 % Step 6, part 1 (this order allows us to clear W more rapidly)
217 YT(5*m+1:7*m,1:N*m)=[r1 r2]';
218 if (strcmp(options.Mode,'DispStruct'))
221 YT(2*m+1:5*m,1:N*m)=temp;
224 temp=KT(rowp*m+1:(1+rowp)*m,:);
226 YT((2+rowp)*m+1:(3+rowp)*m,1:N*m)=temp;
230 Zu=[zeros(m,m); uhat(m+1:end,:)];
231 temp=[[r1(1:m,1:m) r2(1:m,1:m)]' [r1 r2]'*Zu];
232 temp=temp*[S T; S eye(m)+T];
233 temp2=temp(:,1:m)*vT;
234 temp2(:,1:m)=temp2(:,1:m)+temp(:,m+1:2*m);
235 if (strcmp(options.Mode,'DispStruct'))
239 YT(1:2*m,1:N*m)=temp;
241 supertemp2=temp2+[r1 r2]';
244 temp=supertemp2(rowp*m+1:(1+rowp)*m,:);
246 YT(rowp*m+1:(1+rowp)*m,1:N*m)=temp;
257 [U,Xsi,V]=svd(R1*R2');
259 first2m(temp)=Xsi(temp,temp);
266 temp=Q1*U(:,1:2*m)*diag(first2m);
272 temp=(V(:,1:2*m)'*Q2')';
278 % update other variables
289 check=min(sum(sum(b)),norm(D0,inf));
290 if (options.Verbose==1)
291 fprintf('Check value of iteration %d equals %d \n',numit,check);
297if (numit == options.MaxNumIt && check > 10^(-15))
298 warning('Maximum Number of Iterations %d reached',numit);
301% Compute G by means of formula at the end of Section 3.
302temp=eye(m)-D(:,m+1:end)*uhat;
305if (options.Verbose==1)
306 temp=D(:,end-m+1:end);
307 for i=size(D,2)/m-1:-1:1
308 temp=D(:,(i-1)*m+1:i*m)+temp*G;
310 res_norm=norm(G-temp,inf);
311 fprintf('Final Residual Error for G: %d\n',res_norm);