LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
pfqn_mvald.m
1%{
2%{
3 % @file pfqn_mvald.m
4 % @brief Exact MVA for load-dependent closed queueing networks.
5%}
6%}
7
8%{
9%{
10 % @brief Exact MVA for load-dependent closed queueing networks.
11 % @fn pfqn_mvald(L, N, Z, mu, stabilize)
12 % @param L Service demand matrix.
13 % @param N Population vector.
14 % @param Z Think time vector.
15 % @param mu Load-dependent rate matrix (MxNt).
16 % @param stabilize Force non-negative probabilities (default: true).
17 % @return XN System throughput.
18 % @return QN Mean queue lengths.
19 % @return UN Utilization.
20 % @return CN Cycle times.
21 % @return lGN Logarithm of normalizing constant evolution.
22 % @return isNumStable Numerical stability flag.
23 % @return pi Marginal queue-length probabilities.
24%}
25%}
26function [XN,QN,UN,CN,lGN,isNumStable,pi]=pfqn_mvald(L,N,Z,mu,stabilize)
27% [XN,QN,UN,CN,LGN]=PFQN_MVALD(L,N,Z,MU)
28
29[M,R]=size(L); % get number of queues (M) and classes (R)
30
31XN = zeros(M,R);
32QN = zeros(M,R);
33UN = zeros(M,R);
34CN = zeros(M,R);
35WN = zeros(M,R);
36lGN = -Inf;
37pi = zeros(M,1,1);
38
39if any(N<0)
40 isNumStable = true;
41 return
42end
43% stabilize ensures that probabilities do not become negative
44if nargin<5
45 stabilize = true;
46end
47
48warn = true;
49isNumStable = true;
50Xs=zeros(R,prod(N+1)); % throughput for a model with station i less
51pi=ones(M,sum(N)+1,prod(N+1)); % marginal queue-length probabilities pi(k)
52n=pprod(N); % initialize the current population
53numLGTerms = sum(N) + 1;
54lGN = zeros(1, numLGTerms);
55lgIdx = 1;
56while n~=-1
57 WN=0*WN;
58 for s=1:R
59 if n(s)>0
60 for ist=1:M
61 WN(ist,s)=0;
62 for k=1:sum(n)
63 WN(ist,s)=WN(ist,s)+(L(ist,s)/mu(ist,k))*k*pi(ist,(k-1)+1,hashpop(oner(n,s),N));
64 end
65 end
66 Xs(s,hashpop(n,N))=n(s)/(Z(s)+sum(WN(:,s)));
67 end
68 end
69
70 % compute pi(k|n)
71 for k=1:sum(n)
72 for ist=1:M
73 pi(ist,(k)+1,hashpop(n,N))=0;
74 end
75 for s=1:R
76 if n(s)>0
77 for ist=1:M
78 pi(ist,(k)+1,hashpop(n,N)) = pi(ist,(k)+1,hashpop(n,N)) + (L(ist,s)/mu(ist,k))*Xs(s,hashpop(n,N))*pi(ist,(k-1)+1,hashpop(oner(n,s),N));
79 end
80 end
81 end
82 end
83
84 % compute pi(0|n)
85 for ist=1:M
86 p0 = 1-sum(pi(ist,(1:sum(n))+1,hashpop(n,N)));
87 if p0<0
88 if warn
89 line_warning(mfilename,'MVA-LD is numerically unstable on this model, LINE will force all probabilities to be non-negative.\n');
90% N
91 warn=false;
92 isNumStable = false;
93 end
94 if stabilize
95 pi(ist,(0)+1,hashpop(n,N)) = eps;
96 else
97 pi(ist,(0)+1,hashpop(n,N)) = p0;
98 end
99 else
100 pi(ist,(0)+1,hashpop(n,N)) = p0;
101 end
102 end
103
104 last_nnz = last_nonzero_index(n);
105 if last_nnz > 0 && sum(n(1:last_nnz-1)) == sum(N(1:last_nnz-1)) && sum(n((last_nnz+1):R))==0
106 logX = log(Xs(last_nnz,hashpop(n,N)));
107 lgIdx = lgIdx + 1;
108 lGN(lgIdx) = lGN(lgIdx-1) - logX;
109 end
110
111 n=pprod(n,N); % get the next population
112end
113lGN = lGN(1:lgIdx);
114X=Xs(:,hashpop(N,N));
115XN=X';
116pi=pi(:,:,hashpop(N,N));
117QN = WN.*repmat(XN,M,1);
118%UN = repmat(XN,M,1) .* L;
119UN = 1-pi(:,1);
120CN = N./XN - Z; % cycle time exclusive of think time
121end
122
123function i=hashpop(n,N)
124% I=HASHPOP(N,N)
125
126i=1; % index of the empty population
127for r=1:length(N)
128 i=i+prod(N(1:r-1)+1)*n(r);
129end
130end
131
132function idx = last_nonzero_index(v)
133idx = 0;
134for i = length(v):-1:1
135 if v(i) ~= 0
136 idx = i;
137 return
138 end
139end
140end