1function pi=QBD_pi(B0,B1,R,varargin)
2%QBD_pi Stationary vector of a Quasi-Birth-Death Markov Chains [Neuts]
6% pi=QBD_pi(B0,B1,R) computes the stationary vector of a Quasi-Birth-Death
7% Markov chain with a transition matrix of the form
15% the input matrix R
is the minimal nonnegative solution to the matrix
16% equation R = A2 + R A1 + R^2 A0
18% CONTINUOUS TIME CASE:
20% pi=QBD_pi(B0,B1,R) computes the stationary vector of a Quasi-Birth-Death
21% Markov chain with a rate matrix of the form
29% the input matrix R
is the minimal nonnegative solution to the matrix
30% equation 0 = A2 + R A1 + R^2 A0
34% MaxNumComp: Maximum number of components (
default: 500)
35% Verbose: The accumulated probability mass
is printed at every
36% n steps when set to n (default:0)
37% Boundary: Allows solving the QBD with a more general boundary
41%
P (or Q) = 0 A0 A1 A2 0 ...
45% the parameter value contains the matrix [B2; A1+R*A0].
46% The matrices B0 and B2 need not to be square.
61for i=1:size(OptionNames,1)
62 options.(deblank(OptionNames(i,:)))=[];
67options.MaxNumComp=10000;
70% Parse Optional Parameters
71options=ParseOptPara(options,OptionNames,OptionTypes,OptionValues,varargin);
75% Convert to discrete time problem, if needed
76if (sum(diag(B1)<0)) % continuous time
78 if (~isempty(options.Boundary))
80 lamb=max(lamb,max(-diag(options.Boundary(mb+1:end,:))));
81 options.Boundary=options.Boundary/lamb;
82 options.Boundary(mb+1:end,:)=options.Boundary(mb+1:end,:)+eye(m);
91if( max(temp<-100*eps) )
92 error('MATLAB:QBD_pi:InvalidRInput',...
93 'The spectral radius of R
is not below 1: QBD
is not pos. recurrent');
96if (isempty(options.Boundary))
97 pi=statvec(B1+R*B0); % compute pi_0
98 pi=pi/(pi*temp*ones(m,1)); % normalize pi_0
101 pi(2:options.MaxNumComp,:)=0;
102 while (sumpi < 1-10^(-10) && numit < 1+options.MaxNumComp)
103 pvec = pi(numit,:)*R;
104 pi(numit+1,1:m)=pvec; % compute pi_(numit+1)
106 sumpi=sumpi+sum(pi(numit,:));
107 if (~mod(numit,options.Verbose))
108 fprintf('Accumulated mass after %d iterations: %d\n',numit,sumpi);
112% pi=reshape(pi',1,[]);
115 pi0=statvec([[B1; B0] options.Boundary]); % compute pi_0 and pi_1
116 pi0=pi0/(pi0(1:mb)*ones(mb,1)+pi0(mb+1:end)*temp*ones(m,1)); % normalize
119 sumpi=sum(pi0)+sum(pi);
121 while (sumpi < 1-10^(-10) && numit < options.MaxNumComp)
122 pi(numit+1,1:m)=pi(numit,:)*R; % compute pi_(numit+1)
124 sumpi=sumpi+sum(pi(numit,:));
125 if (~mod(numit,options.Verbose))
126 fprintf('Accumulated mass after %d iterations: %d\n',numit,sumpi);
130 pi=[pi0 reshape(pi',1,[])];
134if (numit == 1+options.MaxNumComp)
135% warning('Maximum Number of Components %d reached',numit-1);