1function [ql,qlT,wait,waitT,soj,sojT]=Q_DT_SMK_PHK_1(D,alpha,S,varargin)
2%[ql,qlT,wait,waitT,soj,sojT]=Q_DT_SMK_PHK_1(D,alpha,S) computes the
3% Queuelength, Waiting Time and Sojourn time distribution of an
4% SM[K]/PH[K]/1/FCFS queue (per type and overall)
7% * SM[K] arrival process (with m states)
8% D{k}=[Dk_0 Dk_1 ... Dk_Imax],
for k=1...K, where the entry (j,j
') of
9% the mxm matrix Dk_i, holds the probabilities of having a type k
10% arrival, with an interarrival time of i time slots, while the
11% underlying phase changes from j to j'
13% * PH[K] services time distributions (i=1:K)
14% alpha{k} holds the 1xmk alpha vector of the PH service time of
15% type k customers S{k} holds the mixmi matrix S of the
16% PH service time of a type k customer
19% * Per type queue length distribution,
20% ql{k}(i) = Prob[(i-1) type k customers in the queue]
21% * Overall queue length distribution,
22% qlT(i) = Prob[(i-1) customers in the queue (any type)]
23% * Per type waiting time distribution,
24% wait{k}(i) = Prob[a type k customers has waiting time = (i-1)]
25% * Overall waiting time distribution,
26% waitT(i) = Prob[a customer (of any type) has wainting time = (i-1)]
27% * Per type sojourn time distribution,
28% soj{k}(i) = Prob[a type k customers has sojourn time = (i-1)]
29% * Overall sojourn time distribution,
30% sojT(i) = Prob[a customer (of any type) has sojourn time = (i-1)]
35% Mode: The underlying function to compute the R matrix of the
36% underlying GIM1-type Markov chain can be selected using
37% the following parameter values (default:
'CR')
39%
'CR' : Cyclic Reduction [Bini, Meini]
40%
'FI' : Functional Iterations [Neuts]
41%
'IS' : Invariant Subspace [Akar, Sohraby]
42%
'RR' : Ramaswami Reduction [Bini, Meini, Ramaswami]
44% MaxNumComp: Maximum number of components for the vectors containig
45% the performance measure.
47% Verbose: When set to 1, the progress of the computation
is printed
50% Optfname: Optional parameters for the underlying function fname.
51% These parameters are included in a cell with one entry holding
52% the name of the parameter and the next entry the parameter
53% value. In this function, fname can be equal to:
54%
'GIM1_R' : Options for the GIM1_R functions
56% USES: GIM1_R of the SMCSolver tool
75for i=1:size(OptionNames,1)
76 options.(deblank(OptionNames(i,:)))=[];
81options.MaxNumComp = 1000;
83options.OptGIM1_R=cell(0);
87Q_DT_SMK_ParsePara(D,'D',1);
90 Q_DT_PH_ParsePara(alpha{i}, [
'alpha_' int2str(i)], S{i}, [
'S_', int2str(i)] )
93% Parse Optional Parameters
94options=Q_ParseOptPara(options,OptionNames,OptionTypes,OptionValues,varargin);
102 smk(i+1)=smk(i)+size(alpha{i},2);
107% Test the load of the queue
114 for i=1:size(D{k},2)/m
115 Dsums{k}=Dsums{k}+D{k}(:,(i-1)*m+1:i*m);
116 meanI=meanI+i*D{k}(:,(i-1)*m+1:i*m);
119 maxIs(k)=size(D{k},2)/m;
123lambda=1/(pi*meanI*ones(m,1));
127 lambdas(k)=lambda*pi*Dsums{k}*ones(m,1);
128 means(k)=sum(alpha{k}*(eye(size(alpha{k},2))-S{k})^(-1));
132 error('MATLAB:Q_DT_SMK_PHK_1:LoadExceedsOne
',...
133 'The load %d of the system exceeds one
',load);
136% Construct building blocks A0, A1, ... AImax
137Dmats=zeros(m*maxI,m*K);
138Dmatssum=zeros(m*maxI,m);
140 for i=1:size(D{k},2)/m
141 Dmats((i-1)*m+1:i*m,(k-1)*m+1:k*m)=D{k}(:,(i-1)*m+1:i*m);
142 Dmatssum((i-1)*m+1:i*m,:)=Dmatssum((i-1)*m+1:i*m,:)+D{k}(:,(i-1)*m+1:i*m);
146Tser=zeros(mser,mser);
149 Tser(smk(k)+1:smk(k+1),smk(k)+1:smk(k+1))=S{k};
150 tser(smk(k)+1:smk(k+1),1)=1-sum(S{k},2);
154Temp=zeros(m*maxI,mtot); % i > 0
156 Temp(:,m*smk(k)+1:m*smk(k+1))=kron(alpha{k},Dmats(:,(k-1)*m+1:k*m));
158Ais=zeros(mtot*maxI,mtot); % i > 0
160 Ais((i-1)*mtot+1:i*mtot,:)=kron(tser,Temp((i-1)*m+1:i*m,:));
164A=zeros(mtot,mtot*(maxI+1));
167 A(:,i*mtot+1:(i+1)*mtot)=Ais((i-1)*mtot+1:i*mtot,:);
172 R=GIM1_R(A,'CR
',options.OptGIM1_R{:});
174 R=GIM1_R(A,'FI
',options.OptGIM1_R{:});
176 R=GIM1_R(A,'IS
',options.OptGIM1_R{:});
178 R=GIM1_R(A,'RR
',options.OptGIM1_R{:});
184 Asum=Asum+A(:,i*mtot+1:(i+1)*mtot);
188% compute pi's with preallocation based on Caudal characteristic
189pi=zeros(ceil(log(10^(-12))/log(max(eig(R)))),mtot);
190pi(1,:)=load*theta_tot*(eye(mtot)-R);
193while (sumpi < load*(1-10^(-12)) && i < 1+options.MaxNumComp )
194 pi(i,1:mtot)=pi(i-1,1:mtot)*R;
195 sumpi=sumpi+sum(pi(i,1:mtot));
197 if (~mod(i,options.Verbose))
198 fprintf(
'Accumulated mass after %d iterations: %d\n',i,sumpi);
202if (i == 1+options.MaxNumComp)
203 warning(
'Maximum Number of Components %d reached',i-1);
206% compute sojourn times per type
207piS=sum(reshape(pi
',m,size(pi,1)*mser),1);
208piS=reshape(piS,mser,size(piS,2)/mser);
210 soj{k}=zeros(1,size(piS,2)+1);
213 for k=1:K %order: good for caching (MATLAB is columnwise)
214 soj{k}(i+1)=piS(smk(k)+1:smk(k+1),i)'*tser(smk(k)+1:smk(k+1),1);
218 soj{k}=soj{k}/lambdas(k);
221% compute overall sojourn time
222sojT=zeros(size(soj{1}));
224 sojT=sojT+lambdas(i)*soj{i};
228% compute the waiting time per type (no deconvolution -> not stable)
230piT=pi*kron(tser,eye(m));
231piT=reshape(piT
',1,m*size(pi,1));
232Dmatse=zeros(maxI*m,K);
234 Dmatse(:,k)=sum(Dmats(:,(k-1)*m+1:k*m),2);
237 wait{k}=zeros(1,maxwait+1);
239 wait{k}(n+1)=piT(n*m+1:min(maxwait+1,n+maxIs(k))*m)*...
240 Dmatse(1:m*min(maxIs(k),maxwait+1-n),k);
242 wait{k}=wait{k}/lambdas(k);
243 wait{k}(1)=1-sum(wait{k});
246%compute overall waiting time
247waitT=zeros(size(wait{1}));
249 waitT(1,1:size(wait{i},2))=waitT(1,1:size(wait{i},2))+lambdas(i)*wait{i};
251waitT=waitT/sum(lambdas);
253% compute queue length per type (new arrivals at current time are not included)
254piTA=zeros(size(pi,1),m*K);
257 piTA(:,m*(k-1)+j)=sum(pi(:,m*smk(k)+j:m:m*smk(k+1)),2);
258 % elements piTA(i,m*(k-1)+1:m*k) give type k in service
261piA=zeros(size(pi,1),m);
263 piA(:,j)=sum(piTA(:,j:m:end),2);
266 Dtemps=zeros(m*maxI,size(pi,1));
267 piAk=piA-piTA(:,m*(k-1)+1:m*k); % no type k in service
268 ql{k}=zeros(1,size(pi,1)+1);
271 Dkmats=zeros(m,m*maxIs(k));
273 Dkmats(:,(maxIs(k)-i)*m+1:(maxIs(k)-i+1)*m)=...
274 Dmats((i-1)*m+1:i*m,(k-1)*m+1:k*m);
275 end % Dkmats = [Dk(maxIs(k)) ... Dk(2) Dk(1)]
276 Dnokmats=zeros(m,m*maxI);
278 Dnokmats(:,(maxI-i)*m+1:(maxI-i+1)*m)=...
279 Dmatssum((i-1)*m+1:i*m,:)-Dmats((i-1)*m+1:i*m,(k-1)*m+1:k*m);
280 end % Dnokmats = [Dnok(maxI) ... Dnok(2) Dnok(1)]
282 Dtemps(1:m,1)=ones(m,1);
284 ql{k}(1:i)=ql{k}(1:i)+piAk(i,:)*Dtemps((i-1)*m+1:i*m,1:i);
286 ql{k}(2:i+1)=ql{k}(2:i+1)+piTA(i,m*(k-1)+1:m*k)*...
287 Dtemps((i-1)*m+1:i*m,1:i);
289 Dtemps(i*m+1:(i+1)*m,1:(i+1))=...
290 [zeros(m,1) Dkmats(:,m*(maxIs(k)-i)+1:m*maxIs(k))*Dtemps(1:m*i,1:i)]+...
291 [Dnokmats(:,m*(maxI-i)+1:m*maxI)*Dtemps(1:m*i,1:i) zeros(m,1)];
292 Dtemps(i*m+1:(i+1)*m,1)=ones(m,1)-sum(Dtemps(i*m+1:(i+1)*m,2:(i+1)),2);
294 for i=maxIs(k):maxI-1
295 ql{k}(1:i)=ql{k}(1:i)+piAk(i,:)*Dtemps((i-1)*m+1:i*m,1:i);
297 ql{k}(2:i+1)=ql{k}(2:i+1)+piTA(i,m*(k-1)+1:m*k)*...
298 Dtemps((i-1)*m+1:i*m,1:i);
300 Dtemps(i*m+1:(i+1)*m,1:(i+1))=...
301 [zeros(m,1) Dkmats*Dtemps((i-maxIs(k))*m+1:m*i,1:i)]+...
302 [Dnokmats(:,m*(maxI-i)+1:m*maxI)*Dtemps(1:m*i,1:i) zeros(m,1)];
303 Dtemps(i*m+1:(i+1)*m,1)=ones(m,1)-sum(Dtemps(i*m+1:(i+1)*m,2:(i+1)),2);
305 for i=maxI:size(pi,1)
306 ql{k}(1:i)=ql{k}(1:i)+piAk(i,:)*Dtemps((maxI-1)*m+1:maxI*m,1:i);
308 ql{k}(2:i+1)=ql{k}(2:i+1)+piTA(i,m*(k-1)+1:m*k)*...
309 Dtemps((maxI-1)*m+1:maxI*m,1:i);
311 Dtemps(maxI*m+1:(maxI+1)*m,1:(i+1))=...
312 [zeros(m,1) Dkmats*Dtemps((maxI-maxIs(k))*m+1:m*maxI,1:i)]+...
313 [Dnokmats*Dtemps(:,1:i) zeros(m,1)];
314 Dtemps(maxI*m+1:(maxI+1)*m,1)=...
315 ones(m,1)-sum(Dtemps(maxI*m+1:(maxI+1)*m,2:(i+1)),2);
318 ql{k}=ql{k}(1:max(find(ql{k}>10^(-14))));
321% compute overall queue length
322Dtemps=zeros(m*maxI,size(pi,1));
323qlT=zeros(1,size(pi,1)+1);
326DTmats=zeros(m,m*maxI);
328 DTmats(:,(maxI-i)*m+1:(maxI-i+1)*m)=Dmatssum((i-1)*m+1:i*m,:);
331Dtemps(1:m,1)=ones(m,1);
333 % customer in service
334 qlT(2:i+1)=qlT(2:i+1)+piA(i,:)*Dtemps((i-1)*m+1:i*m,1:i);
336 Dtemps(i*m+1:(i+1)*m,1:(i+1))=...
337 [zeros(m,1) DTmats(:,m*(maxI-i)+1:m*maxI)*Dtemps(1:m*i,1:i)];
338 Dtemps(i*m+1:(i+1)*m,1)=ones(m,1)-sum(Dtemps(i*m+1:(i+1)*m,2:(i+1)),2);
341 % customer in service
342 qlT(2:i+1)=qlT(2:i+1)+piA(i,:)*Dtemps((maxI-1)*m+1:maxI*m,1:i);
344 Dtemps(maxI*m+1:(maxI+1)*m,1:(i+1))=[zeros(m,1) DTmats*Dtemps(:,1:i)];
345 Dtemps(maxI*m+1:(maxI+1)*m,1)=...
346 ones(m,1)-sum(Dtemps(maxI*m+1:(maxI+1)*m,2:(i+1)),2);
349qlT=qlT(1:max(find(qlT>10^(-14))));