1function pi=MG1_pi(B,A,G,varargin)
2%MG1_pi Stationary vector of a Quasi-Birth-Death Markov Chains [Neuts, Ramaswami]
4% pi=MG1_pi(B,A,G) computes the stationary vector of an M/G/1-type
5% Markov chain with a transition matrix of the form
13% the input matrix G
is the minimal nonnegative solution to the matrix
14% equation G = A0 + A1 G + A2 G^2 + ... + Aamax G^amax
15% A = [A0 A1 ... Aamax] and B=[B0 B1 B2 ... Bbmax]
17% pi=MG1_pi([],A,G) computes the stationary vector of an M/G/1-type
18% Markov chain with a transition matrix of the form
22%
P = 0 A0 A1 A2 A3 ...
28% MaxNumComp: Maximum number of components (
default: 500)
29% Verbose: The accumulated probability mass
is printed at every
30% n steps when set to n (default:0)
31% Boundary: Allows solving the MG1 type Markov chain with a more
36%
P = 0 A0 A1 A2 A3 ...
40% the parameter value contains the matrix C0.
41% The matrices C0 and B1,B2,... need not to be square.
43% InputPiZero: The first component of the steady state vector pi
44% can be given as input by setting this parameter value
45% equal to its first component pi_0 (default: not given)
62for i=1:size(OptionNames,1)
63 options.(deblank(OptionNames(i,:)))=[];
67options.MaxNumComp=500;
70options.InputPiZero=[];
72% Parse Optional Parameters
73options=ParseOptPara(options,OptionNames,OptionTypes,OptionValues,varargin);
81 if (~isempty(options.Boundary))
86 if (mod(size(B,2)-mb,m) ~= 0)
87 error('Matrix B has an incorrect number of columns');
89 degb=(size(B,2)-mb)/m;
92if (isempty(options.Boundary) & mb ~= m)
93 error('The Boundary option must be used as dimension of B0
is not identical to A0');
96if (~isempty(options.Boundary))
97 if (size(options.Boundary,1) ~= m || size(options.Boundary,2) ~= mb)
98 error('The Boundary parameter value has an incorrect dimension');
101% Compute theta and beta, sum_v>=0 Av and sum_v>=k Av G^v-1
102% the last sums (for k=1,...,amax) are stored in A
103sumA=A(:,dega*m+1:end);
105% beta = (A_maxd)e + (A_maxd + A_maxd-1)e + ... + (Amaxd+...+A1)e
107 sumA=sumA+A(:,i*m+1:(i+1)*m);
108 A(:,i*m+1:(i+1)*m)=A(:,i*m+1:(i+1)*m)+A(:,(i+1)*m+1:(i+2)*m)*G;
109 beta=beta+sum(sumA,2);
116 error('MATLAB:MG1_pi:NotPossitiveRecurrent',...
117 'The Markov chain characterized by A
is not positive recurrent');
121if (isempty(options.InputPiZero))
129 % Compute sum_v>=1 Bv, sum_v>=1 (v-1) Bv e, sum_v>=k Bv G^v-1
130 % the last sums (for k=1,...,bmax) are stored in B
131 sumBB0=B(:,mb+(degb-1)*m+1:end);
134 Bbeta=Bbeta+sum(sumBB0,2);
135 sumBB0=sumBB0+B(:,mb+(i-1)*m+1:mb+i*m);
136 B(:,mb+(i-1)*m+1:mb+i*m)=B(:,mb+(i-1)*m+1:mb+i*m)+B(:,mb+i*m+1:mb+(i+1)*m)*G;
141 if (isempty(options.Boundary)) %m=mb
142 K=B(:,1:mb)+B(:,mb+1:mb+m)*G;
144 L=(eye(m)-A(:,m+1:2*m))^(-1)*options.Boundary;
145 K=B(:,1:mb)+B(:,mb+1:mb+m)*L;
150 temp=sum((eye(m)-sumA-(ones(m,1)-beta)*g)^(-1),2);
151 psi1=(eye(m)-A(:,1:m)-A(:,m+1:2*m))*temp+...
152 (1-drift)^(-1)*sum(A(:,1:m),2);
153 psi2=ones(mb,1)+(sumBB0-B(:,mb+1:mb+m))*temp+(1-drift)^(-1)*Bbeta;
156 tildekappa1=psi2+B(:,mb+1:mb+m)*(eye(m)-A(:,m+1:2*m))^(-1)*psi1;
159 pi0=(kappa*tildekappa1)^(-1)*kappa;
163 % Compute sum_v>=1 Bv, sum_v>=1 (v-1) Bv e, sum_v>=k Bv G^v-1
164 % the last sums (for k=1,...,bmax) are stored in B
165 sumBB0=B(:,mb+(degb-1)*m+1:end);
168 Bbeta=Bbeta+sum(sumBB0,2);
169 sumBB0=sumBB0+B(:,mb+(i-1)*m+1:mb+i*m);
170 B(:,mb+(i-1)*m+1:mb+i*m)=B(:,mb+(i-1)*m+1:mb+i*m)+B(:,mb+i*m+1:mb+(i+1)*m)*G;
173 pi0=options.InputPiZero;
180% Start stable RAMASWAMI formula
181invbarA1=(eye(m)-A(:,m+1:2*m))^(-1);
182while (sumpi < 1-10^(-10) && numit < options.MaxNumComp)
185 pi(numit,1:m)=pi0*A(:,numit*mb+1:(numit+1)*mb);
187 pi(numit,1:m)=pi0*B(:,mb+(numit-1)*m+1:mb+numit*m);
190 pi(numit,1:m)=zeros(1,m);
192 for j=1:min(numit-1,dega-1)
193 pi(numit,1:m)=pi(numit,1:m)+...
194 pi(numit-j,:)*A(:,(j+1)*m+1:(j+2)*m);
196 pi(numit,:)=pi(numit,:)*invbarA1;
197 sumpi=sumpi+sum(pi(numit,:));
198 if (~mod(numit,options.Verbose))
199 fprintf('Accumulated mass of the first %d (reblocked) components: %d\n',numit,sumpi);
204pi=[pi0 reshape(pi',1,[])];
205if (numit == options.MaxNumComp)
206 warning('Maximum Number of Components %d reached',numit);