LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
pfqn_comom.m
1%{
2%{
3 % @file pfqn_comom.m
4 % @brief CoMoM algorithm for computing the normalizing constant.
5%}
6%}
7
8function lG=pfqn_comom(L,N,Z,atol)
9%{
10%{
11 % @brief CoMoM algorithm for computing the normalizing constant.
12 % @fn pfqn_comom(L, N, Z, atol)
13 % @param L Service demand matrix.
14 % @param N Population vector.
15 % @param Z Think time vector.
16 % @param atol Tolerance.
17 % @return lG Logarithm of the normalizing constant.
18%}
19%}
20if nargin<3
21 Z=0*N;
22end
23[M,R]=size(L);
24if M>1
25 line_error(mfilename,'pfqn_comom supports at most one queueing station (repairman models with a delay); use pfqn_ca or pfqn_recal for M>1.');
26end
27% rescale demands
28Lmax = L; % use L
29Lmax(Lmax<atol)=Z(Lmax<atol); % unless zero
30Lmax = max(Lmax,[],1);
31L = L./repmat(Lmax,M,1);
32Z = Z./repmat(Lmax,M,1);
33% sort from smallest to largest
34%[~,rsort] = sort(Z,'ascend');
35%L=L(:,rsort);
36%Z=Z(:,rsort);
37% prepare comom data structures
38Dn=multichoose(R,M);
39Dn(:,R)=0;
40Dn=sortbynnzpos(Dn);
41% initialize
42nvec=zeros(1,R);
43h=ginit(L);
44lh=log(h) + factln(sum(nvec)+M-1) - sum(factln(nvec));
45h=exp(lh);
46scale=zeros(1,sum(N));
47matrixDim = nchoosek(M+R-1,M)*(M+1);
48A = zeros(matrixDim);
49B = zeros(matrixDim);
50DA = zeros(matrixDim);
51% iterate
52for r=1:R
53 for Nr=1:N(r)
54 nvec(r)=nvec(r)+1;
55 if Nr==1
56 [A,B,DA]=genmatrix(L,nvec,Z,r);
57 else
58 A=A+DA;
59 end
60 b = B*h*nvec(r)/(sum(nvec)+M-1);
61 h = A\b;
62 nt=sum(nvec);
63 scale(nt)=abs(sum(sort(h)));
64 h = abs(h)/scale(nt); % rescale so that |h|=1
65 end
66end
67% unscale and return the log of the normalizing constant
68lG=log(h(end-(R-1))) + factln(sum(N)+M-1) - sum(factln(N)) + N*log(Lmax)' + sum(log(scale));
69
70 function [A,B,DA]=genmatrix(L,N,Z,r)
71 [M,R]=size(L);
72 A=zeros(nchoosek(M+R-1,M)*(M+1));
73 DA=zeros(nchoosek(M+R-1,M)*(M+1));
74 B=zeros(nchoosek(M+R-1,M)*(M+1));
75 row=0;
76 lastnnz=0;
77 for d=1:length(Dn)
78 hnnz=hashnnz(Dn(d,:),R);
79 if hnnz~=lastnnz
80 lastnnz=hnnz;
81 end
82 end
83 for d=1:length(Dn)
84 if sum(Dn(d,(r):R-1))>0
85 % dummy rows for unused norm consts
86 for k=0:M
87 row=row+1;
88 col = hash(N,N-Dn(d,:),k+1);
89 A(row,col)=1;
90 if sum(Dn(d,(r+1):R-1))>0
91 col = hash(N,N-Dn(d,:),k+1);
92 B(row,col)=1;
93 else
94 er=zeros(1,R); er(r)=1;
95 col = hash(N,N-Dn(d,:)+er,k+1);
96 B(row,col)=1;
97 end
98 end
99 else
100 if sum(Dn(d,1:r))<M
101 for k=1:M
102 % add CE
103 row=row+1;
104 A(row,hash(N,N-Dn(d,:),k+1))=1;
105 A(row,hash(N,N-Dn(d,:),0+1))=-1;
106 for s=1:r-1
107 A(row,hash(N,oner(N-Dn(d,:),s),k+1))=-L(k,s);
108 end
109 B(row,hash(N,N-Dn(d,:),k+1))=L(k,r);
110 end
111 for s=1:(r-1)
112 % add PC to A
113 row=row+1;
114 n=N-Dn(d,:);
115 A(row,hash(N,n,0+1))=n(s);
116 A(row,hash(N,oner(n,s),0+1))=-Z(s);
117 for k=1:M
118 A(row,hash(N,oner(n,s),k+1))=-L(k,s);
119 end
120 B(row,:)=0;
121 end
122 end
123 end
124 end
125 %add PC of class R
126 for d=1:length(Dn)
127 if sum(Dn(d,(r):R-1))<=0
128 row=row+1;
129 n=N-Dn(d,:);
130 A(row,hash(N,n,0+1))=n(r);
131 DA(row,hash(N,n,0+1))=1;
132 B(row,hash(N,n,0+1))=Z(r);
133 for k=1:M
134 B(row,hash(N,n,k+1))=L(k,r);
135 end
136 end
137 end
138 end
139
140 function val=hashnnz(dn,R)
141 val=0;
142 for t=1:R
143 if dn(t)==0
144 val=val+2^(t-1);
145 end
146 end
147 end
148
149 function col=hash(N,n,i)
150 if i==1
151 col=size(Dn,1)*M+matchrow(Dn,N-n);
152 else
153 col=(matchrow(Dn,N-n)-1)*M+i-1;
154 end
155 end
156
157 function g=ginit(L)
158 e1=zeros(1,R);
159 g=zeros(size(Dn,1)*(M+1),1);
160 for i=0:M
161 g(hash(N,N,i+1))=1;
162 end
163 g=g(:);
164 end
165
166 function I=sortbynnzpos(I)
167 % sorts a set of combinations with repetition according to the number of
168 % nonzeros
169 for i=1:size(I,1)-1
170 for j=i+1:size(I,1)
171 if nnzcmp(I(i,:),I(j,:))==1
172 v=I(i,:);
173 I(i,:)=I(j,:);
174 I(j,:)=v;
175 end
176 end
177 end
178 end
179
180 function r=nnzcmp(i1,i2) % return 1 if i1<i2
181 nnz1=nnz(i1);
182 nnz2=nnz(i2);
183 if(nnz1>nnz2)
184 r=1; % i2 has more zeros and is thus greater
185 elseif(nnz1<nnz2)
186 r=0; % i1 has more zeros and is thus greater
187 else %nnz1==nnz2
188 for j=1:length(i1)
189 if i1(j)==0 & i2(j)>0
190 r=1; % i2 has the left-most zero
191 return
192 elseif i1(j)>0 & i2(j)==0
193 r=0;
194 return
195 end
196 end
197 r=0;
198 end
199 end
200
201end
Definition Station.m:245