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