LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
Q_DT_MMAPK_PHK_1.m
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)
5%
6% INPUT PARAMETERS:
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
10%
11% * PH[K] services time distributions (i=1:K)
12% alpha{i} holds the 1xmi alpha vector of the PH service time of
13% type i customers
14% S{i} holds the mixmi matrix S of the PH service time of a type
15% i customer
16%
17% RETURN VALUES:
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)]
30%
31% OPTIONAL PARAMETERS:
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
40%
41% MaxNumComp: Maximum number of components for the vectors containig
42% the performance measure.
43%
44% Verbose: When set to 1, the progress of the computation is printed
45% (default:0).
46%
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
56%
57% USES: QBD Solver and QBD_pi of the SMCSolver tool
58
59
60OptionNames=[
61 'Mode ';
62 'MaxNumComp ';
63 'Verbose ';
64 'OptQBD_CR ';
65 'OptQBD_FI ';
66 'OptQBD_IS ';
67 'OptQBD_LR ';
68 'OptQBD_NI '];
69OptionTypes=[
70 'char ';
71 'numeric';
72 'numeric';
73 'cell ';
74 'cell ';
75 'cell ';
76 'cell ';
77 'cell '];
78
79OptionValues{1}=['CR';
80 'FI';
81 'IS';
82 'LR';
83 'NI'];
84
85options=[];
86for i=1:size(OptionNames,1)
87 options.(deblank(OptionNames(i,:)))=[];
88end
89
90% Default settings
91options.Mode='CR';
92options.MaxNumComp = 1000;
93options.Verbose = 0;
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);
99
100% Parse Parameters
101K=size(alpha,2);
102Q_DT_MMAPK_ParsePara(D0,'D0',D,'D');
103for i=1:K
104 Q_DT_PH_ParsePara(alpha{i}, ['alpha_' int2str(i)], S{i}, ['S_', int2str(i)] )
105end
106
107% Parse Optional Parameters
108options=Q_ParseOptPara(options,OptionNames,OptionTypes,OptionValues,varargin);
109
110% Check Unused Optional Parameters
111Q_CheckUnusedParaQBD(options);
112
113% Determine constants
114m=size(D0,1);
115K=size(alpha,2);
116size(alpha{1},2);
117smk=zeros(1,K+1);
118smk(1)=0;
119for i=1:K
120 smk(i+1)=smk(i)+size(alpha{i},2);
121end
122mser=smk(K+1);
123mtot=mser*m;
124
125% Test the load of the queue
126Dsum=D0;
127for i=1:K
128 Dsum=Dsum+D{i};
129end
130pi=stat(Dsum);
131lambdas=zeros(1,K);
132mus=zeros(1,K);
133for i=1:K
134 lambdas(i)=pi*D{i}*ones(m,1);
135 means(i)=sum(alpha{i}*(eye(size(alpha{i},2))-S{i})^(-1));
136end
137lambdas
138means
139lambdas.*means
140load=lambdas*means'
141if load >= 1
142 error('MATLAB:Q_DT_MMAPK_PHK_1:LoadExceedsOne',...
143 'The load %d of the system exceeds one',load);
144end
145
146% Construct building blocks
147L=zeros(m,mtot);
148Tser=zeros(mser,mser);
149tser=zeros(mser,1);
150
151for i=1:K
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);
155end
156
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)];
161
162B0=[zeros(m,m) L];
163B1=D0;
164B2=[D0; kron(tser,D0)];
165
166switch options.Mode
167 case 'CR'
168 [G,R]=QBD_CR(A2,A1,A0,options.OptQBD_CR{:});
169 case 'FI'
170 [G,R]=QBD_FI(A2,A1,A0,options.OptQBD_FI{:});
171 case 'LR'
172 [G,R]=QBD_LR(A2,A1,A0,options.OptQBD_LR{:});
173 case 'IS'
174 [G,R]=QBD_IS(A2,A1,A0,options.OptQBD_IS{:});
175 case 'NI'
176 [G,R]=QBD_NI(A2,A1,A0,options.OptQBD_NI{:});
177end
178pi=QBD_pi(B2,B1,R,'MaxNumComp',options.MaxNumComp,'Verbose', options.Verbose,'Boundary',[B0; A1+R*A2]);
179
180% remove additional states
181pi0=pi(1:m);
182pi=reshape(pi(m+1:end),mtot+m,size(pi(m+1:end),2)/(mtot+m));
183c=sum(sum(pi(1:m,:)));
184pi0=pi0/(1-c);
185pi=pi(m+1:end,:)/(1-c);
186
187% compute sojourn times per type
188piS=sum(reshape(pi,m,size(pi,2)*mser),1);
189piS=reshape(piS,mser,size(piS,2)/mser);
190for k=1:K
191 soj{k}=zeros(1,size(piS,2)+1);
192end
193for i=1:size(pi,2)
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);
196 end
197end
198for k=1:K
199 soj{k}=soj{k}/lambdas(k);
200end
201
202% compute overall sojourn time
203sojT=zeros(size(soj{1}));
204for i=1:K
205 sojT=sojT+lambdas(i)*soj{i};
206end
207sojT=sojT/sum(lambdas);
208
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);
214for k=1:K
215 temp=sum(D{k},2);
216 for i=1:maxwait+1
217 Dmatse((i-1)*m+1:i*m,k)=temp;
218 temp=D0*temp;
219 end
220end
221for k=1:K
222 wait{k}=zeros(1,maxwait+1);
223 for n=1:maxwait
224 wait{k}(n+1)=piW(n*m+1:(maxwait+1)*m)*...
225 Dmatse(1:m*(maxwait+1-n),k);
226 end
227 wait{k}=wait{k}/lambdas(k);
228 wait{k}(1)=1-sum(wait{k});
229end
230
231% old waiting time -> sometimes unstable
232% for i=1:K
233% temp=alpha{i};
234% prob=0;
235% sprob=prob;
236% j=1;
237% while (sprob < 1-10^(-10))
238% j=j+1;
239% prob(j)=temp*tser(smk(i)+1:smk(i+1));
240% temp=temp*S{i};
241% sprob=sprob+prob(j);
242% end
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);
246% end
247
248% compute overall waiting time
249waitT=zeros(size(wait{1}));
250for i=1:K
251 waitT(1,1:size(wait{i},2))=waitT(1,1:size(wait{i},2))+lambdas(i)*wait{i};
252end
253waitT=waitT/sum(lambdas);
254
255% compute queue length per type
256piTA=zeros(m*K,size(pi,2));
257for k=1:K
258 for j=1:m
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
261 end
262end
263piA=zeros(m,size(pi,2));
264for j=1:m
265 piA(j,:)=sum(piTA(j:m:end,:),1);
266end
267Dtemps=zeros(m,size(pi,2));
268for k=1:K
269 piAk=piA-piTA(m*(k-1)+1:m*k,:); % no type k in service
270 ql{k}=zeros(1,size(pi,2)+1);
271 ql{k}(1)=sum(pi0);
272 Dnok=Dsum-D{k};
273 Dtemps(:,1)=ones(m,1);
274 for i=1:size(pi,2)
275 % no type k in service
276 ql{k}(1:i)=ql{k}(1:i)+piAk(:,i)'*Dtemps(:,1:i);
277 % type k in service
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)];
281 end
282 ql{k}=ql{k}(1:max(find(ql{k}>10^(-10))));
283end
284
285% compute overall queue length
286Dtemps=zeros(m,size(pi,2));
287Dtemps(:,1)=ones(m,1);
288qlT=zeros(size(pi,2)+1);
289qlT(1)=sum(pi0);
290D1=Dsum-D0;
291for i=1:size(pi,2)
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)];
296end
297qlT=qlT(1:max(find(qlT>10^(-10))));