LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
pfqn_mva.m
1%{
2%{
3 % @file pfqn_mva.m
4 % @brief Exact Mean Value Analysis (MVA) for product-form queueing networks.
5%}
6%}
7
8function [XN,QN,UN,CN,lGN] = pfqn_mva(L,N,Z,mi)
9%{
10%{
11 % @brief Exact Mean Value Analysis (MVA) for product-form queueing networks.
12 % @fn pfqn_mva(L, N, Z, mi)
13 % @param L Service demand matrix (M x R).
14 % @param N Population vector (1 x R).
15 % @param Z Think time vector (1 x R).
16 % @param mi (Optional) Server multiplicity vector (1 x M). Default: single servers.
17 % @return XN System throughput (1 x R).
18 % @return QN Mean queue length (M x R).
19 % @return UN Utilization (M x R).
20 % @return CN Residence time (M x R).
21 % @return lGN Logarithm of the normalizing constant.
22%}
23%}
24% [XN,QN,UN,CN,LGN] = PFQN_MVA(L,N,Z,MI)
25% [XN,QN,UN,CN] = pfqn_mva(L,N,Z,mi)
26XN=[];
27QN=[];
28UN=[];
29CN=[];
30lGN = 0;
31InfServ=1;
32if nargin == 2
33 InfServ=0;
34end
35N = ceil(N);
36[M_original,R]=size(L); % M stations, R classes
37N=N(:)';
38if nargin<4
39 mi=ones(1,M_original);
40end
41if nargin<3 || isempty(Z)
42 Z = zeros(1,R);
43end
44
45% Station consolidation disabled: pfqn_unique merges stations with identical
46% demand rows, but this is incorrect for tandem (serial) networks where distinct
47% stations happen to have the same service demand. The consolidation treats them
48% as replicated (parallel) copies, producing wrong queue lengths and response times.
49M = M_original;
50mapping = 1:M_original;
51if (~any(N>0))
52 %line_warning(mfilename,'closed populations are empty');
53 return
54end
55NR=length(N);
56if (R~=NR)
57 line_error(mfilename,'demand matrix and population vector have different number of classes');
58end
59
60XN=zeros(1,R);
61QN=zeros(M,R);
62UN=zeros(M,R);
63CN=zeros(M,R);
64if InfServ==1
65 Z=Z(:)';
66else
67 Z=zeros(1,R);
68end
69
70prods=zeros(1,R-1); % generate population indices
71for w=1:R-1
72 prods(1,w) = prod(ones(1,R-(w+1)+1)+N(1,w+1:R));
73end
74
75firstnonempty=R;
76while (N(firstnonempty)==0)
77 firstnonempty = firstnonempty-1;
78end
79
80totpop=prod(N+1);
81ctr=totpop;
82Q=zeros(totpop,M);
83currentpop=2;
84
85n=zeros(1,R);
86n(1,firstnonempty)=1;
87while ctr % for each population
88 s=1;
89 while s <= R
90 pos_n_1s=0;
91 if n(s)>0
92 n(s) = n(s)-1;
93 pos_n_1s= n(R);
94 w=1;
95 while w <= R-1
96 pos_n_1s = pos_n_1s + n(w)*prods(w);
97 w=w+1;
98 end % while w <= R-1
99 n(s) = n(s)+1;
100 end % if
101 CNtot=0;
102 i=1;
103 while i <= M
104 Lis=L(i,s);
105 CN(i,s)=Lis*(mi(i)+Q(1+pos_n_1s,i));
106 CNtot=CNtot+CN(i,s);
107 i=i+1;
108 end % while i <= M
109 XN(s)=n(s)/(Z(s)+CNtot);
110 i=1;
111 while i <= M
112 QN(i,s)=XN(s)*CN(i,s);
113 Q(currentpop,i)=Q(currentpop,i)+QN(i,s);
114 i=i+1;
115 end % while i <= M
116 s=s+1;
117 end % while s <= R
118 s=R;
119 while s>0 && (n(1,s)==N(s)) || s>firstnonempty
120 s=s-1;
121 end
122 % now compute the normalizing constant
123 last_nnz = last_nonzero_index(n);
124 if last_nnz > 0 && sum(n(1:last_nnz-1)) == sum(N(1:last_nnz-1)) && sum(n((last_nnz+1):R))==0
125 logX = log(XN(last_nnz));
126 lGN = lGN - logX;
127 end
128 if s==0
129 break;
130 end
131 n(s)=n(s)+1;
132 s=s+1;
133 while s<=R
134 n(s)=0;
135 s=s+1;
136 end
137 ctr=ctr-1;
138 currentpop=currentpop+1;
139end
140for m=1:M
141 for r=1:R
142 UN(m,r)=XN(r)*L(m,r);
143 end
144end
145
146% Expand results back to original dimensions if stations were consolidated
147if M < M_original
148 [QN, UN, CN] = pfqn_expand(QN, UN, CN, mapping, M_original);
149end
150end
151
152function idx = last_nonzero_index(v)
153idx = 0;
154for i = length(v):-1:1
155 if v(i) ~= 0
156 idx = i;
157 return
158 end
159end
160end