4 % @brief Convolution Algorithm
for exact normalizing constant computation.
8function [Gn,lGn]=pfqn_ca(L,N,Z)
11 % @brief Convolution Algorithm
for exact normalizing constant computation.
12 % @fn pfqn_ca(L, N, Z)
13 % @param L Service demand matrix.
14 % @param N Population vector.
15 % @param Z Think time vector.
16 % @
return Gn Normalizing constant.
17 % @
return lGn Logarithm of the normalizing constant.
21if nargin<3 || isempty(Z)
25 lGn = - sum(factln(N)) + sum(N.*log(sum(Z,1)));
42% see _kb/03-api-layer.md (pfqn/ family: scaling, log-domain switches, dispatch gates)
50 t = t + N(r)*log(L(i,r));
56 if ok, lGest = max(lGest, t); end
58if any(Z > 0) % all jobs at the delay
63 t = t + N(r)*log(sum(Z(:,r))) - factln(N(r));
69 if ok, lGest = max(lGest, t); end
74 kscale = round(lGest/(Nt*log(2)));
80G = ones(M+1,prod(N+1)); % stores G across recursion
86 G(m,idxn) = G(m-1,idxn); % norm constant with m-1 queues
90 idxn_1r = hashpop(n,N);
92 G(m,idxn) = G(m,idxn) + L(m-1,r)*G(m,idxn_1r);
98% Undo the scaling in log space: log G = log G_scaled + sum(N) log c. lGn
is
99% therefore finite whenever log G itself
is, even though Gn may legitimately
100% overflow to Inf (the
true constant really
is outside
double range).
101lGn = log(G(M+1,end)) + sum(N)*kscale*log(2);
102% see _kb/03-api-layer.md (pfqn/ family: scaling, log-domain switches, dispatch gates)
103Gn = pow2(G(M+1,end), sum(N)*kscale);
106function idx=hashpop(n,N,R,prods)
107% IDX=HASHPOP(N,N,R,PRODS)
109% hash a population vector in n: 0<=n<=N
114 idx= idx + prod(N(1:r-1)+1)*n(r);
119 idx= idx + prods(r)*n(r);
124function [n]=pprod(n,N)
127% sequentially generate all vectors n: 0<=n<=N
129% n=pprod(n,N) - next state
143while s>0 && n(s)==N(s)