141std::string at(
const std::string& where, std::size_t k) {
142 return where +
"[" + std::to_string(k) +
"]";
146std::size_t size_from_json(
const Json& j,
const std::string& where) {
149 const long long v = std::strtoll(text.c_str(), &end, 10);
150 if (end == text.c_str() || *end !=
'\0')
151 throw InputError(where +
": expected a non-negative integer, got " + text);
152 if (v < 0)
throw InputError(where +
": expected a non-negative integer, got " + text);
153 return static_cast<std::size_t
>(v);
157std::vector<std::size_t> sizes_from_json(
const Json& j,
const std::string& where) {
158 std::vector<std::size_t> out;
160 out.push_back(size_from_json(j, where));
163 for (std::size_t k = 0; k < j.size(); ++k) out.push_back(size_from_json(j[k], at(where, k)));
167Json encode_sizes(
const std::vector<std::size_t>& v) {
168 Json a = Json::array();
169 for (std::size_t x : v) a.push_back(
static_cast<std::uint64_t
>(x));
174std::vector<bool> flags_from_json(
const Json& j,
const std::string& where) {
175 std::vector<bool> out;
176 const Json flat = j.is_array() ? j : Json::array({j});
177 for (std::size_t k = 0; k < flat.size(); ++k) {
178 const Json& e = flat[k];
179 if (e.is_boolean()) {
180 out.push_back(e.get<
bool>());
184 if (text !=
"0" && text !=
"1")
185 throw InputError(at(where, k) +
": a flag must be true, false, 0 or 1, got " + text);
186 out.push_back(text ==
"1");
193std::vector<std::vector<T> > vectors_from_json(
const Json& j,
const std::string& where) {
194 if (!j.is_array())
throw InputError(where +
": expected a list of vectors");
195 std::vector<std::vector<T> > out;
196 for (std::size_t k = 0; k < j.size(); ++k)
203std::vector<Matrix<T> > matrices_from_json(
const Json& j,
const std::string& where) {
204 if (!j.is_array())
throw InputError(where +
": expected a list of matrices");
205 std::vector<Matrix<T> > out;
206 for (std::size_t k = 0; k < j.size(); ++k)
213std::vector<std::vector<Matrix<T> > > matrix_lists_from_json(
const Json& j,
214 const std::string& where) {
215 if (!j.is_array())
throw InputError(where +
": expected a list of lists of matrices");
216 std::vector<std::vector<Matrix<T> > > out;
217 for (std::size_t k = 0; k < j.size(); ++k)
218 out.push_back(matrices_from_json<T>(j[k], at(where, k)));
223Json encode_matrix_lists(
const std::vector<std::vector<Matrix<T> > >& v) {
224 Json a = Json::array();
231mam::Map<T> map_from_json(
const Json& j,
const std::string& where) {
232 if (!j.is_array() || j.size() != 2)
233 throw InputError(where +
": a MAP is the two-element list [D0, D1]");
237 if (m.D0.rows() != m.D0.cols() || m.D1.rows() != m.D0.rows() || m.D1.cols() != m.D0.cols())
238 throw InputError(where +
": D0 and D1 must be square matrices of the same order");
247bool is_map_list(
const Json& j) {
248 return j.is_array() && !j.empty() && j[0].is_array() && !j[0].empty() &&
249 j[0][0].is_array() && !j[0][0].empty() && j[0][0][0].is_array();
253std::vector<mam::Map<T> > maps_from_json(
const Json& j,
const std::string& where) {
255 throw InputError(where +
": expected a list of MAPs [[D0, D1], ...], each matrix "
256 "written as an array of rows");
257 std::vector<mam::Map<T> > out;
258 for (std::size_t k = 0; k < j.size(); ++k) out.push_back(map_from_json<T>(j[k], at(where, k)));
263Json encode_map(
const mam::Map<T>& m) {
264 Json a = Json::array();
271Json encode_maps(
const std::vector<mam::Map<T> >& v) {
272 Json a = Json::array();
273 for (
const auto& m : v) a.push_back(encode_map(m));
277std::string where_of(
const char* fn,
const char* key) {
return std::string(fn) +
": " + key; }
293polling::PollingMoments<T> polling_moments_from_json(
const Json& arv,
const Json& svc,
const Json& sw,
294 const char* fn,
bool per_queue_sw) {
295 for (
const Json* j : {&arv, &svc, &sw})
296 if (!j->is_array())
throw InputError(std::string(fn) +
": arvMAPs, svcMAPs and switchMAPs are lists");
297 const std::size_t n = arv.size();
298 if (svc.size() != n || (per_queue_sw && sw.size() != n))
299 throw InputError(std::string(fn) +
": arvMAPs, svcMAPs and switchMAPs must have one entry per queue");
302 const auto is_map = [](
const Json& e) {
303 return e.is_array() && e.size() == 2 && e[0].is_array() && e[1].is_array();
305 polling::PollingMoments<T> m;
306 for (std::size_t i = 0; i < n; ++i) {
307 const std::string wa = at(std::string(fn) +
": arvMAPs", i);
308 const std::string ws = at(std::string(fn) +
": svcMAPs", i);
309 if (is_map(arv[i])) {
313 if (v.empty())
throw InputError(wa +
": empty moment vector");
314 m.lambda.push_back(v[0]);
316 if (is_map(svc[i])) {
317 const mam::Map<T> s = map_from_json<T>(svc[i], ws);
322 if (v.size() < 2)
throw InputError(ws +
": expected [E[S] E[S^2]]");
324 m.b2.push_back(v[1]);
327 for (std::size_t i = 0; i < sw.size(); ++i) {
328 const std::string wr = at(std::string(fn) +
": switchMAPs", i);
330 const mam::Map<T> r = map_from_json<T>(sw[i], wr);
335 if (v.size() < 2)
throw InputError(wr +
": expected [E[R] Var[R]]");
337 m.delta2.push_back(v[1]);
344polling::PollingMoments<T> polling_moments_from_args(
Args& a,
const char* fn) {
345 const Json& arv = a.get(
"arvMAPs");
346 const Json& svc = a.get(
"svcMAPs");
347 const Json& sw = a.get(
"switchMAPs");
349 return polling_moments_from_json<T>(arv, svc, sw, fn,
true);
352#define LINE_POLLING_OP(Name, fn) \
355 static Json run(Args& a) { \
356 const polling::PollingMoments<T> m = polling_moments_from_args<T>(a, #fn); \
358 r["W"] = encode_vector(polling::fn(m)); \
366#undef LINE_POLLING_OP
374struct OpPollingTable {
376 static Json run(Args& a) {
377 const char* fn =
"polling_qsys_table";
378 const Json& arv = a.get(
"arvMAPs");
379 const Json& svc = a.get(
"svcMAPs");
380 const Json& sw = a.get(
"switchMAPs");
381 const std::vector<int> tab = a.ints(
"table");
382 const Json& disc = a.get(
"discipline");
385 if (disc.is_string()) {
386 std::string d = disc.get<std::string>();
387 for (
auto& ch : d) ch =
static_cast<char>(std::tolower(
static_cast<unsigned char>(ch)));
388 if (d ==
"exhaustive") gated =
false;
389 else if (d ==
"gated") gated =
true;
390 else throw InputError(ErrorKind{
"Argument"}, std::string(fn) +
": The discipline must be 'exhaustive' or 'gated'.");
396 std::string(fn) +
": polling_qsys_table is exact for exhaustive or gated service only.");
398 const polling::PollingMoments<T> m = polling_moments_from_json<T>(arv, svc, sw, fn,
false);
399 std::vector<std::size_t> table;
401 if (t < 1)
throw InputError(ErrorKind{
"Argument"}, std::string(fn) +
": The polling table must list every queue 1.." +
402 std::to_string(m.lambda.size()) +
" at least once.");
403 table.push_back(
static_cast<std::size_t
>(t));
405 const polling::PollingTableResult<T> res =
409 Matrix<T> EX(res.EX.size(), m.lambda.size());
410 for (std::size_t p = 0; p < res.EX.size(); ++p)
411 for (std::size_t i = 0; i < m.lambda.size(); ++i) EX(p, i) = res.EX[p][i];
413 Json ex2 = Json::array();
414 for (
const auto& S : res.EX2) ex2.push_back(
encode_matrix(S));
421struct OpPollingKLimited {
423 static Json run(Args& a) {
424 const char* fn =
"polling_qsys_klimited";
425 const Json& arv = a.get(
"arvMAPs");
426 const Json& svc = a.get(
"svcMAPs");
427 const Json& sw = a.get(
"switchMAPs");
428 const std::vector<int> k = a.ints(
"K");
430 const polling::PollingMoments<T> m = polling_moments_from_json<T>(arv, svc, sw, fn,
true);
444 static Json run(Args& a) {
445 const char* fn =
"polling_pcl";
446 const Json& arv = a.get(
"arvMAPs");
447 const Json& svc = a.get(
"svcMAPs");
448 const Json& sw = a.get(
"switchMAPs");
449 const Json& disc = a.get(
"disc");
451 const polling::PollingMoments<T> m = polling_moments_from_json<T>(arv, svc, sw, fn,
true);
452 const std::size_t n = m.lambda.size();
454 if (disc.is_string()) {
455 code = disc.get<std::string>();
456 if (code.size() == 1) code = std::string(n, code[0]);
467 std::string(fn) +
": unsupported discipline.");
470 if (code.size() == 1) code = std::string(n, code[0]);
485struct OpLjdLinearize {
487 static Json run(Args& a) {
488 const std::vector<int> nvec = a.ints(
"nvec");
489 const std::vector<int> cutoffs = a.ints(
"cutoffs");
502 std::vector<bool> isDelay;
503 std::vector<int> cutoffs;
507FesLoad<T> read_fes_load(
Args& a,
const char* fn) {
509 f.L = a.matrix<T>(
"L");
511 f.isDelay = flags_from_json(a.get(
"isDelay"), where_of(fn,
"isDelay"));
512 f.cutoffs = a.ints(
"cutoffs");
513 a.unsupported(
"options",
"its only field, verbose, prints progress and changes no result; "
514 "the port does not print.");
519struct OpFesComputeThroughputs {
521 static Json run(Args& a) {
522 const FesLoad<T> f = read_fes_load<T>(a,
"fes_compute_throughputs");
530struct OpFesComputeMetrics {
532 static Json run(Args& a) {
533 const FesLoad<T> f = read_fes_load<T>(a,
"fes_compute_metrics");
534 const fes::FesConditionalMetrics<T> m =
551struct OpFesBuildIsolated {
553 static Json run(Args& a) {
554 a.unsupported(
"sn",
"the port takes the subset's service rates as `rates` instead of "
556 a.unsupported(
"subsetIndices",
"the port takes the subset's rows of sn.rates as "
557 "`rates`, so the subset is already selected.");
558 const Matrix<T> rates = a.matrix<T>(
"rates");
559 const Matrix<T> S = a.matrix<T>(
"stochCompS");
575std::vector<mam::Map<T> > fes_levels_from_json(
const Json& j, std::size_t n,
const double* mi,
576 const std::string& where) {
578 const mam::Map<T> m = map_from_json<T>(j, where);
582struct OpFesMapLevels {
584 static Json run(Args& a) {
585 const Json& F = a.get(
"FES");
586 const std::size_t n = a.count(
"n");
587 const bool hasMi = a.has(
"mi");
588 const double mi = hasMi ? a.number<
double>(
"mi") : 0.0;
591 r[
"FESlev"] = encode_maps(
592 fes_levels_from_json<T>(F, n, hasMi ? &mi :
nullptr,
"fes_map_levels: FES"));
597struct OpFesMapInterdeparture {
599 static Json run(Args& a) {
600 const Json& M = a.get(
"MAPs");
601 const Json& F = a.get(
"FES");
602 const std::size_t n = a.count(
"n");
605 const bool hasMi = a.has(
"mi");
606 std::vector<double> mi;
608 mi = a.vector<
double>(
"mi");
610 throw InputError(
"fes_map_interdeparture: mi is [mi_station mi_fes]");
613 const std::vector<mam::Map<T> > maps = fes_levels_from_json<T>(
614 M, n, hasMi ? &mi[0] :
nullptr,
"fes_map_interdeparture: MAPs");
615 const std::vector<mam::Map<T> > fes = fes_levels_from_json<T>(
616 F, n, hasMi ? &mi[1] :
nullptr,
"fes_map_interdeparture: FES");
625struct OpFesMapInterp {
627 static Json run(Args& a) {
628 const std::vector<T> x = a.vector<T>(
"x");
629 const std::vector<T> y = a.vector<T>(
"y");
630 const std::vector<T> xq = a.vector<T>(
"xq");
644struct OpFesMapMoments {
646 static Json run(Args& a) {
648 m.D0 = a.matrix<T>(
"T0");
649 m.D1 = a.matrix<T>(
"T1");
650 const Json* oj = a.opt(
"options");
652 const Json empty = Json::object();
653 Args o(oj ? *oj : empty,
"fes_map_moments options");
654 const char* order[] = {
"method",
"step_safety",
"tol",
"iter_max"};
655 std::size_t given = 0;
656 for (std::size_t k = 0; k < 4; ++k)
657 if (o.has(order[k])) given = k + 1;
658 for (std::size_t k = 0; k < given; ++k)
659 if (!o.has(order[k]))
660 throw InputError(std::string(
"fes_map_moments: options.") + order[given - 1] +
661 " is given without options." + order[k] +
662 "; the port takes these positionally (method, step_safety, "
663 "tol, iter_max), so give every field before the last one used");
664 const std::string method = given > 0 ? o.text(
"method",
"") : std::string();
665 const double step = given > 1 ? o.number<
double>(
"step_safety") : 0.0;
666 const double tol = given > 2 ? o.number<
double>(
"tol") : 0.0;
667 const std::size_t iters = given > 3 ? o.count(
"iter_max") : 0;
669 fes::FesMapMoments<T> r0;
687struct OpFesMapSolve {
689 static Json run(Args& a) {
690 const Json& F = a.get(
"FES");
691 const mam::Map<T> think = map_from_json<T>(a.get(
"thinkMAP"),
"fes_map_solve: thinkMAP");
692 const std::size_t N = a.count(
"N");
694 const std::vector<mam::Map<T> > fes = fes_levels_from_json<T>(F, N,
nullptr,
"fes_map_solve: FES");
705struct OpFesMapAggregate {
707 static Json run(Args& a) {
708 const std::vector<mam::Map<T> > maps = maps_from_json<T>(a.get(
"maps"),
"fes_map_aggregate: maps");
709 const std::vector<double> servers = a.vector<
double>(
"servers");
710 const std::size_t n = a.count(
"n");
711 const Json* oj = a.opt(
"options");
713 const Json empty = Json::object();
714 Args o(oj ? *oj : empty,
"fes_map_aggregate options");
715 o.unsupported(
"verbose",
"it prints progress and changes no result; the port does not print.");
716 const bool hasGrid = o.has(
"grid");
717 const std::vector<std::size_t> grid =
718 hasGrid ? sizes_from_json(o.get(
"grid"),
"fes_map_aggregate: options.grid")
719 : std::vector<std::size_t>();
721 const fes::FesMapAggregateResult<T> s =
728 info[
"grid"] = encode_sizes(s.grid);
730 r[
"FES"] = encode_maps(s.fes);
748Json cache_miss_results(
const T& M,
const std::vector<T>& MU,
const std::vector<T>& MI,
749 const std::vector<T>& pi0) {
761 std::vector<int> sigma, k;
764SizeCaps read_size_caps(
Args& a,
const char* fn,
const char* capKey) {
766 const bool hs = a.has(
"sigma"), hk = a.has(capKey);
768 throw InputError(std::string(fn) +
": sigma and " + capKey +
769 " constrain the cache together; give both or neither");
771 s.sigma = a.ints_or_empty(
"sigma");
772 s.k = a.ints_or_empty(capKey);
778 static Json run(Args& a) {
779 const Matrix<T> gamma = a.matrix<T>(
"gamma");
780 const std::vector<int> m = a.ints(
"m");
781 const SizeCaps s = read_size_caps(a,
"cache_erec",
"k");
790struct OpCacheProbErec {
792 static Json run(Args& a) {
793 const Matrix<T> gamma = a.matrix<T>(
"gamma");
794 const std::vector<int> m = a.ints(
"m");
795 const SizeCaps s = read_size_caps(a,
"cache_prob_erec",
"k");
810 static Json run(Args& a) {
811 const Matrix<T> gamma = a.matrix<T>(
"gamma");
812 const std::vector<int> m = a.ints(
"m");
813 const std::vector<int> sigma = a.ints(
"sigma");
814 const std::vector<int> k = a.ints_or_empty(
"k");
815 const bool hasPij = a.has(
"pij");
816 Matrix<T> pij = a.matrix_or_empty<T>(
"pij");
827struct OpCacheCostPathcheck {
829 static Json run(Args& a) {
830 const Matrix<T> gamma = a.matrix<T>(
"gamma");
831 const std::vector<int> sigma = a.ints(
"sigma");
832 const std::vector<int> k = a.ints(
"k");
833 const std::vector<int> parent = a.ints(
"parent");
835 Json viol = Json::array();
837 viol.push_back(encode_sizes({p.item, p.list, p.blocking_list}));
844struct OpCacheSpmSize {
846 static Json run(Args& a) {
847 const Matrix<T> gamma = a.matrix<T>(
"gamma");
848 const std::vector<int> m = a.ints(
"m");
849 const std::vector<int> sigma = a.ints(
"sigma");
850 const std::vector<int> k = a.ints(
"k");
851 const bool hasMode = a.has(
"costmode");
852 const std::string mode = a.text(
"costmode",
"");
854 cache::CacheSpmSizeResult<T> s;
857 if (mode ==
"atmost" || mode ==
"ATMOST" || mode ==
"AtMost")
859 else if (mode ==
"exact" || mode ==
"EXACT" || mode ==
"Exact")
862 throw InputError(
"cache_spm_size: costmode must be 'atmost' or 'exact', got '" +
871 Json b = Json::array();
872 for (
bool x : s.binding) b.push_back(x);
879 out[
"relerrEst"] = s.relerr_est;
880 out[
"method"] = s.method;
881 out[
"span"] = s.span;
892 static Json run(Args& a) {
893 const std::vector<Matrix<T> > lambda = matrices_from_json<T>(a.get(
"lambda"),
"cache_gamma: lambda");
894 const auto R = matrix_lists_from_json<T>(a.get(
"R"),
"cache_gamma: R");
906struct OpCacheGammaLp {
908 static Json run(Args& a) {
909 const std::vector<Matrix<T> > lambda = matrices_from_json<T>(a.get(
"lambda"),
"cache_gamma_lp: lambda");
910 const auto R = matrix_lists_from_json<T>(a.get(
"R"),
"cache_gamma_lp: R");
924struct OpCacheMissAsy {
926 static Json run(Args& a) {
927 const Matrix<T> gamma = a.matrix<T>(
"gamma");
928 const std::vector<int> m = a.ints(
"m");
929 const bool hi = a.has(
"maxiter"), ht = a.has(
"tol");
931 throw InputError(
"cache_miss_asy: the port takes maxiter and tol together; give "
933 const int maxiter = a.integer(
"maxiter", 0);
934 const T tol = a.scalar<T>(
"tol", T(0));
945 static Json run(Args& a) {
946 const Matrix<T> gamma = a.matrix<T>(
"gamma");
947 const std::vector<int> m = a.ints(
"m");
948 const bool hasLambda = a.has(
"lambda");
949 const Matrix<T> lambda = a.matrix_or_empty<T>(
"lambda");
950 const SizeCaps s = read_size_caps(a,
"cache_miss",
"cap");
952 const cache::CacheMissResult<T> x =
955 : (s.given ? cache::
cache_miss(gamma, m, s.sigma, s.k)
957 return cache_miss_results(x.M, x.MU, x.MI, x.pi0);
961struct OpCacheMissFpi {
963 static Json run(Args& a) {
964 const Matrix<T> gamma = a.matrix<T>(
"gamma");
965 const std::vector<int> m = a.ints(
"m");
966 const Matrix<T> lambda = a.matrix<T>(
"lambda");
969 return cache_miss_results(x.M, x.MU, x.MI, x.pi0);
973struct OpCacheMissSpm {
975 static Json run(Args& a) {
976 const Matrix<T> gamma = a.matrix<T>(
"gamma");
977 const std::vector<int> m = a.ints(
"m");
978 const Matrix<T> lambda = a.matrix<T>(
"lambda");
981 Json r = cache_miss_results(x.M, x.MU, x.MI, x.pi0);
998struct OpCacheMissRmf {
1000 static Json run(Args& a) {
1001 const Matrix<T> gm = a.matrix<T>(
"gamma");
1002 const std::vector<T> gamma(gm.data(), gm.data() + gm.size());
1003 const std::vector<int> m = a.ints(
"m");
1004 const Matrix<T> lambda = a.matrix<T>(
"lambda");
1005 const bool hasTmax = a.has(
"tmax");
1006 const T tmax = a.scalar<T>(
"tmax", T(0));
1007 const bool hasAccost = a.has(
"accost");
1008 const auto accost = hasAccost
1009 ? matrix_lists_from_json<T>(a.get(
"accost"),
"cache_miss_rmf: accost")
1010 : std::vector<std::vector<Matrix<T> > >();
1011 const bool hasTspan = a.has(
"tspan");
1012 const std::vector<T> tspan = a.vector_or_empty<T>(
"tspan");
1013 const bool hasX0 = a.has(
"x0init");
1014 const std::vector<T> x0init = a.vector_or_empty<T>(
"x0init");
1015 const Json* wj = a.opt(
"wgen");
1017 if (hasAccost && !hasTmax)
1018 throw InputError(
"cache_miss_rmf: the port's access-graph overload takes the "
1019 "fixed-point horizon explicitly; give tmax with accost");
1020 if (hasX0 && !hasTspan)
1021 throw InputError(
"cache_miss_rmf: x0init is the initial occupancy of the transient "
1023 if (wj && !hasTspan)
1024 throw InputError(
"cache_miss_rmf: wgen weights the transient and needs tspan");
1025 if (hasTspan && !hasX0)
1026 throw InputError(
"cache_miss_rmf: the port's transient (cache_miss_rmf_transient) "
1027 "has no default initial occupancy; give x0init with tspan");
1028 if (hasTspan && tspan.size() != 2)
1029 throw InputError(
"cache_miss_rmf: tspan is [t0 t1]; the port integrates between "
1030 "the two end points only");
1031 cache::CacheSojournClock<T> clk;
1033 Args w(*wj,
"cache_miss_rmf wgen");
1034 clk.A = w.matrix<T>(
"A");
1035 clk.c = w.vector<T>(
"c");
1036 clk.phi0 = w.vector<T>(
"phi0");
1039 const cache::CacheMissRmfResult<T> s =
1043 Json r = cache_miss_results(s.M, s.MU, s.MI, s.pi0);
1047 const cache::CacheMissRmfResult<T> tr =
1070Matrix<T> occupancy_matrix(
const std::vector<T>& x, std::size_t n) {
1071 const std::size_t c = n ? x.size() / n : 0;
1073 for (std::size_t s = 0; s < c; ++s)
1074 for (std::size_t k = 0; k < n; ++k) X(k, s) = x[k + s * n];
1083struct OpCacheRrmMeanfield {
1085 static Json run(Args& a) {
1086 const std::vector<T> lambda = a.vector<T>(
"lambda");
1087 const std::vector<int> m = a.ints(
"m");
1088 const bool hasTmax = a.has(
"tmax");
1089 const T tmax = a.scalar<T>(
"tmax", T(0));
1091 const cache::CacheRrmMeanfieldResult<T> s =
1094 r[
"x"] =
encode_matrix(occupancy_matrix(s.x, lambda.size()));
1106struct OpCacheRrmMeanfieldOde {
1108 static Json run(Args& a) {
1109 const Matrix<T> X = a.matrix<T>(
"x");
1110 const std::vector<T> lambda = a.vector<T>(
"lambda");
1111 const std::vector<int> m = a.ints(
"m");
1112 const bool hn = a.has(
"n"), hh = a.has(
"h");
1113 const std::size_t n = a.count(
"n", 0), h = a.count(
"h", 0);
1115 if (hn && n != lambda.size())
1116 throw InputError(
"cache_rrm_meanfield_ode: n = " + std::to_string(n) +
1117 " but lambda has " + std::to_string(lambda.size()) +
" items");
1118 if (hh && h != m.size())
1119 throw InputError(
"cache_rrm_meanfield_ode: h = " + std::to_string(h) +
" but m has " +
1120 std::to_string(m.size()) +
" lists");
1123 if (X.rows() == lambda.size() && X.cols() == m.size() + 1) {
1124 for (std::size_t s = 0; s < X.cols(); ++s)
1125 for (std::size_t k = 0; k < X.rows(); ++k) x.push_back(X(k, s));
1127 x.assign(X.data(), X.data() + X.size());
1137 static Json run(Args& a) {
1138 const Matrix<T> gamma = a.matrix<T>(
"gamma");
1139 const std::vector<int> m = a.ints(
"m");
1153struct OpCacheMvaMiss {
1155 static Json run(Args& a) {
1156 const std::vector<T> p = a.vector<T>(
"p");
1157 const std::vector<int> m = a.ints(
"m");
1158 const Matrix<T> R = a.matrix<T>(
"R");
1169#define LINE_CACHE_GM_MATRIX_OP(Name, fn, out, ...) \
1171 template <class T> \
1172 static Json run(Args& a) { \
1173 const Matrix<T> gamma = a.matrix<T>("gamma"); \
1174 const std::vector<int> m = a.ints("m"); \
1178 r[out] = encode_matrix(cache::fn(gamma, m)); \
1184 a.unsupported(
"lE",
"the port computes the log normalizing constant "
1185 "itself and takes no precomputed value."))
1186#undef LINE_CACHE_GM_MATRIX_OP
1188struct OpCacheTtlHlru {
1190 static Json run(Args& a) {
1191 const Matrix<T> lambda = a.matrix<T>(
"lambda");
1192 const std::vector<int> m = a.ints(
"m");
1195 r[
"pij"] = encode_matrix(cache::cache_ttl_hlru(lambda, m));
1200struct OpCacheTHlru {
1202 static Json run(Args& a) {
1203 const Matrix<T> gamma = a.matrix<T>(
"gamma");
1204 const std::vector<int> m = a.ints(
"m");
1214 static Json run(Args& a) {
1215 const Matrix<T> gamma = a.matrix<T>(
"gamma");
1216 const std::vector<int> m = a.ints(
"m");
1217 a.unsupported(
"xi0",
"the port starts the saddle-point iteration from its own initial "
1218 "point and takes none.");
1231 static Json run(Args& a) {
1232 const Matrix<T> gamma = a.matrix<T>(
"gamma");
1233 const std::vector<int> m = a.ints(
"m");
1234 a.unsupported(
"xi",
"the port starts the fixed point from its own initial point and "
1247struct OpCacheXiIter {
1249 static Json run(Args& a) {
1250 const Matrix<T> gamma = a.matrix<T>(
"gamma");
1251 const std::vector<int> m = a.ints(
"m");
1252 a.unsupported(
"tmax",
"the port has no iteration-count argument.");
1267 bool sampled =
false;
1268 std::size_t samples = 0;
1269 std::uint64_t seed = 0;
1273IsControls read_is_controls(
Args& a,
const char* fn) {
1275 const bool hs = a.has(
"samples"), hd = a.has(
"seed");
1277 throw InputError(std::string(fn) +
": the port takes samples and seed together; give "
1280 c.samples = a.count(
"samples", 0);
1281 c.seed =
static_cast<std::uint64_t
>(a.count(
"seed", 0));
1282 c.caps = read_size_caps(a, fn,
"k");
1283 if (c.caps.given && !c.sampled)
1284 throw InputError(std::string(fn) +
": the port's size-constrained overload also takes "
1285 "samples and seed; give them with sigma and k");
1291 static Json run(Args& a) {
1292 const Matrix<T> gamma = a.matrix<T>(
"gamma");
1293 const std::vector<int> m = a.ints(
"m");
1294 const IsControls c = read_is_controls(a,
"cache_is");
1296 const cache::CacheIsResult<T> s =
1297 c.caps.given ?
cache::cache_is(gamma, m, c.samples, c.seed, c.caps.sigma, c.caps.k)
1298 : (c.sampled ? cache::
cache_is(gamma, m, c.samples, c.seed)
1307struct OpCacheProbIs {
1309 static Json run(Args& a) {
1310 const Matrix<T> gamma = a.matrix<T>(
"gamma");
1311 const std::vector<int> m = a.ints(
"m");
1312 const IsControls c = read_is_controls(a,
"cache_prob_is");
1323struct OpCacheMissIs {
1325 static Json run(Args& a) {
1326 const Matrix<T> gamma = a.matrix<T>(
"gamma");
1327 const std::vector<int> m = a.ints(
"m");
1328 const Matrix<T> lambda = a.matrix<T>(
"lambda");
1329 const IsControls c = read_is_controls(a,
"cache_miss_is");
1331 const cache::CacheMissIsResult<T> s =
1334 : (c.sampled ? cache::
cache_miss_is(gamma, m, lambda, c.samples, c.seed)
1336 Json r = cache_miss_results(s.M, s.MU, s.MI, s.pi0);
1342struct OpCacheLrumMapLevelstats {
1344 static Json run(Args& a) {
1345 const Matrix<T> D0 = a.matrix<T>(
"D0");
1346 const Matrix<T> D1 = a.matrix<T>(
"D1");
1347 const std::vector<T> Tv = a.vector<T>(
"T");
1360std::vector<mam::Map<T> > item_maps(
Args& a,
const char* fn) {
1361 const std::vector<Matrix<T> > D0 = matrices_from_json<T>(a.get(
"D0c"), where_of(fn,
"D0c"));
1362 const std::vector<Matrix<T> > D1 = matrices_from_json<T>(a.get(
"D1c"), where_of(fn,
"D1c"));
1363 if (D0.size() != D1.size())
1364 throw InputError(std::string(fn) +
": D0c and D1c must have one matrix per item");
1365 std::vector<mam::Map<T> > items(D0.size());
1366 for (std::size_t k = 0; k < D0.size(); ++k) {
1367 items[k].D0 = D0[k];
1368 items[k].D1 = D1[k];
1379struct OpCacheTLrumMap {
1381 static Json run(Args& a) {
1382 const std::vector<mam::Map<T> > items = item_maps<T>(a,
"cache_t_lrum_map");
1383 const std::vector<T> m = a.vector<T>(
"m");
1384 const T tol = a.number<T>(
"tol");
1385 const bool hasSw = a.has(
"maxswp");
1386 const unsigned maxswp = a.uinteger(
"maxswp", 0);
1395struct OpCacheTtlLrumMap {
1397 static Json run(Args& a) {
1398 const std::vector<mam::Map<T> > items = item_maps<T>(a,
"cache_ttl_lrum_map");
1399 const std::vector<T> m = a.vector<T>(
"m");
1400 const T tol = a.number<T>(
"tol");
1410struct OpCacheTtlLrua {
1412 static Json run(Args& a) {
1413 const std::vector<Matrix<T> > lambda = matrices_from_json<T>(a.get(
"lambda"),
"cache_ttl_lrua: lambda");
1414 const auto R = matrix_lists_from_json<T>(a.get(
"R"),
"cache_ttl_lrua: R");
1415 const std::vector<T> m = a.vector<T>(
"m");
1416 a.unsupported(
"seed",
"the port solves for the characteristic times by deterministic "
1417 "bisection and draws nothing.");
1418 const T tol = a.number<T>(
"tol");
1419 const bool hasSw = a.has(
"maxswp");
1420 const unsigned maxswp = a.uinteger(
"maxswp", 0);
1438struct OpDaCacheIsolate {
1440 static Json run(Args& a) {
1441 const Json& chj = a.get(
"ch");
1442 const std::vector<T> lambda = a.vector<T>(
"lambda");
1444 if (!chj.is_object())
throw InputError(
"da_cache_isolate: ch must be an object");
1445 Args ch(chj,
"da_cache_isolate ch");
1446 da::CacheParam<T> p;
1447 p.itemcap = ch.ints(
"itemcap");
1448 p.nitems = ch.count(
"nitems");
1449 const Json& pr = ch.get(
"pread");
1450 if (!pr.is_array())
throw InputError(
"da_cache_isolate: ch.pread must be a list, one row per class");
1451 for (std::size_t v = 0; v < pr.size(); ++v) {
1452 if (pr[v].is_null() || (pr[v].is_array() && pr[v].empty())) {
1453 p.pread.push_back(std::vector<T>());
1458 if (ch.has(
"accost")) {
1459 const Json& ac = ch.get(
"accost");
1460 if (!(ac.is_array() && ac.empty()))
1461 p.accost = matrix_lists_from_json<T>(ac,
"da_cache_isolate: ch.accost");
1468 r[
"Rcost"] = encode_matrix_lists(s.Rcost);
1474struct OpDaTrafficSuperpos {
1476 static Json run(Args& a) {
1477 const std::vector<T> lambda = a.vector<T>(
"lambda");
1478 const std::vector<T> a2 = a.vector<T>(
"a2");
1490struct OpLossnErlangfp {
1492 static Json run(Args& a) {
1493 const std::vector<T> nu = a.vector<T>(
"nu");
1494 const Matrix<T> A = a.matrix<T>(
"A");
1495 const std::vector<T> C = a.vector<T>(
"C");
1508struct OpLossnManjunath {
1510 static Json run(Args& a) {
1511 const std::vector<T> nu = a.vector<T>(
"nu");
1512 const Matrix<T> A = a.matrix<T>(
"A");
1513 const std::vector<T> C = a.vector<T>(
"C");
1514 lossn::LossnManjunathOptions o;
1515 if (a.has(
"options")) {
1516 Args op(*a.opt(
"options"),
"lossn_manjunath options");
1517 if (op.has(
"max_live_states")) o.max_live_states = op.count(
"max_live_states");
1538 static Json run(Args& a) {
1539 const std::vector<T> nu = a.vector<T>(
"nu");
1540 const Matrix<T> A = a.matrix<T>(
"A");
1541 const std::vector<T> C = a.vector<T>(
"C");
1542 const Json* oj = a.opt(
"options");
1545 throw InputError(
"lossn_mci: options.seed is required; the port draws from a seeded "
1546 "generator and has no session RNG to fall back on");
1547 Args op(*oj,
"lossn_mci options");
1548 lossn::LossnMciOptions<T> o;
1549 if (op.has(
"samples")) o.samples = op.count(
"samples");
1550 if (op.has(
"alpha")) o.alpha = op.scalar<
double>(
"alpha", 0.0);
1551 if (op.has(
"gamma")) o.gamma = op.vector<T>(
"gamma");
1552 if (op.has(
"revenue")) o.revenue = op.vector<T>(
"revenue");
1553 if (!op.has(
"seed"))
1554 throw InputError(
"lossn_mci: options.seed is required; the port draws from a seeded "
1555 "generator and has no session RNG to fall back on");
1556 const std::uint64_t seed =
static_cast<std::uint64_t
>(op.uinteger(
"seed"));
1585 static Json run(Args& a) {
1586 const std::vector<T> nu = a.vector<T>(
"nu");
1587 const Matrix<T> A = a.matrix<T>(
"A");
1588 const std::vector<T> C = a.vector<T>(
"C");
1595 r[
"niter"] = s.iterations;
1603 static Json run(Args& a) {
1604 const std::vector<T> rho = a.vector<T>(
"rho");
1605 const std::vector<T> b = a.vector<T>(
"b");
1606 const T C = a.number<T>(
"C");
1618struct OpLossnKrDim {
1620 static Json run(Args& a) {
1621 const std::vector<T> rho = a.vector<T>(
"rho");
1622 const std::vector<T> b = a.vector<T>(
"b");
1623 std::vector<T> Bt = a.vector<T>(
"Btarget");
1625 if (Bt.size() == 1) Bt.assign(rho.size(), Bt[0]);
1635struct OpLossnKrAsy {
1637 static Json run(Args& a) {
1638 const std::vector<T> rho = a.vector<T>(
"rho");
1639 const std::vector<T> b = a.vector<T>(
"b");
1640 const T C = a.number<T>(
"C");
1655 static Json run(Args& a) {
1656 const std::vector<T> nu = a.vector<T>(
"nu");
1657 const Matrix<T> A = a.matrix<T>(
"A");
1658 const std::vector<T> C = a.vector<T>(
"C");
1665 r[
"niter"] = s.niter;
1676void lossn_parse_mci_options(
const Json* oj,
const std::string& fn,
bool isMci,
1677 lossn::LossnMciOptions<T>& o, std::uint64_t& seed) {
1678 bool haveSeed =
false;
1680 Args op(*oj, fn +
" options");
1681 if (op.has(
"samples")) o.samples = op.count(
"samples");
1682 if (op.has(
"alpha")) o.alpha = op.scalar<
double>(
"alpha", 0.0);
1683 if (op.has(
"gamma")) o.gamma = op.vector<T>(
"gamma");
1684 if (op.has(
"seed")) {
1685 seed =
static_cast<std::uint64_t
>(op.uinteger(
"seed"));
1690 if (isMci && !haveSeed)
1691 throw InputError(fn +
": options.seed is required for method 'mci'; the port draws from a "
1692 "seeded generator and has no session RNG to fall back on");
1696struct OpLossnLinks {
1698 static Json run(Args& a) {
1699 const std::vector<T> nu = a.vector<T>(
"nu");
1700 const Matrix<T> A = a.matrix<T>(
"A");
1701 const std::vector<T> C = a.vector<T>(
"C");
1702 const std::string method = a.text(
"method",
"exact");
1703 const Json* oj = a.opt(
"options");
1705 lossn::LossnMciOptions<T> o;
1706 std::uint64_t seed = 0;
1707 lossn_parse_mci_options<T>(oj,
"lossn_links", lossn::detail::lossn_lower(method) ==
"mci", o,
1720struct OpLossnRevsens {
1722 static Json run(Args& a) {
1723 const std::vector<T> nu = a.vector<T>(
"nu");
1724 const Matrix<T> A = a.matrix<T>(
"A");
1725 const std::vector<T> C = a.vector<T>(
"C");
1726 const std::vector<T> w = a.vector<T>(
"w");
1727 const std::string method = a.text(
"method",
"exact");
1728 const Json* oj = a.opt(
"options");
1730 lossn::LossnMciOptions<T> o;
1731 std::uint64_t seed = 0;
1732 lossn_parse_mci_options<T>(oj,
"lossn_revsens", lossn::detail::lossn_lower(method) ==
"mci",
1747 r[
"ci"] = Json::array();
1763struct OpDqsysBernoulli1 {
1765 static Json run(Args& a) {
1768 const T b = a.number<T>(
"b");
1769 const T p = a.number<T>(
"p");
1772 r[
"capacity"] =
"Inf";
1784 r[
"analyzer"] = s.analyzer;
1787 const std::vector<T> b = a.vector<T>(
"b");
1788 const std::vector<T> p = a.vector<T>(
"p");
1789 const std::size_t L = a.count(
"L");
1806 r[
"analyzer"] = s.analyzer;
1817 static Json run(Args& a) {
1818 const mam::Map<T> m = map_from_json<T>(a.get(
"MAPIN"),
"map2ph: MAPIN");
1830 static Json run(Args& a) {
1831 const mam::Map<T> m = map_from_json<T>(a.get(
"MAP"),
"map2mmpp: MAP");
1843 static Json run(Args& a) {
1844 const std::vector<T> X = a.vector<T>(
"X");
1855 static Json run(Args& a) {
1856 const T e1 = a.number<T>(
"e1");
1857 const T e2 = a.number<T>(
"e2");
1858 const T e3 = a.number<T>(
"e3");
1859 const bool hn = a.has(
"nmax"), ht = a.has(
"tol");
1861 throw InputError(
"aph_fit: tol follows nmax in the port's overloads; give nmax too");
1862 mam::AphFitResult<T> s;
1864 const unsigned nmax =
static_cast<unsigned>(a.count(
"nmax"));
1865 const T tol = a.number<T>(
"tol");
1869 const unsigned nmax =
static_cast<unsigned>(a.count(
"nmax"));
1877 r[
"APH"] = encode_map(s.aph);
1878 r[
"isexact"] = s.isexact;
1884struct OpM3pp22FitcApproxCov {
1886 static Json run(Args& a) {
1887 const T av = a.number<T>(
"a");
1888 const T bt1 = a.number<T>(
"bt1");
1889 const T bt2 = a.number<T>(
"bt2");
1890 const T binf = a.number<T>(
"binf");
1891 const T m3t2 = a.number<T>(
"m3t2");
1892 const T t1 = a.number<T>(
"t1");
1893 const T t2 = a.number<T>(
"t2");
1894 const std::vector<T> ai = a.vector<T>(
"ai");
1895 const T st3 = a.number<T>(
"st3");
1896 const T t3 = a.number<T>(
"t3");
1898 const mam::M3pp22FitcCovResult<T> s =
1900 Json fit = Json::array();
1903 for (
const auto& d : s.mmap.Dc) fit.push_back(
encode_matrix(d));
1910struct OpPhMultisets {
1912 static Json run(Args& a) {
1913 const std::size_t p = a.count(
"p");
1914 const std::size_t k = a.count(
"k");
1917 Json rows = Json::array();
1918 for (
const auto& row : M) rows.push_back(
encode_ints(row));
1925struct OpMmdpIsfeasible {
1927 static Json run(Args& a) {
1928 const Matrix<T> Q = a.matrix<T>(
"Q");
1929 const Matrix<T> R = a.matrix<T>(
"R");
1941struct OpInfradiusH {
1943 static Json run(Args& a) {
1944 const std::vector<T> x = a.vector<T>(
"x");
1945 const Matrix<T> L = a.matrix<T>(
"L");
1946 const std::vector<T> N = a.vector<T>(
"N");
1947 const Matrix<T> alpha = a.matrix<T>(
"alpha");
1960struct OpPasPlacement {
1962 static Json run(Args& a) {
1963 const Matrix<T> H = a.matrix<T>(
"H");
1964 const bool hx = a.has(
"x");
1965 const std::vector<T> x = hx ? a.vector<T>(
"x") : std::vector<T>();
1970 if (hx) r[
"placeable"] = encode_sizes(s.placeable(x));
1981 static Json run(Args& a) {
1982 const std::vector<T> mu = a.vector<T>(
"mu");
1983 const std::vector<Matrix<T> > D0s = matrices_from_json<T>(a.get(
"D0s"),
"mapqn_amva: D0s");
1984 const std::vector<Matrix<T> > D1s = matrices_from_json<T>(a.get(
"D1s"),
"mapqn_amva: D1s");
1985 const std::vector<int> N = a.ints(
"N");
2002 throw InputError(std::string(fn) +
": sense must be 'max' or 'min', got '" + s +
"'");
2006template <
class T,
class P>
2007void read_mapqn_core(
Args& p, P& out,
const char* fn) {
2008 out.M = p.required_integer(
"M");
2009 out.N = p.required_integer(
"N");
2010 out.K = p.ints(
"K");
2011 out.mu = matrices_from_json<T>(p.get(
"mu"), where_of(fn,
"params.mu"));
2012 out.v = matrices_from_json<T>(p.get(
"v"), where_of(fn,
"params.v"));
2013 out.r = p.matrix<T>(
"r");
2014 p.unsupported(
"verbose",
"the port prints nothing, so there is no verbosity to set.");
2015 p.unsupported(
"lpAlgorithm",
"the port solves the LP with its own simplex and offers no "
2016 "algorithm choice.");
2019const Json& params_object(
Args& a,
const char* fn) {
2020 const Json& j = a.get(
"params");
2021 if (!j.is_object())
throw InputError(std::string(fn) +
": params must be an object");
2026Json mapqn_lp_status(
const R& s) {
2030 r[
"status"] = s.status;
2040#define LINE_MAPQN_UIQ_OP(OPNAME, FN, RESULT) \
2042 template <class T> \
2043 static Json run(Args& a) { \
2044 Args p(params_object(a, #FN), #FN " params"); \
2045 mapqn::MapqnParams<T> prm; \
2046 read_mapqn_core<T>(p, prm, #FN); \
2048 const int q = a.required_integer("objective_queue"); \
2049 const int ph = a.required_integer("objective_phase"); \
2050 const bool hs = a.has("sense"); \
2051 const std::string sense = a.text("sense", ""); \
2053 const mapqn::RESULT<T> s = hs ? mapqn::FN(prm, q, ph, mapqn_sense(sense, #FN))\
2054 : mapqn::FN(prm, q, ph); \
2055 Json res = mapqn_lp_status(s); \
2056 res["U"] = encode_matrix(s.U); \
2057 res["IT"] = encode_matrix(s.IT); \
2058 res["Q"] = encode_matrix(s.Q); \
2060 r["result"] = res; \
2061 r["x"] = encode_vector(s.x); \
2062 r["fval"] = encode_scalar(s.objective); \
2069#undef LINE_MAPQN_UIQ_OP
2077Json mapqn_qr_ld_like(Args& a,
const char* fn,
bool delay) {
2078 Args p(params_object(a, fn), std::string(fn) +
" params");
2079 mapqn::MapqnParams<T> prm;
2080 read_mapqn_core<T>(p, prm, fn);
2081 prm.alpha = p.matrix<T>(
"alpha");
2083 prm.Z = p.number<T>(
"Z");
2084 prm.D1 = p.number<T>(
"D1");
2087 const int q = a.required_integer(
"objective_queue");
2088 const int ph = a.required_integer(
"objective_phase");
2089 const int n = a.required_integer(
"objective_n");
2090 const bool hs = a.has(
"sense");
2091 const std::string sense = a.text(
"sense",
"");
2093 mapqn::MapqnQrResult<T> s;
2100 Json res = mapqn_lp_status(s);
2109struct OpMapqnBndQrLd {
2111 static Json run(Args& a) {
return mapqn_qr_ld_like<T>(a,
"mapqn_bnd_qr_ld",
false); }
2114struct OpMapqnBndQrDelay {
2116 static Json run(Args& a) {
return mapqn_qr_ld_like<T>(a,
"mapqn_bnd_qr_delay",
true); }
2124struct OpMapqnBndLrMva {
2126 static Json run(Args& a) {
2127 const char* fn =
"mapqn_bnd_lr_mva";
2128 Args p(params_object(a, fn),
"mapqn_bnd_lr_mva params");
2129 mapqn::LrMvaParams<T> prm;
2130 prm.M = p.required_integer(
"M");
2131 prm.N = p.required_integer(
"N");
2132 prm.K = p.required_integer(
"K");
2133 prm.muM = p.vector<T>(
"muM");
2134 prm.muMAP = p.matrix<T>(
"muMAP");
2135 prm.v = p.matrix<T>(
"v");
2136 prm.r = p.matrix<T>(
"r");
2137 p.unsupported(
"verbose",
"the port prints nothing, so there is no verbosity to set.");
2138 p.unsupported(
"lpAlgorithm",
"the port solves the LP with its own simplex and offers no "
2139 "algorithm choice.");
2141 const int q = a.required_integer(
"objective_queue");
2142 const int lev = a.required_integer(
"objective_level");
2143 const bool hs = a.has(
"sense"), hv = a.has(
"objective_var");
2145 throw InputError(
"mapqn_bnd_lr_mva: objective_var follows sense in the port's "
2146 "signature; give sense too");
2147 const std::string sense = a.text(
"sense",
"");
2148 const std::string var = a.text(
"objective_var",
"");
2150 mapqn::MapqnBndLrMvaResult<T> s;
2155 else throw InputError(
"mapqn_bnd_lr_mva: objective_var must be 'UN' or 'QN', got '" + var +
"'");
2162 Json res = mapqn_lp_status(s);
2171std::vector<std::vector<int> > int_rows_from_json(
const Json& j,
const std::string& where) {
2172 if (!j.is_array())
throw InputError(where +
": expected a list of integer rows");
2173 std::vector<std::vector<int> > out;
2174 for (std::size_t k = 0; k < j.size(); ++k) out.push_back(
int_vector_from_json(j[k], at(where, k)));
2183struct OpMapqnQrBoundsBas {
2185 static Json run(Args& a) {
2186 const char* fn =
"mapqn_qr_bounds_bas";
2187 Args p(params_object(a, fn),
"mapqn_qr_bounds_bas params");
2188 mapqn::QrBasParams<T> prm;
2189 prm.M = p.required_integer(
"M");
2190 prm.N = p.required_integer(
"N");
2191 prm.f = p.required_integer(
"f");
2192 prm.F = p.ints(
"F");
2193 prm.K = p.ints(
"K");
2194 prm.mu = matrices_from_json<T>(p.get(
"mu"), where_of(fn,
"params.mu"));
2195 prm.v = matrices_from_json<T>(p.get(
"v"), where_of(fn,
"params.v"));
2196 prm.r = p.matrix<T>(
"r");
2197 prm.MR = p.required_integer(
"MR");
2198 prm.BB = int_rows_from_json(p.get(
"BB"), where_of(fn,
"params.BB"));
2199 prm.MM = int_rows_from_json(p.get(
"MM"), where_of(fn,
"params.MM"));
2200 prm.ZZ = p.ints(
"ZZ");
2201 prm.ZM = p.required_integer(
"ZM");
2202 prm.MM1 = int_rows_from_json(p.get(
"MM1"), where_of(fn,
"params.MM1"));
2204 const int q = a.required_integer(
"objective_queue");
2205 const bool hs = a.has(
"sense");
2206 const std::string sense = a.text(
"sense",
"");
2210 Json r = mapqn_lp_status(s);
2220struct OpMapqnQrBoundsRsrd {
2222 static Json run(Args& a) {
2223 const char* fn =
"mapqn_qr_bounds_rsrd";
2224 Args p(params_object(a, fn),
"mapqn_qr_bounds_rsrd params");
2225 mapqn::QrRsrdParams<T> prm;
2226 prm.M = p.required_integer(
"M");
2227 prm.N = p.required_integer(
"N");
2228 prm.F = p.ints(
"F");
2229 prm.K = p.ints(
"K");
2230 prm.mu = matrices_from_json<T>(p.get(
"mu"), where_of(fn,
"params.mu"));
2231 prm.v = matrices_from_json<T>(p.get(
"v"), where_of(fn,
"params.v"));
2232 prm.r = p.matrix<T>(
"r");
2233 if (p.has(
"alpha")) prm.alpha = vectors_from_json<T>(p.get(
"alpha"), where_of(fn,
"params.alpha"));
2235 const int q = a.required_integer(
"objective_queue");
2236 const bool hs = a.has(
"sense");
2237 const std::string sense = a.text(
"sense",
"");
2241 Json r = mapqn_lp_status(s);
2258#define LINE_RETRIEVAL_EXACT_OP(OPNAME, FN) \
2260 template <class T> \
2261 static Json run(Args& a) { \
2262 const std::vector<int> m = a.ints("m"); \
2263 const std::vector<T> lambda = a.vector<T>("lambda"); \
2264 const Matrix<T> eta = a.matrix<T>("eta"); \
2265 const Matrix<T> gamma = a.matrix<T>("gamma"); \
2267 const auto s = retrieval::FN(m, lambda, eta, gamma); \
2269 r["pmiss"] = encode_vector(s.pmiss); \
2270 r["phit"] = encode_matrix(s.phit); \
2271 r["pdh"] = encode_matrix(s.pdh); \
2278#undef LINE_RETRIEVAL_EXACT_OP
2281retrieval::FpiOptions read_fpi_options(Args& a) {
2282 retrieval::FpiOptions o;
2283 if (a.has(
"max_iter")) o.max_iter = a.count(
"max_iter");
2284 if (a.has(
"tol")) o.tol = a.number<
double>(
"tol");
2288struct OpRetrievalFpi {
2290 static Json run(Args& a) {
2291 const std::vector<int> m = a.ints(
"m");
2292 const std::vector<T> lambda = a.vector<T>(
"lambda");
2293 const Matrix<T> eta = a.matrix<T>(
"eta");
2294 const Matrix<T> gamma = a.matrix<T>(
"gamma");
2295 const retrieval::FpiOptions o = read_fpi_options(a);
2307 if (!j.is_string())
throw InputError(where +
": a station type is a string");
2308 const std::string s = j.get<std::string>();
2314 throw InputError(where +
": station type must be IS, PS, SIRO, FCFS or LCFSPR, got '" + s +
"'");
2325struct OpRetrievalFpiLatency {
2327 static Json run(Args& a) {
2328 const char* fn =
"retrieval_fpi_latency";
2329 const std::vector<int> m = a.ints(
"m");
2330 const std::vector<T> lambda = a.vector<T>(
"lambda");
2331 const Matrix<T> gamma = a.matrix<T>(
"gamma");
2332 const std::vector<Matrix<T> > alpha = matrices_from_json<T>(a.get(
"alpha"), where_of(fn,
"alpha"));
2333 const std::vector<std::vector<Matrix<T> > > Tsub =
2334 matrix_lists_from_json<T>(a.get(
"T"), where_of(fn,
"T"));
2335 const std::vector<Matrix<T> > R = matrices_from_json<T>(a.get(
"R"), where_of(fn,
"R"));
2336 const Json& ty = a.get(
"station_type");
2337 const retrieval::FpiOptions o = read_fpi_options(a);
2339 const std::size_t S = alpha.size();
2340 if (Tsub.size() != S)
2341 throw InputError(
"retrieval_fpi_latency: alpha and T disagree on the station count");
2342 std::vector<retrieval::RetrievalStationType> types;
2343 if (ty.is_string()) {
2344 types.push_back(retrieval_station_type(ty, where_of(fn,
"station_type")));
2345 }
else if (ty.is_array()) {
2346 for (std::size_t s = 0; s < ty.size(); ++s)
2347 types.push_back(retrieval_station_type(ty[s], at(where_of(fn,
"station_type"), s)));
2349 throw InputError(
"retrieval_fpi_latency: station_type is a list of strings");
2351 if (types.size() != S)
2352 throw InputError(
"retrieval_fpi_latency: station_type and alpha disagree on the station count");
2353 std::vector<retrieval::RetrievalStationPH<T> > st(S);
2354 for (std::size_t s = 0; s < S; ++s) {
2355 st[s].alpha = alpha[s];
2356 st[s].sub = Tsub[s];
2357 st[s].type = types[s];
2359 const retrieval::RetrievalFpiLatencyResult<T> res =
2370struct OpRetrievalNc {
2372 static Json run(Args& a) {
2373 const std::vector<int> v = a.ints(
"v");
2374 const std::vector<int> m = a.ints(
"m");
2375 const std::vector<T> lambda = a.vector<T>(
"lambda");
2376 const Matrix<T> eta = a.matrix<T>(
"eta");
2377 const Matrix<T> gamma = a.matrix<T>(
"gamma");
2386struct OpRetrievalRayint {
2388 static Json run(Args& a) {
2389 const Matrix<T> gamma = a.matrix<T>(
"gamma");
2390 const std::vector<int> m = a.ints(
"m");
2391 a.unsupported(
"n",
"it selects the form whose gamma is a function handle gfun(t), which "
2392 "has no JSON form; give gamma as an (n x h) matrix instead.");
2393 a.unsupported(
"nquad",
"it is the quadrature size of the gfun form, whose gamma is a "
2394 "function handle with no JSON form.");
2401 out[
"relerrEst"] = s.relerr_est;
2402 out[
"method"] = s.method;
2416std::vector<sum::Servers> servers_from_json(
const Json& j,
const std::string& where) {
2417 if (!j.is_array())
throw InputError(where +
": expected a list of server counts");
2418 std::vector<sum::Servers> out;
2419 for (std::size_t k = 0; k < j.size(); ++k) {
2420 const Json& e = j[k];
2421 if (e.is_string()) {
2422 const std::string s = e.get<std::string>();
2423 if (s ==
"Inf" || s ==
"inf") {
2428 const long m =
static_cast<long>(size_from_json(e, at(where, k)));
2429 if (m < 1)
throw InputError(at(where, k) +
": a station needs at least one server");
2436std::vector<long> populations_from_json(
const Json& j,
const std::string& where,
2437 const std::vector<bool>* allowInf) {
2438 if (!j.is_array())
throw InputError(where +
": expected a list of populations");
2439 std::vector<long> out;
2440 for (std::size_t k = 0; k < j.size(); ++k) {
2441 const Json& e = j[k];
2442 if (e.is_string() && (e.get<std::string>() ==
"Inf" || e.get<std::string>() ==
"inf")) {
2443 if (!allowInf || k >= allowInf->size() || !(*allowInf)[k])
2444 throw InputError(at(where, k) +
": Inf marks an open class (lambda0 > 0) only");
2448 out.push_back(
static_cast<long>(size_from_json(e, at(where, k))));
2453sum::SumOptions read_sum_options(
Args& a) {
2455 if (a.has(
"tol")) o.tol = a.number<
double>(
"tol");
2456 if (a.has(
"maxiter")) o.maxiter = a.count(
"maxiter");
2466 static Json run(Args& a) {
2467 const Matrix<T> L = a.matrix<T>(
"L");
2468 const std::vector<long> N = populations_from_json(a.get(
"N"),
"sum_closed: N",
nullptr);
2469 const std::vector<T> Z = a.vector<T>(
"Z");
2470 const std::vector<sum::Servers> mi = servers_from_json(a.get(
"mi"),
"sum_closed: mi");
2471 const Matrix<T> scv = a.matrix<T>(
"scv");
2472 const sum::SumOptions o = read_sum_options(a);
2474 const sum::SumClosedResult<T> s =
sum::sum_closed(L, N, Z, mi, scv, o);
2490struct OpSumClosing {
2492 static Json run(Args& a) {
2493 const std::vector<T> lambda0 = a.vector<T>(
"lambda0");
2494 const std::vector<T> scva = a.vector<T>(
"scva");
2495 const Matrix<T> L = a.matrix<T>(
"L");
2496 const std::vector<sum::Servers> mi = servers_from_json(a.get(
"mi"),
"sum_closing: mi");
2497 const Matrix<T> scv = a.matrix<T>(
"scv");
2498 std::vector<bool> open(lambda0.size());
2499 for (std::size_t r = 0; r < lambda0.size(); ++r)
2500 open[r] = num_traits<T>::to_double(lambda0[r]) > 0.0;
2501 const std::vector<long> N = populations_from_json(a.get(
"N"),
"sum_closing: N", &open);
2502 const std::vector<T> Z = a.vector<T>(
"Z");
2503 sum::ClosingOptions o;
2504 if (a.has(
"Kclosed")) o.Kclosed =
static_cast<long>(a.count(
"Kclosed"));
2505 o.sum = read_sum_options(a);
2507 const sum::SumClosingResult<T> s =
sum::sum_closing(lambda0, scva, L, mi, scv, N, Z, o);
2529struct OpWfBranchDetector {
2531 static Json run(Args& a) {
2532 const Matrix<T> link = a.matrix<T>(
"linkMatrix");
2533 const std::vector<int> serviceNodes = a.ints(
"serviceNodes");
2534 const std::vector<int> joinNodes = a.ints(
"joinNodes");
2536 const std::vector<wf::BranchPattern<T> > p =
wf::detect_branches(link, serviceNodes, joinNodes);
2537 Json pats = Json::array();
2538 for (std::size_t k = 0; k < p.size(); ++k) {
2542 e[
"forkNode"] = p[k].forkNode;
2543 e[
"joinNode"] = p[k].hasJoinNode ?
Json(p[k].joinNode) :
Json(nullptr);
2547 dj[
"normalizedEntropy"] =
encode_scalar(d.normalizedEntropy);
2550 e[
"diversity"] = dj;
2556 st[
"totalBranchNodes"] =
encode_count(s.totalBranchNodes);
2563 r[
"patterns"] = pats;
2570struct OpWfLoopDetector {
2572 static Json run(Args& a) {
2573 const Matrix<T> link = a.matrix<T>(
"linkMatrix");
2574 const std::vector<int> serviceNodes = a.ints(
"serviceNodes");
2575 const std::vector<int> routerNodes = a.ints(
"routerNodes");
2576 const bool hj = a.has(
"joinNodes");
2577 const std::vector<int> joinNodes = a.ints_or_empty(
"joinNodes");
2579 const std::vector<int> loops = hj ?
wf::detect_loops(link, serviceNodes, routerNodes, joinNodes)
2581 Json lj = Json::array();
2582 for (std::size_t k = 0; k < loops.size(); ++k) {
2584 e[
"node"] = loops[k];
2594 st[
"avgLoopProbability"] =
encode_scalar(s.avgLoopProbability);
2595 st[
"maxLoopProbability"] =
encode_scalar(s.maxLoopProbability);
2596 st[
"minLoopProbability"] =
encode_scalar(s.minLoopProbability);
2597 st[
"avgExpectedIterations"] =
encode_scalar(s.avgExpectedIterations);
2598 st[
"maxExpectedIterations"] =
encode_scalar(s.maxExpectedIterations);
2606Json encode_int_rows(
const std::vector<std::vector<int> >& v) {
2607 Json j = Json::array();
2608 for (std::size_t k = 0; k < v.size(); ++k) j.push_back(
encode_ints(v[k]));
2612struct OpWfParallelDetector {
2614 static Json run(Args& a) {
2615 const Matrix<T> link = a.matrix<T>(
"linkMatrix");
2616 const std::vector<int> serviceNodes = a.ints(
"serviceNodes");
2617 const std::vector<int> forkNodes = a.ints(
"forkNodes");
2618 const std::vector<int> joinNodes = a.ints(
"joinNodes");
2620 const std::vector<std::vector<int> > p =
wf::detect_parallel(link, serviceNodes, forkNodes, joinNodes);
2624 st[
"totalParallelNodes"] =
encode_count(s.totalParallelNodes);
2628 r[
"patterns"] = encode_int_rows(p);
2634struct OpWfSequenceDetector {
2636 static Json run(Args& a) {
2637 const Matrix<T> link = a.matrix<T>(
"linkMatrix");
2638 const std::vector<int> serviceNodes = a.ints(
"serviceNodes");
2649 r[
"sequences"] = encode_int_rows(p);
2660mdd::MddStruct mdd_struct_from_json(
const Json& j,
const std::string& where) {
2661 if (!j.is_object())
throw InputError(where +
": expected the MDD.toStruct object {K, domain, root, nnodes, node}");
2665 m.domain = s.ints(
"domain");
2666 m.root = s.required_integer(
"root");
2667 m.nnodes = s.ints(
"nnodes");
2668 const Json& node = s.get(
"node");
2670 if (!node.is_array())
throw InputError(where +
".node: expected one list of nodes per level");
2671 for (std::size_t k = 0; k < node.size(); ++k)
2672 m.node.push_back(int_rows_from_json(node[k], at(where +
".node", k)));
2673 if (m.domain.size() != m.K || m.nnodes.size() != m.K || m.node.size() != m.K)
2674 throw InputError(where +
": domain, nnodes and node need one entry per level (K)");
2675 for (std::size_t k = 0; k < m.K; ++k)
2676 if (
static_cast<int>(m.node[k].size()) != m.nnodes[k])
2677 throw InputError(at(where +
".node", k) +
": holds a different node count from nnodes");
2681Json encode_mdd_struct(
const mdd::MddStruct& m) {
2687 Json node = Json::array();
2688 for (std::size_t k = 0; k < m.node.size(); ++k) node.push_back(encode_int_rows(m.node[k]));
2696 static Json run(Args& a) {
2697 const mdd::MddStruct m = mdd_struct_from_json(a.get(
"mdds"),
"mdd_rec: mdds");
2698 const std::vector<std::vector<T> > g = vectors_from_json<T>(a.get(
"g"),
"mdd_rec: g");
2707struct OpMddClosedqn {
2709 static Json run(Args& a) {
2710 const std::vector<T> mu = a.vector<T>(
"mu");
2711 const Matrix<T>
P = a.matrix<T>(
"P");
2712 const std::vector<double> servers = a.vector<
double>(
"servers");
2713 const int N = a.required_integer(
"N");
2714 if (
const Json* o = a.opt(
"options")) {
2715 Args op(*o,
"mdd_closedqn options");
2716 op.unsupported(
"verbose",
"the port prints no storage summary; the same figures are "
2717 "returned in stats.");
2718 op.unsupported(
"mdd",
"it is a live MDD object to reuse, which has no JSON form; the "
2719 "reachable set is rebuilt instead.");
2724 const mdd::MddStats st = s.mdd.stats();
2727 sj[
"nodesPerLevel"] =
encode_ints(st.nodes_per_level);
2728 sj[
"numNodes"] = st.num_nodes;
2729 sj[
"liveNodes"] = st.num_nodes;
2730 sj[
"tableNodes"] = st.table_nodes;
2731 sj[
"numStates"] = st.num_states;
2732 sj[
"mddInts"] = st.mdd_ints;
2733 sj[
"explicitInts"] = st.explicit_ints;
2734 sj[
"compression"] = st.compression();
2736 tj[
"reach"] = s.time_reach;
2737 tj[
"gen"] = s.time_gen;
2738 tj[
"solve"] = s.time_solve;
2739 tj[
"metrics"] = s.time_metrics;
2741 r[
"mdd"] = encode_mdd_struct(s.mdd.to_struct());
2744 r[
"states"] = encode_int_rows(s.states);
2754std::vector<long long> ll_vector_from_json(
const Json& j,
const std::string& where) {
2755 if (!j.is_array())
throw InputError(where +
": expected a list of integers");
2756 std::vector<long long> out;
2757 for (std::size_t k = 0; k < j.size(); ++k) {
2758 const Json& e = j[k];
2759 if (!e.is_number_integer() && !e.is_number_unsigned())
2760 throw InputError(at(where, k) +
": expected an integer");
2761 out.push_back(e.get<
long long>());
2766std::vector<std::vector<long long> > ll_rows_from_json(
const Json& j,
const std::string& where) {
2767 if (!j.is_array())
throw InputError(where +
": expected a list of integer rows");
2768 std::vector<std::vector<long long> > out;
2769 for (std::size_t k = 0; k < j.size(); ++k) out.push_back(ll_vector_from_json(j[k], at(where, k)));
2780 static Json run(Args& a) {
2781 const Json& Sj = a.get(
"S");
2782 const std::vector<std::vector<T> > g = vectors_from_json<T>(a.get(
"g"),
"spn_conv: g");
2784 if (Sj.is_object()) {
2786 throw InputError(
"spn_conv: S is the spn_sinvariants struct, which carries V; do not give V too");
2787 Args s(Sj,
"spn_conv S");
2788 spn::SpnInvariants
inv;
2789 inv.S = ll_rows_from_json(s.get(
"S"),
"spn_conv: S.S");
2790 inv.V = ll_vector_from_json(s.get(
"V"),
"spn_conv: S.V");
2791 if (
const Json* p = s.opt(
"places")) {
2793 inv.places.assign(pl.begin(), pl.end());
2795 if (
const Json* m0 = s.opt(
"m0"))
inv.m0 = ll_vector_from_json(*m0,
"spn_conv: S.m0");
2800 const std::vector<std::vector<long long> > S = ll_rows_from_json(Sj,
"spn_conv: S");
2801 const std::vector<long long> V = ll_vector_from_json(a.get(
"V"),
"spn_conv: V");
2818 static std::vector<std::vector<double> > rows(
const Matrix<double>& m) {
2819 std::vector<std::vector<double> > r(m.rows(), std::vector<double>(m.cols()));
2820 for (std::size_t i = 0; i < m.rows(); ++i)
2821 for (std::size_t j = 0; j < m.cols(); ++j) r[i][j] = m(i, j);
2824 static Json run(Args& a) {
2825 const std::vector<std::vector<double> > pre = rows(a.matrix<
double>(
"pre"));
2826 const std::vector<std::vector<double> > post = rows(a.matrix<
double>(
"post"));
2827 const std::vector<std::vector<double> > inh = rows(a.matrix_or_empty<
double>(
"inh"));
2828 const std::vector<double> rate = a.vector<
double>(
"rate");
2829 const std::vector<double> immd = a.vector_or_empty<
double>(
"imm");
2830 const std::vector<double> srv = a.vector_or_empty<
double>(
"srv");
2831 const std::vector<double> m0 = a.vector<
double>(
"m0");
2832 const std::size_t P0 = a.count(
"p0");
2834 if (
const Json* oj = a.opt(
"options")) {
2835 Args op(*oj,
"spn_ispn options");
2836 if (op.has(
"extra")) o.extra =
static_cast<int>(op.count(
"extra"));
2837 if (op.has(
"maxlevel")) o.maxlevel =
static_cast<int>(op.count(
"maxlevel"));
2838 if (op.has(
"maxstates")) o.maxstates = op.count(
"maxstates");
2839 if (op.has(
"tol")) o.tol = op.number<
double>(
"tol");
2840 if (op.has(
"distmax")) o.distmax = op.number<
double>(
"distmax");
2841 o.qbdmethod = op.text(
"qbdmethod", o.qbdmethod);
2842 op.unsupported(
"rewards",
"they are functions of the marking, callables with no JSON form.");
2846 if (P0 < 1)
throw InputError(ErrorKind{
"Argument"},
"spn_ispn: p0 is a 1-based place index");
2847 std::vector<bool> imm(immd.size());
2848 for (std::size_t t = 0; t < immd.size(); ++t) imm[t] = immd[t] != 0;
2849 const spn::IspnResult r =
spn::spn_ispn(pre, post, inh, rate, imm, srv, m0, P0 - 1, o);
2851 res[
"K"] =
encode_count(
static_cast<std::size_t
>(r.K));
2859 Json lm = Json::array();
2860 for (
const auto& m : r.levelmarkings) lm.push_back(
encode_vectors(m));
2861 res[
"levelmarkings"] = lm;
2879struct OpSpnIspnCovered {
2880 static Json run(Args& a) {
2881 const Matrix<double> C = a.matrix<
double>(
"C");
2884 Json v = Json::array();
2885 for (
bool b : cov) v.push_back(b);
2898struct OpSpnRecEnabled {
2900 static Json run(Args& a) {
2901 const mdd::MddStruct m = mdd_struct_from_json(a.get(
"mdds"),
"spn_rec_enabled: mdds");
2902 const std::vector<std::vector<T> > g = vectors_from_json<T>(a.get(
"g"),
"spn_rec_enabled: g");
2903 const Json& mj = a.get(
"mde");
2904 const std::size_t L = a.count(
"nplacelevels");
2906 if (!mj.is_object())
throw InputError(
"spn_rec_enabled: mde is one entry of INFO.modes, an object");
2907 Args md(mj,
"spn_rec_enabled mde");
2908 spn::SpnMode<T> mode;
2909 mode.enab = md.vector<
double>(
"enab");
2910 mode.inhib = md.vector<
double>(
"inhib");
2911 if (md.has(
"fire")) mode.fire = md.vector<
double>(
"fire");
2912 if (md.has(
"trans")) mode.trans = md.count(
"trans");
2913 if (md.has(
"mode")) mode.mode = md.count(
"mode");
2914 if (md.has(
"D0")) mode.D0 = md.matrix<T>(
"D0");
2915 if (md.has(
"D1")) mode.D1 = md.matrix<T>(
"D1");
2916 if (md.has(
"pie")) mode.pie = md.vector<T>(
"pie");
2917 if (md.has(
"nph")) mode.nph = md.count(
"nph");
2918 if (md.has(
"srv")) mode.srv = md.number<
double>(
"srv");
2919 md.unsupported(
"dep",
"it is a marking-dependent rate function, a callable with no JSON form.");
2921 if (mode.enab.size() < L || mode.inhib.size() < L)
2922 throw InputError(
"spn_rec_enabled: mde.enab and mde.inhib need one entry per place level");
3036 const std::string fn_arg =
3037 "it takes a C++ callable as an argument, which has no JSON form.";
3038 t[
"cd_peak_scaling"] = fn_arg;
3039 t[
"da_fpi"] = fn_arg;
3040 t[
"hyperexp_fit_longtail"] = fn_arg;
3041 t[
"laplace_invert"] = fn_arg;
3042 t[
"laplaceapprox"] = fn_arg;
3043 t[
"pas_swap2order"] = fn_arg;
3044 t[
"mdd_reachset"] = fn_arg;
3045 t[
"fes_beta_handle"] =
3046 "it returns a C++ callable (the per-class rate function of the aggregate), which has "
3048 const std::string mdd_desc =
3049 "it returns a Kronecker rate descriptor whose successor function is a C++ callable, "
3050 "which has no JSON form; run line-cli -s ctmc -a <analysis> on the model instead.";
3051 t[
"mdd_descriptor"] = mdd_desc;
3052 t[
"mdd_ps"] = mdd_desc;
3054 "it takes a Kronecker rate descriptor whose successor function is a C++ callable, "
3055 "which has no JSON form; run line-cli -s ctmc -a <analysis> on the model instead.";
3056 const std::string sn_mva =
3057 "it takes a NetworkStruct; build the model and run line-cli -s mva -a <analysis> "
3059 t[
"cache_retrieval_inputs"] = sn_mva;
3060 t[
"fes_validate"] = sn_mva;
3061 t[
"da_cacheqn"] = sn_mva;
3062 t[
"da_cacheqn_retrieval"] = sn_mva;
3064 "it takes a NetworkStruct; build the model and run line-cli -s ba -a <analysis> "
3067 "it takes a NetworkStruct; build the model and run line-cli -s ctmc -a <analysis> "
3069 const std::string sn_nc =
3070 "it takes a NetworkStruct; build the model and run line-cli -s nc -a <analysis> "
3072 t[
"spn_pf"] = sn_nc;
3073 t[
"spn_sinvariants"] = sn_nc;
3074 const std::string sn_props =
3075 "it takes a NetworkStruct and returns the Petri-net property structs; build the "
3076 "model and call it from C++ (line/api/spn/spn_properties.h) instead.";
3078 t[
"spn_net"] = sn_props;
3079 t[
"spn_properties"] = sn_props;
3080 t[
"spn_reachgraph"] = sn_props;
3081 t[
"spn_reachprops"] = sn_props;
3082 t[
"spn_siphons"] = sn_props;
3083 t[
"spn_structprops"] = sn_props;
3084 t[
"spn_tinvariants"] = sn_props;
3085 t[
"spn_traps"] = sn_props;
3087 "it takes the SpnInfo that spn_mdd returns, which holds an MDD object and callable "
3088 "marking-dependence laws with no JSON form; build the net and run line-cli -s nc "
3089 "-a <analysis> on it instead.";
Minimal-order acyclic phase-type fit of the first three moments (matlab/lib/kpctoolbox/aph/aph_fit....
Internal to the –api dispatcher: what a per-domain translation unit needs to add entries to the table...
#define LINE_POLLING_OP(Name, fn)
#define LINE_CACHE_GM_MATRIX_OP(Name, fn, out,...)
The (gamma, m) -> prob family.
#define LINE_MAPQN_UIQ_OP(OPNAME, FN, RESULT)
mapqn_bnd_lr and mapqn_bnd_qr share the signature (params, objective_queue, objective_phase[,...
#define LINE_RETRIEVAL_EXACT_OP(OPNAME, FN)
retrieval_metrics and retrieval_mva share (m, lambda, eta, gamma) and the [pmiss, phit,...
Sample autocovariance sequence of a trace, lags 0 .
Mean per-list storage cost of a cache with item sizes, and the screen for promotion paths that storag...
Exact recursive normalizing constant of a multi-list cache model.
Access factors of a multi-list cache whose lists form a general access GRAPH.
Access factors of a tree-structured multi-list cache.
Importance-sampling estimate of the cache normalizing constant.
Level statistics of one item's embedded (list, phase) chain in the LRU(m)-MAP TTL approximation.
Exact cache miss rates from the recursive normalizing constant.
Asymptotic (large-cache) miss ratio by a rank-threshold fixed point.
Cache miss rates from the fixed-point multipliers.
Cache miss rates from the importance-sampling hit probabilities.
Refined mean field (RMF) miss rates of a multi-list RANDOM(m) cache.
Saddle-point approximation of the cache miss rates.
Exact mean value analysis of a multi-list cache.
Per-item and global cache miss probabilities by mean value analysis.
Exact per-item hit and miss probabilities of a multi-list cache.
Cache hit and miss probabilities from the fixed-point multipliers.
Importance-sampling estimate of the cache hit-probability distribution.
Saddle-point approximation of the per-item cache hit probabilities.
Steady state of the RANDOM(m) multi-list mean field.
Mean-field drift of the RANDOM(m) multi-list cache.
Grid-independent sojourn-weighted average of a cache mean-field transient.
Saddle-point approximation of the cache normalizing constant.
Ray (WKB) asymptotic expansion of the cost-capped cache normalizing constant.
Characteristic times of the h-LRU / LRU(m) TTL approximation.
Characteristic times of the LRU(m)-MAP TTL approximation.
TTL (characteristic-time) approximation of an h-LRU / LRU(m) cache.
TTL (characteristic-time) approximation of an LRU cache whose lists form an arbitrary access graph.
TTL approximation of an LRU(m) cache whose items are requested by Markovian arrival processes.
Lagrange multipliers of a multi-list cache by fixed-point iteration.
Lagrange multipliers of a multi-list cache by the Gast-Van Houdt iteration.
UnsupportedError(const std::string &what)
Named-argument reader over the parsed JSON object.
Isolated-cache input construction for the decomposition methods.
Superposition of independent renewal flows (Whitt's QNA stationary-interval method).
State dependent Bernoulli server on a discrete time scale.
Service demands and visit ratios of an isolated subnetwork, from the stochastic complement of its rou...
Per-station metrics of the ISOLATED subnetwork at every population state, the companion of fes_comput...
Per-class throughput table of an isolated subnetwork, tabulated over the population lattice,...
Recursive MAP flow-equivalent server for a station subset.
Inter-departure MAP of a closed subnetwork made of one MAP station and one MAP flow-equivalent server...
Shape-preserving interpolation of the flow-equivalent descriptors, and the population grid they are e...
Per-level processes of a load-dependent flow-equivalent server.
Moments and index of dispersion of an inter-departure MAP.
Closed model left by a MAP flow-equivalent server, and the per-station metrics behind it.
Integrands of the Norlund-Rice inversion of the normalizing constant, in their two changes of variabl...
Enumerations and the minimal distribution descriptor shared by the model layer of the C++ port.
Port of ldqbd_mphc.m and ph_multisets.m: the exact level-dependent QBD blocks of an M/PH/c queue.
Linearized index of a per-class population vector, for Limited Joint Dependence (LJD) tables.
Large-capacity (Kelly limit) approximation of loss networks.
Erlang fixed-point (reduced-load) approximation for a loss network.
The multirate single-link loss system (stochastic knapsack): exact blocking by the Kaufman-Roberts re...
Per-link blocking and occupancy of a loss network.
Exact analysis of a loss network by the Manjunath-Sikdar transform.
Monte Carlo importance-sampling summation for product-form loss networks.
Exact analysis of a loss network by MDD-rec.
Revenue sensitivities and implied costs of a loss network.
M3PP(2, 2) fitted to the count COVARIANCE between its two classes (matlab/lib/m3a/m3a/m3pp/m3pp22_fit...
Read a MAP as an MMPP (matlab/lib/kpctoolbox/map/map2mmpp.m).
Markovian arrival process descriptors: stationary vectors, rate, moments, autocorrelation and the ind...
Horizontal-cut mean value analysis for a MAP server (SolverMVA method 'amva.mapqn').
General linear-reduction (LR) bound on the utilization of one queue-phase of a closed MAP queueing ne...
MVA-shaped linear-reduction bound for a closed network of M - 1 exponential queues and ONE MAP queue.
General quadratic-reduction (QR) bound on the utilization of one queue-phase of a closed MAP queueing...
Quadratic-reduction bound for a MAP queueing network with a delay (think time) station.
Quadratic-reduction bound on a marginal of a load-dependent MAP queueing network.
Quadratic-reduction bound on the utilization of one queue of a closed MAP queueing network with a FIN...
Quadratic-reduction bound on the utilization of one queue of a closed MAP queueing network under RS-R...
Quasi-reduced ordered Multi-valued Decision Diagram.
Exact solve of a single-class closed exponential queueing network whose CTMC state space (reachable o...
MDD-rec: the normalising constant of a product-form model whose reachable set is held in a decision d...
Feasibility predicate for a Markov-modulated deterministic process.
std::vector< CacheBlockedPair > cache_cost_pathcheck(const Matrix< T > &gamma, const std::vector< int > &sigma, const std::vector< int > &k, const std::vector< int > &parent)
CacheIsResult< T > cache_is(const Matrix< T > &gamma_in, const std::vector< int > &m, std::size_t samples, std::uint64_t seed, const std::vector< int > &sigma_in, const std::vector< int > &k)
Importance-sampling estimate of the cache normalizing constant.
std::vector< T > cache_cost(const Matrix< T > &gamma, const std::vector< int > &m, const std::vector< int > &sigma, const std::vector< int > &k, const Matrix< T > &pij)
Mean per-list storage cost of a cache with item sizes, and the screen for promotion paths that storag...
std::vector< T > cache_rrm_meanfield_ode(const std::vector< T > &x, const std::vector< T > &lambda, const std::vector< int > &m)
Mean-field drift of the RANDOM(m) multi-list cache.
std::vector< T > cache_xi_iter(const Matrix< T > &gamma, const std::vector< int > &m)
Lagrange multipliers of a multi-list cache by the Gast-Van Houdt iteration.
CacheMissRmfResult< T > cache_miss_rmf(const std::vector< T > &gamma, const std::vector< int > &m_in, const Matrix< T > &lambda, const T &tmax, const std::vector< std::vector< Matrix< T > > > &accost)
Refined mean-field miss rates of a RANDOM(m) multi-list cache.
CacheGammaGraphResult< T > cache_gamma(const std::vector< Matrix< T > > &lambda, const std::vector< std::vector< Matrix< T > > > &R)
Access factors of a multi-list cache whose lists form a general access GRAPH.
CacheGammaResult< T > cache_gamma_lp(const std::vector< Matrix< T > > &lambda, const std::vector< std::vector< Matrix< T > > > &R)
Access factors of a tree-structured multi-list cache.
CacheMissResult< T > cache_miss(const Matrix< T > &gamma, const std::vector< int > &m, const Matrix< T > &lambda)
Exact cache miss rates from the recursive normalizing constant.
CacheMvaResult< T > cache_mva(const Matrix< T > &gamma, const std::vector< int > &m)
Exact mean value analysis of a multi-list cache.
CacheMissIsResult< T > cache_miss_is(const Matrix< T > &gamma, const std::vector< int > &m, const Matrix< T > &lambda, std::size_t samples, std::uint64_t seed, const std::vector< int > &sigma, const std::vector< int > &cap)
Cache miss rates from the importance-sampling hit probabilities.
CacheXiFpResult< T > cache_xi_fp(const Matrix< T > &gamma, const std::vector< int > &m)
Lagrange multipliers of a multi-list cache by fixed-point iteration.
CacheMissResult< T > cache_miss_fpi(const Matrix< T > &gamma, const std::vector< int > &m, const Matrix< T > &lambda)
Cache miss rates from the fixed-point multipliers.
std::vector< T > cache_t_hlru(const Matrix< T > &gamma, const std::vector< int > &m)
Characteristic times of the h-LRU / LRU(m) TTL approximation.
CacheMissRmfResult< T > cache_miss_rmf_transient(const std::vector< int > &m_in, const Matrix< T > &lambda, const T &t0, const T &t1, const std::vector< T > &x0init, const std::vector< std::vector< Matrix< T > > > &accost, const CacheSojournClock< T > &clk=CacheSojournClock< T >())
Transient mean-field trajectory over [t0,t1] from a given initial occupancy, the optional TSPAN/X0INI...
CacheLrumMapLevelStats< T > cache_lrum_map_levelstats(const Matrix< T > &D0, const Matrix< T > &D1, const std::vector< T > &Tv)
Level statistics of one item's embedded (list, phase) chain in the LRU(m)-MAP TTL approximation.
CacheMvaMissResult< T > cache_mva_miss(const std::vector< T > &p, const std::vector< int > &m, const Matrix< T > &R)
Per-item and global cache miss probabilities by mean value analysis.
Matrix< T > cache_prob_erec(const Matrix< T > &gamma, const std::vector< int > &m, const std::vector< int > &sigma, const std::vector< int > &k)
Per-item hit and miss probabilities under per-list storage cost caps, pi_ij = m_j gamma(i,...
CacheCostMode
Whether the caps bound the cost from above (matching cache_erec) or resolve it exactly.
Matrix< T > cache_prob_is(const Matrix< T > &gamma, const std::vector< int > &m, std::size_t samples, std::uint64_t seed, const std::vector< int > &sigma, const std::vector< int > &k)
Importance-sampling estimate of the cache hit-probability distribution.
CacheSpmSizeResult< T > cache_spm_size(const Matrix< T > &gamma, const std::vector< int > &m, const std::vector< int > &sigma, const std::vector< int > &k, CacheCostMode mode=CacheCostMode::AtMost)
Ray (WKB) asymptotic expansion of the cost-capped cache normalizing constant.
CacheSpmResult< T > cache_spm(const Matrix< T > &gamma_in, const std::vector< int > &m)
Saddle-point approximation of the cache normalizing constant.
T cache_miss_asy(const Matrix< T > &gamma, const std::vector< int > &m, int maxIter, const T &tolerance)
Asymptotic (large-cache) miss ratio by a rank-threshold fixed point.
std::vector< T > cache_t_lrum_map(const std::vector< mam::Map< T > > &items, const std::vector< T > &m, const T &tol, unsigned maxswp=200)
Characteristic times of the LRU(m)-MAP TTL approximation.
CacheTtlLrumMapResult< T > cache_ttl_lrum_map(const std::vector< mam::Map< T > > &items, const std::vector< T > &m, const T &tol)
TTL approximation of an LRU(m) cache whose items are requested by Markovian arrival processes.
T cache_erec(const Matrix< T > &gamma, const std::vector< int > &m)
Exact recursive normalizing constant of a multi-list cache model.
CacheRrmMeanfieldResult< T > cache_rrm_meanfield(const std::vector< T > &lambda, const std::vector< int > &m, const T &tmax)
Steady state of the RANDOM(m) multi-list mean field.
Matrix< T > cache_ttl_lrua(const Matrix< T > &lambda, const std::vector< Matrix< T > > &R, const std::vector< T > &m, const T &tol, unsigned maxswp=200)
TTL (characteristic-time) approximation of an LRU cache whose lists form an arbitrary access graph.
CacheMissSpmResult< T > cache_miss_spm(const Matrix< T > &gamma, const std::vector< int > &m, const Matrix< T > &lambda)
Saddle-point approximation of the cache miss rates.
T da_traffic_superpos(const std::vector< T > &lambda, const std::vector< T > &a2)
Superposition of independent renewal flows (Whitt's QNA stationary-interval method).
CacheIsolateResult< T > da_cache_isolate(const CacheParam< T > &ch, const std::vector< T > &lambda)
Isolated-cache input construction for the decomposition methods.
Bernoulli1InfiniteResult< T > dqsys_bernoulli1(const T &b, const T &p)
dqsys_bernoulli1(b, p) with the reference's default L = Inf.
std::vector< std::vector< T > > fes_compute_throughputs(const Matrix< T > &L, const std::vector< int > &mi, const std::vector< bool > &isDelay, const std::vector< int > &cutoffs)
Per-class throughput table of an isolated subnetwork, tabulated over the population lattice,...
FesIsolated< T > fes_build_isolated(const Matrix< T > &rates, const Matrix< T > &stochCompS)
Build the isolated subnetwork's demands and visit ratios.
std::vector< mam::Map< T > > fes_map_levels(const mam::Map< T > &map, std::size_t n, double mi=1.0)
Replicate a load independent MAP over n levels, scaling level k by min(k, mi).
FesMapMoments< T > fes_map_moments(const mam::Map< T > &map, const std::string &method="ssolve", double step_safety=0.1, double tol=1e-12, std::size_t iter_max=1000000)
Moments and index of dispersion of an inter-departure MAP.
mam::Map< T > fes_map_interdeparture(const std::vector< mam::Map< T > > &maps, const std::vector< mam::Map< T > > &fes, std::size_t n)
Inter-departure MAP of a closed subnetwork made of one MAP station and one MAP flow-equivalent server...
FesMapSolveResult< T > fes_map_solve(const std::vector< mam::Map< T > > &fes, const mam::Map< T > &think_map, std::size_t n)
Closed model left by a MAP flow-equivalent server, and the per-station metrics behind it.
FesMapAggregateResult< T > fes_map_aggregate(const std::vector< mam::Map< T > > &maps, const std::vector< double > &servers, std::size_t n, const std::vector< std::size_t > &grid, const std::string &method="ssolve")
Recursive MAP flow-equivalent server for a station subset.
std::vector< T > fes_map_interp(const std::vector< T > &x, const std::vector< T > &y, const std::vector< T > &xq)
Monotone piecewise cubic Hermite interpolation of one series.
std::size_t ljd_linearize(const std::vector< int > &nvec, const std::vector< int > &cutoffs)
Linearized index of a per-class population vector, for Limited Joint Dependence (LJD) tables.
FesConditionalMetrics< T > fes_compute_metrics(const Matrix< T > &L, const std::vector< int > &mi, const std::vector< bool > &isDelay, const std::vector< int > &cutoffs)
Per-station metrics of the ISOLATED subnetwork at every population state, the companion of fes_comput...
PollingType
Polling service disciplines, with the values of MATLAB PollingType.
@ KLIMITED
serve at most K per visit (K in pollingPar)
@ EXHAUSTIVE
serve until the queue empties
@ GATED
serve exactly the jobs present at the polling instant
@ GLIMITED
serve at most K of the jobs present at the polling instant
@ DECREMENTING
serve until the queue is one shorter than at arrival
LossnLinksResult< T > lossn_links(const std::vector< T > &nu, const Matrix< T > &A, const std::vector< T > &C, const std::string &method="exact", const LossnMciOptions< T > &mciopt=LossnMciOptions< T >(), std::uint64_t seed=0)
Per-link blocking and occupancy of a loss network.
LossnAsyResult< T > lossn_asy(const std::vector< T > &nu, const Matrix< T > &A, const std::vector< T > &C)
Fluid (Kelly) limit of a loss network by convex duality.
LossnManjunathResult< T > lossn_manjunath(const std::vector< T > &nu, const Matrix< T > &A, const std::vector< T > &C, const LossnManjunathOptions &options=LossnManjunathOptions())
Exact normalizing constant, carried load and blocking of a loss network.
KrResult< T > lossn_kr(const std::vector< T > &rho, const std::vector< T > &b, const T &C)
Exact occupancy distribution and per-class blocking of a stochastic knapsack.
KrDimResult< T > lossn_kr_dim(const std::vector< T > &rho, const std::vector< T > &b, const std::vector< T > &Btarget)
Smallest link capacity meeting per-class blocking targets.
ErlangFpResult< T > lossn_erlangfp(const std::vector< T > &nu, const Matrix< T > &A, const std::vector< T > &C, const da::FpiOptions &options=lossn_erlangfp_options())
Erlang fixed-point (reduced-load) approximation for a loss network.
LossnMciResult< T > lossn_mci(const std::vector< T > &nu, const Matrix< T > &A, const std::vector< T > &C, const LossnMciOptions< T > &opt, Rng &gen)
Estimate the normalizing constant and the blocking probabilities.
KrAsyResult< T > lossn_kr_asy(const std::vector< T > &rho, const std::vector< T > &b, const T &C)
Normal approximation of multirate single-link blocking for large C.
LossnRecResult< T > lossn_rec(const std::vector< T > &nu, const Matrix< T > &A, const std::vector< T > &C)
Exact loss-network analysis by MDD-rec.
LossnRevsensResult< T > lossn_revsens(const std::vector< T > &nu, const Matrix< T > &A, const std::vector< T > &C, const std::vector< T > &w, const std::string &method="exact", const LossnMciOptions< T > &mciopt=LossnMciOptions< T >(), std::uint64_t seed=0)
Revenue sensitivities and implied costs of a loss network.
std::vector< std::vector< int > > ph_multisets(std::size_t p, std::size_t k)
Configurations of k identical servers over p service phases.
Map2mmppResult< T > map2mmpp(const Map< T > &m)
Modulating generator and arrival-rate matrix of a MAP read as an MMPP.
T map_mean(const Map< T > &m)
Mean inter-arrival time, 1/lambda.
T map_var(const Map< T > &m)
Variance of the inter-arrival time.
AphFitResult< T > aph_fit(const T &e1, const T &e2, const T &e3, unsigned nmax, const T &tol)
Fit an APH(n) with n <= nmax to the raw moments e1, e2, e3.
M3pp22FitcCovResult< T > m3pp22_fitc_approx_cov(const T &a, const T &bt1, const T &bt2, const T &binf, const T &m3t2, const T &t1, const T &t2, const std::vector< T > &ai, const T &st3, const T &t3, const AugLagOptions< T > &opt)
Fit the underlying MMPP(2) by optimization, then apply the covariance split.
bool mmdp_isfeasible(const Matrix< T > &Q, const Matrix< T > &R, const T &tol)
True when (Q, R) is a valid MMDP pair up to the given tolerance.
T map_moment(const Map< T > &m, unsigned k)
Raw moment of order k of the inter-arrival time: k!
T map_lambda(const Map< T > &m)
Stationary arrival rate, lambda = pi D1 e.
PhType< T > map2ph(const Map< T > &in)
(alpha, T) of the inter-arrival distribution: alpha = pie, T = D0 (map2ph.m).
MapqnQrResult< T > mapqn_bnd_qr_delay(const MapqnParams< T > &p, int objective_queue, int objective_phase, int objective_n, MapqnSense sense=MapqnSense::Max)
Bound P(queue objective_queue holds objective_n jobs in phaseobjective_phase) for a network with a de...
MapqnBndLrMvaResult< T > mapqn_bnd_lr_mva(const LrMvaParams< T > &p, int objective_queue, int objective_level, MapqnSense sense=MapqnSense::Max, MapqnObjectiveVar objective_var=MapqnObjectiveVar::UN)
Bound UN or QN at (objective_queue, objective_level) over the MVA-shaped LR polytope.
MapqnSense
Which direction the bound is taken in.
QrRsrdResult< T > mapqn_qr_bounds_rsrd(const QrRsrdParams< T > &p, int objective_queue, MapqnSense sense=MapqnSense::Min)
Bound the utilization of one queue over the RS-RD polytope.
MapqnAmvaResult< T > mapqn_amva(const std::vector< T > &mu_in, const std::vector< Matrix< T > > &D0s, const std::vector< Matrix< T > > &D1s, const std::vector< int > &N)
MapqnObjectiveVar
The variable family the objective is taken over.
QrBasResult< T > mapqn_qr_bounds_bas(const QrBasParams< T > &p, int objective_queue, MapqnSense sense=MapqnSense::Min)
Bound the utilization of one queue over the BAS polytope.
MapqnQrResult< T > mapqn_bnd_qr_ld(const MapqnParams< T > &p, int objective_queue, int objective_phase, int objective_n, MapqnSense sense=MapqnSense::Max)
Bound P(queue objective_queue holds objective_n jobs in phaseobjective_phase), in the requested direc...
MddClosedQnResult< T > mdd_closedqn(const std::vector< T > &mu, const Matrix< T > &P, const std::vector< double > &servers, int N, const MDD *reuse=nullptr)
Exact solve of a single-class closed exponential queueing network whose CTMC state space (reachable o...
T mdd_rec(const MddStruct &mdds, const std::vector< std::vector< T > > &g)
The normalising constant G = sum_{s in S} prod_l g_l(s_l).
PasPlacement< T > pas_placement(const Matrix< T > &H)
Precedence closure of a swap graph.
T infradius_h(const std::vector< T > &x, const Matrix< T > &L, const std::vector< T > &N, const Matrix< T > &alpha)
Logistic-substitution integrand (matlab/src/api/pfqn/infradius_h.m).
PollingPcl< T > polling_pcl(const PollingMoments< T > &m, const std::string &code)
Pseudo-conservation law SUM_i w_i E[W_i] = rhs of a cyclic polling system with Poisson arrivals (Taka...
std::vector< T > polling_qsys_klimited(const PollingMoments< T > &m, std::vector< long > K)
PollingTableResult< T > polling_qsys_table_full(const std::vector< T > &lambda, const std::vector< T > &b, const std::vector< T > &b2, const std::vector< std::size_t > &table, const std::vector< T > &s_mean, const std::vector< T > &s_var, bool gated)
Polling table, exhaustive or gated.
Json encode_vectors(const std::vector< std::vector< T > > &v)
A list of vectors, the shape a per-class or per-segment result returns.
Matrix< T > matrix_from_json(const Json &j, const std::string &where)
A matrix from a JSON value: 2-D array as rows, 1-D array as a row vector, scalar as 1x1,...
std::vector< int > int_vector_from_json(const Json &j, const std::string &where)
An integer vector; a non-integral entry is an error, never a truncation.
Json encode_matrices(const std::vector< Matrix< T > > &v)
A list of matrices, the shape the MMAP/BMAP families return as {D0,D1,...}.
void register_library_only_misc(LibraryOnlyTable &t)
std::vector< T > vector_from_json(const Json &j, const std::string &where)
A flat numeric vector: 1-D array, or a 1-row / 1-column 2-D array.
Json encode_vector(const std::vector< T > &v)
Json encode_matrix(const Matrix< T > &m)
std::string decimal_text(const Json &j, const std::string &where)
The decimal literal behind a JSON scalar, per the policy in the file header.
Json encode_scalar(const T &v)
Json encode_count(std::size_t n)
A count.
void register_api_misc(DispatchTable &t)
std::map< std::string, std::string > LibraryOnlyTable
name -> why the function has no named-JSON-argument form.
Json encode_ints(const std::vector< int > &v)
std::map< std::string, Invoker > DispatchTable
RetrievalStationType
Scheduling of a retrieval station, mirroring the MATLAB station_type strings.
RetrievalRayintResult< T > retrieval_rayint(const Matrix< T > &gamma, const std::vector< int > &m)
Discrete (saddle) form.
T retrieval_nc(const std::vector< int > &v, const std::vector< int > &m, const std::vector< T > &lambda, const Matrix< T > &eta, const Matrix< T > &gamma)
Exact normalizing constant E(v,m) of a delayed-hit (list-based) cache.
RetrievalFpiLatencyResult< T > retrieval_fpi_latency(const std::vector< int > &m, const std::vector< T > &lambda, const Matrix< T > &gamma, const std::vector< RetrievalStationPH< T > > &station, const std::vector< Matrix< T > > &R, const FpiOptions &options=FpiOptions())
FPI-based approximation of the delayed-hit count and the expected latency of a list-based cache with ...
RetrievalFpiResult< T > retrieval_fpi(const std::vector< int > &m, const std::vector< T > &lambda, const Matrix< T > &eta, const Matrix< T > &gamma, const FpiOptions &options=FpiOptions())
Fixed-point heuristic for a delayed-hit (list-based) cache.
std::vector< bool > spn_ispn_covered(const std::vector< std::vector< double > > &C)
Places covered by a non-negative S-invariant (P-semiflow) y' C = 0, by Farkas' algorithm on [C | I] k...
IspnResult spn_ispn(const std::vector< std::vector< double > > &pre, const std::vector< std::vector< double > > &post, std::vector< std::vector< double > > inh, const std::vector< double > &rate, std::vector< bool > imm, std::vector< double > srv, const std::vector< double > &m0, std::size_t p0, const IspnOptions &opt=IspnOptions())
Steady state of an infinite-state SPN.
SpnEnabling< T > spn_rec_enabled(const mdd::MddStruct &mdds, const std::vector< std::vector< T > > &g, const SpnMode< T > &mde, std::size_t nplacelevels)
Enabling-degree masses of mode mde over the reachable set in mdds.
T spn_conv(const std::vector< std::vector< long long > > &S, const std::vector< long long > &V, const std::vector< std::vector< T > > &g)
The normalising constant by convolution over the invariant load vector.
SumClosedResult< T > sum_closed(const Matrix< T > &L, const std::vector< long > &N, const std::vector< T > &Z, const std::vector< Servers > &mi, const Matrix< T > &scv, const SumOptions &options=SumOptions())
Summation method (SUM) and its extension (ESUM) for closed queueing networks, including non-product-f...
SumClosingResult< T > sum_closing(const std::vector< T > &lambda0, const std::vector< T > &scva, const Matrix< T > &L, const std::vector< Servers > &mi, const Matrix< T > &scv, const std::vector< long > &N, const std::vector< T > &Z, const ClosingOptions &options=ClosingOptions())
Closing method for open and mixed non-product-form queueing networks, solved with the summation metho...
std::vector< T > autocov(const std::vector< T > &S)
Sample autocovariance sequence of a trace, lags 0 .
std::vector< int > detect_loops(const Matrix< T > &linkMatrix, const std::vector< int > &serviceNodes, const std::vector< int > &routerNodes, const std::vector< int > &joinNodes=std::vector< int >())
BranchStats< T > get_branch_stats(const std::vector< BranchPattern< T > > &patterns)
Count, total, mean/max/min alternatives, and the mean entropy and balance.
ExpectedIterations< T > get_expected_loop_iterations(const T &loopProbability)
Mean number of visits of a geometric loop, 1/(1-p).
BranchDiversity< T > calculate_branch_diversity(const BranchPattern< T > &pattern)
Shannon entropy of the branch probabilities, the same entropy normalized by log(n),...
std::vector< std::vector< int > > detect_sequences(const Matrix< T > &linkMatrix, const std::vector< int > &serviceNodes)
SequenceStats< T > get_sequence_stats(const std::vector< std::vector< int > > &sequences)
Count, total, mean, maximum and minimum chain length.
std::vector< BranchPattern< T > > detect_branches(const Matrix< T > &linkMatrix, const std::vector< int > &serviceNodes, const std::vector< int > &joinNodes)
ParallelStats< T > get_parallel_stats(const std::vector< std::vector< int > > &patterns)
Count, total, mean and maximum degree of parallelism.
T get_loop_probability(int serviceNode, const Matrix< T > &linkMatrix, const std::vector< int > &routerNodes)
Probability on the router-to-service edge that closes the loop, 0 when the node is not on a simple lo...
LoopStats< T > get_loop_stats(const std::vector< int > &loopNodes, const Matrix< T > &linkMatrix, const std::vector< int > &routerNodes)
Count and moments of the loop probabilities and iteration counts.
std::vector< std::vector< int > > detect_parallel(const Matrix< T > &linkMatrix, const std::vector< int > &serviceNodes, const std::vector< int > &forkNodes, const std::vector< int > &joinNodes)
Conservation laws of a layered queueing network, enumerated from its structure.
Placement order of a pass-and-swap (P&S) order-independent network.
Mean waiting times in polling systems: 1-limited and decrementing service, and the pseudo-conservatio...
Mean waiting times of a polling system under exhaustive service.
Approximate mean waiting times of a cyclic k-limited polling system.
Exact mean waiting times of a polling system with a polling table.
Fixed-point heuristic for a delayed-hit (list-based) cache.
FPI-based approximation of the delayed-hit count and the expected latency of a list-based cache with ...
Exact miss, hit and delayed-hit metrics of a delayed-hit (list-based) cache.
Exact MVA-style recursion for delayed-hit (list-based) cache metrics.
Exact normalizing constant E(v,m) of a delayed-hit (list-based) cache.
Ray (WKB) asymptotic expansion of the list-based cache normalizing constant.
Convolution algorithm for the normalising constant of an S-invariant reachable product-form stochasti...
Infinite-state stochastic Petri nets (iSPN) by the matrix-geometric method.
Decision-diagram reachable set and Kronecker rate descriptor of a stochastic Petri net,...
Enabling-degree distribution of one mode of a product-form stochastic Petri net, by the masked MDD-re...
Minimal-support S-invariants (P-invariants) of a stochastic Petri net, and the load vector V = S m0.
static Servers of(long m)
Summation method (SUM) and its extension (ESUM) for closed queueing networks, including non-product-f...
Closing method for open and mixed non-product-form queueing networks, solved with the summation metho...
Branch (probabilistic choice) pattern detection in a workflow network.
Loop pattern detection in a workflow network.
Parallel (fork-join) pattern detection in a workflow network.
Sequence pattern detection in a workflow network.