198 if (text ==
"double") {
202 if (text ==
"exact") {
206 if (text.compare(0, 5,
"real:") == 0 || text ==
"real") {
208 if (text !=
"real") {
209 const std::string d = text.substr(5);
210 if (d.empty() || d.find_first_not_of(
"0123456789") != std::string::npos)
211 throw InputError(
"--arith real:<digits> needs a decimal digit count, got '" + d +
213 want =
static_cast<unsigned>(std::strtoul(d.c_str(),
nullptr, 10));
214 if (want == 0)
throw InputError(
"--arith real:<digits> needs at least one digit");
220 else if (want <= 100)
222 else if (want <= 200)
226 "--arith real:" + std::to_string(want) +
227 " exceeds the precision tiers this build instantiates (50, 100, 200 digits); "
228 "a wider tier has to be compiled in, it cannot be selected at run time.");
232 "'; accepted forms are: double, exact, real:<digits> "
233 "(digits rounded up to 50, 100 or 200)");
249Json run_at(
const ArithSpec& s, Args& a) {
252 case Arith::Exact:
return Op::template run<Rational>(a);
254 if (s.digits <= 50)
return Op::template run<Real50>(a);
255 if (s.digits <= 100)
return Op::template run<Real100>(a);
256 return Op::template run<Real200>(a);
258 throw InputError(
"unreachable arithmetic selection");
273struct NeedsTranscendental {
275 static Json run(Args& a) {
276 if constexpr (num_traits<T>::has_transcendental) {
277 return Op::template run<T>(a);
281 "this function evaluates transcendental terms (exp, log, sqrt or a "
282 "matrix exponential), which the exact rational field does not contain; "
283 "rerun with --arith double or --arith real:<digits>.");
290Json nc_results(
const pfqn::NcResult<T>& r) {
299 static Json run(Args& a) {
300 const Matrix<T> L = a.matrix<T>(
"L");
301 const std::vector<int> N = a.ints(
"N");
302 const Matrix<T> Z = a.matrix_or_empty<T>(
"Z");
310 static Json run(Args& a) {
311 const Matrix<T> L = a.matrix<T>(
"L");
312 const std::vector<int> N = a.ints(
"N");
313 const Matrix<T> Z = a.matrix_or_empty<T>(
"Z");
314 a.unsupported(
"cdscaling",
315 "the class-dependence scaling argument is a vector of callables, which has "
316 "no JSON representation; call pfqn_conv from the library for that case");
317 a.unsupported(
"options",
"solver options are not carried over the --api boundary");
325 static Json run(Args& a) {
326 const Matrix<T> L = a.matrix<T>(
"L");
327 const std::vector<int> N = a.ints(
"N");
328 const Matrix<T> Z = a.matrix_or_empty<T>(
"Z");
329 const std::vector<int> m0 = a.ints_or_empty(
"m0");
337 static Json run(Args& a) {
338 const Matrix<T> L = a.matrix<T>(
"L");
339 const std::vector<int> N = a.ints(
"N");
340 const Matrix<T> mu = a.matrix<T>(
"mu");
341 a.unsupported(
"options",
"solver options are not carried over the --api boundary");
349 static Json run(Args& a) {
350 const Matrix<T> L = a.matrix<T>(
"L");
351 const std::vector<int> N = a.ints(
"N");
352 const Matrix<T> Z = a.matrix_or_empty<T>(
"Z");
353 const std::vector<int> mi = a.ints_or_empty(
"mi");
369Json comom_results(
const pfqn::ComomResult<T>& r) {
379 static Json run(Args& a) {
380 const Matrix<T> L = a.matrix<T>(
"L");
381 const std::vector<int> N = a.ints(
"N");
382 const std::vector<T> Z = a.vector_or_empty<T>(
"Z");
383 const T atol = a.scalar<T>(
"atol", num_traits<T>::from_int(0));
389struct OpPfqnComomrm {
391 static Json run(Args& a) {
392 const Matrix<T> L = a.matrix<T>(
"L");
393 const std::vector<int> N = a.ints(
"N");
394 const Matrix<T> Z = a.matrix_or_empty<T>(
"Z");
395 const int m = a.integer(
"m", 1);
401struct OpPfqnComomrmOrig {
403 static Json run(Args& a) {
404 const Matrix<T> L = a.matrix<T>(
"L");
405 const std::vector<int> N = a.ints(
"N");
406 const Matrix<T> Z = a.matrix_or_empty<T>(
"Z");
407 const T atol = a.scalar<T>(
"atol", num_traits<T>::from_int(0));
413struct OpPfqnComomrmMs {
415 static Json run(Args& a) {
416 const Matrix<T> L = a.matrix<T>(
"L");
417 const std::vector<int> N = a.ints(
"N");
418 const Matrix<T> Z = a.matrix_or_empty<T>(
"Z");
419 const int m = a.integer(
"m", 1);
420 const int S = a.integer(
"S", 1);
431struct OpPfqnProcomom {
433 static Json run(Args& a) {
434 const Matrix<T> L = a.matrix<T>(
"L");
435 const std::vector<int> N = a.ints(
"N");
436 const std::vector<T> Z = a.vector_or_empty<T>(
"Z");
437 const T atol = a.scalar<T>(
"atol", num_traits<T>::from_int(0));
443 out[
"rankdef"] = r.rankdef;
450 static Json run(Args& a) {
451 const Matrix<T> Q = a.matrix<T>(
"Q");
452 a.unsupported(
"options",
"solver options are not carried over the --api boundary");
462 static Json run(Args& a) {
463 const Matrix<T> P = a.matrix<T>(
"P");
464 a.unsupported(
"options",
"solver options are not carried over the --api boundary");
472struct OpCtmcMakeinfgen {
474 static Json run(Args& a) {
475 const Matrix<T> Q = a.matrix<T>(
"Q");
503struct QuestOptionsRead {
504 sim::QuestOptions opt;
505 bool supplied =
false;
509QuestOptionsRead read_quest_options(
Args& a) {
510 QuestOptionsRead out;
511 const char* keys[] = {
"b0",
"m0",
"s",
"beta",
"eta",
"theta",
"weight",
"force"};
512 for (std::size_t k = 0; k <
sizeof(keys) /
sizeof(keys[0]); ++k)
513 if (a.has(keys[k])) out.supplied =
true;
514 out.opt.b0 =
static_cast<long>(a.integer(
"b0",
static_cast<int>(out.opt.b0)));
515 out.opt.m0 =
static_cast<long>(a.integer(
"m0",
static_cast<int>(out.opt.m0)));
516 const std::vector<int> s = a.ints_or_empty(
"s");
519 for (std::size_t i = 0; i < s.size(); ++i) out.opt.s.push_back(
static_cast<long>(s[i]));
521 out.opt.beta = a.scalar<
double>(
"beta", out.opt.beta);
522 out.opt.eta = a.scalar<
double>(
"eta", out.opt.eta);
523 out.opt.theta = a.scalar<
double>(
"theta", out.opt.theta);
524 out.opt.weight = a.scalar<
double>(
"weight", out.opt.weight);
525 out.opt.force = a.integer(
"force", out.opt.force ? 1 : 0) != 0;
531Json quest_results(
const sim::QuestResult<T>& r) {
537 out[
"b"] =
static_cast<long long>(r.b);
538 out[
"m"] =
static_cast<long long>(r.m);
539 out[
"n"] =
static_cast<long long>(r.n);
540 out[
"R"] =
static_cast<long long>(r.R);
541 out[
"truncated"] =
static_cast<long long>(r.truncated);
545 out[
"heuristic"] = r.heuristic;
546 out[
"warnings"] = r.warnings;
551std::string sim_exact_refusal(
const char* fn,
const char* why) {
552 return std::string(fn) +
": " + why +
553 ", so exact rational arithmetic has nothing to preserve and is refused; rerun with "
554 "--arith double or --arith real";
557struct OpSimVonneumann {
559 static Json run(Args& a) {
560 if constexpr (!num_traits<T>::has_transcendental) {
562 sim_exact_refusal(
"sim_vonneumann",
"the p-value is a normal tail"));
565 const double alpha = a.scalar<
double>(
"alpha", 0.05);
570 out[
"zscore"] = r.zscore;
571 out[
"pvalue"] = r.pvalue;
572 out[
"reject"] = r.reject;
573 out[
"nobs"] =
static_cast<long long>(r.nobs);
579struct OpSimShapirowilk {
581 static Json run(Args& a) {
582 if constexpr (!num_traits<T>::has_transcendental) {
584 "sim_shapirowilk",
"the weights and the p-value are normal-order statistics"));
587 const double alpha = a.scalar<
double>(
"alpha", 0.05);
592 out[
"pvalue"] = r.pvalue;
593 out[
"zscore"] = r.zscore;
594 out[
"reject"] = r.reject;
595 out[
"nobs"] =
static_cast<long long>(r.nobs);
601struct OpSimStsQuantileAreas {
603 static Json run(Args& a) {
604 if constexpr (!num_traits<T>::has_transcendental) {
606 "sim_sts_quantile_areas",
"the areas carry the irrational weight sqrt(12)"));
608 const std::vector<T> Y =
610 const int b = a.integer(
"b", 0);
611 const int m = a.integer(
"m", 0);
612 const double p = a.scalar<
double>(
"p", 0.5);
613 const double weight = a.scalar<
double>(
"weight", std::sqrt(12.0));
615 if (b <= 0 || m <= 0)
617 "sim_sts_quantile_areas: the batch count b and batch size m are required and "
618 "must be positive integers");
620 Y,
static_cast<std::size_t
>(b),
static_cast<std::size_t
>(m), p, weight);
628 out[
"b"] =
static_cast<long long>(r.b);
629 out[
"m"] =
static_cast<long long>(r.m);
630 out[
"n"] =
static_cast<long long>(r.n);
638 static Json run(Args& a) {
639 if constexpr (!num_traits<T>::has_transcendental) {
641 "sim_fquest",
"the interval is a t quantile times a square root"));
644 const double p = a.scalar<
double>(
"p", 0.5);
645 const double alpha = a.scalar<
double>(
"alpha", 0.05);
646 const QuestOptionsRead o = read_quest_options(a);
653struct OpSimFirquest {
655 static Json run(Args& a) {
656 if constexpr (!num_traits<T>::has_transcendental) {
658 "sim_firquest",
"the interval is a t quantile times a square root"));
664 const Matrix<T> Ym = a.matrix<T>(
"Y");
665 const double p = a.scalar<
double>(
"p", 0.5);
666 const double alpha = a.scalar<
double>(
"alpha", 0.05);
667 const QuestOptionsRead o = read_quest_options(a);
669 std::vector<std::vector<T> > Y(Ym.cols(), std::vector<T>(Ym.rows()));
670 for (std::size_t i = 0; i < Ym.rows(); ++i)
671 for (std::size_t r = 0; r < Ym.cols(); ++r) Y[r][i] = Ym(i, r);
675 return quest_results(
709Json qsys_results(
const qsys::QsysResult<T>& r) {
720#define LINE_QSYS_GIG1(OpName, fn) \
723 static Json run(Args& a) { \
724 const T lambda = a.number<T>("lambda"); \
725 const T mu = a.number<T>("mu"); \
726 const T ca = a.number<T>("ca"); \
727 const T cs = a.number<T>("cs"); \
729 return qsys_results(qsys::fn(lambda, mu, ca, cs)); \
733LINE_QSYS_GIG1(OpQsysGig1AllenCunneen, qsys_gig1_approx_allencunneen);
744#define LINE_QSYS_GIGK(OpName, fn) \
747 static Json run(Args& a) { \
748 const T lambda = a.number<T>("lambda"); \
749 const T mu = a.number<T>("mu"); \
750 const T ca = a.number<T>("ca"); \
751 const T cs = a.number<T>("cs"); \
752 const unsigned k = a.uinteger("k"); \
754 return qsys_results(qsys::fn(lambda, mu, ca, cs, k)); \
770struct OpQsysErlangA {
772 static Json run(Args& a) {
773 const T lambda = a.number<T>(
"lambda");
774 const T mu = a.number<T>(
"mu");
775 const T theta = a.number<T>(
"theta");
776 const unsigned s = a.uinteger(
"s");
779 : std::numeric_limits<double>::infinity();
780 qsys::MgisrgiOptions opts;
781 opts.wPoints = a.vector_or_empty<
double>(
"wPoints");
782 opts.maxQueue = a.count(
"maxQueue", qsys::MgisrgiOptions().maxQueue);
784 const qsys::QsysAbandonResult<T> res =
qsys::qsys_erlanga(lambda, mu, theta, s, r, opts);
803 out[
"secondMomentWait"] =
encode_scalar(res.secondMomentWait);
804 out[
"numWaitingSpaces"] =
static_cast<double>(res.numWaitingSpaces);
805 if (!res.waitPoints.empty()) {
815struct OpQsysGgnmDiffusion {
817 static Json run(Args& a) {
818 const T lambda = a.number<T>(
"lambda");
819 const T mu = a.number<T>(
"mu");
820 const unsigned n = a.uinteger(
"n");
822 const double m = a.has(
"m") ? a.number<
double>(
"m")
823 : std::numeric_limits<double>::infinity();
824 const T ca = a.number<T>(
"ca");
825 const T cs = a.number<T>(
"cs");
845struct OpQsysGig1BndsExtremal {
847 static Json run(Args& a) {
848 const T lambda = a.number<T>(
"lambda");
849 const T mu = a.number<T>(
"mu");
850 const T ca = a.number<T>(
"ca");
851 const T cs = a.number<T>(
"cs");
852 const std::size_t K = a.count(
"K", 4000);
853 const std::size_t N = a.count(
"N", 2000);
854 const bool skipTight = a.boolean(
"skipTight",
false);
856 const qsys::Gig1ExtremalResult<T> r =
864 out[
"upperBoundKingman"] =
encode_scalar(r.upperBoundKingman);
868 out[
"tightComputed"] = r.tightComputed;
875 static Json run(Args& a) {
876 const T lambda = a.number<T>(
"lambda");
877 const T mu = a.number<T>(
"mu");
878 const unsigned s = a.uinteger(
"s");
895struct OpQsysMmkQedAlpha {
897 static Json run(Args& a) {
898 const T beta = a.number<T>(
"beta");
906struct OpQsysMmkQedStaffing {
908 static Json run(Args& a) {
909 const T lambda = a.number<T>(
"lambda");
910 const T mu = a.number<T>(
"mu");
911 const std::string crit = a.text(
"criterion",
"delay");
912 const T target = a.has(
"target") ? a.number<T>(
"target") : num_traits<T>::from_int(0);
913 const T deadline = a.has(
"deadline") ? a.number<T>(
"deadline") : num_traits<T>::from_int(0);
914 const T level = a.has(
"level") ? a.number<T>(
"level") : num_traits<T>::from_int(0);
915 const bool exact = a.boolean(
"exact",
false);
918 if (crit ==
"meanwait") {
920 }
else if (crit ==
"servicelevel") {
922 }
else if (crit !=
"delay") {
923 throw InputError(
"qsys_mmk_qed_staffing: unknown criterion '" + crit +
"'");
925 const qsys::QsysQedStaffingResult<T> r =
928 out[
"numServers"] =
static_cast<double>(r.numServers);
942struct OpQsysGigkRqt {
944 static Json run(Args& a) {
945 const T lambda = a.number<T>(
"lambda");
946 const T mu = a.number<T>(
"mu");
947 const T Gamma_a = a.number<T>(
"Gamma_a");
948 const T Gamma_s = a.number<T>(
"Gamma_s");
949 const unsigned k = a.uinteger(
"k");
950 const T alpha_a = a.number<T>(
"alpha_a");
951 const T alpha_s = a.number<T>(
"alpha_s");
953 const qsys::GigkRqtResult<T> r =
963struct OpQsysGig1Rqt {
965 static Json run(Args& a) {
966 const T lambda = a.number<T>(
"lambda");
967 const T mu = a.number<T>(
"mu");
968 const T Gamma_a = a.number<T>(
"Gamma_a");
969 const T Gamma_s = a.number<T>(
"Gamma_s");
970 const T alpha_a = a.number<T>(
"alpha_a");
971 const T alpha_s = a.number<T>(
"alpha_s");
973 const qsys::GigkRqtResult<T> r =
983struct OpQsysGigkRqtGamma {
985 static Json run(Args& a) {
986 const T rho = a.number<T>(
"rho");
987 const T mu = a.number<T>(
"mu");
988 const T Gamma_a = a.number<T>(
"Gamma_a");
989 const T sigma_s = a.number<T>(
"sigma_s");
990 const unsigned k = a.uinteger(
"k");
991 const T alpha_a = a.number<T>(
"alpha_a");
992 const std::string regime = a.text(
"regime",
"independent");
1001#define LINE_QSYS_MYSKJA(OpName, fn) \
1003 template <class T> \
1004 static Json run(Args& a) { \
1005 const T lambda = a.number<T>("lambda"); \
1006 const T mu = a.number<T>("mu"); \
1007 const T ca = a.number<T>("ca"); \
1008 const T cs = a.number<T>("cs"); \
1009 const T q0 = a.number<T>("q0"); \
1010 const T qa = a.number<T>("qa"); \
1012 return qsys_results(qsys::fn(lambda, mu, ca, cs, q0, qa)); \
1018#undef LINE_QSYS_MYSKJA
1022 static Json run(Args& a) {
1023 const T lambda = a.number<T>(
"lambda");
1024 const T mu = a.number<T>(
"mu");
1032 static Json run(Args& a) {
1033 const T lambda = a.number<T>(
"lambda");
1034 const T mu = a.number<T>(
"mu");
1035 const unsigned k = a.uinteger(
"k");
1043 static Json run(Args& a) {
1044 const T lambda = a.number<T>(
"lambda");
1045 const T mu = a.number<T>(
"mu");
1046 const T cs = a.number<T>(
"cs");
1054 static Json run(Args& a) {
1055 const T lambda = a.number<T>(
"lambda");
1056 const T mu = a.number<T>(
"mu");
1057 const T ca2 = a.number<T>(
"ca2");
1058 const T cs2 = a.number<T>(
"cs2");
1067 static Json run(Args& a) {
1068 const T sigma = a.number<T>(
"sigma");
1069 const T mu = a.number<T>(
"mu");
1079 static Json run(Args& a) {
1080 const T lambda = a.number<T>(
"lambda");
1081 const T mu = a.number<T>(
"mu");
1082 const bool has_k = a.has(
"k");
1083 const unsigned k = has_k ? a.uinteger(
"k") : 0u;
1085 const qsys::MginfResult<T> r =
1103 static Json run(Args& a) {
1104 const T lambda = a.number<T>(
"lambda");
1105 const T mu = a.number<T>(
"mu");
1106 const unsigned c = a.uinteger(
"c");
1107 const unsigned K = a.uinteger(
"K");
1112 out[
"meanQueueLengthQ"] =
encode_scalar(r.meanQueueLengthQ);
1123struct OpQsysMm1kLoss {
1125 static Json run(Args& a) {
1126 const T lambda = a.number<T>(
"lambda");
1127 const T mu = a.number<T>(
"mu");
1128 const unsigned K = a.uinteger(
"K");
1138struct OpQsysMg1kLossMgs {
1140 static Json run(Args& a) {
1141 const T lambda = a.number<T>(
"lambda");
1142 const T mu = a.number<T>(
"mu");
1143 const T mu_scv = a.number<T>(
"mu_scv");
1144 const unsigned K = a.uinteger(
"K");
1162 static Json run(Args& a) {
1163 const T lambda_batch = a.number<T>(
"lambda_batch");
1164 const T mu = a.number<T>(
"mu");
1165 const T E_X = a.number<T>(
"E_X");
1166 const bool has_m2 = a.has(
"E_X2"), has_var = a.has(
"Var_X");
1167 if (has_m2 == has_var)
1169 "qsys_mxm1: give exactly one of 'E_X2' (the second moment of the batch size) "
1170 "and 'Var_X' (its variance); MATLAB selects between them with a trailing "
1171 "'variance' flag, which has no place in a named-argument object");
1172 const T m2 = has_m2 ? a.number<T>(
"E_X2")
1173 : T(a.number<T>(
"Var_X") + E_X * E_X);
1175 const qsys::MxM1Result<T> r =
qsys::qsys_mxm1(lambda_batch, mu, E_X, m2);
1187 static Json run(Args& a) {
1188 const T lambda = a.number<T>(
"lambda_arr");
1189 const T mu = a.number<T>(
"mu");
1190 const unsigned c = a.uinteger(
"c");
1191 const bool tuned = a.has(
"truncation") || a.has(
"quadSteps");
1192 const unsigned truncation = a.uinteger(
"truncation", 0u);
1193 const unsigned quadSteps = a.uinteger(
"quadSteps", 200u);
1195 const qsys::DmcResult<T> r = tuned ?
qsys::qsys_dmc(lambda, mu, c, truncation, quadSteps)
1199 out[
"meanWaitingQueue"] =
encode_scalar(r.meanWaitingQueue);
1207struct OpQsysMmccRetrialFp {
1209 static Json run(Args& a) {
1210 const T lambda = a.number<T>(
"lambda");
1211 const T mu = a.number<T>(
"mu");
1212 const unsigned c = a.uinteger(
"c");
1213 const bool tuned = a.has(
"tol") || a.has(
"maxiter");
1214 const T tol = a.scalar<T>(
"tol", num_traits<T>::from_int(0));
1215 const std::size_t maxiter = a.count(
"maxiter", 0);
1217 const qsys::MmccRetrialFpResult<T> r =
1221 out[
"blockingProbability"] =
encode_scalar(r.blockingProbability);
1224 out[
"converged"] = r.converged;
1229struct OpQsysMm1Dps {
1231 static Json run(Args& a) {
1232 const std::vector<T> lambda = a.vector<T>(
"lambda");
1233 const std::vector<T> mu = a.vector<T>(
"mu");
1234 const std::vector<T> w = a.vector<T>(
"w");
1235 const bool tuned = a.has(
"tol") || a.has(
"maxCutoff");
1236 const T tol = a.scalar<T>(
"tol", num_traits<T>::from_int(0));
1237 const unsigned maxCutoff = a.uinteger(
"maxCutoff", 0u);
1239 const qsys::Mm1DpsResult<T> r = tuned
1253#define LINE_QSYS_MG1_DISC(OpName, fn, ResultT) \
1255 template <class T> \
1256 static Json run(Args& a) { \
1257 const std::vector<T> lambda = a.vector<T>("lambda"); \
1258 const std::vector<T> mu = a.vector<T>("mu"); \
1259 const std::vector<T> cs = a.vector<T>("cs"); \
1261 const qsys::ResultT<T> r = qsys::fn(lambda, mu, cs); \
1263 out["W"] = encode_vector(r.W); \
1264 out["rhohat"] = encode_scalar(r.rhohat); \
1275#undef LINE_QSYS_MG1_DISC
1284 const std::string c = a.text(
"convention",
"LAS_DA");
1287 throw InputError(
"'convention' must be LAS_DA or EAS, got '" + c +
"'");
1294struct OpQsysGeoGeo1 {
1296 static Json run(Args& a) {
1297 const T arrival = a.number<T>(
"a");
1298 const T service = a.number<T>(
"s");
1303 out[
"convention"] = geo_convention_name(r.convention);
1311 out[
"meanWaitingQueue"] =
encode_scalar(r.meanWaitingQueue);
1319struct OpQsysGeoxGeo1 {
1321 static Json run(Args& a) {
1322 const T arrival = a.number<T>(
"a");
1323 const T beta = a.number<T>(
"beta");
1324 const T service = a.number<T>(
"s");
1329 out[
"convention"] = geo_convention_name(r.convention);
1330 out[
"batchArrivalProb"] =
encode_scalar(r.batchArrivalProb);
1332 out[
"batchSecondFactorialMoment"] =
encode_scalar(r.batchSecondFactorialMoment);
1337 out[
"boundaryEmptyProb"] =
encode_scalar(r.boundaryEmptyProb);
1339 out[
"meanWaitingQueue"] =
encode_scalar(r.meanWaitingQueue);
1349Json qsys_map_results(
const R& r) {
1361mam::Map<T> read_map(
Args& a,
const char* d0,
const char* d1) {
1363 m.D0 = a.matrix<T>(d0);
1364 m.D1 = a.matrix<T>(d1);
1370 static Json run(Args& a) {
1371 const mam::Map<T> arrival = read_map<T>(a,
"D0",
"D1");
1372 const T mu = a.number<T>(
"mu");
1373 const bool sized = a.has(
"dist_size");
1374 const std::size_t dist_size = a.count(
"dist_size", 0);
1383 static Json run(Args& a) {
1384 const mam::Map<T> arrival = read_map<T>(a,
"D0",
"D1");
1385 const T mu = a.number<T>(
"mu");
1386 const unsigned c = a.uinteger(
"c");
1387 const bool sized = a.has(
"dist_size");
1388 const std::size_t dist_size = a.count(
"dist_size", 0);
1390 return qsys_map_results(sized ?
qsys::qsys_mapmc(arrival, mu, c, dist_size)
1395struct OpQsysMapmap1 {
1397 static Json run(Args& a) {
1398 const mam::Map<T> arrival = read_map<T>(a,
"C0",
"C1");
1399 const mam::Map<T> service = read_map<T>(a,
"D0",
"D1");
1400 const bool sized = a.has(
"dist_size");
1401 const std::size_t dist_size = a.count(
"dist_size", 0);
1408struct OpQsysMapph1 {
1410 static Json run(Args& a) {
1411 const mam::Map<T> arrival = read_map<T>(a,
"D0",
"D1");
1412 const std::vector<T> sigma = a.vector<T>(
"sigma");
1413 const Matrix<T> S = a.matrix<T>(
"S");
1414 const bool sized = a.has(
"dist_size");
1415 const std::size_t dist_size = a.count(
"dist_size", 0);
1427struct OpQsysMapphc {
1429 static Json run(Args& a) {
1430 const mam::Map<T> arrival = read_map<T>(a,
"D0",
"D1");
1431 const std::vector<T> alpha = a.vector<T>(
"alpha");
1432 const Matrix<T> S = a.matrix<T>(
"S");
1433 const unsigned c = a.uinteger(
"c");
1435 a.has(
"dist_size") || a.has(
"num_w_moms") || a.has(
"w_points");
1437 a.has(
"dist_size") && a.has(
"num_w_moms") && a.has(
"w_points");
1440 "qsys_mapphc: 'dist_size', 'num_w_moms' and 'w_points' select one tuned "
1441 "overload together; give all three or none");
1442 const std::size_t dist_size = a.count(
"dist_size", 0);
1443 const std::size_t num_w_moms = a.count(
"num_w_moms", 0);
1444 const std::vector<T> w_points = a.vector_or_empty<T>(
"w_points");
1446 const qsys::MapPhcResult<T> r =
1449 Json out = qsys_map_results(r);
1450 out[
"waitingTimeMoments"] =
encode_vector(r.waitingTimeMoments);
1452 out[
"waitingTimePoints"] =
encode_vector(r.waitingTimePoints);
1464 static Json run(Args& a) {
1465 const std::vector<T> alpha = a.vector<T>(
"alpha");
1466 const Matrix<T> Tm = a.matrix<T>(
"T");
1467 const std::vector<T> beta = a.vector<T>(
"beta");
1468 const Matrix<T> S = a.matrix<T>(
"S");
1469 const bool sized = a.has(
"dist_size");
1470 const std::size_t dist_size = a.count(
"dist_size", 0);
1472 return qsys_map_results(sized ?
qsys::qsys_phph1(alpha, Tm, beta, S, dist_size)
1483inline bool qsys_map_d_tuned(
Args& a,
const char* who) {
1484 const bool any = a.has(
"dist_size") || a.has(
"max_arrivals") || a.has(
"max_levels") ||
1486 const bool all = a.has(
"dist_size") && a.has(
"max_arrivals") && a.has(
"max_levels") &&
1490 ": 'dist_size', 'max_arrivals', 'max_levels' and 'tol' tune one "
1491 "truncation together; give all four or none");
1497 static Json run(Args& a) {
1498 const mam::Map<T> arrival = read_map<T>(a,
"D0",
"D1");
1499 const T s = a.number<T>(
"s");
1500 const bool tuned = qsys_map_d_tuned(a,
"qsys_mapd1");
1501 const std::size_t dist_size = a.count(
"dist_size", 0);
1502 const unsigned max_arrivals = a.uinteger(
"max_arrivals", 0u);
1503 const std::size_t max_levels = a.count(
"max_levels", 0);
1504 const T tol = a.scalar<T>(
"tol", num_traits<T>::from_int(0));
1506 return qsys_map_results(
1507 tuned ?
qsys::qsys_mapd1(arrival, s, dist_size, max_arrivals, max_levels, tol)
1514 static Json run(Args& a) {
1515 const mam::Map<T> arrival = read_map<T>(a,
"D0",
"D1");
1516 const T s = a.number<T>(
"s");
1517 const unsigned c = a.uinteger(
"c");
1518 const bool tuned = qsys_map_d_tuned(a,
"qsys_mapdc");
1519 const std::size_t dist_size = a.count(
"dist_size", 0);
1520 const unsigned max_arrivals = a.uinteger(
"max_arrivals", 0u);
1521 const std::size_t max_levels = a.count(
"max_levels", 0);
1522 const T tol = a.scalar<T>(
"tol", num_traits<T>::from_int(0));
1524 return qsys_map_results(
1525 tuned ?
qsys::qsys_mapdc(arrival, s, c, dist_size, max_arrivals, max_levels, tol)
1532 static Json run(Args& a) {
1533 const mam::Map<T> arrival = read_map<T>(a,
"D0",
"D1");
1534 const std::vector<T> moments = a.vector<T>(
"serviceMoments");
1535 const bool sized = a.has(
"dist_size");
1536 const std::size_t dist_size = a.count(
"dist_size", 0);
1538 const qsys::MapG1Result<T> r = sized ?
qsys::qsys_mapg1(arrival, moments, dist_size)
1540 Json out = qsys_map_results(r);
1545 const char* kind =
"Acyclic";
1546 switch (r.fitKind) {
1552 out[
"fitKind"] = kind;
1562 static Json run(Args& a) {
1563 const std::vector<T> alpha = a.vector<T>(
"alpha");
1564 const Matrix<T> Tm = a.matrix<T>(
"T");
1565 const T mu = a.number<T>(
"mu");
1566 const bool tuned = a.has(
"tol");
1567 const T tol = a.scalar<T>(
"tol", num_traits<T>::from_int(0));
1569 const qsys::PhM1Result<T> r = tuned ?
qsys::qsys_phm1(alpha, Tm, mu, tol)
1573 out[
"meanWaitingQueue"] =
encode_scalar(r.meanWaitingQueue);
1584 static Json run(Args& a) {
1585 const std::vector<T> alpha = a.vector<T>(
"alpha");
1586 const Matrix<T> Tm = a.matrix<T>(
"T");
1587 const T mu = a.number<T>(
"mu");
1588 const unsigned c = a.uinteger(
"c");
1589 const bool any = a.has(
"maxIter") || a.has(
"tol");
1590 const bool all = a.has(
"maxIter") && a.has(
"tol");
1593 "qsys_phmc: 'maxIter' and 'tol' bound one fixed-point iteration together; give "
1595 const unsigned maxIter = a.uinteger(
"maxIter", 0u);
1596 const T tol = a.scalar<T>(
"tol", num_traits<T>::from_int(0));
1598 const qsys::PhMcResult<T> r = all ?
qsys::qsys_phmc(alpha, Tm, mu, c, maxIter, tol)
1602 out[
"meanWaitingQueue"] =
encode_scalar(r.meanWaitingQueue);
1610struct OpQsysBmapphnnRetrial {
1612 static Json run(Args& a) {
1613 const std::vector<Matrix<T> > D = a.matrices<T>(
"D");
1614 const std::vector<T> beta = a.vector<T>(
"beta");
1615 const Matrix<T> S = a.matrix<T>(
"S");
1616 const int N = a.required_integer(
"N");
1617 const T alpha = a.number<T>(
"alpha");
1618 const T gamma = a.number<T>(
"gamma");
1619 const T p = a.number<T>(
"p");
1620 const std::vector<int> Ri = a.ints(
"R");
1621 qsys::BmapPhNnRetrialOptions opt;
1622 opt.maxLevel = a.count(
"maxLevel", 0);
1624 std::vector<long> R(Ri.size());
1625 for (std::size_t i = 0; i < Ri.size(); ++i) R[i] =
static_cast<long>(Ri[i]);
1626 const qsys::BmapPhNnRetrialResult<T> r =
1642 out[
"clipped"] = r.clipped;
1657#define LINE_MOMENT_VEC(OpName, fn, in_key, out_key) \
1659 template <class T> \
1660 static Json run(Args& a) { \
1661 const std::vector<T> v = a.vector<T>(in_key); \
1664 out[out_key] = encode_vector(moment::fn(v)); \
1669LINE_MOMENT_VEC(OpMomentBinomialFromFactorial, moment_binomial_from_factorial,
"f",
"b");
1670LINE_MOMENT_VEC(OpMomentBinomialFromNegbinomial, moment_binomial_from_negbinomial,
"bm",
"b");
1673LINE_MOMENT_VEC(OpMomentCentralFromRaw, moment_central_from_raw,
"m",
"mc");
1674LINE_MOMENT_VEC(OpMomentFactorialFromBinomial, moment_factorial_from_binomial,
"b",
"f");
1675LINE_MOMENT_VEC(OpMomentFactorialFromRaw, moment_factorial_from_raw,
"m",
"f");
1676LINE_MOMENT_VEC(OpMomentFactorialFromUpfactorial, moment_factorial_from_upfactorial,
"fp",
"f");
1677LINE_MOMENT_VEC(OpMomentNegbinomialFromBinomial, moment_negbinomial_from_binomial,
"b",
"bm");
1678LINE_MOMENT_VEC(OpMomentNegbinomialFromUpfactorial, moment_negbinomial_from_upfactorial,
"fp",
1680LINE_MOMENT_VEC(OpMomentRawFromFactorial, moment_raw_from_factorial,
"f",
"m");
1681LINE_MOMENT_VEC(OpMomentRawFromUpfactorial, moment_raw_from_upfactorial,
"fp",
"m");
1682LINE_MOMENT_VEC(OpMomentUpfactorialFromFactorial, moment_upfactorial_from_factorial,
"f",
"fp");
1683LINE_MOMENT_VEC(OpMomentUpfactorialFromNegbinomial, moment_upfactorial_from_negbinomial,
"bm",
1685LINE_MOMENT_VEC(OpMomentUpfactorialFromRaw, moment_upfactorial_from_raw,
"m",
"fp");
1686#undef LINE_MOMENT_VEC
1693struct OpMomentRawFromCentral {
1695 static Json run(Args& a) {
1696 const std::vector<T> mc = a.vector<T>(
"mc");
1697 const T m1 = a.number<T>(
"m1");
1706#define LINE_MOMENT_TRI(OpName, fn, out_key) \
1708 template <class T> \
1709 static Json run(Args& a) { \
1710 const int n = a.required_integer("n"); \
1713 out[out_key] = encode_matrix(moment::fn<T>(n)); \
1722#undef LINE_MOMENT_TRI
1738inline std::vector<std::vector<std::size_t> > read_partition(Args& a,
const char* key) {
1739 const Json& j = a.get(key);
1740 const std::string where = std::string(
"partition '") + key +
"'";
1741 if (!j.is_array())
throw InputError(where +
" must be an array of index arrays");
1742 std::vector<std::vector<std::size_t> > out;
1743 for (std::size_t b = 0; b < j.size(); ++b) {
1744 if (!j[b].is_array())
1745 throw InputError(where +
": block " + std::to_string(b) +
" must be an array");
1746 std::vector<std::size_t> blk;
1747 for (std::size_t i = 0; i < j[b].size(); ++i) {
1749 const long long v = std::strtoll(text.c_str(),
nullptr, 10);
1751 throw InputError(where +
": a state index cannot be negative, got " + text);
1752 blk.push_back(
static_cast<std::size_t
>(v));
1760inline Json encode_indices(
const std::vector<std::size_t>& v) {
1761 Json a = Json::array();
1762 for (std::size_t i = 0; i < v.size(); ++i) a.push_back(
static_cast<std::uint64_t
>(v[i]));
1773Json reducible_results(
const mc::ReducibleResult<T>& r) {
1778 out[
"scc"] = encode_indices(r.scc);
1779 Json isrec = Json::array();
1780 for (std::size_t i = 0; i < r.isrec.size(); ++i) isrec.push_back(
bool(r.isrec[i]));
1781 out[
"isrec"] = isrec;
1789Json blkdecomp_results(
const mc::BlkDecompResult<T>& r) {
1794 out[
"scc"] = encode_indices(r.scc);
1795 Json isrec = Json::array();
1796 for (std::size_t i = 0; i < r.isrec.size(); ++i) isrec.push_back(
bool(r.isrec[i]));
1797 out[
"isrec"] = isrec;
1801struct OpCtmcSolveReducible {
1803 static Json run(Args& a) {
1804 const Matrix<T> Q = a.matrix<T>(
"Q");
1805 const std::vector<T> pi0 = a.vector<T>(
"pi0");
1806 const double zeroColTol = a.scalar<
double>(
"zeroColTol", 1e-12);
1809 return reducible_results(r);
1813struct OpCtmcSolveReducibleBlkdecomp {
1815 static Json run(Args& a) {
1816 const Matrix<T> Q = a.matrix<T>(
"Q");
1817 const std::vector<T> pin = a.vector<T>(
"pin");
1818 const double reachTol = a.scalar<
double>(
"reachTol", 1e-15);
1819 const double zeroColTol = a.scalar<
double>(
"zeroColTol", 1e-12);
1821 const mc::BlkDecompResult<T> r =
1823 return blkdecomp_results(r);
1827struct OpDtmcSolveReducible {
1829 static Json run(Args& a) {
1830 const Matrix<T> P = a.matrix<T>(
"P");
1831 const std::vector<T> pin = a.vector<T>(
"pin");
1832 const double zeroColTol = a.scalar<
double>(
"zeroColTol", 1e-12);
1835 return reducible_results(r);
1839struct OpDtmcMakestochastic {
1841 static Json run(Args& a) {
1842 const Matrix<T> P = a.matrix<T>(
"Pin");
1852 static Json run(Args& a) {
1853 const Matrix<T> Q = a.matrix<T>(
"Q");
1854 const Matrix<T> dQ = a.matrix<T>(
"dQ");
1855 const std::vector<T> pi = a.vector<T>(
"pi");
1863struct OpStronglyConnComp {
1865 static Json run(Args& a) {
1866 const Matrix<T> A = a.matrix<T>(
"A");
1870 out[
"scc"] = encode_indices(r.scc);
1871 Json rec = Json::array();
1872 for (std::size_t i = 0; i < r.recurrent.size(); ++i) rec.push_back(
bool(r.recurrent[i]));
1873 out[
"recurrent"] = rec;
1874 Json mem = Json::array();
1875 for (std::size_t i = 0; i < r.members.size(); ++i)
1876 mem.push_back(encode_indices(r.members[i]));
1877 out[
"members"] = mem;
1882struct OpCtmcRandomization {
1884 static Json run(Args& a) {
1885 const Matrix<T> Q = a.matrix<T>(
"Q");
1886 const bool given = a.has(
"q");
1887 const T q = a.scalar<T>(
"q", num_traits<T>::from_int(0));
1891 "ctmc_randomization: 'q' is the uniformization rate and has no default here; "
1892 "MATLAB requires it too");
1907struct OpCtmcCourtois {
1909 static Json run(Args& a) {
1910 const Matrix<T> Q = a.matrix<T>(
"Q");
1911 const std::vector<std::vector<std::size_t> > MS = read_partition(a,
"MS");
1912 const bool given = a.has(
"q");
1913 const T q = a.scalar<T>(
"q", num_traits<T>::from_int(0));
1915 const mc::CourtoisResult<T> r =
1919 out[
"v"] = encode_indices(r.v);
1935Json kms_results(
const R& r) {
1948 static Json run(Args& a) {
1949 const Matrix<T> Q = a.matrix<T>(
"Q");
1950 const std::vector<std::vector<std::size_t> > MS = read_partition(a,
"MS");
1951 const std::size_t numSteps = a.count(
"numSteps");
1957struct OpCtmcTakahashi {
1959 static Json run(Args& a) {
1960 const Matrix<T> Q = a.matrix<T>(
"Q");
1961 const std::vector<std::vector<std::size_t> > MS = read_partition(a,
"MS");
1962 const std::size_t numSteps = a.count(
"numSteps");
1963 const double massTol = a.scalar<
double>(
"massTol", 1e-14);
1971 static Json run(Args& a) {
1972 const Matrix<T> Q = a.matrix<T>(
"Q");
1973 const std::vector<std::vector<std::size_t> > MS = read_partition(a,
"MS");
1974 const std::vector<std::vector<std::size_t> > MSS = read_partition(a,
"MSS");
1975 const bool given = a.has(
"q");
1976 const T q = a.scalar<T>(
"q", num_traits<T>::from_int(0));
1978 const mc::MultiResult<T> r =
1997 static Json run(Args& a) {
1998 const Matrix<T> A = a.matrix<T>(
"A");
1999 const std::vector<T> b = a.vector<T>(
"b");
2000 const double tol = a.scalar<
double>(
"tol", 1e-12);
2001 const int restart = a.integer(
"restart", 0);
2002 const int maxit = a.integer(
"maxit", 0);
2003 const std::vector<T> x0 = a.vector_or_empty<T>(
"x0");
2005 const mc::GmresResult<T> r =
mc::ctmc_gmres(A, b, tol, restart, maxit, x0);
2008 out[
"flag"] = r.flag;
2010 out[
"iter"] =
static_cast<std::int64_t
>(r.iter);
2015struct OpCtmcGmresMulti {
2017 static Json run(Args& a) {
2018 const Matrix<T> A = a.matrix<T>(
"A");
2019 const Matrix<T> B = a.matrix<T>(
"B");
2020 const double tol = a.scalar<
double>(
"tol", 1e-12);
2021 const int restart = a.integer(
"restart", 0);
2022 const int maxit = a.integer(
"maxit", 0);
2027 out[
"flag"] = r.flag;
2039struct OpCtmcBicgstab {
2041 static Json run(Args& a) {
2042 const Matrix<T> A = a.matrix<T>(
"A");
2043 const std::vector<T> b = a.vector<T>(
"b");
2044 const double tol = a.scalar<
double>(
"tol", 1e-12);
2045 const int maxit = a.integer(
"maxit", 0);
2046 const std::vector<T> x0 = a.vector_or_empty<T>(
"x0");
2051 out[
"flag"] = r.flag;
2053 out[
"iter"] =
static_cast<std::int64_t
>(r.iter);
2058struct OpCtmcBicgstabMulti {
2060 static Json run(Args& a) {
2061 const Matrix<T> A = a.matrix<T>(
"A");
2062 const Matrix<T> B = a.matrix<T>(
"B");
2063 const double tol = a.scalar<
double>(
"tol", 1e-12);
2064 const int maxit = a.integer(
"maxit", 0);
2069 out[
"flag"] = r.flag;
2074struct OpCtmcFoxglynn {
2076 static Json run(Args& a) {
2077 const std::vector<T> pi0 = a.vector<T>(
"pi0");
2078 const Matrix<T> Q = a.matrix<T>(
"Q");
2079 const T t = a.number<T>(
"t");
2080 const double tol = a.scalar<
double>(
"tol", 1e-12);
2081 const int maxiter = a.integer(
"maxiter", -1);
2089 out[
"left"] =
static_cast<std::int64_t
>(r.left);
2090 out[
"right"] =
static_cast<std::int64_t
>(r.right);
2096struct OpCtmcSaddlepoint {
2098 static Json run(Args& a) {
2099 const Matrix<T> D0 = a.matrix<T>(
"D0");
2100 const Matrix<T> D1 = a.matrix<T>(
"D1");
2101 const std::vector<T> t = a.vector<T>(
"t");
2102 const std::vector<int> ki = a.ints(
"k");
2103 const std::string method = a.text(
"method",
"daniels2");
2104 const std::vector<T> pi0 = a.vector_or_empty<T>(
"pi0");
2107 if (method ==
"daniels" || method ==
"sp1")
2109 else if (method ==
"plain" || method ==
"bare")
2111 else if (!(method ==
"daniels2" || method ==
"sp2"))
2112 throw InputError(
"ctmc_saddlepoint: unknown method '" + method +
2113 "', expected daniels2, daniels or plain");
2114 std::vector<long> k(ki.size());
2115 for (std::size_t i = 0; i < ki.size(); ++i) k[i] =
static_cast<long>(ki[i]);
2125 out[
"outOfRegime"] = r.out_of_regime;
2132 static Json run(Args& a) {
2133 const std::vector<T> pi0 = a.vector<T>(
"pi0");
2134 const Matrix<T> Q = a.matrix<T>(
"Q");
2135 const T t = a.number<T>(
"t");
2136 const double epsilon = a.scalar<
double>(
"epsilon", 1e-6);
2137 const double delta = a.scalar<
double>(
"delta", 1e-12);
2138 const int maxsteps = a.integer(
"maxsteps", -1);
2140 const mc::FauResult<T> r =
mc::ctmc_fau(pi0, Q, t, epsilon, delta, maxsteps);
2146 out[
"steps"] =
static_cast<std::int64_t
>(r.steps);
2147 out[
"lambdaMin"] = r.lambdaMin;
2148 out[
"lambdaMax"] = r.lambdaMax;
2149 out[
"uniformRate"] = r.uniformRate;
2150 out[
"weightTail"] = num_traits<T>::to_double(r.weightTail);
2151 out[
"weightWindow"] = num_traits<T>::to_double(r.weightWindow);
2152 out[
"droppedMass"] = num_traits<T>::to_double(r.droppedMass);
2153 out[
"errorBound"] = num_traits<T>::to_double(r.errorBound);
2154 out[
"supportMax"] =
static_cast<std::int64_t
>(r.supportMax);
2155 out[
"supportFinal"] =
static_cast<std::int64_t
>(r.supportFinal);
2156 out[
"truncated"] = r.truncated;
2157 out[
"absorbed"] = r.absorbed;
2162struct OpCtmcTransient {
2164 static Json run(Args& a) {
2165 const Matrix<T> Q = a.matrix<T>(
"Q");
2166 const std::vector<T> pi0 = a.vector<T>(
"pi0");
2167 const T t0 = a.number<T>(
"t0");
2168 const T t1 = a.number<T>(
"t1");
2169 const double rtol = a.scalar<
double>(
"rtol", 1e-3);
2170 const double atol = a.scalar<
double>(
"atol", 1e-6);
2180struct OpCtmcTransientSens {
2182 static Json run(Args& a) {
2183 const Matrix<T> Q = a.matrix<T>(
"Q");
2184 const Matrix<T> dQ = a.matrix<T>(
"dQ");
2185 const std::vector<T> pi0 = a.vector<T>(
"pi0");
2186 const T t0 = a.number<T>(
"t0");
2187 const T t1 = a.number<T>(
"t1");
2188 const double rtol = a.scalar<
double>(
"rtol", 1e-3);
2189 const double atol = a.scalar<
double>(
"atol", 1e-6);
2191 const mc::TransientSensResult<T> r =
2219 const std::string kind = a.text(
"lst",
"");
2222 "'lst' names the service law whose Laplace-Stieltjes transform this age formula "
2223 "needs: exp, erlang, det or ph. A transform itself cannot cross a JSON boundary");
2225 if (kind ==
"exp") {
2226 const T mu = a.number<T>(
"lst_mu");
2227 E1 = T(num_traits<T>::from_int(1) / mu);
2228 E2 = T(num_traits<T>::from_int(2) / (mu * mu));
2231 if (kind ==
"erlang") {
2232 const unsigned k = a.uinteger(
"lst_k");
2233 const T mu = a.number<T>(
"lst_mu");
2234 const T kk = num_traits<T>::from_int(
static_cast<int>(k));
2236 E2 = T(kk * (kk + num_traits<T>::from_int(1)) / (mu * mu));
2239 if (kind ==
"det") {
2240 const T d = a.number<T>(
"lst_d");
2246 const std::vector<T> alpha = a.vector<T>(
"lst_alpha");
2247 const Matrix<T> Tmat = a.matrix<T>(
"lst_T");
2252 E1 = a.number<T>(
"E_1");
2253 E2 = a.number<T>(
"E_2");
2256 throw InputError(
"'lst' must be one of exp, erlang, det, ph; got '" + kind +
"'");
2261Json aoi_results(
const aoi::AoiResult<T>& r) {
2271Json aoi_lst_results(
const aoi::AoiLstResult<T>& r) {
2275 out[
"has_lst"] = r.has_lst;
2279#define LINE_AOI_TWO(OpName, fn, k1, k2) \
2281 template <class T> \
2282 static Json run(Args& a) { \
2283 const T x = a.number<T>(k1); \
2284 const T y = a.number<T>(k2); \
2286 return aoi_results(aoi::fn(x, y)); \
2291LINE_AOI_TWO(OpAoiFcfsMd1, aoi_fcfs_md1,
"lambda",
"d");
2292LINE_AOI_TWO(OpAoiFcfsMm1, aoi_fcfs_mm1,
"lambda",
"mu");
2293LINE_AOI_TWO(OpAoiLcfsprDm1, aoi_lcfspr_dm1,
"tau",
"mu");
2294LINE_AOI_TWO(OpAoiLcfsprMd1, aoi_lcfspr_md1,
"lambda",
"d");
2295LINE_AOI_TWO(OpAoiLcfsprMm1, aoi_lcfspr_mm1,
"lambda",
"mu");
2299#define LINE_AOI_MGI1_MOMENTS(OpName, fn) \
2301 template <class T> \
2302 static Json run(Args& a) { \
2303 const T lambda = a.number<T>("lambda"); \
2304 const T E_H = a.number<T>("E_H"); \
2305 const T E_H2 = a.number<T>("E_H2"); \
2307 return aoi_lst_results(aoi::fn(lambda, E_H, E_H2)); \
2313#undef LINE_AOI_MGI1_MOMENTS
2315struct OpAoiFcfsMgi1 {
2317 static Json run(Args& a) {
2318 const T lambda = a.number<T>(
"lambda");
2319 T E1 = num_traits<T>::from_int(0), E2 = num_traits<T>::from_int(0);
2320 bool has_E2 =
false;
2321 const aoi::Lst<T> H = read_aoi_lst<T>(a, E1, E2, has_E2);
2327struct OpAoiLcfsprMgi1 {
2329 static Json run(Args& a) {
2330 const T lambda = a.number<T>(
"lambda");
2331 T E1 = num_traits<T>::from_int(0), E2 = num_traits<T>::from_int(0);
2332 bool has_E2 =
false;
2333 const aoi::Lst<T> H = read_aoi_lst<T>(a, E1, E2, has_E2);
2339struct OpAoiFcfsGim1 {
2341 static Json run(Args& a) {
2342 const T mu = a.number<T>(
"mu");
2343 T E1 = num_traits<T>::from_int(0), E2 = num_traits<T>::from_int(0);
2344 bool has_E2 =
false;
2345 const aoi::Lst<T> Y = read_aoi_lst<T>(a, E1, E2, has_E2);
2351#define LINE_AOI_GIM1_ONE(OpName, fn) \
2353 template <class T> \
2354 static Json run(Args& a) { \
2355 const T mu = a.number<T>("mu"); \
2356 T E1 = num_traits<T>::from_int(0), E2 = num_traits<T>::from_int(0); \
2357 bool has_E2 = false; \
2358 const aoi::Lst<T> Y = read_aoi_lst<T>(a, E1, E2, has_E2); \
2360 return aoi_lst_results(aoi::fn(Y, mu, E1)); \
2367#undef LINE_AOI_GIM1_ONE
2379#define LINE_FJ_K_LAMBDA_MU(OpName, fn, out_key) \
2381 template <class T> \
2382 static Json run(Args& a) { \
2383 const unsigned K = a.uinteger("K"); \
2384 const T lambda = a.number<T>("lambda"); \
2385 const T mu = a.number<T>("mu"); \
2388 out[out_key] = encode_scalar(fj::fn(K, lambda, mu)); \
2397#undef LINE_FJ_K_LAMBDA_MU
2399#define LINE_FJ_K_MU(OpName, fn, out_key) \
2401 template <class T> \
2402 static Json run(Args& a) { \
2403 const unsigned K = a.uinteger("K"); \
2404 const T mu = a.number<T>("mu"); \
2407 out[out_key] = encode_scalar(fj::fn(K, mu)); \
2417struct OpFjHarmonic {
2419 static Json run(Args& a) {
2420 const unsigned K = a.uinteger(
"K");
2428struct OpFjQuantile {
2430 static Json run(Args& a) {
2431 const unsigned K = a.uinteger(
"K");
2432 const T q = a.number<T>(
"q");
2440struct OpFjResptTwoway {
2442 static Json run(Args& a) {
2443 const T lambda = a.number<T>(
"lambda");
2444 const T mu = a.number<T>(
"mu");
2452struct OpFjSynchDelay {
2454 static Json run(Args& a) {
2455 const T lambda = a.number<T>(
"lambda");
2456 const T mu = a.number<T>(
"mu");
2466 static Json run(Args& a) {
2467 const T lambda1 = a.number<T>(
"lambda1");
2468 const T lambda2 = a.number<T>(
"lambda2");
2476struct OpFjXmaxErlang {
2478 static Json run(Args& a) {
2479 const unsigned K = a.uinteger(
"K");
2480 const unsigned k = a.uinteger(
"k");
2481 const T mu = a.number<T>(
"mu");
2489struct OpFjRmaxErlang {
2491 static Json run(Args& a) {
2492 const unsigned K = a.uinteger(
"K");
2493 const unsigned k = a.uinteger(
"k");
2494 const T lambda = a.number<T>(
"lambda");
2495 const T mu = a.number<T>(
"mu");
2503struct OpFjXmaxHyperexp {
2505 static Json run(Args& a) {
2506 const unsigned K = a.uinteger(
"K");
2507 const T p1 = a.number<T>(
"p1");
2508 const T mu1 = a.number<T>(
"mu1");
2509 const T mu2 = a.number<T>(
"mu2");
2525 static Json run(Args& a) {
2526 const unsigned K = a.uinteger(
"K");
2527 const T R = a.number<T>(
"R");
2528 const T sigma_R = a.number<T>(
"sigma_R");
2529 const bool calibrated = a.boolean(
"calibrated",
false);
2539 static Json run(Args& a) {
2540 const unsigned K = a.uinteger(
"K");
2541 const T lambda = a.number<T>(
"lambda");
2542 const T mu = a.number<T>(
"mu");
2544 const fj::FJBoundsResult<T> r =
fj::fj_bounds(K, lambda, mu);
2554 static Json run(Args& a) {
2555 const unsigned K = a.uinteger(
"K");
2556 const T mu = a.number<T>(
"mu");
2568 static Json run(Args& a) {
2569 const unsigned K = a.uinteger(
"K");
2582struct OpFjOrdstatExp {
2584 static Json run(Args& a) {
2585 const std::vector<T> ri = a.vector<T>(
"ri");
2586 const std::size_t k = a.count(
"k");
2594struct OpFjQuorumMoments {
2596 static Json run(Args& a) {
2597 const std::vector<T> branchMeans = a.vector<T>(
"branchMeans");
2598 const std::vector<T> branchVars = a.vector<T>(
"branchVars");
2599 const std::size_t k = a.count(
"k");
2601 const fj::FJQuorumMomentsResult<T> r =
2610struct OpFjXmaxApprox {
2612 static Json run(Args& a) {
2613 const unsigned K = a.uinteger(
"K");
2614 const T mu_X = a.number<T>(
"mu_X");
2615 const T sigma_X = a.number<T>(
"sigma_X");
2616 const std::string t = a.text(
"type",
"Exp");
2622 else throw InputError(
"'type' must be Exp, Uniform, Evd or Bound; got '" + t +
"'");
2632struct OpFjXmaxNormal {
2634 static Json run(Args& a) {
2635 const unsigned K = a.uinteger(
"K");
2636 const T mu = a.number<T>(
"mu");
2637 const T sigma = a.number<T>(
"sigma");
2638 const std::string m = a.text(
"method",
"Johnson");
2643 else throw InputError(
"'method' must be Johnson, Arnold or Corrected; got '" + m +
"'");
2653struct OpFjXmaxPareto {
2655 static Json run(Args& a) {
2656 const unsigned K = a.uinteger(
"K");
2657 const T beta = a.number<T>(
"beta");
2658 const T k = a.number<T>(
"k");
2674 return [](
const ArithSpec& s,
Args& a) {
return run_at<Op>(s, a); };
2677const std::map<std::string, Invoker>& dispatch_table() {
2678 static const std::map<std::string, Invoker> table = {
2679 {
"pfqn_ca", make<OpPfqnCa>()},
2680 {
"pfqn_conv", make<OpPfqnConv>()},
2681 {
"pfqn_recal", make<OpPfqnRecal>()},
2682 {
"pfqn_gld", make<OpPfqnGld>()},
2683 {
"pfqn_mva", make<OpPfqnMva>()},
2684 {
"pfqn_comom", make<OpPfqnComom>()},
2685 {
"pfqn_comomrm", make<OpPfqnComomrm>()},
2686 {
"pfqn_comomrm_orig", make<OpPfqnComomrmOrig>()},
2687 {
"pfqn_comomrm_ms", make<OpPfqnComomrmMs>()},
2688 {
"pfqn_procomom", make<OpPfqnProcomom>()},
2689 {
"ctmc_solve", make<OpCtmcSolve>()},
2690 {
"dtmc_solve", make<OpDtmcSolve>()},
2691 {
"ctmc_makeinfgen", make<OpCtmcMakeinfgen>()},
2692 {
"sim_vonneumann", make<OpSimVonneumann>()},
2693 {
"sim_shapirowilk", make<OpSimShapirowilk>()},
2694 {
"sim_sts_quantile_areas", make<OpSimStsQuantileAreas>()},
2695 {
"sim_fquest", make<OpSimFquest>()},
2696 {
"sim_firquest", make<OpSimFirquest>()},
2697 {
"qsys_bmapphnn_retrial", make<OpQsysBmapphnnRetrial>()},
2698 {
"aoi_fcfs_dm1", make<NeedsTranscendental<OpAoiFcfsDm1>>()},
2699 {
"aoi_fcfs_gim1", make<NeedsTranscendental<OpAoiFcfsGim1>>()},
2700 {
"aoi_fcfs_md1", make<NeedsTranscendental<OpAoiFcfsMd1>>()},
2701 {
"aoi_fcfs_mgi1", make<NeedsTranscendental<OpAoiFcfsMgi1>>()},
2702 {
"aoi_fcfs_mm1", make<OpAoiFcfsMm1>()},
2703 {
"aoi_lcfsd_gim1", make<NeedsTranscendental<OpAoiLcfsdGim1>>()},
2704 {
"aoi_lcfsd_mgi1", make<OpAoiLcfsdMgi1>()},
2705 {
"aoi_lcfspr_dm1", make<NeedsTranscendental<OpAoiLcfsprDm1>>()},
2706 {
"aoi_lcfspr_gim1", make<NeedsTranscendental<OpAoiLcfsprGim1>>()},
2707 {
"aoi_lcfspr_md1", make<NeedsTranscendental<OpAoiLcfsprMd1>>()},
2708 {
"aoi_lcfspr_mgi1", make<NeedsTranscendental<OpAoiLcfsprMgi1>>()},
2709 {
"aoi_lcfspr_mm1", make<OpAoiLcfsprMm1>()},
2710 {
"aoi_lcfss_gim1", make<NeedsTranscendental<OpAoiLcfssGim1>>()},
2711 {
"aoi_lcfss_mgi1", make<OpAoiLcfssMgi1>()},
2712 {
"fj_bounds", make<OpFjBounds>()},
2713 {
"fj_char_max", make<NeedsTranscendental<OpFjCharMax>>()},
2714 {
"fj_gk_bound", make<NeedsTranscendental<OpFjGkBound>>()},
2715 {
"fj_harmonic", make<OpFjHarmonic>()},
2716 {
"fj_quantile", make<NeedsTranscendental<OpFjQuantile>>()},
2717 {
"fj_ordstat_exp", make<OpFjOrdstatExp>()},
2718 {
"fj_quorum_moments", make<NeedsTranscendental<OpFjQuorumMoments>>()},
2719 {
"fj_respt_2way", make<OpFjResptTwoway>()},
2720 {
"fj_respt_nt", make<OpFjResptNt>()},
2721 {
"fj_respt_varki", make<OpFjResptVarki>()},
2722 {
"fj_respt_vm", make<OpFjResptVm>()},
2723 {
"fj_rmax", make<OpFjRmax>()},
2724 {
"fj_rmax_erlang", make<NeedsTranscendental<OpFjRmaxErlang>>()},
2725 {
"fj_rmax_evd", make<NeedsTranscendental<OpFjRmaxEvd>>()},
2726 {
"fj_sm_tput", make<OpFjSmTput>()},
2727 {
"fj_synch_delay", make<OpFjSynchDelay>()},
2728 {
"fj_xmax_2", make<OpFjXmax2>()},
2729 {
"fj_xmax_approx", make<NeedsTranscendental<OpFjXmaxApprox>>()},
2730 {
"fj_xmax_emma", make<NeedsTranscendental<OpFjXmaxEmma>>()},
2731 {
"fj_xmax_erlang", make<NeedsTranscendental<OpFjXmaxErlang>>()},
2732 {
"fj_xmax_exp", make<OpFjXmaxExp>()},
2733 {
"fj_xmax_hyperexp", make<OpFjXmaxHyperexp>()},
2734 {
"fj_xmax_normal", make<NeedsTranscendental<OpFjXmaxNormal>>()},
2735 {
"fj_xmax_pareto", make<NeedsTranscendental<OpFjXmaxPareto>>()},
2736 {
"ctmc_courtois", make<NeedsTranscendental<OpCtmcCourtois>>()},
2737 {
"ctmc_fau", make<NeedsTranscendental<OpCtmcFau>>()},
2738 {
"ctmc_foxglynn", make<NeedsTranscendental<OpCtmcFoxglynn>>()},
2739 {
"ctmc_saddlepoint", make<NeedsTranscendental<OpCtmcSaddlepoint>>()},
2740 {
"ctmc_bicgstab", make<NeedsTranscendental<OpCtmcBicgstab>>()},
2741 {
"ctmc_bicgstab_multi", make<NeedsTranscendental<OpCtmcBicgstabMulti>>()},
2742 {
"ctmc_gmres", make<NeedsTranscendental<OpCtmcGmres>>()},
2743 {
"ctmc_gmres_multi", make<NeedsTranscendental<OpCtmcGmresMulti>>()},
2744 {
"ctmc_kms", make<NeedsTranscendental<OpCtmcKms>>()},
2745 {
"ctmc_multi", make<NeedsTranscendental<OpCtmcMulti>>()},
2746 {
"ctmc_randomization", make<OpCtmcRandomization>()},
2747 {
"ctmc_sens", make<OpCtmcSens>()},
2748 {
"ctmc_solve_reducible", make<OpCtmcSolveReducible>()},
2749 {
"ctmc_solve_reducible_blkdecomp", make<OpCtmcSolveReducibleBlkdecomp>()},
2750 {
"ctmc_takahashi", make<NeedsTranscendental<OpCtmcTakahashi>>()},
2751 {
"ctmc_transient", make<NeedsTranscendental<OpCtmcTransient>>()},
2752 {
"ctmc_transient_sens", make<NeedsTranscendental<OpCtmcTransientSens>>()},
2753 {
"dtmc_makestochastic", make<OpDtmcMakestochastic>()},
2754 {
"dtmc_solve_reducible", make<OpDtmcSolveReducible>()},
2755 {
"moment_binomial_from_factorial", make<OpMomentBinomialFromFactorial>()},
2756 {
"moment_binomial_from_negbinomial", make<OpMomentBinomialFromNegbinomial>()},
2757 {
"moment_binotrans", make<OpMomentBinotrans>()},
2758 {
"moment_binotransinv", make<OpMomentBinotransinv>()},
2759 {
"moment_central_from_raw", make<OpMomentCentralFromRaw>()},
2760 {
"moment_factorial_from_binomial", make<OpMomentFactorialFromBinomial>()},
2761 {
"moment_factorial_from_raw", make<OpMomentFactorialFromRaw>()},
2762 {
"moment_factorial_from_upfactorial", make<OpMomentFactorialFromUpfactorial>()},
2763 {
"moment_lah", make<OpMomentLah>()},
2764 {
"moment_negbinomial_from_binomial", make<OpMomentNegbinomialFromBinomial>()},
2765 {
"moment_negbinomial_from_upfactorial", make<OpMomentNegbinomialFromUpfactorial>()},
2766 {
"moment_raw_from_central", make<OpMomentRawFromCentral>()},
2767 {
"moment_raw_from_factorial", make<OpMomentRawFromFactorial>()},
2768 {
"moment_raw_from_upfactorial", make<OpMomentRawFromUpfactorial>()},
2769 {
"moment_stirling1", make<OpMomentStirling1>()},
2770 {
"moment_stirling2", make<OpMomentStirling2>()},
2771 {
"moment_stirlingcycle", make<OpMomentStirlingcycle>()},
2772 {
"moment_upfactorial_from_factorial", make<OpMomentUpfactorialFromFactorial>()},
2773 {
"moment_upfactorial_from_negbinomial", make<OpMomentUpfactorialFromNegbinomial>()},
2774 {
"moment_upfactorial_from_raw", make<OpMomentUpfactorialFromRaw>()},
2775 {
"stronglyconncomp", make<OpStronglyConnComp>()},
2776 {
"qsys_dmc", make<NeedsTranscendental<OpQsysDmc>>()},
2777 {
"dqsys_geogeo1", make<OpQsysGeoGeo1>()},
2778 {
"dqsys_geoxgeo1", make<OpQsysGeoxGeo1>()},
2779 {
"qsys_gg1", make<NeedsTranscendental<OpQsysGg1>>()},
2780 {
"qsys_gig1_approx_allencunneen", make<OpQsysGig1AllenCunneen>()},
2781 {
"qsys_gig1_approx_gelenbe", make<NeedsTranscendental<OpQsysGig1Gelenbe>>()},
2782 {
"qsys_gig1_approx_heyman", make<OpQsysGig1Heyman>()},
2783 {
"qsys_gig1_approx_kimura", make<OpQsysGig1Kimura>()},
2784 {
"qsys_gig1_approx_klb", make<NeedsTranscendental<OpQsysGig1Klb>>()},
2785 {
"qsys_gig1_approx_kobayashi", make<NeedsTranscendental<OpQsysGig1Kobayashi>>()},
2786 {
"qsys_gig1_approx_marchal", make<OpQsysGig1Marchal>()},
2787 {
"qsys_gig1_approx_myskja", make<NeedsTranscendental<OpQsysGig1Myskja>>()},
2788 {
"qsys_gig1_approx_myskja2", make<NeedsTranscendental<OpQsysGig1Myskja2>>()},
2789 {
"qsys_gig1_lbnd", make<OpQsysGig1Lbnd>()},
2790 {
"qsys_gig1_ubnd_kingman", make<OpQsysGig1UbndKingman>()},
2791 {
"qsys_gigk_approx", make<NeedsTranscendental<OpQsysGigkApprox>>()},
2792 {
"qsys_gigk_approx_cosmetatos", make<NeedsTranscendental<OpQsysGigkCosmetatos>>()},
2793 {
"qsys_gigk_approx_kingman", make<OpQsysGigkKingman>()},
2794 {
"qsys_gigk_approx_whitt", make<NeedsTranscendental<OpQsysGigkWhitt>>()},
2795 {
"qsys_erlanga", make<NeedsTranscendental<OpQsysErlangA>>()},
2796 {
"qsys_ggnm_diffusion", make<NeedsTranscendental<OpQsysGgnmDiffusion>>()},
2797 {
"qsys_gig1_bnds_extremal", make<NeedsTranscendental<OpQsysGig1BndsExtremal>>()},
2798 {
"qsys_mmk_qed", make<NeedsTranscendental<OpQsysMmkQed>>()},
2799 {
"qsys_mmk_qed_alpha", make<NeedsTranscendental<OpQsysMmkQedAlpha>>()},
2800 {
"qsys_mmk_qed_staffing", make<NeedsTranscendental<OpQsysMmkQedStaffing>>()},
2801 {
"qsys_gigk_rqt", make<NeedsTranscendental<OpQsysGigkRqt>>()},
2802 {
"qsys_gig1_rqt", make<NeedsTranscendental<OpQsysGig1Rqt>>()},
2803 {
"qsys_gigk_rqt_gamma", make<NeedsTranscendental<OpQsysGigkRqtGamma>>()},
2804 {
"qsys_gm1", make<OpQsysGm1>()},
2805 {
"qsys_mapd1", make<NeedsTranscendental<OpQsysMapd1>>()},
2806 {
"qsys_mapdc", make<NeedsTranscendental<OpQsysMapdc>>()},
2807 {
"qsys_mapg1", make<NeedsTranscendental<OpQsysMapg1>>()},
2808 {
"qsys_mapm1", make<NeedsTranscendental<OpQsysMapm1>>()},
2809 {
"qsys_mapmap1", make<NeedsTranscendental<OpQsysMapmap1>>()},
2810 {
"qsys_mapmc", make<NeedsTranscendental<OpQsysMapmc>>()},
2811 {
"qsys_mapph1", make<NeedsTranscendental<OpQsysMapph1>>()},
2812 {
"qsys_mapphc", make<NeedsTranscendental<OpQsysMapphc>>()},
2813 {
"qsys_mg1", make<OpQsysMg1>()},
2814 {
"qsys_mg1_fb", make<NeedsTranscendental<OpQsysMg1Fb>>()},
2815 {
"qsys_mg1_lrpt", make<NeedsTranscendental<OpQsysMg1Lrpt>>()},
2816 {
"qsys_mg1_prio", make<OpQsysMg1Prio>()},
2817 {
"qsys_mg1_psjf", make<NeedsTranscendental<OpQsysMg1Psjf>>()},
2818 {
"qsys_mg1_setf", make<NeedsTranscendental<OpQsysMg1Setf>>()},
2819 {
"qsys_mg1_srpt", make<NeedsTranscendental<OpQsysMg1Srpt>>()},
2820 {
"qsys_mg1k_loss_mgs", make<NeedsTranscendental<OpQsysMg1kLossMgs>>()},
2821 {
"qsys_mginf", make<NeedsTranscendental<OpQsysMginf>>()},
2822 {
"qsys_mm1", make<OpQsysMm1>()},
2823 {
"qsys_mm1_dps", make<NeedsTranscendental<OpQsysMm1Dps>>()},
2824 {
"qsys_mm1k_loss", make<OpQsysMm1kLoss>()},
2825 {
"qsys_mmcc_retrial_fp", make<NeedsTranscendental<OpQsysMmccRetrialFp>>()},
2826 {
"qsys_mmck", make<OpQsysMmck>()},
2827 {
"qsys_mmk", make<OpQsysMmk>()},
2828 {
"qsys_mxm1", make<OpQsysMxm1>()},
2829 {
"qsys_phm1", make<NeedsTranscendental<OpQsysPhm1>>()},
2830 {
"qsys_phmc", make<NeedsTranscendental<OpQsysPhmc>>()},
2831 {
"qsys_phph1", make<NeedsTranscendental<OpQsysPhph1>>()},
2836std::string join(
const std::vector<std::string>& v,
const char* sep) {
2838 for (std::size_t i = 0; i < v.size(); ++i) {
2848 std::vector<std::string> names;
2849 for (
const auto& kv : dispatch_table()) names.push_back(kv.first);
2854 return dispatch_table().find(name) != dispatch_table().end();
2859 if (entry ==
nullptr)
2861 "' is not ported to C++ yet (--list-api shows what is).");
2867 std::vector<std::string> modes;
2869 throw UnsupportedError(
"API function '" + name +
"' does not support --arith " +
2870 spec.
str() +
"; it supports: " + join(modes,
", ") +
".");
2873 auto it = dispatch_table().find(name);
2874 if (it == dispatch_table().end()) {
2881 "API function '" + name +
2882 "' takes a NetworkStruct or a LayeredNetworkStruct, not matrices, so it has no "
2883 "named-JSON-argument form and --api cannot carry it in any future version. Reach "
2884 "the model-level answer with -s <solver> -a <analysis>, or call it from the "
2887 "API function '" + name +
2888 "' is ported to C++ but not yet exposed over --api; it is reachable from the library "
2889 "and its tests only. Exposed over --api so far: " +
2893 Args reader(args, name);
2895 out[
"function"] = name;
2896 out[
"arith"] = spec.
str();
2897 out[
"results"] = it->second(spec, reader);
2907void render_value(std::ostringstream& os,
const Json& v,
const std::string& indent) {
2909 if (v.is_object() && v.contains(
"double")) {
2910 os << v[
"double"].dump();
2911 if (v.contains(
"num"))
2912 os <<
" = " << v[
"num"].get<std::string>() <<
" / " << v[
"den"].get<std::string>();
2913 else if (v.contains(
"dec"))
2914 os <<
" = " << v[
"dec"].get<std::string>();
2919 if (!v.empty() && v[0].is_array()) {
2921 for (
const Json& row : v) {
2922 os << indent <<
" ";
2923 for (std::size_t k = 0; k < row.size(); ++k) {
2925 if (row[k].is_object() && row[k].contains(
"double"))
2926 os << row[k][
"double"].dump();
2928 os << row[k].dump();
2935 for (std::size_t k = 0; k < v.size(); ++k) {
2937 if (v[k].is_object() && v[k].contains(
"double"))
2938 os << v[k][
"double"].dump();
2945 os << v.dump() <<
"\n";
2951 std::ostringstream os;
2952 os << result[
"function"].get<std::string>() <<
" (arith: "
2953 << result[
"arith"].get<std::string>() <<
")\n";
2954 const Json& res = result[
"results"];
2955 for (
auto it = res.begin(); it != res.end(); ++it) {
2956 os <<
" " << it.key() <<
" = ";
2957 render_value(os, it.value(),
" ");
Mean, variance and peak Age of Information of a D/M/1 FCFS queue.
Mean Age of Information, its transform and the peak age of a GI/M/1 FCFS queue.
Mean, variance and peak Age of Information of an M/D/1 FCFS queue.
Mean Age of Information, its transform and the peak age of an M/GI/1 FCFS queue.
Mean, variance and peak Age of Information of an M/M/1 FCFS queue.
Mean and peak Age of Information of a GI/M/1 non-preemptive LCFS queue with discarding (LCFS-D,...
Mean and peak Age of Information of an M/GI/1 non-preemptive LCFS queue with discarding (LCFS-D,...
Mean, variance and peak Age of Information of a D/M/1 preemptive LCFS queue.
Mean Age of Information, its transform and the peak age of a GI/M/1 preemptive LCFS queue.
Mean, variance and peak Age of Information of an M/D/1 preemptive LCFS queue.
Mean Age of Information, its transform and the peak age of an M/GI/1 preemptive LCFS queue.
Mean, variance and peak Age of Information of an M/M/1 preemptive LCFS queue.
Mean and peak Age of Information of a GI/M/1 non-preemptive LCFS queue with set-aside (LCFS-S).
Mean and peak Age of Information of an M/GI/1 non-preemptive LCFS queue with set-aside (LCFS-S).
Laplace-Stieltjes transform of a deterministic (constant) distribution.
Laplace-Stieltjes transform of an Erlang-k distribution.
Laplace-Stieltjes transform of an exponential distribution.
Laplace-Stieltjes transform of a phase-type distribution PH(alpha, T).
#define LINE_MOMENT_VEC(OpName, fn, in_key, out_key)
#define LINE_QSYS_MG1_DISC(OpName, fn, ResultT)
The six M/G/1 disciplines, all {W per class, rhohat}.
#define LINE_AOI_MGI1_MOMENTS(OpName, fn)
The two M/GI/1 laws that need only the first two service moments.
#define LINE_FJ_K_LAMBDA_MU(OpName, fn, out_key)
The many members returning one bare number, under the reference's name.
#define LINE_AOI_GIM1_ONE(OpName, fn)
#define LINE_QSYS_MYSKJA(OpName, fn)
#define LINE_MOMENT_TRI(OpName, fn, out_key)
The four triangular coefficient matrices, each a function of the order n.
#define LINE_FJ_K_MU(OpName, fn, out_key)
#define LINE_QSYS_GIG1(OpName, fn)
#define LINE_AOI_TWO(OpName, fn, k1, k2)
#define LINE_QSYS_GIGK(OpName, fn)
Direct invocation of a single API function from named JSON arguments.
UnsupportedError(const std::string &what)
Named-argument reader over the parsed JSON object.
Preconditioned stabilized biconjugate gradients, for the linear systems a generator produces.
Courtois decomposition of a nearly completely decomposable (NCD) CTMC.
Transient distribution of a CTMC by fast adaptive uniformization.
Transient distribution of a CTMC by uniformization with Fox-Glynn Poisson weights.
Restarted GMRES with an ILUT preconditioner, for the linear systems a generator produces.
Restarted GMRES for a block of right-hand sides sharing one coefficient matrix.
Koury-McAllister-Stewart aggregation-disaggregation for a nearly completely decomposable CTMC.
Two-level multigrid aggregation-disaggregation for a nearly completely decomposable CTMC.
Uniformization (randomization) of a CTMC: the embedded DTMC P = I + Q/q.
Saddlepoint approximation of Pr{N(t)=k} for the counting process of a MAP.
Sensitivity of the steady-state distribution of a CTMC to a scalar parameter.
Steady-state distribution of a continuous-time Markov chain.
Limiting distribution of a CTMC whose generator may be reducible.
Limiting distribution of a reducible CTMC by direct block decomposition of the generator.
Takahashi's aggregation-disaggregation for a nearly completely decomposable CTMC.
Transient distribution of a CTMC over a time interval, by integrating the forward equations d pi/dt =...
Sensitivity of the transient distribution of a CTMC to a scalar parameter.
Geo/Geo/1: the discrete-time single-server queue with geometric interarrival and service times.
Geo^X/Geo/1: the discrete-time single-server queue with batch arrivals.
Normalize a non-negative matrix into a stochastic transition matrix.
Equilibrium distribution of a discrete-time Markov chain, and stochastic complementation.
Limiting distribution of a discrete-time Markov chain whose transition matrix may be reducible.
Upper and lower bounds on the mean response time of a K-way fork-join system of M/M/1 branches.
Gravey's characteristic maximum M_K, an upper bound on the expected maximum of K i....
G(K) factors for the standardized-maximum approximation X_K^max ~ mu + sigma G(K).
Harmonic number H_K = sum_{k=1..K} 1/k.
Mean of the k-th smallest of n independent EXPONENTIAL branch completion times, i....
Quantile of the maximum of K i.i.d.
Mean and variance of a k-of-n (quorum) join completion time, from the mean and variance of each branc...
Exact mean response time of a 2-way fork-join system of M/M/1 branches.
Nelson-Tantawi approximation to the mean response time of a K-way fork-join system of M/M/1 branches.
Varki approximation to the mean response time of a K-way fork-join system of M/M/1 branches.
Varma-Makowski light-traffic interpolation for the mean response time of a K-way fork-join system of ...
Pessimistic (independence) fork-join response time: the expected maximum of K independent M/M/1 respo...
Expected maximum of K M/E_k/1 branch response times.
Extreme-value approximation to the maximum of K branch response times, from their mean and standard d...
Saturated (single-message) maximum throughput of a K-way fork-join system with exponential branch ser...
Mean synchronization delay of a 2-way fork-join system of M/M/1 branches, i.e.
Expected maximum of two independent, possibly unequal-rate exponentials.
Two-moment approximation to the expected maximum of K i.i.d.
EMMA (Extreme-value Maximum Moment Approximation) to the expected maximum of K i.i....
Expected maximum of K i.i.d.
Expected maximum of K i.i.d.
Expected maximum of K i.i.d.
Expected maximum and variance of K i.i.d.
Expected maximum and characteristic maximum of K i.i.d.
Binomial moments from falling-factorial moments.
Binomial moments from negative-binomial moments.
Binomial transform with alternating signs.
Inverse binomial transform.
Central moments from raw moments.
Falling-factorial moments from binomial moments.
Factorial moments from raw moments, via the signed Stirling table.
Falling-factorial moments from rising-factorial moments, via the Lah numbers.
Negative-binomial moments from binomial moments.
Negative-binomial moments from rising-factorial moments.
Raw moments from central moments and the mean.
Raw moments from factorial moments, via the Stirling table of the second kind.
Raw moments from rising-factorial moments.
Signed Stirling numbers of the first kind.
Stirling numbers of the second kind.
Unsigned Stirling numbers of the first kind (cycle numbers), orders 0..n.
Rising-factorial moments from falling-factorial moments, via the Lah numbers.
Rising-factorial moments from negative-binomial moments.
Rising-factorial moments from raw moments, via the cycle numbers.
std::function< T(const T &)> Lst
A Laplace-Stieltjes transform evaluated at real arguments.
AoiLstResult< T > aoi_fcfs_gim1(const Lst< T > &Y_lst, const T &mu, const T &E_Y, const T &E_Y2)
Mean Age of Information, its transform and the peak age of a GI/M/1 FCFS queue.
Lst< T > aoi_lst_exp(const T &mu)
Laplace-Stieltjes transform of an exponential distribution.
Lst< T > aoi_lst_erlang(unsigned k, const T &mu)
Laplace-Stieltjes transform of an Erlang-k distribution.
Lst< T > aoi_lst_ph(const std::vector< T > &alpha, const Matrix< T > &Tmat)
Laplace-Stieltjes transform of a phase-type distribution PH(alpha, T).
AoiLstResult< T > aoi_lcfspr_mgi1(const T &lambda, const Lst< T > &H_lst, const T &E_H)
Mean Age of Information, its transform and the peak age of an M/GI/1 preemptive LCFS queue.
Lst< T > aoi_lst_det(const T &d)
Laplace-Stieltjes transform of a deterministic (constant) distribution.
AoiLstResult< T > aoi_fcfs_mgi1(const T &lambda, const Lst< T > &H_lst, const T &E_H, const T &E_H2)
Mean Age of Information, its transform and the peak age of an M/GI/1 FCFS queue.
GeoXGeo1Result< T > dqsys_geoxgeo1(const T &a, const T &beta, const T &s, GeoConvention convention=GeoConvention::LAS_DA)
Geo^X/Geo/1: the discrete-time single-server queue with batch arrivals.
GeoGeo1Result< T > dqsys_geogeo1(const T &a, const T &s, GeoConvention convention=GeoConvention::LAS_DA)
Geo/Geo/1: the discrete-time single-server queue with geometric interarrival and service times.
FJCharMaxResult< T > fj_char_max(unsigned K, const T &mu)
Exponential branch.
FJBoundsResult< T > fj_bounds(unsigned K, const T &lambda, const T &mu)
Upper and lower bounds on the mean response time of a K-way fork-join system of M/M/1 branches.
T fj_rmax_erlang(unsigned K, unsigned k, const T &lambda, const T &mu)
Expected maximum of K M/E_k/1 branch response times.
T fj_synch_delay(const T &lambda, const T &mu)
Mean synchronization delay of a 2-way fork-join system of M/M/1 branches, i.e.
FJGKBoundResult< T > fj_gk_bound(unsigned K)
G(K) factors for the standardized-maximum approximation X_K^max ~ mu.
T fj_respt_2way(const T &lambda, const T &mu)
Exact mean response time of a 2-way fork-join system of M/M/1 branches.
T fj_xmax_hyperexp(unsigned K, const T &p1, const T &mu1, const T &mu2)
Expected maximum of K i.i.d.
FJNormalMethod
Bracketing methods for the normal-maximum approximation.
T fj_rmax_evd(unsigned K, const T &R, const T &sigma_R, bool calibrated=false)
Extreme-value approximation to the maximum of K branch response times, from their mean and standard d...
T fj_xmax_2(const T &lambda1, const T &lambda2)
Expected maximum of two independent, possibly unequal-rate exponentials.
T fj_xmax_erlang(unsigned K, unsigned k, const T &mu)
Expected maximum of K i.i.d.
FJXmaxApproxResult< T > fj_xmax_approx(unsigned K, const T &mu_X, const T &sigma_X, FJDistType type=FJDistType::Exp)
Two-moment approximation to the expected maximum of K i.i.d.
T fj_ordstat_exp(const std::vector< T > &ri, std::size_t k)
Mean of the k-th smallest of n independent EXPONENTIAL branch completion times, i....
FJDistType
Distribution families for which a G(K) standardized-maximum factor exists.
FJQuorumMomentsResult< T > fj_quorum_moments(const std::vector< T > &branchMeans, const std::vector< T > &branchVars, std::size_t k)
Mean and variance of a k-of-n (quorum) join completion time, from the mean and variance of each branc...
T fj_quantile(unsigned K, const T &q)
Gumbel approximation.
FJXmaxParetoResult< T > fj_xmax_pareto(unsigned K, const T &beta, const T &k)
Expected maximum and characteristic maximum of K i.i.d.
T fj_harmonic(unsigned K)
Harmonic number H_K = sum_{k=1..K} 1/k.
FJXmaxNormalResult< T > fj_xmax_normal(unsigned K, const T &mu, const T &sigma, FJNormalMethod method=FJNormalMethod::Johnson)
Expected maximum and variance of K i.i.d.
BicgstabResult< T > ctmc_bicgstab(const Matrix< T > &A, const std::vector< T > &b, double tol=1e-12, long maxit=0, const std::vector< T > &x0=std::vector< T >())
Preconditioned stabilized biconjugate gradients, for the linear systems a generator produces.
ReducibleResult< T > dtmc_solve_reducible(const Matrix< T > &P, const std::vector< T > &pin, double zeroColTol=1e-12)
Limiting distribution of a discrete-time Markov chain whose transition matrix may be reducible.
BlkDecompResult< T > ctmc_solve_reducible_blkdecomp(const Matrix< T > &Qin, const std::vector< T > &pin, double reachTol=1e-15, double zeroColTol=1e-12)
Limiting distribution of a reducible CTMC by direct block decomposition of the generator.
SaddlepointMethod
Which term of the steepest-descent expansion to stop at.
@ SADDLEPOINT_DANIELS2
second order, error O(1/K2^2) – the DEFAULT
@ SADDLEPOINT_PLAIN
bare first order, amplitude set to 1
@ SADDLEPOINT_DANIELS
first order with the Perron amplitude, O(1/K2)
Matrix< T > dtmc_makestochastic(const Matrix< T > &Pin)
Normalize a non-negative matrix into a stochastic transition matrix.
Matrix< T > ctmc_makeinfgen(const Matrix< T > &Q)
Set the diagonal so that every row sums to zero (ctmc_makeinfgen).
std::vector< T > ctmc_solve(const Matrix< T > &Qin)
Steady-state distribution of a continuous-time Markov chain.
KmsResult< T > ctmc_kms(const Matrix< T > &Q, const std::vector< std::vector< std::size_t > > &MS, std::size_t numSteps)
Koury-McAllister-Stewart aggregation-disaggregation for a nearly completely decomposable CTMC.
GmresMultiResult< T > ctmc_gmres_multi(const Matrix< T > &A, const Matrix< T > &B, double tol=1e-12, long restart=0, long maxit=0)
Restarted GMRES for a block of right-hand sides sharing one coefficient matrix.
TakahashiResult< T > ctmc_takahashi(const Matrix< T > &Q, const std::vector< std::vector< std::size_t > > &MS, std::size_t numSteps, double massTol=1e-14)
Takahashi's aggregation-disaggregation for a nearly completely decomposable CTMC.
ReducibleResult< T > ctmc_solve_reducible(const Matrix< T > &Q, const std::vector< T > &pi0, double zeroColTol=1e-12)
Limiting distribution of a CTMC whose generator may be reducible.
MultiResult< T > ctmc_multi(const Matrix< T > &Q, const std::vector< std::vector< std::size_t > > &MS, const std::vector< std::vector< std::size_t > > &MSS, const T &q)
Two-level multigrid aggregation-disaggregation for a nearly completely decomposable CTMC.
SccResult stronglyconncomp(const Matrix< T > &A)
Strongly connected components of a directed graph, and which of them are recurrent (closed under the ...
BicgstabMultiResult< T > ctmc_bicgstab_multi(const Matrix< T > &A, const Matrix< T > &B, double tol=1e-12, long maxit=0)
Every column of B solved against the SAME equilibration, reordering and ILUT factorization,...
std::vector< T > dtmc_solve(const Matrix< T > &P)
Stationary distribution of a stochastic matrix P.
SaddlepointResult< T > ctmc_saddlepoint(const Matrix< T > &D0, const Matrix< T > &D1, const std::vector< T > &t, const std::vector< long > &k, SaddlepointMethod method=SADDLEPOINT_DANIELS2, const std::vector< T > &pi0=std::vector< T >())
Pr{N(t)=k} over arrays of horizons and counts.
RandomizationResult< T > ctmc_randomization(const Matrix< T > &Q, const T &q)
Uniformization (randomization) of a CTMC: the embedded DTMC P = I + Q/q.
GmresResult< T > ctmc_gmres(const Matrix< T > &A, const std::vector< T > &b, double tol=1e-12, long restart=0, long maxit=0, const std::vector< T > &x0=std::vector< T >())
Restarted GMRES with an ILUT preconditioner, for the linear systems a generator produces.
TransientSensResult< T > ctmc_transient_sens(const Matrix< T > &Q, const Matrix< T > &dQ, const std::vector< T > &pi0, const T &t0, const T &t1, double rtol=1e-3, double atol=1e-6)
Sensitivity of the transient distribution of a CTMC to a scalar parameter.
TransientResult< T > ctmc_transient(const Matrix< T > &Q, const std::vector< T > &pi0, const T &t0, const T &t1, double rtol=1e-3, double atol=1e-6)
Transient distribution of a CTMC over a time interval, by integrating the forward equations d pi/dt =...
FoxGlynnResult< T > ctmc_foxglynn(const std::vector< T > &pi0, const Matrix< T > &Q, const T &t, double tol=1e-12, long maxiter=-1)
Transient distribution of a CTMC by uniformization with Fox-Glynn Poisson weights.
CourtoisResult< T > ctmc_courtois(const Matrix< T > &Q, const std::vector< std::vector< std::size_t > > &MS, const T &q)
Courtois decomposition of a nearly completely decomposable (NCD) CTMC.
FauResult< T > ctmc_fau(const std::vector< T > &pi0, const Matrix< T > &Q, const T &t, double epsilon=1e-6, double delta=1e-12, long maxsteps=-1)
Transient distribution of a CTMC by fast adaptive uniformization.
std::vector< T > ctmc_sens(const Matrix< T > &Q, const Matrix< T > &dQ, const std::vector< T > &pi)
Sensitivity of the steady-state distribution of a CTMC to a scalar parameter.
std::vector< T > moment_raw_from_central(const std::vector< T > &mc, const T &m1)
m_i = sum_k C(i,k) mc_k m1^(i-k).
NcResult< T > pfqn_recal(const Matrix< T > &L, const std::vector< int > &N, const Matrix< T > &Z, const std::vector< int > &m0)
RECAL (REcursive CALculation) for the exact normalizing constant of a closed product-form network (Co...
ProcomomResult< T > pfqn_procomom(const Matrix< T > &L, const std::vector< int > &N, const std::vector< T > &Z, const T &atol)
Marginal queue-length distributions of every station.
MvaResult< T > pfqn_mva(const Matrix< T > &L, const std::vector< int > &N, const Matrix< T > &Z, const std::vector< int > &mi)
Exact Mean Value Analysis for closed product-form networks (Reiser and Lavenberg 1980).
ComomResult< T > pfqn_comomrm_orig(const Matrix< T > &L, const std::vector< int > &N, const Matrix< T > &Z, const T &atol)
Original CoMoM for the finite repairman model (matlab pfqn_comomrm_orig.m).
ComomResult< T > pfqn_comomrm(const Matrix< T > &L, const std::vector< int > &N, const Matrix< T > &Z, int m)
CoMoM (class-oriented method of moments) for the finite repairman model: one queueing station of mult...
NcResult< T > pfqn_ca(const Matrix< T > &L, const std::vector< int > &N, const Matrix< T > &Z)
Convolution algorithm for the exact normalizing constant of a closed product-form network (Buzen 1973...
ComomRmResult< T > pfqn_comomrm_ms(const Matrix< T > &L, const std::vector< int > &N, const Matrix< T > &Z, int m, int S)
CoMoM for the MULTISERVER repairman model: one queueing station with S servers (optionally replicated...
NcResult< T > pfqn_conv(const Matrix< T > &L, const std::vector< int > &N, const Matrix< T > &Z, const std::vector< CdScaling< T > > &cdscaling)
Multichain convolution algorithm with class-dependent service rates (Sauer 1983, "Computational Algor...
ComomResult< T > pfqn_comom(const Matrix< T > &L, const std::vector< int > &N, const std::vector< T > &Z, const T &atol)
CoMoM on the general basis (matlab pfqn_comom.m).
NcResult< T > pfqn_gld(const Matrix< T > &L, const std::vector< int > &N, const Matrix< T > &mu)
Exact normalizing constant of a closed product-form network whose stations may be load dependent (gen...
MapMcResult< T > qsys_mapmc(const mam::Map< T > &arrival, const T &mu, unsigned c, std::size_t dist_size)
MAP/M/c by the matrix-geometric solution.
GigkRqtResult< T > qsys_gigk_rqt(const T &lambda, const T &mu, const T &Gamma_a, const T &Gamma_s, std::size_t k, const T &alpha_a, const T &alpha_s)
Robust Queueing Theory (RQT) worst-case system time of a G/G/k FCFS queue.
MmccRetrialFpResult< T > qsys_mmcc_retrial_fp(const T &lambda, const T &mu, unsigned c, const T &tol, std::size_t maxiter)
M/M/c/c with retrials by the Cohen fixed point.
QsysQedResult< T > qsys_mmk_qed(const T &lambda, const T &mu, unsigned s)
Halfin-Whitt QED approximation for the M/M/s queue, and the square-root staffing rule that inverts it...
QsysResult< T > qsys_mm1(const T &lambda, const T &mu)
Exact mean response time of the M/M/1 queue.
Mm1kLossResult< T > qsys_mm1k_loss(const T &lambda, const T &mu, unsigned K)
Blocking probability of the M/M/1/K queue.
Gig1ExtremalResult< T > qsys_gig1_bnds_extremal(const T &lambda, const T &mu, const T &ca, const T &cs, std::size_t K=4000, std::size_t N=2000, bool skipTight=false)
Extremal two-moment bounds for the GI/GI/1 queue.
MapMap1Result< T > qsys_phph1(const std::vector< T > &alpha, const Matrix< T > &Tm, const std::vector< T > &beta, const Matrix< T > &S, std::size_t dist_size)
PH/PH/1 by the exact QBD solution of the equivalent MAP/MAP/1 queue.
@ Acyclic
three or more moments
@ Hyperexponential
cv2 > 1
@ Exponential
one moment, or cv2 exactly 1
@ Erlang
0 < cv2 < 1, or the cv2 <= 0 branch
QsysGgnmResult< T > qsys_ggnm_diffusion(const T &lambda, const T &mu, unsigned n, double m, const T &ca, const T &cs, const std::function< T(const T &)> &serviceCcdf=std::function< T(const T &)>(), double tol=1e-12, std::size_t panels=4000)
Diffusion approximation for the G/GI/n/m queue.
MxM1Result< T > qsys_mxm1(const T &lambda_batch, const T &mu, const T &E_X, const T &E_X2)
M^X/M/1: the batch-arrival queue with exponential service.
QsysAbandonResult< T > qsys_erlanga(const T &lambda, const T &mu, const T &theta, unsigned s, double r=std::numeric_limits< double >::infinity(), const MgisrgiOptions &opts=MgisrgiOptions())
Exact analysis of the Erlang A model M/M/s/r+M.
T qsys_gm1(const T &sigma, const T &mu)
Exact mean response time of the G/M/1 queue.
QsysQedStaffingResult< T > qsys_mmk_qed_staffing(const T &lambda, const T &mu, const T &target, QedCriterion crit=QedCriterion::Delay, const T &deadline=num_traits< T >::from_int(0), const T &level=num_traits< T >::from_int(0), bool exact=false)
Square-root staffing of the M/M/s queue.
MapD1Result< T > qsys_mapd1(const mam::Map< T > &arrival, const T &s, std::size_t dist_size, unsigned max_arrivals, std::size_t max_levels, const T &tol)
MAP/D/1 by the exact embedded M/G/1-type chain.
MmckResult< T > qsys_mmck(const T &lambda, const T &mu, unsigned c, unsigned K)
Exact analysis of the M/M/c/K queue (truncated Erlang form).
GigkRqtResult< T > qsys_gig1_rqt(const T &lambda, const T &mu, const T &Gamma_a, const T &Gamma_s, const T &alpha_a, const T &alpha_s)
Robust Queueing Theory (RQT) worst-case system time of a G/G/1 FCFS queue, the single-server case of ...
QedCriterion
Which target the staffing rule is asked to meet.
PhM1Result< T > qsys_phm1(const std::vector< T > &alpha, const Matrix< T > &Tm, const T &mu, const T &tol)
Exact PH/M/1, the GI/M/1 queue with phase-type interarrival times.
Mm1DpsResult< T > qsys_mm1_dps(const std::vector< T > &lambda, const std::vector< T > &mu, const std::vector< T > &w, const T &tol, unsigned maxCutoff)
Multiclass M/M/1 under DPS (discriminatory processor sharing), solved numerically on the truncated po...
T qsys_mmk_qed_alpha(const T &beta)
The Halfin-Whitt delay-probability function alpha(beta); 1 at beta <= 0.
QsysResult< T > qsys_mg1(const T &lambda, const T &mu, const T &cs)
Exact mean response time of the M/G/1 queue (Pollaczek-Khinchine).
MapPhcResult< T > qsys_mapphc(const mam::Map< T > &arrival, const std::vector< T > &alpha, const Matrix< T > &S, unsigned c, std::size_t dist_size, std::size_t num_w_moms, const std::vector< T > &w_points)
MAP/PH/c FCFS, exactly.
Mg1kLossMgsResult< T > qsys_mg1k_loss_mgs(const T &lambda, const T &mu, const T &mu_scv, unsigned K)
MacGregor Smith's closed-form approximation of the M/G/1/K loss probability.
T qsys_gigk_rqt_gamma(const T &rho, const T &mu, const T &Gamma_a, const T &sigma_s, std::size_t k, const T &alpha_a, const std::string ®ime="independent")
Service variability parameter of the Robust Queueing Theory (RQT) framework.
QsysResult< T > qsys_mmk(const T &lambda, const T &mu, unsigned k)
Exact mean response time of the M/M/k queue (Erlang-C).
BmapPhNnRetrialResult< T > qsys_bmapphnn_retrial(const std::vector< Matrix< T > > &D, const std::vector< T > &beta, const Matrix< T > &S, int N, const T &alpha, const T &gamma, const T &p, const std::vector< long > &R, const BmapPhNnRetrialOptions &opt)
The BMAP/PH/N/N bufferless retrial queue.
QsysResult< T > qsys_gg1(const T &lambda, const T &mu, const T &ca2, const T &cs2)
G/G/1 dispatcher: exact where a two-moment description determines the answer, Allen-Cunneen otherwise...
MginfResult< T > qsys_mginf(const T &lambda, const T &mu)
Exact solution of the M/G/infinity queue.
MapDcResult< T > qsys_mapdc(const mam::Map< T > &arrival, const T &s, unsigned c, std::size_t dist_size, unsigned max_arrivals, std::size_t max_levels, const T &tol)
MAP/D/c by Crommelin's exact embedded lattice chain.
MapMcResult< T > qsys_mapm1(const mam::Map< T > &arrival, const T &mu, std::size_t dist_size)
MAP/M/1 by the matrix-geometric solution, i.e.
MapMap1Result< T > qsys_mapph1(const mam::Map< T > &arrival, const std::vector< T > &sigma, const Matrix< T > &S, std::size_t dist_size)
MAP/PH/1 by the exact QBD solution of the equivalent MAP/MAP/1 queue.
DmcResult< T > qsys_dmc(const T &lambda, const T &mu, unsigned c, unsigned truncation, unsigned quadSteps)
D/M/c: deterministic interarrival times, exponential service.
MapMap1Result< T > qsys_mapmap1(const mam::Map< T > &arrival, const mam::Map< T > &service, std::size_t dist_size)
MAP/MAP/1 by the exact QBD solution.
PhMcResult< T > qsys_phmc(const std::vector< T > &alpha, const Matrix< T > &Tm, const T &mu, unsigned c, unsigned maxIter, const T &tol)
Exact PH/M/c by Neuts' matrix-geometric method.
MapG1Result< T > qsys_mapg1(const mam::Map< T > &arrival, const std::vector< T > &moments, std::size_t dist_size)
The MAP/G/1 FCFS queue.
std::string api_render_readable(const Json &result)
Human-readable rendering of the object api_invoke returns, for -o readable.
ArithSpec parse_arith(const std::string &text)
Parse –arith.
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)
std::vector< std::string > api_exposed_functions()
Names exposed over this boundary, sorted; a subset of the registry.
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.
bool api_is_exposed(const std::string &name)
True when the named function has a dispatch entry.
Json api_invoke(const std::string &name, const std::string &arith, const Json &args)
Invoke one API function.
QuestResult< T > sim_fquest(const std::vector< T > &Y, double p, double alpha=0.05, const QuestOptions &options=QuestOptions())
Fixed-sample-size confidence interval for a steady-state quantile.
QuestResult< T > sim_firquest(const std::vector< std::vector< T > > &Y, double p, double alpha=0.05, const QuestOptions *options=nullptr)
Fixed-sample-size quantile interval from independent replications.
StsQuantileStats< T > sim_sts_quantile_areas(const std::vector< T > &Y, std::size_t b, std::size_t m, double p, double weight=std::sqrt(12.0))
Standardized time series areas of the batched quantile process.
VonNeumannResult< T > sim_vonneumann(const std::vector< T > &x, double alpha=0.05)
Von Neumann ratio test for randomness of a sequence.
ShapiroWilkResult< T > sim_shapirowilk(const std::vector< T > &x, double alpha=0.05)
Shapiro-Wilk test for univariate normality.
const char * arith_name(Arith a)
const ApiEntry * find_api(const std::string &name)
bool api_supports(const ApiEntry &e, Arith a)
Convolution algorithm for the exact normalizing constant of a closed product-form network (Buzen 1973...
CoMoM (class-oriented method of moments), the general basis formulation, and the original repairman-m...
CoMoM (class-oriented method of moments) for the finite repairman model: one queueing station of mult...
CoMoM for the MULTISERVER repairman model: one queueing station with S servers (optionally replicated...
Multichain convolution algorithm with class-dependent service rates (Sauer 1983, "Computational Algor...
Exact normalizing constant of a closed product-form network whose stations may be load dependent (gen...
Exact Mean Value Analysis for closed product-form networks (Reiser and Lavenberg 1980).
ProCoMoM: marginal queue-length probabilities of a closed multiclass product-form network by the clas...
RECAL (REcursive CALculation) for the exact normalizing constant of a closed product-form network (Co...
The BMAP/PH/N/N bufferless retrial queue with flexible retrial admission control.
D/M/c: deterministic interarrival times, exponential service.
G/G/1 dispatcher: exact where a two-moment description determines the answer, Allen-Cunneen otherwise...
Diffusion approximation for the G/GI/n/m queue.
Allen-Cunneen approximation of the mean response time of a G/I/G/1 queue.
Gelenbe diffusion approximation with instantaneous-return boundary.
Heyman approximation of the mean response time of a G/I/G/1 queue.
Kimura diffusion-interpolation approximation for the G/I/G/1 queue.
Kraemer and Langenbach-Belz approximation for the G/I/G/1 queue.
Kobayashi diffusion approximation for the G/I/G/1 queue.
Marchal approximation of the mean response time of a G/I/G/1 queue.
Myskja's enhanced third-moment approximation of the mean response time of a G/I/G/1 queue.
Myskja's third-moment approximation of the mean response time of a G/I/G/1 queue.
Extremal two-moment bounds for the GI/GI/1 queue.
Fundamental lower bound on the mean response time of a G/G/1 queue.
Robust Queueing Theory (RQT) worst-case system time of a G/G/1 FCFS queue, the single-server case of ...
Kingman upper bound on the mean waiting time of a G/G/1 queue.
Default G/I/G/k approximation of the mean response time.
Kingman (Lee-Longton) scaling of the exact M/M/k waiting time.
Whitt (1993) approximation for the GI/G/k queue, eqs.
Robust Queueing Theory (RQT) worst-case system time of a G/G/k FCFS queue.
Service variability parameter of the Robust Queueing Theory (RQT) framework.
Exact mean response time of the G/M/1 queue.
The MAP/D/1 FCFS queue: deterministic service of length s fed by a Markovian arrival process.
The MAP/D/c FCFS queue: c servers, deterministic service of length s, fed by a Markovian arrival proc...
The MAP/G/1 FCFS queue, by moment-matching the general service time to a phase-type distribution.
The MAP/M/1 FCFS queue, the single-server case of MAP/M/c.
The MAP/MAP/1 FCFS queue: mean number in system, waiting time, sojourn time, utilization and the queu...
The MAP/M/c FCFS queue: c identical exponential servers of rate mu fed by a Markovian arrival process...
The MAP/PH/c FCFS queue, solved exactly.
Exact mean response time of the M/G/1 queue (Pollaczek-Khinchine).
M/G/1 under FB (feedback), also called LAS (least attained service).
M/G/1 under LRPT (longest remaining processing time).
M/G/1 with non-preemptive head-of-line priorities: per-class mean response times from the Cobham/Klei...
M/G/1 under PSJF (preemptive shortest job first).
M/G/1 under SETF (shortest elapsed time first), the non-preemptive counterpart of FB/LAS.
M/G/1 under SRPT (shortest remaining processing time), by the Schrage-Miller formula.
MacGregor Smith's closed-form approximation of the M/G/1/K loss probability.
Exact solution of the M/G/infinity queue.
Engineering solution of the call-center model M/GI/s/r+GI.
Exact mean response time of the M/M/1 queue.
Multiclass M/M/1 under DPS (discriminatory processor sharing), solved numerically on the truncated po...
Blocking probability of the M/M/1/K queue.
Fixed-point approximation for the M/M/c/c retrial queue.
Exact analysis of the M/M/c/K queue (truncated Erlang form).
Exact mean response time of the M/M/k queue (Erlang-C).
Halfin-Whitt QED approximation for the M/M/s queue, and the square-root staffing rule that inverts it...
M^X/M/1: the batch-arrival queue with exponential service.
Exact PH/M/1, the GI/M/1 queue with phase-type interarrival times.
Exact PH/M/c by Neuts' matrix-geometric method.
Fixed-sample-size quantile interval from independent replications.
Fixed-sample-size confidence interval for a steady-state quantile.
Options of the QUEST procedures, with the published FQUEST defaults.
Shapiro-Wilk test for univariate normality.
Standardized time series areas of the batched quantile process.
Von Neumann ratio test for randomness of a sequence.
Strongly connected components of a directed graph, and which of them are recurrent (closed under the ...
std::vector< Arith > arith
arithmetic modes this function is instantiated for
std::string domain
api domain, e.g. "pfqn"
static double to_double(const double &v)
The arithmetic a call runs at: Real also carries the precision tier.
std::string str() const
Canonical text, e.g.
unsigned digits
significant decimal digits, Real only