5#ifndef LINE_SOLVERS_NC_SOLVER_NC_RUNNER_H
6#define LINE_SOLVERS_NC_SOLVER_NC_RUNNER_H
90 return {
"default",
"exact",
"rayint",
"spm",
"erlangfp",
"mci",
"imci",
"ls",
"le",
91 "ble",
"aghq",
"mmint2",
"gleint",
"pana",
"panald",
"ca",
"clw",
"kt",
"bkt",
"lekt",
92 "bk",
"bkue",
"lc",
"lc.ue",
93 "sampling",
"is",
"propfair",
"comom",
"cub",
"rgf",
105 "nrl",
"nre",
"gm",
"mem",
"comomld",
"ms",
138 std::vector<std::string> toks;
139 for (
char ch : method) {
140 if (ch ==
'.' || ch ==
'/') {
144 tok +=
static_cast<char>(std::tolower(
static_cast<unsigned char>(ch)));
148 for (
const std::string& t : toks)
149 if (t ==
"mci" || t ==
"imci" || t ==
"ls" || t ==
"sampling" || t ==
"is" ||
172 if (method !=
"default")
return method;
174 for (std::size_t i = 0; i < L.
nstations; ++i)
175 for (std::size_t r = 0; r < L.
nclasses; ++r) {
186 if (std::find(valid.begin(), valid.end(), method) != valid.end())
return;
187 throw UnsupportedError(
"SolverNC: the '" + method +
"' method is unsupported by this solver");
215bool multiserver_to_lld(qn::NetworkStruct<T>& sn) {
217 for (
const qn::JobClass& c : sn.classes) {
218 if (std::isinf(c.population))
return false;
221 const std::size_t n =
static_cast<std::size_t
>(std::llround(Nt));
222 if (n < 1)
return false;
223 for (std::size_t i = 0; i < sn.nstations; ++i) {
224 std::vector<T> lld(n, num_traits<T>::from_int(1));
225 const double c = sn.stations[i].nservers;
226 if (std::isfinite(c) && c > 1.0)
227 for (std::size_t k = 1; k <= n; ++k)
229 num_traits<T>::from_double(std::min<double>(
static_cast<double>(k), c));
230 sn.stations[i].lldscaling = lld;
247inline std::string nc_multiserver_policy(
const std::string& requested,
248 std::string* warning =
nullptr) {
249 if (requested.empty() || requested ==
"default")
return "default";
250 if (requested ==
"seidmann")
return "seidmann";
251 if (requested ==
"lld" || requested ==
"exact" || requested ==
"loaddep" ||
252 requested ==
"load-dependent")
254 if (warning !=
nullptr)
255 *warning =
"SolverNC does not implement config.multiserver='" + requested +
256 "' (it is a SolverMVA approximation); using 'default'. SolverNC accepts "
257 "'default', 'seidmann' and 'lld'.";
266double nc_population_lattice(
const qn::NetworkStruct<T>& sn) {
267 double lattice = 1.0;
268 if (!sn.chains.empty()) {
270 for (std::size_t c = 0; c < sn.chains.size(); ++c) {
272 for (std::size_t r = 0; r < sn.nclasses && r < sn.chains[c].size(); ++r)
273 if (sn.chains[c][r]) {
274 const double v = sn.classes[r].population;
275 if (std::isfinite(v)) popc += v;
277 lattice *= (1.0 + popc);
280 for (
const qn::JobClass& c : sn.classes)
281 if (std::isfinite(c.population)) lattice *= (1.0 + c.population);
310 if (
sn.has_open_classes())
return true;
311 const std::size_t M =
sn.nstations, C =
sn.nchains;
312 const std::vector<double> Nchain = detail::chain_population(
sn);
314 for (std::size_t c = 0; c < C; ++c)
315 if (std::isfinite(Nchain[c])) NtD += Nchain[c];
316 const std::size_t Nt =
static_cast<std::size_t
>(std::llround(NtD));
317 if (Nt < 1)
return true;
321 std::vector<double> Ztot(C, 0.0);
322 for (std::size_t i = 0; i < M; ++i)
323 if (std::isinf(
sn.stations[i].nservers))
324 for (std::size_t c = 0; c < C; ++c)
326 for (std::size_t c = 0; c < C; ++c)
327 if (Nchain[c] > 0.0 && !(Ztot[c] > 0.0))
330 for (std::size_t i = 0; i < M; ++i) {
331 const double nserv =
sn.stations[i].nservers;
332 if (std::isinf(nserv))
continue;
333 const std::vector<T>& lld =
sn.stations[i].lldscaling;
337 else if (nserv > 1.0)
338 muK = std::min(
static_cast<double>(Nt), nserv);
341 if (!(muK > 0.0) || !std::isfinite(muK))
return false;
343 for (std::size_t c = 0; c < C; ++c)
346 if (!(1.0 - lambda / muK > 0.0))
return false;
363 const std::size_t M =
sn.nstations, C =
sn.nchains;
364 const std::vector<double> Nchain = detail::chain_population(
sn);
365 bool any_closed =
false;
366 std::vector<bool> closed(C,
false);
367 for (std::size_t c = 0; c < C; ++c) {
368 closed[c] = std::isfinite(Nchain[c]) && Nchain[c] > 0.0;
369 if (closed[c]) any_closed =
true;
371 if (!any_closed)
return 0;
375 for (std::size_t i = 0; i < M; ++i) {
376 if (std::isinf(
sn.stations[i].nservers))
continue;
377 for (std::size_t c = 0; c < C; ++c)
430 bool slotted =
false,
bool for_report =
true) {
431 const std::string m = method.empty() ? std::string(
"default") : method;
436 if (slotted)
return "";
444 if (m !=
"default" && m !=
"morrison")
445 return "SolverNC: method '" + m +
446 "' cannot represent the DPS weights of a discriminatory processor-sharing "
447 "station; it would return the egalitarian-PS network. Use method 'default' or "
448 "'morrison' (npfqn_dps_morrison), SolverMVA, SolverFLD or SolverCTMC.";
455 return "SolverNC analyzes a discriminatory processor-sharing station only in the shape "
456 "Morrison's expansion is derived for: a CLOSED network of exactly two stations, one "
457 "infinite-server (think) station and one single-server DPS station, exponential "
458 "service, each class visiting the two equally often. Use SolverMVA, SolverFLD or "
459 "SolverCTMC for any other DPS model.";
465 return "SolverNC: method 'morrison' is the heavy-usage expansion of a CLOSED network of "
466 "exactly two stations, one infinite-server (think) station and one single-server DPS "
467 "station with exponential service, which this model is not. Remove the method option "
468 "to let SolverNC choose, or use SolverMVA, SolverFLD or SolverCTMC.";
473 if (!
sn.sdr.branch.empty())
return "";
474 if (m ==
"sdr" || m ==
"sdr.mva")
475 return "SolverNC: method '" + m +
476 "' requires state-dependent routing, which this model does not declare.";
482 for (std::size_t ind = 0; ind <
sn.nodes.size(); ++ind)
484 if (m !=
"default" && m !=
"rec")
485 return "solver_nc: a stochastic Petri net is solved by the MDD-rec route; method '" +
486 m +
"' is a normalizing-constant algorithm for queueing networks. Use 'rec' "
496 if (m !=
"default" && m !=
"exact" && m !=
"is" && m !=
"sampling")
497 return "SolverNC: method '" + m +
498 "' cannot represent the rank rate mu(n) of an order-independent station; use "
499 "method 'default' or 'exact' (pfqn_ncoi), 'is', SolverMVA, or SolverCTMC.";
507 for (std::size_t ind = 0; ind <
sn.nodes.size(); ++ind)
508 if (
sn.nodes[ind].nodetype == qn::NodeType::Cache) {
510 const auto itp =
sn.nodeparam.find(ind + 1);
514 if (itp !=
sn.nodeparam.end() &&
517 return "solver_nc_cache_analyzer: NC does not support the exact solution of "
518 "this cache replacement policy -- only RR and FIFO are exchangeable, "
519 "and a recency-based policy (LRU, h-LRU, q-LRU, CLIMB) would silently "
520 "receive the exchangeable answer. Use the default (approximate) method "
525 if (m ==
"rayint" || m ==
"spm")
526 return "SolverNC: method " + m +
527 " names the SPM saddle point of a cache and, on a retrieval model, the ray/WKB "
528 "delayed-hit expansion; this model declares no Cache node.";
533 return "SolverNC: the Finite Capacity Region holds a single infinite server but does not "
534 "apply DROP to every class; holding an arrival back (WAITQ) or blocking the server "
535 "(BAS/BBS/RSRD) keeps the job in the region while it waits, which the Erlang loss "
536 "model has no state for -- use DROP, or SolverCTMC/SolverJMT";
538 return "SolverNC: the 'erlangfp' Erlang fixed point applies only to a loss network, which "
539 "is an open model whose single Delay sits inside a Finite Capacity Region under a "
540 "DROP rule; this model declares no such region (see nc_is_lossn_model)";
542 return "SolverNC: method 'ms' is admissible only on a loss network (open model, one DROP "
543 "region holding a single Delay).";
545 return "SolverNC: method rec is the MDD-rec route, admissible on a stochastic Petri net or "
546 "on a loss network (open model, one DROP region holding a single Delay); this model "
548 if (!
sn.regions.empty())
549 return "SolverNC: this model applies a Finite Capacity Region to queueing stations, whose "
550 "aggregate population limit no normalizing-constant algorithm here enforces; only "
551 "the loss network -- one region over a single infinite server, DROP on every "
552 "class -- is solvable. Use SolverCTMC or SolverJMT, or setCapacity for a "
553 "single-station limit";
569 if ((m ==
"pana" || m ==
"panald") && !
sn.has_open_classes()) {
570 bool diverted_to_conv =
false, any_lld =
false;
571 for (std::size_t i = 0; i <
sn.nstations; ++i) {
572 if (
static_cast<bool>(
sn.stations[i].cdscaling)) diverted_to_conv =
true;
573 if (!
sn.stations[i].lldscaling.empty()) any_lld =
true;
575 const bool reaches_ld_kernel = (m ==
"panald") || any_lld;
577 const std::string why =
578 "the model is not in normal usage, so the 'panald' asymptotic expansion does "
579 "not apply. Use 'exact', 'clw' or an approximate load-dependent method instead.";
581 return "SolverNC: method 'pana' reaches the load-dependent kernel on this "
582 "model, where pfqn_ncld evaluates it as 'panald', and " + why;
583 return "SolverNC: " + why;
603 if (m ==
"comomld" || (for_report && (m ==
"mmint2" || m ==
"gleint"))) {
607 return "SolverNC: method 'comomld' is the load-dependent CoMoM recursion, and "
608 "pfqn_comomrm_ld accepts at most a single queueing station; this model has " +
609 std::to_string(nq) +
".";
610 return "SolverNC: the '" + m +
611 "' method requires a model with a delay and a single queueing station; this "
612 "model has " + std::to_string(nq) +
".";
617 if (m ==
"exact" &&
sn.has_open_classes()) {
618 for (std::size_t i = 0; i <
sn.nstations; ++i)
619 if (std::isfinite(
sn.stations[i].nservers) &&
sn.stations[i].nservers > 1.0)
620 return "solver_nc_analyzer: the NC solver cannot provide exact solutions for open "
621 "or mixed multiserver queueing networks. Remove the 'exact' option";
660 const std::string refusal =
707 bool mem_blocking =
false;
708 if (
opt.method ==
"mem") {
721 std::vector<T> lam(
tr.V.classes.size() + 1,
770 for (std::size_t ind = 0; ind < L.
nodes.size(); ++ind)
774 bool multiserver =
false;
784 std::string ms_warning;
785 const std::string ms_policy =
786 detail::nc_multiserver_policy(
opt.multiserver, &ms_warning);
788 if (
opt.method ==
"default") {
792 if (L.
nstations == 2 && !detail::has_node_type(L, qn::NodeType::Cache) &&
793 detail::has_node_type(L, qn::NodeType::Delay) && multiserver) {
795 if (detail::multiserver_to_lld(L)) anyLld =
true;
797 opt.method =
"comom";
799 }
else if (ms_policy ==
"lld" && multiserver && !anyLld && L.
has_product_form() &&
800 detail::nc_population_lattice(L) <= 6000.0) {
806 if (detail::multiserver_to_lld(L)) anyLld =
true;
808 }
else if (
opt.method ==
"exact" ||
opt.method ==
"is" ||
opt.method ==
"panald") {
829 "SolverNC: the '" +
opt.method +
830 "' method requires the model to have a product-form solution, and this model "
838 if (!anyLld && multiserver && ms_policy !=
"seidmann") {
839 if (detail::multiserver_to_lld(L)) anyLld =
true;
849 if (detail::has_node_type(L, qn::NodeType::Source)) {
870 std::vector<T>(), std::vector<T>(),
883 for (std::size_t ci = 0; ci < res.
cache.caches.size() && ci < cr.
itemprob.size(); ++ci)
912 if (anyLld || nc::detail::has_scaling(L)) {
914 }
else if (
opt.method ==
"rd" ||
opt.method ==
"nrp" ||
opt.method ==
"nrl" ||
915 opt.method ==
"nre" ||
opt.method ==
"comomld" ||
opt.method ==
"panald") {
923 if (!ms_warning.empty())
936 const std::string origmethod = opt_in.
method;
943 std::vector<std::vector<bool>> mask(M, std::vector<bool>(K,
false));
944 for (std::size_t i = 0; i < M; ++i)
945 for (std::size_t k = 0; k < K; ++k)
947 std::vector<std::vector<bool>> srcmask(M, std::vector<bool>(K,
false));
948 for (std::size_t i = 0; i < M; ++i)
949 if (L.
stations[i].nodetype == qn::NodeType::Source)
950 for (std::size_t k = 0; k < K; ++k) srcmask[i][k] =
true;
972 out.
actualmethod = (origmethod ==
"default" && !actualmethod.empty() &&
973 actualmethod !=
"default")
974 ?
"default/" + actualmethod
982 "SolverNC does not handle immediate feedback (immfeed); the solver will treat "
983 "self-loops as class-switching with re-queueing.";
1000 if (std::isfinite(lg))
What a solver observed about the Cache nodes of a model.
UnsupportedError(const std::string &what)
A network plus its refreshed NetworkStruct.
bool has_immediate_feedback() const
any(sn.immfeed(:)): whether any (station, class) pair feeds back.
std::vector< std::vector< bool > > disabled
std::vector< Station< T > > stations
stations[k-1] is the k-th station
std::vector< NodeDef > nodes
every node, in creation order
bool has_product_form() const
static void step(const char *fmt,...)
Write one progress line.
The exception types the port throws.
The fork-join fixed point that drives one inner MVA solve.
The Heidelberger-Trivedi fork-join transform, options.config.fork_join='ht'.
The fork-join transform SolverMVA applies before solving a layer that contains a Fork.
Running progress log of a LINE solver run (the "solver console").
NodeType
Node kinds, with the values of MATLAB NodeType.
@ FIFO
first in, first out
Matrix< T > sn_get_residt_from_respt(const qn::NetworkStruct< T > &L, const Matrix< T > &RN)
Port of sn_get_residt_from_respt: the per-JOB residence time.
Matrix< T > filter_metric(const qn::NetworkStruct< T > &L, const Matrix< T > &metric, MetricKind kind, const std::vector< std::vector< bool > > *zero_mask)
Port of filterMetric: what @@NetworkSolver/getAvg does between the analyzer and the caller.
FjMmt< T > fj_fork_join_transform(const qn::NetworkStruct< T > &L, const std::string &method)
options.config.fork_join -> the transform it names.
Matrix< T > sn_get_arvr_from_tput(const qn::NetworkStruct< T > &L, const Matrix< T > &TN)
MvaSolution< T > fj_fixed_point(const qn::NetworkStruct< T > &L, FjMmt< T > &tr, std::vector< T > &lam, const MvaOptions &opt, InnerSolve inner)
Drive the fork-join fixed point of a transformed model to convergence.
ChainDemands< T > sn_get_demands_chain(const qn::NetworkStruct< T > &L)
Port of sn_get_demands_chain.
mva::AvgResult< T > solver_nc_run_analyzer(const qn::NetworkStruct< T > &L_in, const NcSolverOptions &opt_in)
Port of @@SolverNC/runAnalyzer.m for the lang='matlab' path: solve, then apply the metric filter @@Ne...
bool nc_is_cacheqn(const qn::NetworkStruct< T > &sn)
True when the model has a Cache node and is not the Source-Cache-Sink shape.
bool nc_is_oi_model(const qn::NetworkStruct< T > &sn)
Port of nc_is_oi_model.m: a closed network with at least one OI station and nothing but BCMP product-...
NcSolution< T > solver_nc_dt(const qn::NetworkStruct< T > &sn, const NcSolverOptions &opt)
Exact discrete-time analysis of sn.
NcSpnSolution< T > solver_nc_spn_analyzer(const qn::NetworkStruct< T > &sn, const NcSolverOptions &opt)
Analyse a product-form stochastic Petri net.
NcSolution< T > solver_nc_dps_analyzer(const qn::NetworkStruct< T > &sn, const NcSolverOptions &opt)
Analyzes the closed think+DPS network.
MemSupport solver_nc_mem_supports(const qn::NetworkStruct< T > &sn)
Port of solver_nc_mem_supports.m.
NcCacheSolution< T > solver_nc_cache_analyzer(const qn::NetworkStruct< T > &sn, const NcSolverOptions &opt)
Port of solver_nc_cache_analyzer.m.
bool nc_is_lossn_model(const qn::NetworkStruct< T > &sn)
True when the model is a loss network: the shape above, with EVERY class dropped at the region.
bool nc_is_pas_model(const qn::NetworkStruct< T > &sn)
Port of nc_is_pas_model.m: a closed two-station OI / P&S tandem.
NcSolution< T > solver_nc_oi_analyzer(const qn::NetworkStruct< T > &sn, const NcSolverOptions &opt)
Port of solver_nc_oi_analyzer.m.
double solver_nc_lognormconst(const qn::NetworkStruct< T > &L, const NcSolverOptions &opt)
Port of @@SolverNC/getProbNormConstAggr.m: the log normalizing constant.
NcCacheqnRetrievalSolution< T > solver_nc_cacheqn_retrieval_analyzer(const qn::NetworkStruct< T > &sn, const NcSolverOptions &opt)
Port of solver_nc_cacheqn_retrieval_analyzer.m.
void check_method(const std::string &method)
Port of runAnalyzerChecks' method gate: an unlisted method is refused.
std::vector< std::string > list_valid_methods()
Port of SolverNC.listValidMethods.
std::size_t nc_closed_queueing_stations(const qn::NetworkStruct< T > &sn)
How many queueing (non-infinite-server) stations carry demand from a CLOSED chain?
NcRetrievalSolution< T > solver_nc_retrieval_analyzer(const qn::NetworkStruct< T > &sn, const NcSolverOptions &opt)
Port of solver_nc_retrieval_analyzer.m.
NcSolution< T > solver_nc_analyzer(const qn::NetworkStruct< T > &sn, const NcSolverOptions &opt)
Port of solver_nc_analyzer.m.
bool is_stochastic_method(const std::string &method)
Port of SolverNC.isStochasticMethod.
NcSolution< T > solver_nc_solve(const qn::NetworkStruct< T > &L_in, const NcSolverOptions &opt_in)
The gates, the multiserver conversion and the dispatch of @@SolverNC/runAnalyzer.m,...
bool nc_has_lossn_shape(const qn::NetworkStruct< T > &sn)
True when the model has the SHAPE of a loss network – open, one region, one member station,...
NcCacheqnSolution< T > solver_nc_cacheqn_analyzer(const qn::NetworkStruct< T > &sn, const NcSolverOptions &opt)
Port of solver_nc_cacheqn_analyzer.m.
NcSolution< T > solver_ncld_analyzer(const qn::NetworkStruct< T > &sn, const NcSolverOptions &opt)
Port of solver_ncld_analyzer.m: the load-dependent analyzer, which is solver_ncld plus the same fract...
bool sn_has_dps(const qn::NetworkStruct< T > &sn)
True when any station of the network is scheduled DPS.
bool nc_has_retrieval(const qn::NetworkStruct< T > &sn)
True when the model's Cache carries a delayed-hit retrieval system.
std::string resolve_method(const qn::NetworkStruct< T > &L, const std::string &method)
Port of SolverNC.resolveMethod: the feature-driven resolution of method='default'.
NcLossnSolution< T > solver_nc_lossn_analyzer(const qn::NetworkStruct< T > &sn, const NcSolverOptions &opt)
Port of solver_nc_lossn_analyzer.m.
bool nc_is_normal_usage(const qn::NetworkStruct< T > &sn)
Is the closed model in NORMAL USAGE, the domain of the Mitra-McKenna PANACEA asymptotic expansion (J.
bool nc_is_noreentrant_cache(const qn::NetworkStruct< T > &sn)
True when the model is exactly a Source, a Cache and a Sink.
std::string nc_method_refusal(const qn::NetworkStruct< T > &sn, const std::string &method, bool slotted=false, bool for_report=true)
May method run on this model?
bool nc_is_dps_model(const qn::NetworkStruct< T > &sn)
True when the model is the closed two-station network Morrison's expansion is derived for: one infini...
NcSolution< T > nc_dispatch(const qn::NetworkStruct< T > &sn, const NcSolverOptions &opt)
Port of @@SolverNC/ncDispatch.m: the inner solve of the fork-join fixed point, which is the load-depe...
FeatureSet nc_feature_set(const std::string &method)
SolverNC.getFeatureSet, 48 names, transcribed unchanged.
void check_binding_capacity(const std::string &solver, const NetworkStruct< T > &sn)
void feature_gate(const std::string &solver, const FeatureSet &declared, const NetworkStruct< T > &sn, const std::string &requested_method="", const std::string &resolved_method="")
runAnalyzerChecks: refuse a model the solver does not declare, by name.
CacheMetrics< T > cache_metrics_of(const qn::NetworkStruct< T > &sn, const std::vector< T > &hitprob, const std::vector< T > &missprob, const std::vector< T > &delayedprob, const std::vector< T > &latency, const Matrix< T > &hitproblist, const Matrix< T > &itemprob, const std::vector< T > &listcost)
Assemble CacheMetrics from what a cache analyzer returned.
CacheMetrics< T > cache_metrics_of_matrix(const qn::NetworkStruct< T > &sn, const Matrix< T > &hitprob, const Matrix< T > &missprob)
The same, for the integrated caching-queueing branch, whose hit and miss probabilities are (ncaches x...
Port of solver_nc_analyzer.m, solver_ncld_analyzer.m and @@SolverNC/ncDispatch.m: one inner solve,...
Controls and result shape shared by the normalizing-constant analyzers.
A queueing network and its refreshed NetworkStruct.
Chain aggregation and de-aggregation.
The DECLARED side of the gate: one feature set per solver.
The SolverMVA class surface: @@SolverMVA/runAnalyzer.m and the gates around it.
Port of solver_nc_cache_analyzer.m: the NON-REENTRANT cache, a model that is exactly a Source,...
Port of solver_nc_cacheqn_analyzer.m: the INTEGRATED caching-queueing network, where a Cache sits ins...
Port of solver_nc_cacheqn_retrieval_analyzer.m: a CLOSED integrated cache-queueing model whose Cache ...
Heavy-usage asymptotic analysis of the closed two-station network with one think (infinite-server) st...
Port of solver_nc_lossn_analyzer.m: the open LOSS NETWORK, which is a Source, ONE multiclass Delay si...
Port of solver_nc_mem.m and solver_nc_mem_supports.m: the Maximum Entropy Method of Kouvatsos (1994).
Order-independent (OI) and pass-and-swap (P&S) normalizing-constant analysis.
Port of solver_nc_retrieval_analyzer.m: the OPEN delayed-hit (retrieval-system) cache.
Stationary analysis of a PRODUCT-FORM stochastic Petri net by MDD-rec.
The metrics getAvg returns, after filtering.
Matrix< T > RN
response time, per visit
std::string warning
The reference's own warning text, verbatim, empty when it did not warn.
Matrix< T > UN
utilization
std::vector< T > listcost
(h) mean storage cost held by each cache list, K_j = sum_i sigma_i pi_ij, filled only by the NC cache...
std::optional< double > lognormconst
@@SolverNC/getProbNormConstAggr, i.e.
Matrix< T > WN
residence time, per job
std::string method
the method asked for
std::string actualmethod
the algorithm that ran
Matrix< T > QN
queue length
std::vector< T > CN
system response time per class
std::vector< T > XN
system throughput per class
solvers::CacheMetrics< T > cache
What the cache branches observed, EMPTY on a model with no Cache node and on every solver that does n...
Matrix< T > AN
arrival rate
The chain-level view of a layer, as sn_get_demands_chain returns it.
Matrix< T > Lchain
(M x C) demand
The transformed layer and the bookkeeping the fixed point needs to drive it and to merge its results ...
The options SolverMVA reads.
bool base_has_fork
Whether the model this solve came from has a Fork, which the model handed to the analyzer no longer d...
std::string fork_join
options.config.fork_join: which fork-join arm the fixed point takes.
Class-level results, the [Q,U,R,T,C,X] of the MATLAB analyzers.
double lG
log of the normalizing constant, the reference's lG.
static constexpr double FineTol
The verdict of solver_nc_mem_supports.
bool blocking
the model carries a binding finite station buffer
What the cache analyzer returns beyond the usual metric table.
Matrix< T > hitproblist
(u x h) access-weighted per-list hit probability, NaN if not exact
std::vector< T > missprob
(u) per-class miss and hit PROBABILITIES, missrate divided by the read class's arrival rate and its c...
Matrix< T > itemprob
(n x h+1) the same from the EXACT recursion, NaN above 10 items
std::vector< T > listcost
(h) mean storage cost held by each list, EMPTY without item sizes
What the closed delayed-hit analyzer returns.
std::vector< T > delayedprob
(K) zero on this path, by the reference's convention
std::vector< T > missprob
(K) the delayed fraction is folded in here
std::vector< T > hitprob
(K) P(item cached)
std::vector< T > latency
(K) NaN: not computed on this path
Matrix< T > hitproblist
(K x h) NaN: not computed on this path
What the integrated analyzer returns: the metrics plus the converged split.
Matrix< T > hitprob
(ncaches x nclasses) converged hit probability
Matrix< T > missprob
(ncaches x nclasses)
qn::NetworkStruct< T > refreshed
The struct whose cache self-switch carries the CONVERGED split rather than the offered one,...
std::vector< Matrix< T > > itemprob
per cache, (n x h+1); EMPTY = not computed
What the delayed-hit analyzer returns beyond the metric table.
Matrix< T > itemprob
(n x h+1) column 0 = miss, 1.. = per list
std::vector< T > missprob
(K)
std::vector< T > hitprob
(K) TRUE hit fraction, NaN off the read class
Matrix< T > hitproblist
(K x h) per-list hit fraction
std::vector< T > delayedprob
(K) delayed-hit fraction
std::vector< T > latency
(K) NaN: the latency belongs to SolverMVA
The [Q,U,R,T,C,X,lG] of the reference, plus the algorithm that ran.
std::vector< T > listcost
(h) mean storage cost held by each cache list, K_j = sum_i sigma_i pi_ij.
mva::MvaSolution< T > sol
std::string warning
The reference's warning text, verbatim, empty when it did not warn.
std::shared_ptr< qn::NetworkStruct< T > > refreshed_struct
Set only by the integrated cacheqn branch: the converged struct whose routing carries the ACTUAL hit/...
solvers::CacheMetrics< T > cache
What the cache branches observed, EMPTY on a model with no Cache node.
Controls, defaulting to SolverOptions('NC') in the reference.
bool base_has_fork
Whether the model this solve came from has a Fork, which the model handed to the analyzer no longer d...
bool slotted
options.config.slotted.
One station of the network.
double nservers
may be infinite (a Delay, or an inf-scheduled task)
std::vector< T > lldscaling
sn.lldscaling for this station: the multiplier at population 1, 2, ... Empty when the station is not ...