LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
Q_DT_SMK_PHK_1.m
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)
5%
6% INPUT PARAMETERS:
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'
12%
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
17%
18% RETURN VALUES:
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)]
31%
32%
33% OPTIONAL PARAMETERS:
34%
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')
38%
39% 'CR' : Cyclic Reduction [Bini, Meini]
40% 'FI' : Functional Iterations [Neuts]
41% 'IS' : Invariant Subspace [Akar, Sohraby]
42% 'RR' : Ramaswami Reduction [Bini, Meini, Ramaswami]
43%
44% MaxNumComp: Maximum number of components for the vectors containig
45% the performance measure.
46%
47% Verbose: When set to 1, the progress of the computation is printed
48% (default:0).
49%
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
55%
56% USES: GIM1_R of the SMCSolver tool
57
58OptionNames=[
59 'Mode ';
60 'MaxNumComp ';
61 'Verbose ';
62 'OptGIM1_R '];
63OptionTypes=[
64 'char ';
65 'numeric';
66 'numeric';
67 'cell '];
68
69OptionValues{1}=['CR';
70 'FI';
71 'IS';
72 'RR'];
73
74options=[];
75for i=1:size(OptionNames,1)
76 options.(deblank(OptionNames(i,:)))=[];
77end
78
79% Default settings
80options.Mode='CR';
81options.MaxNumComp = 1000;
82options.Verbose = 0;
83options.OptGIM1_R=cell(0);
84
85
86% Parse Parameters
87Q_DT_SMK_ParsePara(D,'D',1);
88K=size(alpha,2);
89for i=1:K
90 Q_DT_PH_ParsePara(alpha{i}, ['alpha_' int2str(i)], S{i}, ['S_', int2str(i)] )
91end
92
93% Parse Optional Parameters
94options=Q_ParseOptPara(options,OptionNames,OptionTypes,OptionValues,varargin);
95
96% Determine constants
97m=size(D{1},1);
98K=size(alpha,2);
99smk=zeros(1,K+1);
100smk(1)=0;
101for i=1:K
102 smk(i+1)=smk(i)+size(alpha{i},2);
103end
104mser=smk(K+1);
105mtot=mser*m;
106
107% Test the load of the queue
108Dsum=zeros(m,m);
109meanI=zeros(m,m);
110maxI=1;
111maxIs=ones(1,K);
112for k=1:K
113 Dsums{k}=zeros(m,m);
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);
117 end
118 Dsum=Dsum+Dsums{k};
119 maxIs(k)=size(D{k},2)/m;
120end
121maxI=max(maxIs);
122pi=stat(Dsum);
123lambda=1/(pi*meanI*ones(m,1));
124lambdas=zeros(1,K);
125mus=zeros(1,K);
126for k=1:K
127 lambdas(k)=lambda*pi*Dsums{k}*ones(m,1);
128 means(k)=sum(alpha{k}*(eye(size(alpha{k},2))-S{k})^(-1));
129end
130load=lambdas*means';
131if load >= 1
132 error('MATLAB:Q_DT_SMK_PHK_1:LoadExceedsOne',...
133 'The load %d of the system exceeds one',load);
134end
135
136% Construct building blocks A0, A1, ... AImax
137Dmats=zeros(m*maxI,m*K);
138Dmatssum=zeros(m*maxI,m);
139for k=1:k
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);
143 end
144end
145
146Tser=zeros(mser,mser);
147tser=zeros(mser,1);
148for k=1:K
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);
151end
152
153A0=kron(Tser,eye(m));
154Temp=zeros(m*maxI,mtot); % i > 0
155for k=1:K
156 Temp(:,m*smk(k)+1:m*smk(k+1))=kron(alpha{k},Dmats(:,(k-1)*m+1:k*m));
157end
158Ais=zeros(mtot*maxI,mtot); % i > 0
159for i=1:maxI
160 Ais((i-1)*mtot+1:i*mtot,:)=kron(tser,Temp((i-1)*m+1:i*m,:));
161end
162
163%Prepare input GIM1_R
164A=zeros(mtot,mtot*(maxI+1));
165A(:,1:mtot)=A0;
166for i=1:maxI
167 A(:,i*mtot+1:(i+1)*mtot)=Ais((i-1)*mtot+1:i*mtot,:);
168end
169
170switch options.Mode
171 case 'CR'
172 R=GIM1_R(A,'CR',options.OptGIM1_R{:});
173 case 'FI'
174 R=GIM1_R(A,'FI',options.OptGIM1_R{:});
175 case 'IS'
176 R=GIM1_R(A,'IS',options.OptGIM1_R{:});
177 case 'RR'
178 R=GIM1_R(A,'RR',options.OptGIM1_R{:});
179end
180
181% compute theta_tot
182Asum=A0;
183for i=1:maxI
184 Asum=Asum+A(:,i*mtot+1:(i+1)*mtot);
185end
186theta_tot=stat(Asum);
187
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);
191sumpi=sum(pi(1,:));
192i=2;
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));
196 i=i+1;
197 if (~mod(i,options.Verbose))
198 fprintf('Accumulated mass after %d iterations: %d\n',i,sumpi);
199 drawnow;
200 end
201end
202if (i == 1+options.MaxNumComp)
203 warning('Maximum Number of Components %d reached',i-1);
204end
205
206% compute sojourn times per type
207piS=sum(reshape(pi',m,size(pi,1)*mser),1);
208piS=reshape(piS,mser,size(piS,2)/mser);
209for k=1:K
210 soj{k}=zeros(1,size(piS,2)+1);
211end
212for i=1:size(piS,2)
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);
215 end
216end
217for k=1:K
218 soj{k}=soj{k}/lambdas(k);
219end
220
221% compute overall sojourn time
222sojT=zeros(size(soj{1}));
223for i=1:K
224 sojT=sojT+lambdas(i)*soj{i};
225end
226sojT=sojT/lambda;
227
228% compute the waiting time per type (no deconvolution -> not stable)
229maxwait=size(pi,1)-1;
230piT=pi*kron(tser,eye(m));
231piT=reshape(piT',1,m*size(pi,1));
232Dmatse=zeros(maxI*m,K);
233for k=1:K
234 Dmatse(:,k)=sum(Dmats(:,(k-1)*m+1:k*m),2);
235end
236for k=1:K
237 wait{k}=zeros(1,maxwait+1);
238 for n=1:maxwait
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);
241 end
242 wait{k}=wait{k}/lambdas(k);
243 wait{k}(1)=1-sum(wait{k});
244end
245
246%compute overall waiting time
247waitT=zeros(size(wait{1}));
248for i=1:K
249 waitT(1,1:size(wait{i},2))=waitT(1,1:size(wait{i},2))+lambdas(i)*wait{i};
250end
251waitT=waitT/sum(lambdas);
252
253% compute queue length per type (new arrivals at current time are not included)
254piTA=zeros(size(pi,1),m*K);
255for k=1:K
256 for j=1:m
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
259 end
260end
261piA=zeros(size(pi,1),m);
262for j=1:m
263 piA(:,j)=sum(piTA(:,j:m:end),2);
264end
265for k=1:K
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);
269 ql{k}(1)=1-load;
270
271 Dkmats=zeros(m,m*maxIs(k));
272 for i=1: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);
277 for i=1: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)]
281
282 Dtemps(1:m,1)=ones(m,1);
283 for i=1:maxIs(k)-1
284 ql{k}(1:i)=ql{k}(1:i)+piAk(i,:)*Dtemps((i-1)*m+1:i*m,1:i);
285 % type k in service
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);
288 % update Dtemps
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);
293 end
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);
296 % type k in service
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);
299 % update Dtemps
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);
304 end
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);
307 % type k in service
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);
310 % update Dtemps
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);
316 Dtemps(1:m,:)=[];
317 end
318 ql{k}=ql{k}(1:max(find(ql{k}>10^(-14))));
319end
320
321% compute overall queue length
322Dtemps=zeros(m*maxI,size(pi,1));
323qlT=zeros(1,size(pi,1)+1);
324qlT(1)=1-load;
325
326DTmats=zeros(m,m*maxI);
327for i=1:maxI
328 DTmats(:,(maxI-i)*m+1:(maxI-i+1)*m)=Dmatssum((i-1)*m+1:i*m,:);
329end
330
331Dtemps(1:m,1)=ones(m,1);
332for i=1:maxI-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);
335 % update Dtemps
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);
339end
340for i=maxI:size(pi,1)
341 % customer in service
342 qlT(2:i+1)=qlT(2:i+1)+piA(i,:)*Dtemps((maxI-1)*m+1:maxI*m,1:i);
343 % update Dtemps
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);
347 Dtemps(1:m,:)=[];
348end
349qlT=qlT(1:max(find(qlT>10^(-14))));