1function G=MG1_FI(A,varargin)
2%MG1_FI Functional Iterations
for M/G/1-Type Markov Chains [Neuts]
4% G=MG1_FI(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
10% G=MG1_FI(A,
'NonZeroBlocks',vec) computes the minimal nonnegative
11% solution to the matrix equation G = A0 + Av1 G^v1 + Av2 G^v2 + ...
12% Av3 G^v3 + ... + A_vmax G^vmax, where A = [A0 Av1 Av2 Av3 ... A_vmax]
13% has m rows and m*max columns and
is a nonnegative matrix, with
14% (A0+Av1+Av2+...+A_vmax) irreducible and stochastic and vec = [v1 v2
15% v3 v4 ... vmax]
is an increasing list of integers with v1 > 0
19% MaxNumIt: Maximum number of iterations (default: 10000)
20% Mode:
'Traditional': G(n+1) = (I-A1)^(-1) * ...
21% (A0 + A2*G(n)^2 + A3*G(n)^3 + ... + A_max*G(n)^max)
22%
'Natural': G(n+1) = A0 + A1*G(n) + A2*G(n)^2+ ...
23% A3*G(n)^3 + ... + A_max*G(n)^max)
24%
'U-Based': G(n+1) = ...
25% (I-A1-A2*G(n)-A3*G(n)^2-...-A_max*G(n)^(max-1))^(-1)*A0
26%
'Shift<Mode>': where <Mode>
is Traditional, Natural or
27% U-Based uses the Shift Technique
29% Verbose: When set to k, the residual error
is printed every
34% StartValue: Starting value for iteration (default: 0)
35% NonZeroBlocks: Reduces the computation time when several of the
36% Ai, i>0, matrices are equal to zero. A vector vec
37% passed as an argument specifies the indices of the
38% nonzero blocks (default: vec=[1 2 ... max])
39% When set the possible Shift in the Mode
is ignored
54OptionValues{1}=[
'Traditional ';
60OptionValues{4}=[
'one';
65for i=1:size(OptionNames,1)
66 options.(deblank(OptionNames(i,:)))=[];
70options.Mode='U-Based';
71options.MaxNumIt=10000;
72options.ShiftType='one';
75options.StartValue=zeros(m,m);
77options.NonZeroBlocks=0;
79% Parse Optional Parameters
80options=ParseOptPara(options,OptionNames,OptionTypes,OptionValues,varargin);
82% check whether G
is known explicitly
83G=MG1_EG(A,options.Verbose);
92if (options.NonZeroBlocks == 0)
94 if (strfind(options.Mode,'Shift')>0)
95 if (options.Verbose >= 1)
98 [A,drift,tau,v]=MG1_Shifts(A,options.ShiftType);
100 if (strfind(options.Mode,'Natural')>0)
101 while(check > 10^(-14) && numit < options.MaxNumIt)
105 G=A(:,j*m+1:(j+1)*m)+G*Gold;
107 check=norm(G-Gold,inf);
109 if (~mod(numit,options.Verbose))
110 fprintf('Check after %d iterations: %d\n',numit,check);
116 if (strfind(options.Mode,'Traditional')>0)
117 while(check > 10^(-14) && numit < options.MaxNumIt)
121 G=A(:,j*m+1:(j+1)*m)+G*Gold;
124 G=(eye(m)-A(:,m+1:2*m))^(-1)*G;
125 check=norm(G-Gold,inf);
127 if (~mod(numit,options.Verbose))
128 fprintf('Check after %d iterations: %d\n',numit,check);
134 if (strfind(options.Mode,'U-Based')>0)
135 while(check > 10^(-14) && numit < options.MaxNumIt)
139 G=A(:,j*m+1:(j+1)*m)+G*Gold;
141 G=(eye(m)-G)^(-1)*A(:,1:m);
142 check=norm(G-Gold,inf);
144 if (~mod(numit,options.Verbose))
145 fprintf('Check after %d iterations: %d\n',numit,check);
150 if (strfind(options.Mode,'Shift')>0)
151 switch options.ShiftType
153 G=G+(drift<1)*ones(m,m)/m;
155 G=G+(drift>1)*tau*v*ones(1,m);
157 G=G+(drift<1)*ones(m,m)/m+(drift>1)*tau*v*ones(1,m);
159 if (options.Verbose >= 1)
164 if (strfind(options.Mode,'Shift')>0)
165 warning('MATLAB:MG1_FI:ShiftIgnored',...
166 'Shift
is ignored due to NonZeroBlocks option');
168 % Check length of vec option
169 if (max(size(options.NonZeroBlocks) ~= [1 maxd]))
170 error('MATLAB:MG1_FI:InvalidNonZeroBlockVec',...
171 'The NonZeroBlocks option vector must be of length %d',maxd);
173 vec=[0 options.NonZeroBlocks];
174 vec=vec(2:end)-vec(1:end-1);
175 % Check whether vec
is increasing
177 error('MATLAB:MG1_FI:InvalidNonZeroBlockVec',...
178 'The NonZeroBlocks option vector must be strictly increasing');
180 % If A1 = 0 then Traditional = Natural
181 if (vec(1) > 1 && strcmp(options.Mode,'Traditional'))
182 options.Mode='Natural';
184 if (strfind(options.Mode,'Natural')>0)
185 while(check > 10^(-14) && numit < options.MaxNumIt)
189 G=A(:,j*m+1:(j+1)*m)+G*Gold^vec(j+1);
191 check=norm(G-Gold,inf);
193 if (~mod(numit,options.Verbose))
194 fprintf('Check after %d iterations: %d\n',numit,check);
200 if (strfind(options.Mode,'Traditional')>0)
202 while(check > 10^(-14) && numit < options.MaxNumIt)
206 G=A(:,j*m+1:(j+1)*m)+G*Gold^vec(j+1);
208 G=A(:,1:m)+G*Gold^(1+vec(2));
209 G=(eye(m)-A(:,m+1:2*m))^(-1)*G;
210 check=norm(G-Gold,inf);
212 if (~mod(numit,options.Verbose))
213 fprintf('Check after %d iterations: %d\n',numit,check);
219 if (strfind(options.Mode,'U-Based')>0)
220 while(check > 10^(-14) && numit < options.MaxNumIt)
224 G=A(:,j*m+1:(j+1)*m)+G*Gold^vec(j+1);
226 G=(eye(m)-G*Gold^(vec(1)-1))^(-1)*A(:,1:m);
227 check=norm(G-Gold,inf);
229 if (~mod(numit,options.Verbose))
230 fprintf('Check after %d iterations: %d\n',numit,check);
237if (numit == options.MaxNumIt)
238 warning('Maximum Number of Iterations %d reached',numit);
241if (options.Verbose>0)
242 Gcheck=A(:,maxd*m+1:end);
244 if (options.NonZeroBlocks == 0)
245 Gcheck=A(:,j*m+1:(j+1)*m)+Gcheck*G;
247 Gcheck=A(:,j*m+1:(j+1)*m)+Gcheck*G^vec(j+1);
250 res_norm=norm(G-Gcheck,inf);
251 fprintf('Final Residual Error for G: %d\n',res_norm);