87 "solver_nc_retrieval_analyzer: the delayed-hit recurrences form a normalizing "
88 "constant in logarithms and need transcendental arithmetic");
93 const std::size_t K =
sn.nclasses, M =
sn.nstations;
96 const std::size_t n = in.
lambda.size();
97 const std::size_t h = in.
m.size();
113 bool useray = (
opt.method ==
"rayint" ||
opt.method ==
"ray");
117 for (std::size_t i = 0; i < n && !has_ps; ++i)
118 for (std::size_t sc = 1; sc <= r; ++sc)
121 for (std::size_t j = 0; j < h; ++j) msum_chk += in.
m[j];
123 reason =
"the retrieval system has a queueing (non infinite-server) fetch station";
124 else if (msum_chk >=
static_cast<long>(n))
125 reason =
"the cache is full (sum(m) >= n), where the saddle point escapes to infinity";
126 if (!reason.empty()) {
127 const std::string w =
"SolverNC: method 'rayint' does not apply because " + reason +
128 "; falling back to the exact recurrences.";
129 out.
sol.warning = out.
sol.warning.empty() ? w : out.
sol.warning +
" " + w;
139 for (std::size_t i = 0; i < n; ++i) {
140 D[i] = one + in.
lambda[i] * in.
eta(i, 0);
141 for (std::size_t j = 0; j < h; ++j) theta(i, j) = in.
gamma(i, j) / D[i];
153 mt.
pmiss.assign(n, zero);
156 for (std::size_t i = 0; i < n; ++i) {
158 for (std::size_t j = 0; j < h; ++j) den += theta(i, j) * ray.
xi[j];
160 for (std::size_t j = 0; j < h; ++j) {
161 mt.
phit(j, i) = theta(i, j) * ray.
xi[j] / den;
162 pihit += mt.
phit(j, i);
164 mt.
pmiss[i] = (one - pihit) / D[i];
178 std::vector<T> pih(n, zero), phid(n, zero);
179 for (std::size_t i = 0; i < n; ++i) {
180 for (std::size_t j = 0; j < mt.
phit.rows(); ++j) pih[i] += mt.
phit(j, i);
181 for (std::size_t s = 0; s < mt.
pdh.rows(); ++s) phid[i] += mt.
pdh(s, i);
186 for (
const T& v : in.
lambda) lamtot += v;
187 std::vector<T> w(n, zero);
188 for (std::size_t i = 0; i < n; ++i) w[i] = lamtot > zero ? T(in.
lambda[i] / lamtot) : zero;
190 T hitAgg = zero, missAgg = zero, delayedAgg = zero;
191 for (std::size_t i = 0; i < n; ++i) {
192 hitAgg += T(w[i] * pih[i]);
193 missAgg += T(w[i] * mt.
pmiss[i]);
194 delayedAgg += T(w[i] * phid[i]);
198 std::size_t sourceStation = 0;
201 if (sourceStation == 0)
203 "solver_nc_retrieval_analyzer: the OPEN delayed-hit analyzer needs a Source node; "
204 "a closed integrated model is solved by solver_nc_cacheqn_retrieval_analyzer");
205 std::vector<T> sourceRate(K, zero);
206 for (std::size_t k = 0; k < K; ++k)
207 if (!
sn.disabled[sourceStation - 1][k]) sourceRate[k] =
sn.rates(sourceStation - 1, k);
213 out.
sol.sol.X.assign(K, zero);
214 out.
sol.sol.C.assign(K, zero);
215 for (std::size_t k = 0; k < K; ++k) out.
sol.sol.Tp(sourceStation - 1, k) = sourceRate[k];
226 for (std::size_t j = 0; j < h && j < mt.
phit.rows(); ++j) {
228 for (std::size_t i = 0; i < n; ++i) acc += T(mt.
phit(j, i) * w[i]);
233 for (std::size_t i = 0; i < n; ++i) {
235 for (std::size_t j = 0; j < h && j < mt.
phit.rows(); ++j)
241 std::size_t cacheNode = 0;
242 for (std::size_t i = 0; i <
sn.nodes.size(); ++i)
243 if (
sn.nodes[i].nodetype == qn::NodeType::Cache) cacheNode = i + 1;
244 if (cacheNode == 0)
throw UnsupportedError(
"solver_nc_retrieval_analyzer: no Cache node");
248 T(sourceRate[rc - 1] * (hitAgg + delayedAgg));
250 out.
sol.sol.X[ch.
missclass[rc - 1] - 1] = T(sourceRate[rc - 1] * missAgg);
255 std::vector<std::size_t> psRow(S, 0);
257 std::size_t seen = 0;
258 for (std::size_t s = 0; s < S; ++s)
264 for (std::size_t s = 0; s < S; ++s) {
266 const std::size_t ist =
sn.nodes[nd - 1].station;
267 if (ist == 0)
continue;
269 if (psRow[s] < mt.
pdh.rows())
270 for (std::size_t i = 0; i < n; ++i) phi_s += mt.
pdh(psRow[s], i);
274 for (std::size_t i = 0; i < n; ++i) {
276 std::vector<T> a(S, zero);
278 for (std::size_t x = 0; x < S; ++x) {
280 for (std::size_t y = 0; y < S; ++y) Pm(x, y) = Ri(x + 1, y + 1);
283 for (std::size_t x = 0; x < S; ++x) {
284 for (std::size_t y = 0; y < S; ++y) A(y, x) = T(-Pm(x, y));
285 A(x, x) = T(A(x, x) + one);
287 const std::vector<T> vis =
solve(A, a);
288 tput_s += T(sourceRate[rc - 1] * w[i] * mt.
pmiss[i] * vis[s]);
290 out.
sol.sol.Q(ist - 1, rc - 1) = phi_s;
291 out.
sol.sol.U(ist - 1, rc - 1) = phi_s;
292 out.
sol.sol.Tp(ist - 1, rc - 1) = tput_s;
293 if (tput_s > zero) out.
sol.sol.R(ist - 1, rc - 1) = T(phi_s / tput_s);
296 out.
sol.sol.iter = 1;
297 out.
sol.sol.method = useray ?
"rayint" :
"exact";
298 out.
sol.actualmethod = useray ?
"rayint" :
"exact";