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% Detect and consolidate replicated stations
46[L, ~, ~, mi_unique, mapping] = pfqn_unique(L);
47[M,~] = size(L);
48
49% Combine user-provided mi with detected multiplicity
50% For each unique station j, sum the mi values of all original stations mapping to it
51mi_combined = zeros(1, M);
52for i = 1:M_original
53 mi_combined(mapping(i)) = mi_combined(mapping(i)) + mi(i);
54end
55mi = mi_combined;
56if (~any(N>0))
57 %line_warning(mfilename,'closed populations are empty');
58 return
59end
60NR=length(N);
61if (R~=NR)
62 line_error(mfilename,'demand matrix and population vector have different number of classes');
63end
64
65XN=zeros(1,R);
66QN=zeros(M,R);
67CN=zeros(M,R);
68if InfServ==1
69 Z=Z(:)';
70else
71 Z=zeros(1,R);
72end
73
74prods=zeros(1,R-1); % generate population indices
75for w=1:R-1
76 prods(1,w) = prod(ones(1,R-(w+1)+1)+N(1,w+1:R));
77end
78
79firstnonempty=R;
80while (N(firstnonempty)==0)
81 firstnonempty = firstnonempty-1;
82end
83
84totpop=prod(N+1);
85ctr=totpop;
86Q=zeros(totpop,M);
87currentpop=2;
88
89n=zeros(1,R);
90n(1,firstnonempty)=1;
91while ctr % for each population
92 s=1;
93 while s <= R
94 pos_n_1s=0;
95 if n(s)>0
96 n(s) = n(s)-1;
97 pos_n_1s= n(R);
98 w=1;
99 while w <= R-1
100 pos_n_1s = pos_n_1s + n(w)*prods(w);
101 w=w+1;
102 end % while w <= R-1
103 n(s) = n(s)+1;
104 end % if
105 CNtot=0;
106 i=1;
107 while i <= M
108 Lis=L(i,s);
109 CN(i,s)=Lis*(mi(i)+Q(1+pos_n_1s,i));
110 CNtot=CNtot+CN(i,s);
111 i=i+1;
112 end % while i <= M
113 XN(s)=n(s)/(Z(s)+CNtot);
114 i=1;
115 while i <= M
116 QN(i,s)=XN(s)*CN(i,s);
117 Q(currentpop,i)=Q(currentpop,i)+QN(i,s);
118 i=i+1;
119 end % while i <= M
120 s=s+1;
121 end % while s <= R
122 s=R;
123 while s>0 && (n(1,s)==N(s)) || s>firstnonempty
124 s=s-1;
125 end
126 % now compute the normalizing constant
127 last_nnz = find(n>0, 1, 'last' );
128 if sum(n(1:last_nnz-1)) == sum(N(1:last_nnz-1)) && sum(n((last_nnz+1):R))==0
129 logX = log(XN(last_nnz));
130 lGN = lGN - logX;
131 end
132 if s==0
133 break;
134 end
135 n(s)=n(s)+1;
136 s=s+1;
137 while s<=R
138 n(s)=0;
139 s=s+1;
140 end
141 ctr=ctr-1;
142 currentpop=currentpop+1;
143end
144for m=1:M
145 for r=1:R
146 UN(m,r)=XN(r)*L(m,r);
147 end
148end
149
150% Expand results back to original dimensions if stations were consolidated
151if M < M_original
152 [QN, UN, CN] = pfqn_expand(QN, UN, CN, mapping, M_original);
153end
154end