1function [ql,qlT,wait,waitT,soj,sojT]=Q_DT_MMAPK_PHK_1(D0,D,alpha,S,varargin)
2%[ql,qlT,wait,waitT,soj,sojT]=Q_DT_MMAPK_PHK_1(D0,D,alpha,S) computes the
3% Queuelength, Waiting time and Sojourn time distribution of a
4% Discrete-Time
MMAP[K]/PH[K]/1/FCFS queue (per type and overall)
7% *
MMAP[K] arrival process (with m states)
8% D{i} holds the mxm matrix D_i, together with the mxm matrix D0
9% these characterize the
MMAP[K] arrival process
11% * PH[K] services time distributions (i=1:K)
12% alpha{i} holds the 1xmi alpha vector of the PH service time of
14% S{i} holds the mixmi matrix S of the PH service time of a type
18% * Per type queue length distribution,
19% ql{k}(i) = Prob[(i-1) type k customers in the queue]
20% * Overall queue length distribution,
21% qlT(i) = Prob[(i-1) customers in the queue (any type)]
22% * Per type waiting time distribution,
23% wait{k}(i) = Prob[a type k customers has waiting time = (i-1)]
24% * Overall waiting time distribution,
25% waitT(i) = Prob[a customer (of any type) has wainting time = (i-1)]
26% * Per type sojourn time distribution,
27% soj{k}(i) = Prob[a type k customers has sojourn time = (i-1)]
28% * Overall sojourn time distribution,
29% sojT(i) = Prob[a customer (of any type) has sojourn time = (i-1)]
32% Mode: The underlying function to compute the R matrix of the
33% underlying QBD can be selected using the following
34% parameter values (default:
'CR')
35%
'CR' : Cyclic Reduction [Bini, Meini]
36%
'FI' : Functional Iterations [Neuts]
37%
'IS' : Invariant Subspace [Akar, Sohraby]
38%
'LR' : Logaritmic Reduction [Latouche, Ramaswami]
39%
'NI' : Newton Iteration
41% MaxNumComp: Maximum number of components for the vectors containig
42% the performance measure.
44% Verbose: When set to 1, the progress of the computation
is printed
47% Optfname: Optional parameters for the underlying function fname.
48% These parameters are included in a cell with one entry holding
49% the name of the parameter and the next entry the parameter
50% value. In this function, fname can be equal to:
51%
'QBD_CR' : Options for Cyclic Reduction [Bini, Meini]
52%
'QBD_FI' : Options for Functional Iterations [Neuts]
53%
'QBD_IS' : Options for Invariant Subspace [Akar, Sohraby]
54%
'QBD_LR' : Options for Logaritmic Reduction [Latouche, Ramaswami]
55%
'QBD_NI' : Options for Newton Iteration
57% USES: QBD Solver and QBD_pi of the SMCSolver tool
86for i=1:size(OptionNames,1)
87 options.(deblank(OptionNames(i,:)))=[];
92options.MaxNumComp = 1000;
94options.OptQBD_CR=cell(0);
95options.OptQBD_FI=cell(0);
96options.OptQBD_IS=cell(0);
97options.OptQBD_LR=cell(0);
98options.OptQBD_NI=cell(0);
102Q_DT_MMAPK_ParsePara(D0,'D0',D,'D');
104 Q_DT_PH_ParsePara(alpha{i}, [
'alpha_' int2str(i)], S{i}, [
'S_', int2str(i)] )
107% Parse Optional Parameters
108options=Q_ParseOptPara(options,OptionNames,OptionTypes,OptionValues,varargin);
110% Check Unused Optional Parameters
111Q_CheckUnusedParaQBD(options);
120 smk(i+1)=smk(i)+size(alpha{i},2);
125% Test the load of the queue
134 lambdas(i)=pi*D{i}*ones(m,1);
135 means(i)=sum(alpha{i}*(eye(size(alpha{i},2))-S{i})^(-1));
142 error('MATLAB:Q_DT_MMAPK_PHK_1:LoadExceedsOne
',...
143 'The load %d of the system exceeds one
',load);
146% Construct building blocks
148Tser=zeros(mser,mser);
152 L(:,m*smk(i)+1:m*smk(i+1))=kron(alpha{i},D{i});
153 Tser(smk(i)+1:smk(i+1),smk(i)+1:smk(i+1))=S{i};
154 tser(smk(i)+1:smk(i+1),1)=1-sum(S{i},2);
157% Compute QBD blocks A0, A1 and A2
158A0=[zeros(m,m+mtot); zeros(mtot,m) kron(Tser,eye(m))];
159A1=[zeros(m,m) L; zeros(mtot,m) kron(tser,L)];
160A2=[D0 zeros(m,mtot); kron(tser,D0) zeros(mtot,mtot)];
164B2=[D0; kron(tser,D0)];
168 [G,R]=QBD_CR(A2,A1,A0,options.OptQBD_CR{:});
170 [G,R]=QBD_FI(A2,A1,A0,options.OptQBD_FI{:});
172 [G,R]=QBD_LR(A2,A1,A0,options.OptQBD_LR{:});
174 [G,R]=QBD_IS(A2,A1,A0,options.OptQBD_IS{:});
176 [G,R]=QBD_NI(A2,A1,A0,options.OptQBD_NI{:});
178pi=QBD_pi(B2,B1,R,'MaxNumComp
',options.MaxNumComp,'Verbose
', options.Verbose,'Boundary
',[B0; A1+R*A2]);
180% remove additional states
182pi=reshape(pi(m+1:end),mtot+m,size(pi(m+1:end),2)/(mtot+m));
183c=sum(sum(pi(1:m,:)));
185pi=pi(m+1:end,:)/(1-c);
187% compute sojourn times per type
188piS=sum(reshape(pi,m,size(pi,2)*mser),1);
189piS=reshape(piS,mser,size(piS,2)/mser);
191 soj{k}=zeros(1,size(piS,2)+1);
194 for k=1:K %order: good for caching (MATLAB is columnwise)
195 soj{k}(i+1)=piS(smk(k)+1:smk(k+1),i)'*tser(smk(k)+1:smk(k+1),1);
199 soj{k}=soj{k}/lambdas(k);
202% compute overall sojourn time
203sojT=zeros(size(soj{1}));
205 sojT=sojT+lambdas(i)*soj{i};
207sojT=sojT/sum(lambdas);
209% compute the waiting time per type
210piW=pi
'*kron(tser,eye(m));
211maxwait=size(piW,1)-1;
212piW=reshape(piW',1,m*size(pi,2));
213Dmatse=zeros((maxwait+1)*m,K);
217 Dmatse((i-1)*m+1:i*m,k)=temp;
222 wait{k}=zeros(1,maxwait+1);
224 wait{k}(n+1)=piW(n*m+1:(maxwait+1)*m)*...
225 Dmatse(1:m*(maxwait+1-n),k);
227 wait{k}=wait{k}/lambdas(k);
228 wait{k}(1)=1-sum(wait{k});
231% old waiting time -> sometimes unstable
237%
while (sprob < 1-10^(-10))
239% prob(j)=temp*tser(smk(i)+1:smk(i+1));
241% sprob=sprob+prob(j);
243% prob=prob(min(find(prob>10^(-12))):end);
244% stemp=soj{i}(min(find(soj{i}>10^(-12))):end);
245% waitold{i}=deconv(stemp,prob);
248% compute overall waiting time
249waitT=zeros(size(wait{1}));
251 waitT(1,1:size(wait{i},2))=waitT(1,1:size(wait{i},2))+lambdas(i)*wait{i};
253waitT=waitT/sum(lambdas);
255% compute queue length per type
256piTA=zeros(m*K,size(pi,2));
259 piTA(m*(k-1)+j,:)=sum(pi(m*smk(k)+j:m:m*smk(k+1),:),1);
260 % elements piTA(m*(k-1)+1:m*k,i) give type k in service
263piA=zeros(m,size(pi,2));
265 piA(j,:)=sum(piTA(j:m:end,:),1);
267Dtemps=zeros(m,size(pi,2));
269 piAk=piA-piTA(m*(k-1)+1:m*k,:); % no type k in service
270 ql{k}=zeros(1,size(pi,2)+1);
273 Dtemps(:,1)=ones(m,1);
275 % no type k in service
276 ql{k}(1:i)=ql{k}(1:i)+piAk(:,i)
'*Dtemps(:,1:i);
278 ql{k}(2:i+1)=ql{k}(2:i+1)+piTA(m*(k-1)+1:m*k,i)'*Dtemps(:,1:i);
279 Dtemps(:,1:(i+1))=[Dnok*Dtemps(:,1:i) zeros(m,1)]+...
280 [zeros(m,1) D{k}*Dtemps(:,1:i)];
282 ql{k}=ql{k}(1:max(find(ql{k}>10^(-10))));
285% compute overall queue length
286Dtemps=zeros(m,size(pi,2));
287Dtemps(:,1)=ones(m,1);
288qlT=zeros(size(pi,2)+1);
292 % customer in service
293 qlT(2:i+1)=qlT(2:i+1)+piA(:,i)
'*Dtemps(:,1:i);
294 Dtemps(:,1:(i+1))=[D0*Dtemps(:,1:i) zeros(m,1)]+...
295 [zeros(m,1) D1*Dtemps(:,1:i)];
297qlT=qlT(1:max(find(qlT>10^(-10))));