82 for (std::size_t c = 1; c <=
lqn.ncalls; ++c)
83 if (
lqn.calltype[c] == CallType::FWD) any_fwd =
true;
89 const std::size_t ncalls0 =
lqn.ncalls;
91 for (std::size_t cidx = 1; cidx <= ncalls0; ++cidx) {
92 if (
lqn.calltype[cidx] != CallType::SYNC)
continue;
93 const std::size_t aidx =
lqn.callpair_src[cidx];
94 const std::size_t tidx =
lqn.parent[aidx];
95 const T base_mean =
lqn.callproc_mean[cidx];
96 if (base_mean <= zero)
continue;
100 std::vector<std::size_t> frontier{
lqn.callpair_dst[cidx]};
101 std::vector<T> probs{one};
102 std::vector<std::size_t> visited;
103 auto seen = [](
const std::vector<std::size_t>& v, std::size_t x) {
104 for (std::size_t e : v)
105 if (e == x)
return true;
109 while (!frontier.empty()) {
110 const std::size_t eidx = frontier.front();
111 const T p_path = probs.front();
112 frontier.erase(frontier.begin());
113 probs.erase(probs.begin());
114 if (seen(visited, eidx))
continue;
115 visited.push_back(eidx);
117 for (std::size_t fcidx = 1; fcidx <= ncalls0; ++fcidx) {
118 if (
lqn.calltype[fcidx] != CallType::FWD)
continue;
119 if (
lqn.callpair_src[fcidx] != eidx)
continue;
120 const T fprob =
lqn.callproc_mean[fcidx];
121 const std::size_t tgt =
lqn.callpair_dst[fcidx];
122 const T pseudo_mean = T(base_mean * p_path * fprob);
126 if (pseudo_mean > zero &&
lqn.parent[tgt] != tidx) {
128 std::size_t mrow = 0;
129 for (std::size_t scan = 1; scan <=
lqn.ncalls; ++scan)
130 if (
lqn.calltype[scan] == CallType::SYNC &&
131 lqn.callpair_src[scan] == aidx &&
lqn.callpair_dst[scan] == tgt) {
138 lqn.callproc_mean[mrow] = T(
lqn.callproc_mean[mrow] + pseudo_mean);
140 const std::size_t ncall =
lqn.ncalls + 1;
142 const std::size_t target_tidx =
lqn.parent[tgt];
143 lqn.calltype.push_back(CallType::SYNC);
144 lqn.callpair_src.push_back(aidx);
145 lqn.callpair_dst.push_back(tgt);
146 lqn.callproc_mean.push_back(pseudo_mean);
147 lqn.callnames.push_back(
lqn.names[aidx] +
"=>" +
lqn.names[tgt]);
148 lqn.callhashnames.push_back(
lqn.hashnames[aidx] +
"=>" +
150 lqn.callsof[aidx].push_back(ncall);
151 lqn.iscaller.set(tidx, target_tidx);
152 lqn.iscaller.set(aidx, target_tidx);
153 lqn.iscaller.set(tidx, tgt);
154 lqn.iscaller.set(aidx, tgt);
155 lqn.issynccaller.set(tidx, target_tidx);
156 lqn.issynccaller.set(aidx, target_tidx);
157 lqn.issynccaller.set(tidx, tgt);
158 lqn.issynccaller.set(aidx, tgt);
159 lqn.graph.set(aidx, tgt, one);
160 lqn.taskgraph.set(tidx, target_tidx, one);
164 if (!seen(visited, tgt) && !seen(frontier, tgt)) {
165 frontier.push_back(tgt);
166 probs.push_back(T(p_path * fprob));
194 const T& y_ik,
const T& t_k, T& a, T& b, T& c, T& d) {
267 const std::vector<T>& y_aj) {
271 if (clientPhases.
rows() < 1 || clientPhases.
cols() < 5)
273 "lqn_overtake_markov: clientPhases must have five columns "
274 "[nSlices service y_ij y_ik t_k] and one row per client phase 0..maxPhaseA");
275 const std::size_t nStates = clientPhases.
rows();
276 const std::size_t maxPhaseA = nStates - 1;
277 if (y_aj.size() < nStates)
279 "lqn_overtake_markov: y_aj must hold the total call count and one entry per client "
284 std::vector<T> a(nStates, zero), b(nStates, zero), c(nStates, zero), d(nStates, zero);
285 for (std::size_t p = 0; p < nStates; ++p) {
286 const T prA = (p == maxPhaseA) ? prVisit : one;
287 detail::ln_set_rates(xj, prA, clientPhases(p, 0), clientPhases(p, 1), clientPhases(p, 2),
288 clientPhases(p, 3), clientPhases(p, 4), a[p], b[p], c[p], d[p]);
301 auto prod_of_b = [&](std::size_t k) {
return T(b[k] / (one - d[k])); };
302 Matrix<T> over(nStates, nStates, zero), next(nStates, nStates, zero);
303 for (std::size_t i0 = 0; i0 < nStates; ++i0) {
305 for (std::size_t r0 = 0; r0 < nStates; ++r0)
306 if (r0 != i0) temp = T(temp * prod_of_b(r0));
307 T product = T(one / (one - (b[i0] * temp + d[i0])));
310 over(i0, r0) = T(c[i0] * product);
311 next(i0, r0) = T(a[i0] * product);
312 r0 = (r0 == 0) ? maxPhaseA : r0 - 1;
313 product = T(product * prod_of_b(r0));
321 std::vector<T> nextProb(nStates, zero);
322 if (maxPhaseA >= 1) nextProb[maxPhaseA] = one;
325 for (std::size_t i = 1; i <= maxPhaseA; ++i) {
326 if (clientPhases(i, 2) == zero)
continue;
328 for (std::size_t r = 1; r <= maxPhaseA; ++r) acc = T(acc + nextProb[r] * over(i, r));
330 prOt = T(prOt + acc * (y_aj[0] / y_aj[i]));
T lqn_overtake_markov(const Matrix< T > &clientPhases, const T &prVisit, const T &xj, const std::vector< T > &y_aj)
Overtaking probability from the LQNS phased-server Markov chain.
LnInterlockChoice ln_interlock_method(const LqnStruct< T > &lqn, const std::string &requested, bool interlocking, const std::string &lnmethod)
Port of matlab/src/solvers/LN/ln_interlock_method.m, asked as a query.