162 const std::size_t I =
sn.nodes.size(), C =
sn.nchains, M =
sn.nstations, R =
sn.nclasses;
164 if (TN.
rows() == 0 || AN.
rows() == 0)
return ANn;
166 for (std::size_t ist = 0; ist < M; ++ist) {
167 const std::size_t ind =
sn.station_to_node[ist];
168 if (ind == 0)
continue;
169 for (std::size_t r = 0; r < R; ++r) ANn(ind - 1, r) = AN(ist, r);
171 for (std::size_t ind = 1; ind <= I; ++ind) {
172 if (
sn.nodes[ind - 1].nodetype == qn::NodeType::Source)
continue;
173 const bool is_cache =
sn.nodes[ind - 1].nodetype == qn::NodeType::Cache;
174 const bool is_station =
sn.nodes[ind - 1].station != 0;
175 for (std::size_t c = 0; c < C; ++c) {
176 const std::vector<std::size_t>& inchain =
sn.inchain[c];
177 const std::size_t refstat = detail::sn_chain_refstat(
sn, c);
178 const T den = detail::sn_chain_refvisits(
sn, c, refstat, inchain);
179 if (!(den > zero))
continue;
180 const T tot = detail::sn_chain_tput(
sn, TN, c, refstat, inchain);
181 for (std::size_t r : inchain) {
183 typename std::map<std::size_t, qn::CacheParam<T>>::const_iterator it =
184 sn.nodeparam.find(ind);
185 if (it !=
sn.nodeparam.end() &&
186 detail::sn_is_cache_class(it->second.hitclass, it->second.missclass, r))
188 }
else if (is_station) {
191 ANn(ind - 1, r - 1) = T(
sn.nodevisits[c](ind - 1, r - 1) / den * tot);
215 const std::size_t I =
sn.nodes.size(), C =
sn.nchains, M =
sn.nstations, R =
sn.nclasses;
217 if (TN.
rows() == 0)
return TNn;
220 for (std::size_t ind = 1; ind <= I; ++ind) {
221 if (
sn.nodes[ind - 1].nodetype != qn::NodeType::Cache)
continue;
222 typename std::map<std::size_t, qn::CacheParam<T>>::const_iterator np =
223 sn.nodeparam.find(ind);
224 if (np ==
sn.nodeparam.end())
continue;
225 const std::vector<std::size_t>& hitclass = np->second.hitclass;
226 const std::vector<std::size_t>& missclass = np->second.missclass;
227 typename std::map<std::size_t, CacheActualProb<T>>::const_iterator cp =
228 cache_prob.find(ind);
229 const bool have_actual = cp != cache_prob.end() && !cp->second.hit.empty();
230 for (std::size_t c = 0; c < C; ++c) {
231 const std::vector<std::size_t>& inchain =
sn.inchain[c];
232 const std::size_t refstat = detail::sn_chain_refstat(
sn, c);
233 const T tot = detail::sn_chain_tput(
sn, TN, c, refstat, inchain);
234 for (std::size_t r : inchain) {
236 for (std::size_t o = 0; o < hitclass.size(); ++o) {
238 if (ANn.
rows() == I && o < R) {
239 arv = ANn(ind - 1, o);
242 for (std::size_t q : inchain)
243 if (q == o + 1) in =
true;
244 if (in && refstat >= 1 && refstat <= M) arv = TN(refstat - 1, o);
252 if (hitclass[o] == r && o < cp->second.hit.size() &&
253 !detail::sn_prob_is_nan(cp->second.hit[o])) {
254 T p = cp->second.hit[o];
255 if (o < cp->second.delayed_hit.size() &&
256 !detail::sn_prob_is_nan(cp->second.delayed_hit[o]))
257 p = T(p + cp->second.delayed_hit[o]);
258 TNn(ind - 1, r - 1) = T(TNn(ind - 1, r - 1) + arv * p);
259 }
else if (o < missclass.size() && missclass[o] == r &&
260 o < cp->second.miss.size() &&
261 !detail::sn_prob_is_nan(cp->second.miss[o])) {
262 TNn(ind - 1, r - 1) = T(TNn(ind - 1, r - 1) + arv * cp->second.miss[o]);
265 }
else if (detail::sn_is_cache_class(hitclass, missclass, r)) {
266 const T den = detail::sn_chain_refvisits(
sn, c, refstat, inchain);
268 TNn(ind - 1, r - 1) =
269 T(
sn.nodevisits[c](ind - 1, r - 1) / den * tot);
276 for (std::size_t ist = 0; ist < M; ++ist) {
277 const std::size_t ind =
sn.station_to_node[ist];
278 if (ind == 0)
continue;
279 for (std::size_t r = 0; r < R; ++r) TNn(ind - 1, r) = TN(ist, r);
283 if (ANn.
rows() != I ||
sn.rtnodes.rows() != I * R)
return TNn;
284 for (std::size_t ind = 1; ind <= I; ++ind) {
286 if (nt == qn::NodeType::Sink)
continue;
287 if (nt == qn::NodeType::Source) {
288 const std::size_t ist =
sn.nodes[ind - 1].station;
290 for (std::size_t s = 0; s < R; ++s) TNn(ind - 1, s) = TN(ist - 1, s);
296 if (nt != qn::NodeType::Join &&
sn.nodes[ind - 1].station != 0)
continue;
297 for (std::size_t c = 0; c < C; ++c) {
298 const std::vector<std::size_t>& inchain =
sn.inchain[c];
299 for (std::size_t r : inchain) {
300 bool anystateful =
false;
301 if (c <
sn.visits.size())
302 for (std::size_t a = 0; a <
sn.visits[c].rows(); ++a)
303 if (
sn.visits[c](a, r - 1) != zero) anystateful =
true;
304 if (!anystateful)
continue;
305 for (std::size_t s : inchain)
306 for (std::size_t jnd = 1; jnd <= I; ++jnd) {
307 if (nt == qn::NodeType::Cache && ind == jnd)
continue;
308 TNn(ind - 1, s - 1) =
309 T(TNn(ind - 1, s - 1) +
310 ANn(ind - 1, r - 1) *
311 sn.rtnodes((ind - 1) * R + (r - 1), (jnd - 1) * R + (s - 1)));
Matrix< T > sn_get_node_tput_from_tput(const qn::NetworkStruct< T > &sn, const Matrix< T > &TN, const Matrix< T > &ANn, const std::map< std::size_t, CacheActualProb< T > > &cache_prob=std::map< std::size_t, CacheActualProb< T > >())
Port of sn_get_node_tput_from_tput.