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);
62CN=zeros(M,R);
63if InfServ==1
64 Z=Z(:)';
65else
66 Z=zeros(1,R);
67end
68
69prods=zeros(1,R-1); % generate population indices
70for w=1:R-1
71 prods(1,w) = prod(ones(1,R-(w+1)+1)+N(1,w+1:R));
72end
73
74firstnonempty=R;
75while (N(firstnonempty)==0)
76 firstnonempty = firstnonempty-1;
77end
78
79totpop=prod(N+1);
80ctr=totpop;
81Q=zeros(totpop,M);
82currentpop=2;
83
84n=zeros(1,R);
85n(1,firstnonempty)=1;
86while ctr % for each population
87 s=1;
88 while s <= R
89 pos_n_1s=0;
90 if n(s)>0
91 n(s) = n(s)-1;
92 pos_n_1s= n(R);
93 w=1;
94 while w <= R-1
95 pos_n_1s = pos_n_1s + n(w)*prods(w);
96 w=w+1;
97 end % while w <= R-1
98 n(s) = n(s)+1;
99 end % if
100 CNtot=0;
101 i=1;
102 while i <= M
103 Lis=L(i,s);
104 CN(i,s)=Lis*(mi(i)+Q(1+pos_n_1s,i));
105 CNtot=CNtot+CN(i,s);
106 i=i+1;
107 end % while i <= M
108 XN(s)=n(s)/(Z(s)+CNtot);
109 i=1;
110 while i <= M
111 QN(i,s)=XN(s)*CN(i,s);
112 Q(currentpop,i)=Q(currentpop,i)+QN(i,s);
113 i=i+1;
114 end % while i <= M
115 s=s+1;
116 end % while s <= R
117 s=R;
118 while s>0 && (n(1,s)==N(s)) || s>firstnonempty
119 s=s-1;
120 end
121 % now compute the normalizing constant
122 last_nnz = find(n>0, 1, 'last' );
123 if sum(n(1:last_nnz-1)) == sum(N(1:last_nnz-1)) && sum(n((last_nnz+1):R))==0
124 logX = log(XN(last_nnz));
125 lGN = lGN - logX;
126 end
127 if s==0
128 break;
129 end
130 n(s)=n(s)+1;
131 s=s+1;
132 while s<=R
133 n(s)=0;
134 s=s+1;
135 end
136 ctr=ctr-1;
137 currentpop=currentpop+1;
138end
139for m=1:M
140 for r=1:R
141 UN(m,r)=XN(r)*L(m,r);
142 end
143end
144
145% Expand results back to original dimensions if stations were consolidated
146if M < M_original
147 [QN, UN, CN] = pfqn_expand(QN, UN, CN, mapping, M_original);
148end
149end