62 const std::string& jobclass)
const {
63 for (std::size_t i = 0; i <
Station.size(); ++i) {
65 if (col ==
"QLen")
return QLen[i];
66 if (col ==
"Util")
return Util[i];
67 if (col ==
"RespT")
return RespT[i];
68 if (col ==
"ResidT")
return ResidT[i];
69 if (col ==
"ArvR")
return ArvR[i];
70 if (col ==
"Tput")
return Tput[i];
71 throw InputError(
"AvgTable::get: unknown column '" + col +
"'");
73 return std::numeric_limits<double>::quiet_NaN();
77 if (col ==
"QLen")
return QLen;
78 if (col ==
"Util")
return Util;
79 if (col ==
"RespT")
return RespT;
80 if (col ==
"ResidT")
return ResidT;
81 if (col ==
"ArvR")
return ArvR;
82 if (col ==
"Tput")
return Tput;
83 throw InputError(
"AvgTable::column: unknown column '" + col +
"'");
101 for (std::size_t i = 0; i < source.
Station.size(); ++i) {
102 if (!keep(i))
continue;
118 return filter_avg_table(*
this, [&](std::size_t i) {
124 return filter_avg_table(*
this, [&](std::size_t i) {
130 return filter_avg_table(*
this, [&](std::size_t i) {
136 return filter_avg_table(*
this, [&](std::size_t i) {
137 return JobClass[i] == jobclass.get_name();
177 const std::ios::fmtflags flags = out.flags();
178 const std::streamsize precision = out.precision();
179 out << std::left << std::setw(16) <<
"Station" << std::setw(14) <<
"JobClass"
180 << std::right << std::setw(12) <<
"QLen" << std::setw(12) <<
"Util"
181 << std::setw(12) <<
"RespT" << std::setw(12) <<
"ResidT"
182 << std::setw(12) <<
"ArvR" << std::setw(12) <<
"Tput" <<
'\n';
183 out << std::setprecision(6);
184 for (std::size_t i = 0; i <
Station.size(); ++i)
185 out << std::left << std::setw(16) <<
Station[i] << std::setw(14) <<
JobClass[i]
186 << std::right << std::setw(12) <<
QLen[i] << std::setw(12) <<
Util[i]
187 << std::setw(12) <<
RespT[i] << std::setw(12) <<
ResidT[i]
188 << std::setw(12) <<
ArvR[i] << std::setw(12) <<
Tput[i] <<
'\n';
190 out.precision(precision);
203void fill_table(AvgTable& t,
const qn::NetworkStruct<double>& sn,
const mva::AvgResult<double>& r) {
204 for (std::size_t i = 0; i < sn.nstations; ++i)
205 for (std::size_t c = 0; c < sn.nclasses; ++c) {
206 const double q = r.QN(i, c), u = r.UN(i, c), rt = r.RN(i, c);
207 const double w = r.WN(i, c), a = r.AN(i, c), x = r.TN(i, c);
208 if (q == 0.0 && u == 0.0 && rt == 0.0 && w == 0.0 && a == 0.0 && x == 0.0)
continue;
209 t.Station.push_back(sn.stations[i].name);
210 t.JobClass.push_back(sn.classes[c].name);
213 t.RespT.push_back(rt);
214 t.ResidT.push_back(w);
218 for (std::size_t c = 0; c <
sn.nclasses && c < r.CN.size(); ++c) {
219 t.SysClass.push_back(
sn.classes[c].name);
220 t.SysRespT.push_back(r.CN[c]);
221 t.SysTput.push_back(c < r.XN.size() ? r.XN[c] : 0.0);
224 t.warning = r.warning;
225 t.ListCost = r.listcost;
226 if (r.lognormconst.has_value()) {
227 t.has_lognormconst =
true;
228 t.lognormconst = r.lognormconst.value();
246 const std::size_t M =
sn.nstations, K =
sn.nclasses;
248 for (std::size_t i = 0; i < M; ++i)
249 for (std::size_t c = 0; c < K; ++c) {
250 RN(i, c) = r.RN(i, c);
251 TN(i, c) = r.TN(i, c);
255 for (std::size_t i = 0; i < M; ++i)
256 for (std::size_t c = 0; c < K; ++c) {
257 const double q = r.QN(i, c), u = r.UN(i, c), rt = r.RN(i, c), x = r.TN(i, c);
259 const double w = WN(i, c), a = is_source ? 0.0 : AN(i, c);
262 if (q == 0.0 && u == 0.0 && rt == 0.0 && w == 0.0 && a == 0.0 && x == 0.0)
continue;
263 t.Station.push_back(
sn.stations[i].name);
264 t.JobClass.push_back(
sn.classes[c].name);
267 t.RespT.push_back(rt);
268 t.ResidT.push_back(w);
272 for (std::size_t c = 0; c <
sn.nclasses && c < r.CN.size(); ++c) {
273 t.SysClass.push_back(
sn.classes[c].name);
274 t.SysRespT.push_back(r.CN[c]);
275 t.SysTput.push_back(c < r.XN.size() ? r.XN[c] : 0.0);
292 for (std::size_t i = 0; i <
sn.nstations; ++i)
293 for (std::size_t c = 0; c <
sn.nclasses; ++c) {
294 const double q = r.QN(i, c), u = r.UN(i, c), rt = r.RN(i, c);
295 const double w = WNfix(i, c), a = r.AN(i, c), x = r.TN(i, c);
296 if (q == 0.0 && u == 0.0 && rt == 0.0 && w == 0.0 && a == 0.0 && x == 0.0)
continue;
297 t.Station.push_back(
sn.stations[i].name);
298 t.JobClass.push_back(
sn.classes[c].name);
301 t.RespT.push_back(rt);
302 t.ResidT.push_back(w);
306 for (std::size_t c = 0; c <
sn.nclasses && c < r.CN.cols(); ++c) {
307 t.SysClass.push_back(
sn.classes[c].name);
308 t.SysRespT.push_back(r.CN(0, c));
309 t.SysTput.push_back(c < r.XN.cols() ? r.XN(0, c) : 0.0);
323 if (!o.map_env.empty()) c.
mode = o.map_env;
324 if (!o.map_env_method.empty()) c.method = o.map_env_method;
325 if (o.map_env_maxstages) c.max_stages = o.map_env_maxstages;
331 if (!o.method.empty()) c.
method = o.method;
332 if (o.cutoff > 0.0) c.cutoff = o.cutoff;
333 if (!o.cutoff_vec.empty()) c.cutoff_vec = o.cutoff_vec;
334 if (o.state_max) c.state_max = o.state_max;
346 if (!o.symbolic.empty()) s.
backend = o.symbolic;
347 if (o.symbolic_timeout > 0) s.timeout_s = o.symbolic_timeout;
353 if (!o.method.empty()) f.
method = o.method;
354 if (o.tol >= 0.0) f.tol = o.tol;
355 if (o.iter_tol >= 0.0) f.iter_tol = o.iter_tol;
356 if (o.iter_max >= 0) f.iter_max =
static_cast<std::size_t
>(o.iter_max);
357 if (o.timespan_end > 0.0) f.timespan_end = o.timespan_end;
358 if (!o.init_sol.empty()) f.init_sol = o.init_sol;
359 if (o.seed) f.seed = o.seed;
360 if (!o.highvar.empty()) f.highvar = o.highvar;
374 if (!o.method.empty()) j.
method = o.method;
375 if (o.samples) j.samples =
static_cast<double>(o.samples);
376 if (o.seed) j.seed =
static_cast<long>(o.seed);
377 if (o.replications > 0) j.replications = o.replications;
378 if (o.timespan_end > 0.0) j.max_simulated_time = o.timespan_end;
380 j.verbose = o.verbose;
386 if (name !=
"AUTO")
return name;
388 std::transform(picked.begin(), picked.end(), picked.begin(), ::toupper);
389 if (picked ==
"FLUID") picked =
"FLD";
408 "' is not wrapped by this facade; its Network path is "
409 "lqns::solve_network_run_analyzer");
411 const std::string name = resolve_auto(
name_,
sn);
432 fill_table(t,
sn, r);
433 }
else if (name ==
"NC") {
449 fill_table(t,
sn, r);
450 }
else if (name ==
"CTMC") {
454 fill_table(t,
sn, r);
455 }
else if (name ==
"MAM") {
462 fill_table(t,
sn, r);
463 }
else if (name ==
"BA") {
475 fill_table(t,
sn, r);
476 }
else if (name ==
"SSA") {
485 fill_table_sim(t,
sn, r);
486 }
else if (name ==
"FLD" || name ==
"FLUID") {
499 fill_table(t,
sn, r);
504 fill_table_sim(t,
sn, r);
506 }
else if (name ==
"JMT") {
510 fill_table(t,
sn, r.
avg);
511 }
else if (name ==
"LDES") {
519 fill_table_ldes(t,
sn, r);
564 opt.keep_filtration =
true;
573 const std::size_t ist =
sn.nodes[node - 1].station;
574 if (ist == 0)
throw InputError(
"prob_aggr: the node is not a station");
575 const std::size_t K =
sn.nclasses;
576 if (state.size() != K)
throw InputError(
"prob_aggr: the state must have one entry per class");
578 for (std::size_t s = 0; s < A.
rows(); ++s) {
580 for (std::size_t k = 0; k < K && hit; ++k) hit = A(s, (ist - 1) * K + k) == state[k];
581 if (hit) p += d.
pi[s];
590 const std::size_t ist =
sn.nodes[node - 1].station;
591 if (ist == 0)
throw InputError(
"marg_aggr: the node is not a station");
592 const std::size_t K =
sn.nclasses;
593 std::size_t nmax = 0;
594 for (std::size_t s = 0; s < A.
rows(); ++s) {
596 for (std::size_t k = 0; k < K; ++k) tot += A(s, (ist - 1) * K + k);
597 nmax = std::max(nmax,
static_cast<std::size_t
>(tot));
599 std::vector<double> pmf(nmax + 1, 0.0);
600 for (std::size_t s = 0; s < A.
rows(); ++s) {
602 for (std::size_t k = 0; k < K; ++k) tot += A(s, (ist - 1) * K + k);
603 pmf[
static_cast<std::size_t
>(tot)] += d.
pi[s];
610 std::vector<std::vector<CdfCurve> > out(
sn.nstations, std::vector<CdfCurve>(
sn.nclasses));
611 const std::vector<std::vector<ctmc::CdfCurve<double> > > R =
613 for (std::size_t i = 0; i < R.size() && i < out.size(); ++i)
614 for (std::size_t c = 0; c < R[i].size() && c < out[i].size(); ++c) {
615 out[i][c].t = R[i][c].t;
616 out[i][c].F = R[i][c].F;
636 std::printf(
"%8s %-28s %s\n",
"State",
"Marking",
"Rates (to: rate)");
637 for (std::size_t i = 0; i < Q.
rows(); ++i) {
639 if (i < space.
rows()) {
640 std::ostringstream os;
642 for (std::size_t c = 0; c < space.
cols(); ++c) os << (c ?
" " :
"") << space(i, c);
646 std::printf(
"%8zu %-28s", i + 1, mark.c_str());
647 for (std::size_t j = 0; j < Q.
cols(); ++j)
648 if (i != j && Q(i, j) != 0.0) std::printf(
" %zu: %.6g", j + 1, Q(i, j));
659 const std::vector<fluid::FluidTranPoint> pts =
662 for (std::size_t i = 0; i <
sn.nstations; ++i)
663 for (std::size_t c = 0; c <
sn.nclasses; ++c)
664 out.
label.push_back(
sn.stations[i].name +
"/" +
sn.classes[c].name);
665 for (std::size_t s = 0; s < pts.size(); ++s) {
666 out.
t.push_back(pts[s].t);
667 std::vector<double> row;
668 for (std::size_t i = 0; i <
sn.nstations; ++i)
669 for (std::size_t c = 0; c <
sn.nclasses; ++c) row.push_back(pts[s].QN(i, c));
670 out.
QNt.push_back(row);
677 std::vector<std::vector<CdfCurve> > out(
sn.nstations, std::vector<CdfCurve>(
sn.nclasses));
678 const std::vector<std::vector<fluid::FluidPassage> > R =
680 for (std::size_t i = 0; i < R.size() && i < out.size(); ++i)
681 for (std::size_t c = 0; c < R[i].size() && c < out[i].size(); ++c) {
682 out[i][c].t = R[i][c].t;
683 out[i][c].F = R[i][c].cdf;
694 std::vector<std::vector<CdfCurve> > out(
sn.nstations, std::vector<CdfCurve>(
sn.nclasses));
699 const std::map<std::pair<std::size_t, std::size_t>, std::vector<std::pair<double, double> > >
701 for (std::map<std::pair<std::size_t, std::size_t>,
702 std::vector<std::pair<double, double> > >::const_iterator it = rd.begin();
703 it != rd.end(); ++it) {
704 const std::size_t i = it->first.first, c = it->first.second;
705 if (i == 0 || i > out.size() || c == 0 || c >
sn.nclasses)
continue;
709 for (std::size_t j = 0; j < it->second.size(); ++j) {
710 out[i - 1][c - 1].F.push_back(it->second[j].first);
711 out[i - 1][c - 1].t.push_back(it->second[j].second);
721 for (std::size_t i = 0; i <
sn.nstations; ++i)
722 for (std::size_t c = 0; c <
sn.nclasses; ++c)
723 out.
label.push_back(
sn.stations[i].name +
"/" +
sn.classes[c].name);
725 for (std::size_t g = 0; g < r.
t.size(); ++g) {
726 std::vector<double> row;
727 for (std::size_t i = 0; i <
sn.nstations; ++i)
728 for (std::size_t c = 0; c <
sn.nclasses; ++c)
729 row.push_back(i < r.
QNt.size() && c < r.
QNt[i].size() && g < r.
QNt[i][c].size()
732 out.
QNt.push_back(row);
739 if (node == 0 || node >
sn.nodes.size())
throw InputError(
"prob_aggr: node index out of range");
740 const std::size_t ist =
sn.nodes[node - 1].station;
741 if (ist == 0)
throw InputError(
"prob_aggr: the node is not a station");
751 if (node >
sn.nodes.size() ||
sn.nodes[node - 1].station == 0)
752 throw InputError(
"sample: the node is not a station, so nothing is logged for it");
754 for (std::size_t c = 0; c <
sn.nclasses; ++c) out.
label.push_back(
sn.classes[c].name);
760 for (std::size_t i = 0; i <
sn.nstations; ++i)
761 for (std::size_t c = 0; c <
sn.nclasses; ++c)
762 out.
label.push_back(
sn.stations[i].name +
"/" +
sn.classes[c].name);
764 for (std::size_t g = 0; g <
tr.t.size(); ++g) {
765 std::vector<double> row;
766 for (std::size_t i = 0; i <
sn.nstations; ++i)
767 for (std::size_t c = 0; c <
sn.nclasses; ++c)
768 row.push_back(i <
tr.state.size() && g <
tr.state[i].size() &&
769 c <
tr.state[i][g].size()
772 out.
state.push_back(row);
789 for (std::size_t i = 0; i <
sn.nstations; ++i)
790 for (std::size_t c = 0; c <
sn.nclasses; ++c) {
791 if (i < b.
keep.size() && c < b.
keep[i].size() && !b.
keep[i][c])
continue;
792 t.
Station.push_back(
sn.stations[i].name);
SolverAUTO.listValidMethods: the method names THIS MODEL can actually run.
std::string method_used()
getMethodUsed(): the method the solve actually resolved to.
std::vector< std::string > list_valid_methods() const
listValidMethods(): the methods this solver advertises on this model.
const AvgTable & avg_table()
getAvgTable(): the average table, solving on first demand.
A node of the model: the index it was given, and the model that owns it.
const std::string & get_name() const
getName().
BoundsTable bounds_table()
getBoundsTable(): the per-class queue-length and throughput bounds.
static void print_inf_gen(const Matrix< double > &Q, const Matrix< double > &space)
CTMC.printInfGen(Q, SS): the generator beside the state it belongs to.
Matrix< double > generator()
getGenerator(): the infinitesimal generator over that space.
double prob_aggr(std::size_t node, const std::vector< double > &state)
getProbAggr(node, state): the aggregate marginal of one state.
Matrix< double > state_space()
getStateSpace(): the aggregate state space, one row per state.
SymbolicSolution symbolic_solution()
getSymbolicSolution(): the stationary law over the rate symbols x1..xE.
std::vector< double > marg_aggr(std::size_t node)
getProbStateAggr(node): the marginal over every state of one station.
std::vector< std::vector< CdfCurve > > cdf_respt()
getCdfRespT(): the response-time CDF per (station, class).
std::vector< std::vector< CdfCurve > > cdf_respt()
getCdfRespT(): the response-time CDF per (station, class).
TranAvg tran_avg()
getTranAvg(): the transient mean queue length per station.
TranAvg tran_avg()
getTranAvg(): E[N](t), averaged over options.config.replications (SolverOptions::replications,...
SamplePath sample(std::size_t events=0, std::size_t node=0)
sampleSysAggr(events), or sampleAggr(node, events) when node is given: one logged trajectory.
std::vector< std::vector< CdfCurve > > cdf_respt()
getCdfRespT(): the EMPIRICAL response-time CDF per (station, class).
double prob_aggr(std::size_t node, const std::vector< double > &state)
getProbAggr(node, state): the time the declared state is held for.
UnsupportedError(const std::string &what)
A network plus its refreshed NetworkStruct.
const NetworkStruct< T > & get_struct()
The refreshed struct, MATLAB's model.getStruct().
The fluid solver's outermost entry point: @@SolverFLD/runAnalyzer.m's method resolution over solver_f...
The log-driven half of SolverJMT: linkAndLog, parseLogs, parseTranState, parseTranRespT,...
Port of @NetworkSolver/mapEnvApprox.m: the solver-agnostic random-environment approximation of a netw...
The stage solvers map_env_approx injects, one per runner that can be a caller.
AutoSolver auto_choose_avg_solver(const qn::NetworkStruct< T > &sn)
const char * auto_solver_name(AutoSolver s)
std::vector< std::string > auto_list_valid_methods(const qn::NetworkStruct< T > &sn)
SolverAUTO.listValidMethods: every method name this model can be asked for.
BaBounds< T > ba_bounds(const qn::NetworkStruct< T > &L, const BaOptions &opt)
Port of SolverBA.getBounds.
mva::AvgResult< T > solver_ba_run_analyzer(const qn::NetworkStruct< T > &L, const BaOptions &opt_in)
Port of @@SolverBA/runAnalyzer.m for the lang='matlab' path.
std::vector< std::string > list_valid_methods()
Port of SolverBA.listValidMethods.
std::vector< std::string > list_valid_methods()
Port of SolverCTMC.listValidMethods.
CtmcGenerator< T > ctmc_get_infgen(const NetworkStruct< T > &sn, const CtmcSolution< T > &d)
@@SolverCTMC/getInfGen.m, a pure alias of getGenerator in the reference.
std::vector< std::vector< CdfCurve< T > > > solver_ctmc_cdf_respt(const NetworkStruct< T > &sn, const CtmcOptions &opt)
Port of @@SolverCTMC/getCdfRespT.m: the per-(station, class) response-time CDF, indexed [ist-1][r-1].
CtmcStateSpace< T > ctmc_get_state_space(const NetworkStruct< T > &, const CtmcSolution< T > &d)
Port of @@SolverCTMC/getStateSpace.m.
Matrix< T > ctmc_get_state_space_aggr(const NetworkStruct< T > &sn, const CtmcOptions &opt)
Port of @@SolverCTMC/getStateSpaceAggr.m: the per-(station, class) job counts of every state,...
CtmcSolution< T > solver_ctmc_analyzer(const NetworkStruct< T > &sn_in, const CtmcOptions &opt)
Port of solver_ctmc_analyzer.m plus the fork-join wrapper of @@SolverCTMC/runAnalyzer....
CtmcSymbolicSolution< T > ctmc_symbolic_solution(const NetworkStruct< T > &sn, const CtmcOptions &opt, const CtmcSymbolicOptions &symopt=CtmcSymbolicOptions())
Port of @@SolverCTMC/getSymbolicSolution.m: pi Q = 0 with sum(pi) = 1 over the field of rational func...
mva::AvgResult< T > solver_ctmc_run_analyzer_any(const NetworkStruct< T > &sn, const CtmcOptions &opt)
Solve on whichever path applies and format, mirroring solver_ctmc_run_analyzer.
std::vector< std::string > fluid_list_valid_methods()
Port of SolverFLD.listValidMethods.
std::vector< FluidTranPoint > solver_fluid_tran_avg(const qn::NetworkStruct< T > &sn, const FluidOptions &opt, std::size_t points=101)
getTranAvg on the first-order closing drift, over that horizon.
FluidSolution solver_fluid_run_analyzer(const qn::NetworkStruct< T > &sn, const FluidOptions &opt, qn::NetworkStruct< T > *sn_out=nullptr, qn::NetworkStruct< T > *refreshed_out=nullptr, solvers::CacheMetrics< T > *cache_out=nullptr)
Port of @@SolverFLD/runAnalyzer.m: resolve the method, route to the function the reference routes to,...
std::vector< std::vector< FluidPassage > > solver_fluid_cdf_respt(const qn::NetworkStruct< T > &sn, const FluidOptions &opt, std::size_t points=201)
Port of @@SolverFLD/getCdfRespT: the response-time law of every (station, class) pair,...
JmtReplication< T > jmt_transient_replications(const qn::NetworkStruct< T > &sn, const JmtOptions &opt)
Port of the transient ensemble of @@SolverJMT/runAnalyzer.m (default over a finite timespan).
JmtSysTrace< T > jmt_sample_sys_aggr(const qn::NetworkStruct< T > &sn, std::size_t num_events, const JmtOptions &opt)
Port of sampleSysAggr: every station's trajectory on one time grid.
JmtNodeTrace< T > jmt_sample_aggr(const qn::NetworkStruct< T > &sn, std::size_t node, std::size_t num_events, const JmtOptions &opt)
Port of sampleAggr: the queue-length trajectory of one node.
std::vector< std::string > jmt_list_valid_methods()
Port of SolverJMT.listValidMethods.
JmtResult< T > solver_jmt_run_analyzer(const qn::NetworkStruct< T > &sn, const JmtOptions &opt_in)
Port of @@SolverJMT/runAnalyzer.m, the jsim and jmva arms.
std::map< std::pair< std::size_t, std::size_t >, std::vector< std::pair< double, double > > > jmt_get_cdf_resp_t(const qn::NetworkStruct< T > &sn, const JmtOptions &opt, bool seed_from_steady=true)
Port of getCdfRespT: the empirical response-time distribution per (station, class),...
JmtProbAggr jmt_prob_aggr(const qn::NetworkStruct< T > &sn, const JmtOptions &opt, std::size_t target_station=0, const std::vector< double > &target=std::vector< double >())
Port of getProbAggr and getProbSysAggr, both off ONE instrumented run.
std::vector< std::string > list_valid_methods()
Port of SolverLDES.listValidMethods.
LdesResult solver_ldes(const qn::NetworkStruct< T > &sn, const LdesOptions &o, const std::vector< std::string > &extra_flags=std::vector< std::string >())
The same, for a model built through the C++ API.
std::vector< std::string > list_valid_methods()
Port of SolverMAM.listValidMethods.
mva::AvgResult< T > solver_mam_run_analyzer(const qn::NetworkStruct< T > &L, const MamOptions &opt)
Port of @@SolverMAM/runAnalyzer.m for the lang='matlab' path: solve, then apply the metric filter @@N...
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.
std::string resolve_method(const qn::NetworkStruct< T > &L, const std::string &method)
Port of SolverMVA.resolveMethod: the feature-driven default -> rqna upgrade for a bursty single-class...
std::vector< std::string > list_valid_methods(const qn::NetworkStruct< T > &L)
Port of SolverMVA.listValidMethods.
Matrix< T > sn_get_arvr_from_tput(const qn::NetworkStruct< T > &L, const Matrix< T > &TN)
AvgResult< T > solver_mva_run_analyzer(const qn::NetworkStruct< T > &L, const MvaOptions &opt_in, const Matrix< T > &init_sol)
Port of @@SolverMVA/runAnalyzer.m for the lang='matlab' path: gate, solve, convert,...
mva::AvgResult< T > solver_nc_run_analyzer(const qn::NetworkStruct< T > &L_in, const NcSolverOptions &opt_in)
std::vector< std::string > list_valid_methods()
Port of SolverNC.listValidMethods.
FeatureSet fluid_feature_set(const std::string &method)
SolverFLD.getFeatureSet, transcribed, MINUS what the requested method cannot evaluate – the port of @...
FeatureSet nc_feature_set(const std::string &method)
SolverNC.getFeatureSet, 48 names, transcribed unchanged.
FeatureSet mva_feature_set(const std::string &raw_method)
MapEnvDecision needs_map_env(const qn::FeatureSet &declared, const qn::NetworkStruct< T > &sn, const MapEnvConfig &cfg=MapEnvConfig())
needsMapEnv: does this model need the environment image, and would the image make it solvable?
env::EnvStageAvgFn< double > nc_stage_fn(const nc::NcSolverOptions &opt)
NC stages, bound to the caller's own NcSolverOptions.
mva::AvgResult< T > run_avg(const qn::NetworkStruct< T > &sn, const std::string &solver, const qn::FeatureSet &declared, const MapEnvConfig &cfg, Run run, StageFn stage_fn, const std::string &requested_method="default")
The getAvg funnel: run the model, or its environment image when the ONLY thing in the way is a non-re...
mva::AvgResult< T > map_env_approx(const qn::NetworkStruct< T > &sn, const std::string &solver, const MapEnvConfig &cfg, StageFn stage_fn, const std::string &requested_method="default")
mapEnvApprox: solve the model through the random-environment image of its non-renewal processes.
env::EnvStageAvgFn< double > fluid_stage_fn(const fluid::FluidOptions &opt)
Fluid stages, bound to the caller's own FluidOptions.
env::EnvStageAvgFn< double > mva_stage_fn(const mva::MvaOptions &opt)
MVA stages, bound to the caller's own MvaOptions.
std::vector< std::string > list_valid_methods()
Port of SolverSSA.listValidMethods.
SsaSolution solver_ssa(const qn::NetworkStruct< T > &sn, const SsaOptions &opt, std::vector< SsaCacheRatio > *cache=nullptr)
@@SolverSSA/runAnalyzer itself: the engine the method selects, then the result assembly the reference...
Conservation laws of a layered queueing network, enumerated from its structure.
std::ostream & operator<<(std::ostream &out, const AvgTable &table)
The model API a user writes, spelled as its Python twin.
The solver API a user writes, spelled as its Python twin.
The SolverAUTO chooser: which solver a model is handed to.
The SolverBA class surface: @@SolverBA/runAnalyzer.m, listValidMethods, getBounds and getBoundsTable.
Port of solver_ctmc_analyzer.m and the parts of @@SolverCTMC/runAnalyzer.m that surround one solve: t...
Port of @@SolverCTMC/getCdfRespT.m and @@SolverCTMC/getCdfSysRespT.m: the exact distribution of the r...
The remaining @@SolverCTMC accessors: getGenerator / getInfGen, getStateSpace / getStateSpaceAggr and...
The SolverCTMC probability family: solver_ctmc_joint, _jointaggr, _marg, _margaggr,...
Port of @@SolverCTMC/getSymbolicGenerator and getSymbolicSolution.
Port of solver_ctmc_fcr_waitq.m: the reachability-built generator of a model whose finite capacity re...
SolverFluid: the closing method, a port of solver_fluid.m, solver_fluid_iteration....
Port of SolverJMT, the Java Modelling Tools client.
Port of SolverLDES, the discrete-event simulator, as its C++ client.
The SolverMAM class surface: @@SolverMAM/runAnalyzer.m and the gates around it.
The SolverMVA class surface: @@SolverMVA/runAnalyzer.m and the gates around it.
The SolverNC class surface: @@SolverNC/runAnalyzer.m and the gates around it.
The SolverSSA entry surface: a port of @@SolverSSA/runAnalyzer.m's method whitelist,...
getAvgTable, one row per (station, class) that carries a metric.
std::vector< double > ArvR
std::vector< double > Tput
std::vector< double > ResidT
void print(std::ostream &out) const
Print the labelled station-class table.
std::vector< double > RespT
std::vector< double > Util
std::vector< std::string > Station
std::vector< double > column(const std::string &column) const
A complete metric column.
std::vector< double > SysTput
std::vector< std::string > JobClass
std::string warning
The reference's own warning text, empty when it did not warn.
double get(const std::string &column, const std::string &station, const std::string &jobclass) const
One cell of the table, by station and class NAME; NaN when absent.
AvgTable tget(const Node &node) const
AvgTable filter_by(const std::string &name) const
Rows whose station or class has name, MATLAB's one-argument filterBy.
AvgTable operator()(const Node &node) const
Direct object indexing: table(queue, jobs).
std::vector< double > ListCost
getAvgCacheTable's ListCost column; empty on a model without item sizes.
std::vector< double > SysRespT
std::vector< std::string > SysClass
getAvgSysTable: system response time and throughput, per class.
std::vector< double > QLen
SolverBA(model, method).getBoundsTable().
std::vector< double > Tlower
std::vector< double > Qupper
std::vector< std::string > Station
std::vector< double > Qlower
std::vector< std::string > JobClass
std::vector< double > Tupper
sampleSysAggr / sampleAggr: ONE simulated trajectory, not a mean.
std::vector< std::vector< double > > state
[step][column]
std::vector< std::string > label
what each column counts
std::vector< double > t
event times, ascending
The knobs a solver reads; a negative or empty field keeps the engine default.
std::string multiserver
The options.config fields of the MVA / NC / fluid families.
int level
SolverBA options.level.
std::string fork_join
MVA / NC options.config.fork_join: 'default'/'mmt'/'fjt' or 'ht'.
std::string state_space_gen
SSA options.config.state_space_gen.
getSymbolicSolution: the stationary law as a function of the rate symbols.
std::vector< double > rate0
nominal value of each symbol
std::string den
common denominator of the vector
std::vector< std::string > pi
stationary probability of each state
std::vector< std::string > symbols
x1..xE, empty where an event has no positive rate
std::string engine
backend that answered, e.g. "sage"
std::vector< std::string > num
numerator of each entry over den
getTranAvg: the transient mean queue length per (station, class).
std::vector< std::string > label
the (station, class) of each column
std::vector< std::vector< double > > QNt
[step][station*class]
std::vector< double > t
the time axis
Port of SolverBA.getBounds: the {lower,upper} bracket of a family.
std::vector< std::vector< bool > > keep
getBoundsTable's row filter, (M x K): whether the (station, class) pair earns a row.
Matrix< T > Qupper
(M x K), all-NaN on a side the family lacks
The options SolverBA reads.
The SolverCTMC knobs this port honours.
Everything one CTMC solve produces.
std::vector< T > pi
stationary distribution over chain.space
Backend selection, mirroring options.config.symbolic and its timeout.
std::string backend
auto to search, a URL, an image name, or none to stay local.
What @@SolverCTMC/getSymbolicSolution.m returns, plus the engine that answered.
std::string engine
backend that solved it, e.g. sage
std::vector< T > rate0
Nominal value of each symbol, i.e.
std::vector< std::string > symbols
x1..xE, empty for an event with no positive rate.
std::vector< std::string > num
numerator of each entry over den
std::vector< std::string > pi
stationary probability of each state
std::string den
common denominator of the vector
Controls, defaulting to SolverOptions('Fluid') in the reference.
What the analyzer returns, in the same shape as the MVA solver's result.
The per-class queue-length trajectory of one node, plus its event stream.
The options of one JMT solve, SolverOptions('JMT') restricted to what is read.
std::string method
default | jsim | jmva | jmva.<alg>
What jmt_prob_aggr reports: the system probability and the per-station ones.
std::vector< double > station
P(station i holds its declared per-class counts).
Transient averages over independent replications, on one time grid.
std::vector< std::vector< std::vector< double > > > QNt
QNt[ist-1][r] over t.
The result of a JMT solve: the shared AvgResult plus what only JMT reports.
The system trajectory: one per-class block per station, on a common grid.
The knobs of one LDES run.
One ldes-result document, parsed.
The options SolverMAM reads.
The metrics getAvg returns, after filtering.
std::string actualmethod
the algorithm that ran
The options SolverMVA reads.
Controls, defaulting to SolverOptions('NC') in the reference.
The caller-facing map_env knobs, options.config.map_env and friends.
What the gate decided, and what it decided it about.
Controls, defaulting to SolverOptions('SSA') in the reference.
What the analyzer returns, in the same shape as the MVA and fluid results.
std::string method
The concrete algorithm, as the reference's method.