1function G=MG1_CR(D,varargin)
2%MG1_CR Cyclic reduction
for M/G/1-Type Markov Chains [Bini,Meini]
4% G=MG1_CR(A) computes the minimal nonnegative solution to the
5% matrix equation G = A0 + A1 G + A2 G^2 + A3 G^3 + ... + A_max G^max,
6% where A = [A0 A1 A2 A3 ... A_max] has m rows and m*max columns and
is
7% a nonnegative matrix, with (A0+A1+A2+...+A_max) irreducible and
12% MaxNumIt: Maximum number of iterations (
default: 50)
13% MaxNumRoot: Maximum number of roots used by Point-Wise CR (default: 2048)
14% EpsilonValue: Required accuracy at each step (default: 10^(-16))
15% Verbose: The residual error
is printed at each step when set to 1,
20% Mode:
'PWCR' uses the Point-Wise Cyclic Reduction
21%
'ShiftPWCR' uses the Shift + Point-Wise Cyclic Reduction
22% (default:
'ShiftPWCR' with ShiftType=
'one')
36OptionValues{1}=[
'ShiftPWCR';
39OptionValues{3}=[
'one';
45for i=1:size(OptionNames,1)
46 options.(deblank(OptionNames(i,:)))=[];
50%options.ProgressBar=0;
51options.Mode='ShiftPWCR';
52options.ShiftType='one';
53options.MaxNumRoot=2048;
56options.EpsilonValue=10^(-16);
58% Parse Optional Parameters
59options=ParseOptPara(options,OptionNames,OptionTypes,OptionValues,varargin);
61% check whether G
is known explicitly
62G=MG1_EG(D,options.Verbose);
67if (strfind(options.Mode,'ShiftPWCR')>0)
68 if (options.Verbose == 1)
71 [D,drift,tau,v]=MG1_Shifts(D,options.ShiftType);
74% start Cyclic Reduction
78D=[D; zeros((2^(1+floor(log2(size(D,1)/m-1)))+1)*m-size(D,1),m)];
82Aeven=D(find(mod(kron(1:size(D,1)/m,ones(1,m)),2)),:);
83Aodd=D(find(~mod(kron(1:size(D,1)/m,ones(1,m)),2)),:);
85Ahatodd=[Aeven(m+1:end,:); D(end-m+1:end,:)];
90 Rj=Rj+D((i-1)*m+1:i*m,:);
97while(1 && numit < options.MaxNumIt)
101 % Evaluate the 4 functions in the nj+1 roots using FFT
102 % prepare for FFTs (such that they can be performed in 4 calls)
103 temp1=reshape(Aodd(1:(nj+1)*m,:)',m^2,(nj+1))';
104 temp2=reshape(Aeven(1:(nj+1)*m,:)',m^2,(nj+1))';
105 temp3=reshape(Ahatodd(1:(nj+1)*m,:)',m^2,(nj+1))';
106 temp4=reshape(Ahateven(1:(nj+1)*m,:)',m^2,(nj+1))';
109 temp1=fft(temp1,(nj+1));
110 temp2=fft(temp2,(nj+1));
111 temp3=fft(temp3,(nj+1));
112 temp4=fft(temp4,(nj+1));
114 % reform the 4*(nj+1) matrices
115 temp1=reshape(temp1.',m,m*(nj+1)).';
116 temp2=reshape(temp2.',m,m*(nj+1)).';
117 temp3=reshape(temp3.',m,m*(nj+1)).';
118 temp4=reshape(temp4.',m,m*(nj+1)).';
120 % Next, we perform a point-wise evaluation of (6.20) - Thesis Meini
122 Ahatnew((cnt-1)*m+1:cnt*m,1:m)=temp4((cnt-1)*m+1:cnt*m,:)+...
123 temp2((cnt-1)*m+1:cnt*m,:)*inv(eye(m)-temp1((cnt-1)*m+1:cnt*m,:))*temp3((cnt-1)*m+1:cnt*m,:);
124 Anew((cnt-1)*m+1:cnt*m,1:m)=exp(-(cnt-1)*2j*pi/(nj+1))*temp1((cnt-1)*m+1:cnt*m,:)+...
125 temp2((cnt-1)*m+1:cnt*m,:)*inv(eye(m)-temp1((cnt-1)*m+1:cnt*m,:))*temp2((cnt-1)*m+1:cnt*m,:);
128 % We now invert the FFTs to get Pz and Phatz
130 % prepare for IFFTs (in 2 calls)
131 Ahatnew=reshape(Ahatnew(1:(nj+1)*m,:).',m^2,(nj+1)).';
132 Anew=reshape(Anew(1:(nj+1)*m,:).',m^2,(nj+1)).';
135 Ahatnew=real(ifft(Ahatnew,(nj+1)));
136 Anew=real(ifft(Anew,(nj+1)));
138 % reform matrices Pi and Phati
139 Ahatnew=reshape(Ahatnew',m,m*(nj+1))';
140 Anew=reshape(Anew',m,m*(nj+1))';
141 else % series Aeven, Aodd, Ahateven and Ahatodd are constant
142 temp=Aeven*(eye(m)-Aodd)^(-1);
143 Ahatnew=Ahateven+temp*Ahatodd;
144 Anew=[temp*Aeven; Aodd];
151 nAnew=max(nAnew,norm(Anew(i*m+1:(i+1)*m,:),inf));
154 deghat=size(Ahatnew,1)/m;
155 for i=deghat/2:deghat-1
156 nAhatnew=max(nAhatnew,norm(Ahatnew(i*m+1:(i+1)*m,:),inf));
160 while ((nAnew > (nj+1)*options.EpsilonValue || ...
161 (nAhatnew > (nj+1)*options.EpsilonValue)) && ...
162 nj+1 < options.MaxNumRoot)
165 stopv=min([nj+1 size(Aodd,1)/m]);
168 temp1=reshape(Aodd(1:stopv*m,:)',m^2,stopv)';
169 temp2=reshape(Aeven(1:stopv*m,:)',m^2,stopv)';
170 temp3=reshape(Ahatodd(1:stopv*m,:)',m^2,stopv)';
171 temp4=reshape(Ahateven(1:stopv*m,:)',m^2,stopv)';
174 temp1=fft(temp1,(nj+1),1);
175 temp2=fft(temp2,(nj+1),1);
176 temp3=fft(temp3,(nj+1),1);
177 temp4=fft(temp4,(nj+1),1);
179 % reform the 4*(nj+1) matrices
180 temp1=reshape(temp1.',m,m*(nj+1)).';
181 temp2=reshape(temp2.',m,m*(nj+1)).';
182 temp3=reshape(temp3.',m,m*(nj+1)).';
183 temp4=reshape(temp4.',m,m*(nj+1)).';
185 % Next, we perform a point-wise evaluation of (6.20) - Thesis Meini
187 Ahatnew((cnt-1)*m+1:cnt*m,1:m)=temp4((cnt-1)*m+1:cnt*m,:)+...
188 temp2((cnt-1)*m+1:cnt*m,:)*inv(eye(m)-temp1((cnt-1)*m+1:cnt*m,:))*temp3((cnt-1)*m+1:cnt*m,:);
189 Anew((cnt-1)*m+1:cnt*m,1:m)=exp(-(cnt-1)*2j*pi/(nj+1))*temp1((cnt-1)*m+1:cnt*m,:)+...
190 temp2((cnt-1)*m+1:cnt*m,:)*inv(eye(m)-temp1((cnt-1)*m+1:cnt*m,:))*temp2((cnt-1)*m+1:cnt*m,:);
193 % We now invert the FFTs to get Pz and Phatz
195 Ahatnew=reshape(Ahatnew(1:(nj+1)*m,:).',m^2,(nj+1)).';
196 Anew=reshape(Anew(1:(nj+1)*m,:).',m^2,(nj+1)).';
199 Ahatnew=real(ifft(Ahatnew,(nj+1)));
200 Anew=real(ifft(Anew,(nj+1)));
202 % reform matrices Pi and Phati
203 Ahatnew=reshape(Ahatnew',m,m*(nj+1))';
204 Anew=reshape(Anew',m,m*(nj+1))';
208 for i=1:size(Anew,1)/m-1
209 vec1=vec1+i*sum(Anew(i*m+1:(i+1)*m,:));
210 vec2=vec2+i*sum(Ahatnew(i*m+1:(i+1)*m,:));
215 nAnew=max(nAnew,norm(Anew(i*m+1:(i+1)*m,:),inf));
218 deghat=size(Ahatnew,1)/m;
219 for i=deghat/2:deghat-1
220 nAhatnew=max(nAhatnew,norm(Ahatnew(i*m+1:(i+1)*m,:),inf));
223 if (( nAnew > (nj+1)*options.EpsilonValue || ...
224 nAhatnew > (nj+1)*options.EpsilonValue ) && ...
225 nj+1 >= options.MaxNumRoot)
226 warning('MATLAB:MG1_CR:MaxNumRootReached',...
227 'Maximum number of ''%d'' reached, accuracy might be affected',options.MaxNumRoot);
231 Anew=Anew(1:m*(nj+1)/2,:);
232 Ahatnew=Ahatnew(1:m*(nj+1)/2,:);
235 % compute Aodd, Aeven, ...
236 Aeven=Anew(find(mod(kron(1:size(Anew,1)/m,ones(1,m)),2)),:);
237 Aodd=Anew(find(~mod(kron(1:size(Anew,1)/m,ones(1,m)),2)),:);
239 Ahateven=Ahatnew(find(mod(kron(1:size(Ahatnew,1)/m,ones(1,m)),2)),:);
240 Ahatodd=Ahatnew(find(~mod(kron(1:size(Ahatnew,1)/m,ones(1,m)),2)),:);
242 if (options.Verbose==1)
243 if (strcmp(options.Mode,'PWCR'))
244 fprintf('The Point-wise evaluation of Iteration %d required %d roots\n',numit,nj+1);
246 fprintf('The Shifted PWCR evaluation of Iteration %d required %d roots\n',numit,nj+1);
252 if (strcmp(options.Mode,'PWCR') || strcmp(options.Mode,'DCR'))
253 Rnewj=Anew(m+1:2*m,:);
254 for i=3:size(Anew,1)/m
255 Rnewj=Rnewj+Anew((i-1)*m+1:i*m,:);
257 Rnewj=inv(eye(m)-Rnewj);
258 Rnewj=Anew(1:m,:)*Rnewj;
259 if (max(max(abs(Rj-Rnewj))) < options.EpsilonValue || ...
260 max(sum(eye(m)-Anew(1:m,:)*inv(eye(m)-Anew(m+1:2*m,:)))) < options.EpsilonValue)
262 for i=2:size(Ahatnew,1)/m
263 G=G+Rnewj*Ahatnew((i-1)*m+1:i*m,:);
265 G=D(1:m,:)*inv(eye(m)-G);
269 % second condition tests whether Ahatnew
is degree 0 (numerically)
270 if (norm(Anew(1:m,1:m))<options.EpsilonValue || sum(sum(Ahatnew(m+1:end,:)))<options.EpsilonValue || max(sum(eye(m)-D(1:m,:)*inv(eye(m)-Ahatnew(1:m,:)))) < options.EpsilonValue)
271 G=D(1:m,:)*inv(eye(m)-Ahatnew(1:m,:));
276 G=D(1:m,:)*inv(eye(m)-Ahatnew(1:m,:));
277 if (norm(G-Gold,inf)<options.EpsilonValue || norm(Ahatnew(m+1:end,:),inf)<options.EpsilonValue)
282if (numit == options.MaxNumIt & isempty(G))
283 warning('Maximum Number of Iterations %d reached',numit);
284 G=D(1:m,:)*inv(eye(m)-Ahatnew(1:m,:));
289if (strcmp(options.Mode,'ShiftPWCR'))
290 switch options.ShiftType
292 G=G+(drift<1)*ones(m,m)/m;
294 G=G+(drift>1)*tau*v*ones(1,m);
296 G=G+(drift<1)*ones(m,m)/m+(drift>1)*tau*v*ones(1,m);
300if (options.Verbose==1)
301 if (strcmp(options.Mode,'PWCR'))
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);