199 if (text ==
"double") {
203 if (text ==
"exact") {
207 if (text.compare(0, 5,
"real:") == 0 || text ==
"real") {
209 if (text !=
"real") {
210 const std::string d = text.substr(5);
211 if (d.empty() || d.find_first_not_of(
"0123456789") != std::string::npos)
212 throw InputError(
"--arith real:<digits> needs a decimal digit count, got '" + d +
214 want =
static_cast<unsigned>(std::strtoul(d.c_str(),
nullptr, 10));
215 if (want == 0)
throw InputError(
"--arith real:<digits> needs at least one digit");
221 else if (want <= 100)
223 else if (want <= 200)
227 "--arith real:" + std::to_string(want) +
228 " exceeds the precision tiers this build instantiates (50, 100, 200 digits); "
229 "a wider tier has to be compiled in, it cannot be selected at run time.");
233 "'; accepted forms are: double, exact, real:<digits> "
234 "(digits rounded up to 50, 100 or 200)");
250Json run_at(
const ArithSpec& s, Args& a) {
253 case Arith::Exact:
return Op::template run<Rational>(a);
255 if (s.digits <= 50)
return Op::template run<Real50>(a);
256 if (s.digits <= 100)
return Op::template run<Real100>(a);
257 return Op::template run<Real200>(a);
259 throw InputError(
"unreachable arithmetic selection");
274struct NeedsTranscendental {
276 static Json run(Args& a) {
277 if constexpr (num_traits<T>::has_transcendental) {
278 return Op::template run<T>(a);
282 "this function evaluates transcendental terms (exp, log, sqrt or a "
283 "matrix exponential), which the exact rational field does not contain; "
284 "rerun with --arith double or --arith real:<digits>.");
291Json nc_results(
const pfqn::NcResult<T>& r) {
300 static Json run(Args& a) {
301 const Matrix<T> L = a.matrix<T>(
"L");
302 const std::vector<int> N = a.ints(
"N");
303 const Matrix<T> Z = a.matrix_or_empty<T>(
"Z");
311 static Json run(Args& a) {
312 const Matrix<T> L = a.matrix<T>(
"L");
313 const std::vector<int> N = a.ints(
"N");
314 const Matrix<T> Z = a.matrix_or_empty<T>(
"Z");
315 a.unsupported(
"cdscaling",
316 "the class-dependence scaling argument is a vector of callables, which has "
317 "no JSON representation; call pfqn_conv from the library for that case");
318 a.unsupported(
"options",
"solver options are not carried over the --api boundary");
326 static Json run(Args& a) {
327 const Matrix<T> L = a.matrix<T>(
"L");
328 const std::vector<int> N = a.ints(
"N");
329 const Matrix<T> Z = a.matrix_or_empty<T>(
"Z");
330 const std::vector<int> m0 = a.ints_or_empty(
"m0");
338 static Json run(Args& a) {
339 const Matrix<T> L = a.matrix<T>(
"L");
340 const std::vector<int> N = a.ints(
"N");
341 const Matrix<T> mu = a.matrix<T>(
"mu");
342 a.unsupported(
"options",
"solver options are not carried over the --api boundary");
350 static Json run(Args& a) {
351 const Matrix<T> L = a.matrix<T>(
"L");
352 const std::vector<int> N = a.ints(
"N");
353 const Matrix<T> Z = a.matrix_or_empty<T>(
"Z");
354 const std::vector<int> mi = a.ints_or_empty(
"mi");
370Json comom_results(
const pfqn::ComomResult<T>& r) {
380 static Json run(Args& a) {
381 const Matrix<T> L = a.matrix<T>(
"L");
382 const std::vector<int> N = a.ints(
"N");
383 const std::vector<T> Z = a.vector_or_empty<T>(
"Z");
384 const T atol = a.scalar<T>(
"atol", num_traits<T>::from_int(0));
390struct OpPfqnComomrm {
392 static Json run(Args& a) {
393 const Matrix<T> L = a.matrix<T>(
"L");
394 const std::vector<int> N = a.ints(
"N");
395 const Matrix<T> Z = a.matrix_or_empty<T>(
"Z");
396 const int m = a.integer(
"m", 1);
402struct OpPfqnComomrmOrig {
404 static Json run(Args& a) {
405 const Matrix<T> L = a.matrix<T>(
"L");
406 const std::vector<int> N = a.ints(
"N");
407 const Matrix<T> Z = a.matrix_or_empty<T>(
"Z");
408 const T atol = a.scalar<T>(
"atol", num_traits<T>::from_int(0));
414struct OpPfqnComomrmMs {
416 static Json run(Args& a) {
417 const Matrix<T> L = a.matrix<T>(
"L");
418 const std::vector<int> N = a.ints(
"N");
419 const Matrix<T> Z = a.matrix_or_empty<T>(
"Z");
420 const int m = a.integer(
"m", 1);
421 const int S = a.integer(
"S", 1);
432struct OpPfqnProcomom {
434 static Json run(Args& a) {
435 const Matrix<T> L = a.matrix<T>(
"L");
436 const std::vector<int> N = a.ints(
"N");
437 const std::vector<T> Z = a.vector_or_empty<T>(
"Z");
438 const T atol = a.scalar<T>(
"atol", num_traits<T>::from_int(0));
444 out[
"rankdef"] = r.rankdef;
451 static Json run(Args& a) {
452 const Matrix<T> Q = a.matrix<T>(
"Q");
453 a.unsupported(
"options",
"solver options are not carried over the --api boundary");
463 static Json run(Args& a) {
464 const Matrix<T>
P = a.matrix<T>(
"P");
465 a.unsupported(
"options",
"solver options are not carried over the --api boundary");
473struct OpCtmcMakeinfgen {
475 static Json run(Args& a) {
476 const Matrix<T> Q = a.matrix<T>(
"Q");
504struct QuestOptionsRead {
505 sim::QuestOptions opt;
506 bool supplied =
false;
510QuestOptionsRead read_quest_options(
Args& a) {
511 QuestOptionsRead out;
512 const char* keys[] = {
"b0",
"m0",
"s",
"beta",
"eta",
"theta",
"weight",
"force"};
513 for (std::size_t k = 0; k <
sizeof(keys) /
sizeof(keys[0]); ++k)
514 if (a.has(keys[k])) out.supplied =
true;
515 out.opt.b0 =
static_cast<long>(a.integer(
"b0",
static_cast<int>(out.opt.b0)));
516 out.opt.m0 =
static_cast<long>(a.integer(
"m0",
static_cast<int>(out.opt.m0)));
517 const std::vector<int> s = a.ints_or_empty(
"s");
520 for (std::size_t i = 0; i < s.size(); ++i) out.opt.s.push_back(
static_cast<long>(s[i]));
522 out.opt.beta = a.scalar<
double>(
"beta", out.opt.beta);
523 out.opt.eta = a.scalar<
double>(
"eta", out.opt.eta);
524 out.opt.theta = a.scalar<
double>(
"theta", out.opt.theta);
525 out.opt.weight = a.scalar<
double>(
"weight", out.opt.weight);
526 out.opt.force = a.integer(
"force", out.opt.force ? 1 : 0) != 0;
532Json quest_results(
const sim::QuestResult<T>& r) {
538 out[
"b"] =
static_cast<long long>(r.b);
539 out[
"m"] =
static_cast<long long>(r.m);
540 out[
"n"] =
static_cast<long long>(r.n);
541 out[
"R"] =
static_cast<long long>(r.R);
542 out[
"truncated"] =
static_cast<long long>(r.truncated);
546 out[
"heuristic"] = r.heuristic;
547 out[
"warnings"] = r.warnings;
552std::string sim_exact_refusal(
const char* fn,
const char* why) {
553 return std::string(fn) +
": " + why +
554 ", so exact rational arithmetic has nothing to preserve and is refused; rerun with "
555 "--arith double or --arith real";
558struct OpSimVonneumann {
560 static Json run(Args& a) {
561 if constexpr (!num_traits<T>::has_transcendental) {
563 sim_exact_refusal(
"sim_vonneumann",
"the p-value is a normal tail"));
566 const double alpha = a.scalar<
double>(
"alpha", 0.05);
571 out[
"zscore"] = r.zscore;
572 out[
"pvalue"] = r.pvalue;
573 out[
"reject"] = r.reject;
574 out[
"nobs"] =
static_cast<long long>(r.nobs);
580struct OpSimShapirowilk {
582 static Json run(Args& a) {
583 if constexpr (!num_traits<T>::has_transcendental) {
585 "sim_shapirowilk",
"the weights and the p-value are normal-order statistics"));
588 const double alpha = a.scalar<
double>(
"alpha", 0.05);
593 out[
"pvalue"] = r.pvalue;
594 out[
"zscore"] = r.zscore;
595 out[
"reject"] = r.reject;
596 out[
"nobs"] =
static_cast<long long>(r.nobs);
602struct OpSimStsQuantileAreas {
604 static Json run(Args& a) {
605 if constexpr (!num_traits<T>::has_transcendental) {
607 "sim_sts_quantile_areas",
"the areas carry the irrational weight sqrt(12)"));
609 const std::vector<T> Y =
611 const int b = a.integer(
"b", 0);
612 const int m = a.integer(
"m", 0);
613 const double p = a.scalar<
double>(
"p", 0.5);
614 const double weight = a.scalar<
double>(
"weight", std::sqrt(12.0));
616 if (b <= 0 || m <= 0)
618 "sim_sts_quantile_areas: the batch count b and batch size m are required and "
619 "must be positive integers");
621 Y,
static_cast<std::size_t
>(b),
static_cast<std::size_t
>(m), p, weight);
629 out[
"b"] =
static_cast<long long>(r.b);
630 out[
"m"] =
static_cast<long long>(r.m);
631 out[
"n"] =
static_cast<long long>(r.n);
639 static Json run(Args& a) {
640 if constexpr (!num_traits<T>::has_transcendental) {
642 "sim_fquest",
"the interval is a t quantile times a square root"));
645 const double p = a.scalar<
double>(
"p", 0.5);
646 const double alpha = a.scalar<
double>(
"alpha", 0.05);
647 const QuestOptionsRead o = read_quest_options(a);
654struct OpSimFirquest {
656 static Json run(Args& a) {
657 if constexpr (!num_traits<T>::has_transcendental) {
659 "sim_firquest",
"the interval is a t quantile times a square root"));
665 const Matrix<T> Ym = a.matrix<T>(
"Y");
666 const double p = a.scalar<
double>(
"p", 0.5);
667 const double alpha = a.scalar<
double>(
"alpha", 0.05);
668 const QuestOptionsRead o = read_quest_options(a);
670 std::vector<std::vector<T> > Y(Ym.cols(), std::vector<T>(Ym.rows()));
671 for (std::size_t i = 0; i < Ym.rows(); ++i)
672 for (std::size_t r = 0; r < Ym.cols(); ++r) Y[r][i] = Ym(i, r);
676 return quest_results(
710Json qsys_results(
const qsys::QsysResult<T>& r) {
721#define LINE_QSYS_GIG1(OpName, fn) \
724 static Json run(Args& a) { \
725 const T lambda = a.number<T>("lambda"); \
726 const T mu = a.number<T>("mu"); \
727 const T ca = a.number<T>("ca"); \
728 const T cs = a.number<T>("cs"); \
730 return qsys_results(qsys::fn(lambda, mu, ca, cs)); \
734LINE_QSYS_GIG1(OpQsysGig1AllenCunneen, qsys_gig1_approx_allencunneen);
745#define LINE_QSYS_GIGK(OpName, fn) \
748 static Json run(Args& a) { \
749 const T lambda = a.number<T>("lambda"); \
750 const T mu = a.number<T>("mu"); \
751 const T ca = a.number<T>("ca"); \
752 const T cs = a.number<T>("cs"); \
753 const unsigned k = a.uinteger("k"); \
755 return qsys_results(qsys::fn(lambda, mu, ca, cs, k)); \
771struct OpQsysErlangA {
773 static Json run(Args& a) {
774 const T lambda = a.number<T>(
"lambda");
775 const T mu = a.number<T>(
"mu");
776 const T theta = a.number<T>(
"theta");
777 const unsigned s = a.uinteger(
"s");
780 : std::numeric_limits<double>::infinity();
781 qsys::MgisrgiOptions opts;
782 opts.wPoints = a.vector_or_empty<
double>(
"wPoints");
783 opts.maxQueue = a.count(
"maxQueue", qsys::MgisrgiOptions().maxQueue);
785 const qsys::QsysAbandonResult<T> res =
qsys::qsys_erlanga(lambda, mu, theta, s, r, opts);
804 out[
"secondMomentWait"] =
encode_scalar(res.secondMomentWait);
805 out[
"numWaitingSpaces"] =
static_cast<double>(res.numWaitingSpaces);
806 if (!res.waitPoints.empty()) {
816struct OpQsysGgnmDiffusion {
818 static Json run(Args& a) {
819 const T lambda = a.number<T>(
"lambda");
820 const T mu = a.number<T>(
"mu");
821 const unsigned n = a.uinteger(
"n");
823 const double m = a.has(
"m") ? a.number<
double>(
"m")
824 : std::numeric_limits<double>::infinity();
825 const T ca = a.number<T>(
"ca");
826 const T cs = a.number<T>(
"cs");
846struct OpQsysGig1BndsExtremal {
848 static Json run(Args& a) {
849 const T lambda = a.number<T>(
"lambda");
850 const T mu = a.number<T>(
"mu");
851 const T ca = a.number<T>(
"ca");
852 const T cs = a.number<T>(
"cs");
853 const std::size_t K = a.count(
"K", 4000);
854 const std::size_t N = a.count(
"N", 2000);
855 const bool skipTight = a.boolean(
"skipTight",
false);
857 const qsys::Gig1ExtremalResult<T> r =
865 out[
"upperBoundKingman"] =
encode_scalar(r.upperBoundKingman);
869 out[
"tightComputed"] = r.tightComputed;
876 static Json run(Args& a) {
877 const T lambda = a.number<T>(
"lambda");
878 const T mu = a.number<T>(
"mu");
879 const unsigned s = a.uinteger(
"s");
896struct OpQsysMmkQedAlpha {
898 static Json run(Args& a) {
899 const T beta = a.number<T>(
"beta");
907struct OpQsysMmkQedStaffing {
909 static Json run(Args& a) {
910 const T lambda = a.number<T>(
"lambda");
911 const T mu = a.number<T>(
"mu");
912 const std::string crit = a.text(
"criterion",
"delay");
913 const T target = a.has(
"target") ? a.number<T>(
"target") : num_traits<T>::from_int(0);
914 const T deadline = a.has(
"deadline") ? a.number<T>(
"deadline") : num_traits<T>::from_int(0);
915 const T level = a.has(
"level") ? a.number<T>(
"level") : num_traits<T>::from_int(0);
916 const bool exact = a.boolean(
"exact",
false);
919 if (crit ==
"meanwait") {
921 }
else if (crit ==
"servicelevel") {
923 }
else if (crit !=
"delay") {
924 throw InputError(
"qsys_mmk_qed_staffing: unknown criterion '" + crit +
"'");
926 const qsys::QsysQedStaffingResult<T> r =
929 out[
"numServers"] =
static_cast<double>(r.numServers);
943struct OpQsysGigkRqt {
945 static Json run(Args& a) {
946 const T lambda = a.number<T>(
"lambda");
947 const T mu = a.number<T>(
"mu");
948 const T Gamma_a = a.number<T>(
"Gamma_a");
949 const T Gamma_s = a.number<T>(
"Gamma_s");
950 const unsigned k = a.uinteger(
"k");
951 const T alpha_a = a.number<T>(
"alpha_a");
952 const T alpha_s = a.number<T>(
"alpha_s");
954 const qsys::GigkRqtResult<T> r =
964struct OpQsysGig1Rqt {
966 static Json run(Args& a) {
967 const T lambda = a.number<T>(
"lambda");
968 const T mu = a.number<T>(
"mu");
969 const T Gamma_a = a.number<T>(
"Gamma_a");
970 const T Gamma_s = a.number<T>(
"Gamma_s");
971 const T alpha_a = a.number<T>(
"alpha_a");
972 const T alpha_s = a.number<T>(
"alpha_s");
974 const qsys::GigkRqtResult<T> r =
984struct OpQsysGigkRqtGamma {
986 static Json run(Args& a) {
987 const T rho = a.number<T>(
"rho");
988 const T mu = a.number<T>(
"mu");
989 const T Gamma_a = a.number<T>(
"Gamma_a");
990 const T sigma_s = a.number<T>(
"sigma_s");
991 const unsigned k = a.uinteger(
"k");
992 const T alpha_a = a.number<T>(
"alpha_a");
993 const std::string regime = a.text(
"regime",
"independent");
1002#define LINE_QSYS_MYSKJA(OpName, fn) \
1004 template <class T> \
1005 static Json run(Args& a) { \
1006 const T lambda = a.number<T>("lambda"); \
1007 const T mu = a.number<T>("mu"); \
1008 const T ca = a.number<T>("ca"); \
1009 const T cs = a.number<T>("cs"); \
1010 const T q0 = a.number<T>("q0"); \
1011 const T qa = a.number<T>("qa"); \
1013 return qsys_results(qsys::fn(lambda, mu, ca, cs, q0, qa)); \
1019#undef LINE_QSYS_MYSKJA
1023 static Json run(Args& a) {
1024 const T lambda = a.number<T>(
"lambda");
1025 const T mu = a.number<T>(
"mu");
1033 static Json run(Args& a) {
1034 const T lambda = a.number<T>(
"lambda");
1035 const T mu = a.number<T>(
"mu");
1036 const unsigned k = a.uinteger(
"k");
1044 static Json run(Args& a) {
1045 const T lambda = a.number<T>(
"lambda");
1046 const T mu = a.number<T>(
"mu");
1047 const T cs = a.number<T>(
"cs");
1055 static Json run(Args& a) {
1056 const T lambda = a.number<T>(
"lambda");
1057 const T mu = a.number<T>(
"mu");
1058 const T ca2 = a.number<T>(
"ca2");
1059 const T cs2 = a.number<T>(
"cs2");
1068 static Json run(Args& a) {
1069 const T sigma = a.number<T>(
"sigma");
1070 const T mu = a.number<T>(
"mu");
1080 static Json run(Args& a) {
1081 const T lambda = a.number<T>(
"lambda");
1082 const T mu = a.number<T>(
"mu");
1083 const bool has_k = a.has(
"k");
1084 const unsigned k = has_k ? a.uinteger(
"k") : 0u;
1086 const qsys::MginfResult<T> r =
1109struct OpQsysMgckSync {
1111 static Json run(Args& a) {
1112 const T lambda = a.number<T>(
"lambda");
1113 const std::size_t c = a.count(
"c");
1114 const std::size_t K = a.count(
"K");
1115 Args sv(a.get(
"svc"),
"qsys_mgck_sync: svc");
1116 const std::string type = sv.text(
"type",
"");
1117 qsys::ServiceLaw<T> svc;
1118 if (type ==
"det") {
1120 }
else if (type ==
"gamma") {
1121 const T al = sv.number<T>(
"alpha");
1123 }
else if (type ==
"ph") {
1124 const std::vector<T> al = sv.vector<T>(
"alpha");
1126 }
else if (type ==
"density") {
1128 "qsys_mgck_sync: a 'density' service law is a function handle and has no "
1129 "named-JSON form; use 'det', 'gamma' or 'ph', or call it from the library");
1132 "qsys_mgck_sync: svc.type must be 'det', 'gamma' or 'ph', got '" + type +
"'");
1135 const std::string variant = a.text(
"variant",
"");
1136 if (variant.empty())
throw InputError(
"qsys_mgck_sync: missing required argument 'variant'");
1137 const std::size_t nphases = a.count(
"nphases", 0);
1138 const bool any = a.has(
"tol") || a.has(
"nmax");
1139 if (any && !(a.has(
"tol") && a.has(
"nmax")))
1140 throw InputError(
"qsys_mgck_sync: 'tol' and 'nmax' tune one truncation together; "
1141 "give both or neither");
1142 const T tol = a.scalar<T>(
"tol", num_traits<T>::from_int(0));
1143 const std::size_t nmax = a.count(
"nmax", 0);
1145 const qsys::MgckSyncResult<T> r =
1153 out[
"meanQueueLengthQ"] =
encode_scalar(r.meanQueueLengthQ);
1159 out[
"variant"] = r.variant;
1160 out[
"nphases"] = r.nphases;
1161 out[
"stateSpaceSize"] = r.stateSpaceSize;
1162 out[
"analyzer"] = r.analyzer;
1169 static Json run(Args& a) {
1170 const T lambda = a.number<T>(
"lambda");
1171 const T mu = a.number<T>(
"mu");
1172 const unsigned c = a.uinteger(
"c");
1173 const unsigned K = a.uinteger(
"K");
1178 out[
"meanQueueLengthQ"] =
encode_scalar(r.meanQueueLengthQ);
1189struct OpQsysMm1kLoss {
1191 static Json run(Args& a) {
1192 const T lambda = a.number<T>(
"lambda");
1193 const T mu = a.number<T>(
"mu");
1194 const unsigned K = a.uinteger(
"K");
1204struct OpQsysMg1kLossMgs {
1206 static Json run(Args& a) {
1207 const T lambda = a.number<T>(
"lambda");
1208 const T mu = a.number<T>(
"mu");
1209 const T mu_scv = a.number<T>(
"mu_scv");
1210 const unsigned K = a.uinteger(
"K");
1228 static Json run(Args& a) {
1229 const T lambda_batch = a.number<T>(
"lambda_batch");
1230 const T mu = a.number<T>(
"mu");
1231 const T E_X = a.number<T>(
"E_X");
1232 const bool has_m2 = a.has(
"E_X2"), has_var = a.has(
"Var_X");
1233 if (has_m2 == has_var)
1235 "qsys_mxm1: give exactly one of 'E_X2' (the second moment of the batch size) "
1236 "and 'Var_X' (its variance); MATLAB selects between them with a trailing "
1237 "'variance' flag, which has no place in a named-argument object");
1238 const T m2 = has_m2 ? a.number<T>(
"E_X2")
1239 : T(a.number<T>(
"Var_X") + E_X * E_X);
1241 const qsys::MxM1Result<T> r =
qsys::qsys_mxm1(lambda_batch, mu, E_X, m2);
1253 static Json run(Args& a) {
1254 const T lambda = a.number<T>(
"lambda_arr");
1255 const T mu = a.number<T>(
"mu");
1256 const unsigned c = a.uinteger(
"c");
1257 const bool tuned = a.has(
"truncation") || a.has(
"quadSteps");
1258 const unsigned truncation = a.uinteger(
"truncation", 0u);
1259 const unsigned quadSteps = a.uinteger(
"quadSteps", 200u);
1261 const qsys::DmcResult<T> r = tuned ?
qsys::qsys_dmc(lambda, mu, c, truncation, quadSteps)
1265 out[
"meanWaitingQueue"] =
encode_scalar(r.meanWaitingQueue);
1273struct OpQsysMmccRetrialFp {
1275 static Json run(Args& a) {
1276 const T lambda = a.number<T>(
"lambda");
1277 const T mu = a.number<T>(
"mu");
1278 const unsigned c = a.uinteger(
"c");
1279 const bool tuned = a.has(
"tol") || a.has(
"maxiter");
1280 const T tol = a.scalar<T>(
"tol", num_traits<T>::from_int(0));
1281 const std::size_t maxiter = a.count(
"maxiter", 0);
1283 const qsys::MmccRetrialFpResult<T> r =
1287 out[
"blockingProbability"] =
encode_scalar(r.blockingProbability);
1290 out[
"converged"] = r.converged;
1295struct OpQsysMm1Dps {
1297 static Json run(Args& a) {
1298 const std::vector<T> lambda = a.vector<T>(
"lambda");
1299 const std::vector<T> mu = a.vector<T>(
"mu");
1300 const std::vector<T> w = a.vector<T>(
"w");
1301 const bool tuned = a.has(
"tol") || a.has(
"maxCutoff");
1302 const T tol = a.scalar<T>(
"tol", num_traits<T>::from_int(0));
1303 const unsigned maxCutoff = a.uinteger(
"maxCutoff", 0u);
1305 const qsys::Mm1DpsResult<T> r = tuned
1319#define LINE_QSYS_MG1_DISC(OpName, fn, ResultT) \
1321 template <class T> \
1322 static Json run(Args& a) { \
1323 const std::vector<T> lambda = a.vector<T>("lambda"); \
1324 const std::vector<T> mu = a.vector<T>("mu"); \
1325 const std::vector<T> cs = a.vector<T>("cs"); \
1327 const qsys::ResultT<T> r = qsys::fn(lambda, mu, cs); \
1329 out["W"] = encode_vector(r.W); \
1330 out["rhohat"] = encode_scalar(r.rhohat); \
1341#undef LINE_QSYS_MG1_DISC
1350 const std::string c = a.text(
"convention",
"LAS_DA");
1353 throw InputError(
"'convention' must be LAS_DA or EAS, got '" + c +
"'");
1360struct OpQsysGeoGeo1 {
1362 static Json run(Args& a) {
1363 const T arrival = a.number<T>(
"a");
1364 const T service = a.number<T>(
"s");
1369 out[
"convention"] = geo_convention_name(r.convention);
1377 out[
"meanWaitingQueue"] =
encode_scalar(r.meanWaitingQueue);
1385struct OpQsysGeoxGeo1 {
1387 static Json run(Args& a) {
1388 const T arrival = a.number<T>(
"a");
1389 const T beta = a.number<T>(
"beta");
1390 const T service = a.number<T>(
"s");
1395 out[
"convention"] = geo_convention_name(r.convention);
1396 out[
"batchArrivalProb"] =
encode_scalar(r.batchArrivalProb);
1398 out[
"batchSecondFactorialMoment"] =
encode_scalar(r.batchSecondFactorialMoment);
1403 out[
"boundaryEmptyProb"] =
encode_scalar(r.boundaryEmptyProb);
1405 out[
"meanWaitingQueue"] =
encode_scalar(r.meanWaitingQueue);
1415Json qsys_map_results(
const R& r) {
1427Json qsys_map_results_moments(
const R& r) {
1428 Json out = qsys_map_results(r);
1429 out[
"queueLengthMoments"] =
encode_vector(r.queueLengthMoments);
1430 out[
"sojournTimeMoments"] =
encode_vector(r.sojournTimeMoments);
1436mam::Map<T> read_map(
Args& a,
const char* d0,
const char* d1) {
1438 m.D0 = a.matrix<T>(d0);
1439 m.D1 = a.matrix<T>(d1);
1445 static Json run(Args& a) {
1446 const mam::Map<T> arrival = read_map<T>(a,
"D0",
"D1");
1447 const T mu = a.number<T>(
"mu");
1448 const bool sized = a.has(
"dist_size");
1449 const std::size_t dist_size = a.count(
"dist_size", 0);
1458 static Json run(Args& a) {
1459 const mam::Map<T> arrival = read_map<T>(a,
"D0",
"D1");
1460 const T mu = a.number<T>(
"mu");
1461 const unsigned c = a.uinteger(
"c");
1462 const bool sized = a.has(
"dist_size");
1463 const std::size_t dist_size = a.count(
"dist_size", 0);
1465 return qsys_map_results(sized ?
qsys::qsys_mapmc(arrival, mu, c, dist_size)
1470struct OpQsysMapmap1 {
1472 static Json run(Args& a) {
1473 const mam::Map<T> arrival = read_map<T>(a,
"C0",
"C1");
1474 const mam::Map<T> service = read_map<T>(a,
"D0",
"D1");
1475 const std::size_t dist_size = a.count(
"dist_size", 100);
1476 const std::size_t numQLMoms = a.count(
"numQLMoms", 3);
1477 const std::size_t numSTMoms = a.count(
"numSTMoms", 3);
1479 return qsys_map_results_moments(
1484struct OpQsysMapph1 {
1486 static Json run(Args& a) {
1487 const mam::Map<T> arrival = read_map<T>(a,
"D0",
"D1");
1488 const std::vector<T> sigma = a.vector<T>(
"sigma");
1489 const Matrix<T> S = a.matrix<T>(
"S");
1490 const bool sized = a.has(
"dist_size");
1491 const std::size_t dist_size = a.count(
"dist_size", 0);
1503struct OpQsysMapphc {
1505 static Json run(Args& a) {
1506 const mam::Map<T> arrival = read_map<T>(a,
"D0",
"D1");
1507 const std::vector<T> alpha = a.vector<T>(
"alpha");
1508 const Matrix<T> S = a.matrix<T>(
"S");
1509 const unsigned c = a.uinteger(
"c");
1511 a.has(
"dist_size") || a.has(
"num_w_moms") || a.has(
"w_points");
1513 a.has(
"dist_size") && a.has(
"num_w_moms") && a.has(
"w_points");
1516 "qsys_mapphc: 'dist_size', 'num_w_moms' and 'w_points' select one tuned "
1517 "overload together; give all three or none");
1518 const std::size_t dist_size = a.count(
"dist_size", 0);
1519 const std::size_t num_w_moms = a.count(
"num_w_moms", 0);
1520 const std::vector<T> w_points = a.vector_or_empty<T>(
"w_points");
1522 const qsys::MapPhcResult<T> r =
1525 Json out = qsys_map_results(r);
1526 out[
"waitingTimeMoments"] =
encode_vector(r.waitingTimeMoments);
1528 out[
"waitingTimePoints"] =
encode_vector(r.waitingTimePoints);
1540 static Json run(Args& a) {
1541 const std::vector<T> alpha = a.vector<T>(
"alpha");
1542 const Matrix<T> Tm = a.matrix<T>(
"T");
1543 const std::vector<T> beta = a.vector<T>(
"beta");
1544 const Matrix<T> S = a.matrix<T>(
"S");
1545 const bool sized = a.has(
"dist_size");
1546 const std::size_t dist_size = a.count(
"dist_size", 0);
1548 return qsys_map_results(sized ?
qsys::qsys_phph1(alpha, Tm, beta, S, dist_size)
1559inline bool qsys_map_d_tuned(
Args& a,
const char* who) {
1560 const bool any = a.has(
"dist_size") || a.has(
"max_arrivals") || a.has(
"max_levels") ||
1562 const bool all = a.has(
"dist_size") && a.has(
"max_arrivals") && a.has(
"max_levels") &&
1566 ": 'dist_size', 'max_arrivals', 'max_levels' and 'tol' tune one "
1567 "truncation together; give all four or none");
1573 static Json run(Args& a) {
1574 const mam::Map<T> arrival = read_map<T>(a,
"D0",
"D1");
1575 const T s = a.number<T>(
"s");
1576 const bool tuned = qsys_map_d_tuned(a,
"qsys_mapd1");
1577 const std::size_t dist_size = a.count(
"dist_size", 0);
1578 const unsigned max_arrivals = a.uinteger(
"max_arrivals", 0u);
1579 const std::size_t max_levels = a.count(
"max_levels", 0);
1580 const T tol = a.scalar<T>(
"tol", num_traits<T>::from_int(0));
1582 return qsys_map_results(
1583 tuned ?
qsys::qsys_mapd1(arrival, s, dist_size, max_arrivals, max_levels, tol)
1590 static Json run(Args& a) {
1591 const mam::Map<T> arrival = read_map<T>(a,
"D0",
"D1");
1592 const T s = a.number<T>(
"s");
1593 const unsigned c = a.uinteger(
"c");
1594 const bool tuned = qsys_map_d_tuned(a,
"qsys_mapdc");
1595 const std::size_t dist_size = a.count(
"dist_size", 0);
1596 const unsigned max_arrivals = a.uinteger(
"max_arrivals", 0u);
1597 const std::size_t max_levels = a.count(
"max_levels", 0);
1598 const T tol = a.scalar<T>(
"tol", num_traits<T>::from_int(0));
1600 return qsys_map_results(
1601 tuned ?
qsys::qsys_mapdc(arrival, s, c, dist_size, max_arrivals, max_levels, tol)
1608 static Json run(Args& a) {
1609 const mam::Map<T> arrival = read_map<T>(a,
"D0",
"D1");
1610 const std::vector<T> moments = a.vector<T>(
"serviceMoments");
1611 const std::size_t dist_size = a.count(
"dist_size", 100);
1612 const std::size_t numQLMoms = a.count(
"numQLMoms", 3);
1613 const std::size_t numSTMoms = a.count(
"numSTMoms", 3);
1615 const qsys::MapG1Result<T> r =
1617 Json out = qsys_map_results_moments(r);
1618 out[
"analyzer"] = r.analyzer;
1623 const char* kind =
"Acyclic";
1624 switch (r.fitKind) {
1630 out[
"fitKind"] = kind;
1640 static Json run(Args& a) {
1641 const std::vector<T> alpha = a.vector<T>(
"alpha");
1642 const Matrix<T> Tm = a.matrix<T>(
"T");
1643 const T mu = a.number<T>(
"mu");
1644 const bool tuned = a.has(
"tol");
1645 const T tol = a.scalar<T>(
"tol", num_traits<T>::from_int(0));
1647 const qsys::PhM1Result<T> r = tuned ?
qsys::qsys_phm1(alpha, Tm, mu, tol)
1651 out[
"meanWaitingQueue"] =
encode_scalar(r.meanWaitingQueue);
1662 static Json run(Args& a) {
1663 const std::vector<T> alpha = a.vector<T>(
"alpha");
1664 const Matrix<T> Tm = a.matrix<T>(
"T");
1665 const T mu = a.number<T>(
"mu");
1666 const unsigned c = a.uinteger(
"c");
1667 const bool any = a.has(
"maxIter") || a.has(
"tol");
1668 const bool all = a.has(
"maxIter") && a.has(
"tol");
1671 "qsys_phmc: 'maxIter' and 'tol' bound one fixed-point iteration together; give "
1673 const unsigned maxIter = a.uinteger(
"maxIter", 0u);
1674 const T tol = a.scalar<T>(
"tol", num_traits<T>::from_int(0));
1676 const qsys::PhMcResult<T> r = all ?
qsys::qsys_phmc(alpha, Tm, mu, c, maxIter, tol)
1680 out[
"meanWaitingQueue"] =
encode_scalar(r.meanWaitingQueue);
1688struct OpQsysBmapphnnRetrial {
1690 static Json run(Args& a) {
1691 const std::vector<Matrix<T> > D = a.matrices<T>(
"D");
1692 const std::vector<T> beta = a.vector<T>(
"beta");
1693 const Matrix<T> S = a.matrix<T>(
"S");
1694 const int N = a.required_integer(
"N");
1695 const T alpha = a.number<T>(
"alpha");
1696 const T gamma = a.number<T>(
"gamma");
1697 const T p = a.number<T>(
"p");
1698 const std::vector<int> Ri = a.ints(
"R");
1699 qsys::BmapPhNnRetrialOptions opt;
1700 opt.maxLevel = a.count(
"maxLevel", 0);
1701 if (a.has(
"retrialPolicy")) {
1702 const std::string pol = a.text(
"retrialPolicy",
"LINEAR");
1705 else throw InputError(
"qsys_bmapphnn_retrial: retrialPolicy must be LINEAR or CONSTANT");
1707 if (a.has(
"tolerance")) opt.tolerance = a.number<
double>(
"tolerance");
1708 if (a.has(
"tailTolerance")) opt.tailTolerance = a.number<
double>(
"tailTolerance");
1709 if (a.has(
"maxDim")) opt.maxDim = a.number<
double>(
"maxDim");
1710 if (a.has(
"maxBlockSize")) opt.maxBlockSize = a.number<
double>(
"maxBlockSize");
1712 std::vector<long> R(Ri.size());
1713 for (std::size_t i = 0; i < Ri.size(); ++i) R[i] =
static_cast<long>(Ri[i]);
1714 const qsys::BmapPhNnRetrialResult<T> r =
1729 out[
"converged"] = r.converged;
1732 out[
"clipped"] = r.clipped;
1747#define LINE_MOMENT_VEC(OpName, fn, in_key, out_key) \
1749 template <class T> \
1750 static Json run(Args& a) { \
1751 const std::vector<T> v = a.vector<T>(in_key); \
1754 out[out_key] = encode_vector(moment::fn(v)); \
1759LINE_MOMENT_VEC(OpMomentBinomialFromFactorial, moment_binomial_from_factorial,
"f",
"b");
1760LINE_MOMENT_VEC(OpMomentBinomialFromNegbinomial, moment_binomial_from_negbinomial,
"bm",
"b");
1763LINE_MOMENT_VEC(OpMomentCentralFromRaw, moment_central_from_raw,
"m",
"mc");
1764LINE_MOMENT_VEC(OpMomentFactorialFromBinomial, moment_factorial_from_binomial,
"b",
"f");
1765LINE_MOMENT_VEC(OpMomentFactorialFromRaw, moment_factorial_from_raw,
"m",
"f");
1766LINE_MOMENT_VEC(OpMomentFactorialFromUpfactorial, moment_factorial_from_upfactorial,
"fp",
"f");
1767LINE_MOMENT_VEC(OpMomentNegbinomialFromBinomial, moment_negbinomial_from_binomial,
"b",
"bm");
1768LINE_MOMENT_VEC(OpMomentNegbinomialFromUpfactorial, moment_negbinomial_from_upfactorial,
"fp",
1770LINE_MOMENT_VEC(OpMomentRawFromFactorial, moment_raw_from_factorial,
"f",
"m");
1771LINE_MOMENT_VEC(OpMomentRawFromUpfactorial, moment_raw_from_upfactorial,
"fp",
"m");
1772LINE_MOMENT_VEC(OpMomentUpfactorialFromFactorial, moment_upfactorial_from_factorial,
"f",
"fp");
1773LINE_MOMENT_VEC(OpMomentUpfactorialFromNegbinomial, moment_upfactorial_from_negbinomial,
"bm",
1775LINE_MOMENT_VEC(OpMomentUpfactorialFromRaw, moment_upfactorial_from_raw,
"m",
"fp");
1776#undef LINE_MOMENT_VEC
1783struct OpMomentRawFromCentral {
1785 static Json run(Args& a) {
1786 const std::vector<T> mc = a.vector<T>(
"mc");
1787 const T m1 = a.number<T>(
"m1");
1796#define LINE_MOMENT_TRI(OpName, fn, out_key) \
1798 template <class T> \
1799 static Json run(Args& a) { \
1800 const int n = a.required_integer("n"); \
1803 out[out_key] = encode_matrix(moment::fn<T>(n)); \
1812#undef LINE_MOMENT_TRI
1828inline std::vector<std::vector<std::size_t> > read_partition(Args& a,
const char* key) {
1829 const Json& j = a.get(key);
1830 const std::string where = std::string(
"partition '") + key +
"'";
1831 if (!j.is_array())
throw InputError(where +
" must be an array of index arrays");
1832 std::vector<std::vector<std::size_t> > out;
1833 for (std::size_t b = 0; b < j.size(); ++b) {
1834 if (!j[b].is_array())
1835 throw InputError(where +
": block " + std::to_string(b) +
" must be an array");
1836 std::vector<std::size_t> blk;
1837 for (std::size_t i = 0; i < j[b].size(); ++i) {
1839 const long long v = std::strtoll(text.c_str(),
nullptr, 10);
1841 throw InputError(where +
": a state index cannot be negative, got " + text);
1842 blk.push_back(
static_cast<std::size_t
>(v));
1850inline Json encode_indices(
const std::vector<std::size_t>& v) {
1851 Json a = Json::array();
1852 for (std::size_t i = 0; i < v.size(); ++i) a.push_back(
static_cast<std::uint64_t
>(v[i]));
1863Json reducible_results(
const mc::ReducibleResult<T>& r) {
1868 out[
"scc"] = encode_indices(r.scc);
1869 Json isrec = Json::array();
1870 for (std::size_t i = 0; i < r.isrec.size(); ++i) isrec.push_back(
bool(r.isrec[i]));
1871 out[
"isrec"] = isrec;
1879Json blkdecomp_results(
const mc::BlkDecompResult<T>& r) {
1884 out[
"scc"] = encode_indices(r.scc);
1885 Json isrec = Json::array();
1886 for (std::size_t i = 0; i < r.isrec.size(); ++i) isrec.push_back(
bool(r.isrec[i]));
1887 out[
"isrec"] = isrec;
1891struct OpCtmcSolveReducible {
1893 static Json run(Args& a) {
1894 const Matrix<T> Q = a.matrix<T>(
"Q");
1895 const std::vector<T> pi0 = a.vector<T>(
"pi0");
1896 const double zeroColTol = a.scalar<
double>(
"zeroColTol", 1e-12);
1899 return reducible_results(r);
1903struct OpCtmcSolveReducibleBlkdecomp {
1905 static Json run(Args& a) {
1906 const Matrix<T> Q = a.matrix<T>(
"Q");
1907 const std::vector<T> pin = a.vector<T>(
"pin");
1908 const double reachTol = a.scalar<
double>(
"reachTol", 1e-15);
1909 const double zeroColTol = a.scalar<
double>(
"zeroColTol", 1e-12);
1911 const mc::BlkDecompResult<T> r =
1913 return blkdecomp_results(r);
1917struct OpDtmcSolveReducible {
1919 static Json run(Args& a) {
1920 const Matrix<T>
P = a.matrix<T>(
"P");
1921 const std::vector<T> pin = a.vector<T>(
"pin");
1922 const double zeroColTol = a.scalar<
double>(
"zeroColTol", 1e-12);
1925 return reducible_results(r);
1929struct OpDtmcMakestochastic {
1931 static Json run(Args& a) {
1932 const Matrix<T>
P = a.matrix<T>(
"Pin");
1942 static Json run(Args& a) {
1943 const Matrix<T> Q = a.matrix<T>(
"Q");
1944 const Matrix<T> dQ = a.matrix<T>(
"dQ");
1945 const std::vector<T> pi = a.vector<T>(
"pi");
1953struct OpStronglyConnComp {
1955 static Json run(Args& a) {
1956 const Matrix<T> A = a.matrix<T>(
"A");
1960 out[
"scc"] = encode_indices(r.scc);
1961 Json rec = Json::array();
1962 for (std::size_t i = 0; i < r.recurrent.size(); ++i) rec.push_back(
bool(r.recurrent[i]));
1963 out[
"recurrent"] = rec;
1964 Json mem = Json::array();
1965 for (std::size_t i = 0; i < r.members.size(); ++i)
1966 mem.push_back(encode_indices(r.members[i]));
1967 out[
"members"] = mem;
1972struct OpCtmcRandomization {
1974 static Json run(Args& a) {
1975 const Matrix<T> Q = a.matrix<T>(
"Q");
1976 const bool given = a.has(
"q");
1977 const T q = a.scalar<T>(
"q", num_traits<T>::from_int(0));
1981 "ctmc_randomization: 'q' is the uniformization rate and has no default here; "
1982 "MATLAB requires it too");
1997struct OpCtmcCourtois {
1999 static Json run(Args& a) {
2000 const Matrix<T> Q = a.matrix<T>(
"Q");
2001 const std::vector<std::vector<std::size_t> > MS = read_partition(a,
"MS");
2002 const bool given = a.has(
"q");
2003 const T q = a.scalar<T>(
"q", num_traits<T>::from_int(0));
2005 const mc::CourtoisResult<T> r =
2009 out[
"v"] = encode_indices(r.v);
2025Json kms_results(
const R& r) {
2038 static Json run(Args& a) {
2039 const Matrix<T> Q = a.matrix<T>(
"Q");
2040 const std::vector<std::vector<std::size_t> > MS = read_partition(a,
"MS");
2041 const std::size_t numSteps = a.count(
"numSteps");
2047struct OpCtmcTakahashi {
2049 static Json run(Args& a) {
2050 const Matrix<T> Q = a.matrix<T>(
"Q");
2051 const std::vector<std::vector<std::size_t> > MS = read_partition(a,
"MS");
2052 const std::size_t numSteps = a.count(
"numSteps");
2053 const double massTol = a.scalar<
double>(
"massTol", 1e-14);
2061 static Json run(Args& a) {
2062 const Matrix<T> Q = a.matrix<T>(
"Q");
2063 const std::vector<std::vector<std::size_t> > MS = read_partition(a,
"MS");
2064 const std::vector<std::vector<std::size_t> > MSS = read_partition(a,
"MSS");
2065 const bool given = a.has(
"q");
2066 const T q = a.scalar<T>(
"q", num_traits<T>::from_int(0));
2068 const mc::MultiResult<T> r =
2087 static Json run(Args& a) {
2088 const Matrix<T> A = a.matrix<T>(
"A");
2089 const std::vector<T> b = a.vector<T>(
"b");
2090 const double tol = a.scalar<
double>(
"tol", 1e-12);
2091 const int restart = a.integer(
"restart", 0);
2092 const int maxit = a.integer(
"maxit", 0);
2093 const std::vector<T> x0 = a.vector_or_empty<T>(
"x0");
2095 const mc::GmresResult<T> r =
mc::ctmc_gmres(A, b, tol, restart, maxit, x0);
2098 out[
"flag"] = r.flag;
2100 out[
"iter"] =
static_cast<std::int64_t
>(r.iter);
2105struct OpCtmcGmresMulti {
2107 static Json run(Args& a) {
2108 const Matrix<T> A = a.matrix<T>(
"A");
2109 const Matrix<T> B = a.matrix<T>(
"B");
2110 const double tol = a.scalar<
double>(
"tol", 1e-12);
2111 const int restart = a.integer(
"restart", 0);
2112 const int maxit = a.integer(
"maxit", 0);
2117 out[
"flag"] = r.flag;
2129struct OpCtmcBicgstab {
2131 static Json run(Args& a) {
2132 const Matrix<T> A = a.matrix<T>(
"A");
2133 const std::vector<T> b = a.vector<T>(
"b");
2134 const double tol = a.scalar<
double>(
"tol", 1e-12);
2135 const int maxit = a.integer(
"maxit", 0);
2136 const std::vector<T> x0 = a.vector_or_empty<T>(
"x0");
2141 out[
"flag"] = r.flag;
2143 out[
"iter"] =
static_cast<std::int64_t
>(r.iter);
2148struct OpCtmcBicgstabMulti {
2150 static Json run(Args& a) {
2151 const Matrix<T> A = a.matrix<T>(
"A");
2152 const Matrix<T> B = a.matrix<T>(
"B");
2153 const double tol = a.scalar<
double>(
"tol", 1e-12);
2154 const int maxit = a.integer(
"maxit", 0);
2159 out[
"flag"] = r.flag;
2164struct OpCtmcFoxglynn {
2166 static Json run(Args& a) {
2167 const std::vector<T> pi0 = a.vector<T>(
"pi0");
2168 const Matrix<T> Q = a.matrix<T>(
"Q");
2169 const T t = a.number<T>(
"t");
2170 const double tol = a.scalar<
double>(
"tol", 1e-12);
2171 const int maxiter = a.integer(
"maxiter", -1);
2179 out[
"left"] =
static_cast<std::int64_t
>(r.left);
2180 out[
"right"] =
static_cast<std::int64_t
>(r.right);
2186struct OpCtmcSaddlepoint {
2188 static Json run(Args& a) {
2189 const Matrix<T> D0 = a.matrix<T>(
"D0");
2190 const Matrix<T> D1 = a.matrix<T>(
"D1");
2191 const std::vector<T> t = a.vector<T>(
"t");
2192 const std::vector<int> ki = a.ints(
"k");
2193 const std::string method = a.text(
"method",
"daniels2");
2194 const std::vector<T> pi0 = a.vector_or_empty<T>(
"pi0");
2197 if (method ==
"daniels" || method ==
"sp1")
2199 else if (method ==
"plain" || method ==
"bare")
2201 else if (!(method ==
"daniels2" || method ==
"sp2"))
2202 throw InputError(
"ctmc_saddlepoint: unknown method '" + method +
2203 "', expected daniels2, daniels or plain");
2204 std::vector<long> k(ki.size());
2205 for (std::size_t i = 0; i < ki.size(); ++i) k[i] =
static_cast<long>(ki[i]);
2215 out[
"outOfRegime"] = r.out_of_regime;
2222 static Json run(Args& a) {
2223 const std::vector<T> pi0 = a.vector<T>(
"pi0");
2224 const Matrix<T> Q = a.matrix<T>(
"Q");
2225 const T t = a.number<T>(
"t");
2226 const double epsilon = a.scalar<
double>(
"epsilon", 1e-6);
2227 const double delta = a.scalar<
double>(
"delta", 1e-12);
2228 const int maxsteps = a.integer(
"maxsteps", -1);
2230 const mc::FauResult<T> r =
mc::ctmc_fau(pi0, Q, t, epsilon, delta, maxsteps);
2236 out[
"steps"] =
static_cast<std::int64_t
>(r.steps);
2237 out[
"lambdaMin"] = r.lambdaMin;
2238 out[
"lambdaMax"] = r.lambdaMax;
2239 out[
"uniformRate"] = r.uniformRate;
2240 out[
"weightTail"] = num_traits<T>::to_double(r.weightTail);
2241 out[
"weightWindow"] = num_traits<T>::to_double(r.weightWindow);
2242 out[
"droppedMass"] = num_traits<T>::to_double(r.droppedMass);
2243 out[
"errorBound"] = num_traits<T>::to_double(r.errorBound);
2244 out[
"supportMax"] =
static_cast<std::int64_t
>(r.supportMax);
2245 out[
"supportFinal"] =
static_cast<std::int64_t
>(r.supportFinal);
2246 out[
"truncated"] = r.truncated;
2247 out[
"absorbed"] = r.absorbed;
2252struct OpCtmcTransient {
2254 static Json run(Args& a) {
2255 const Matrix<T> Q = a.matrix<T>(
"Q");
2256 const std::vector<T> pi0 = a.vector<T>(
"pi0");
2257 const T t0 = a.number<T>(
"t0");
2258 const T t1 = a.number<T>(
"t1");
2259 const double rtol = a.scalar<
double>(
"rtol", 1e-3);
2260 const double atol = a.scalar<
double>(
"atol", 1e-6);
2270struct OpCtmcTransientSens {
2272 static Json run(Args& a) {
2273 const Matrix<T> Q = a.matrix<T>(
"Q");
2274 const Matrix<T> dQ = a.matrix<T>(
"dQ");
2275 const std::vector<T> pi0 = a.vector<T>(
"pi0");
2276 const T t0 = a.number<T>(
"t0");
2277 const T t1 = a.number<T>(
"t1");
2278 const double rtol = a.scalar<
double>(
"rtol", 1e-3);
2279 const double atol = a.scalar<
double>(
"atol", 1e-6);
2281 const mc::TransientSensResult<T> r =
2309 const std::string kind = a.text(
"lst",
"");
2312 "'lst' names the service law whose Laplace-Stieltjes transform this age formula "
2313 "needs: exp, erlang, det or ph. A transform itself cannot cross a JSON boundary");
2315 if (kind ==
"exp") {
2316 const T mu = a.number<T>(
"lst_mu");
2317 E1 = T(num_traits<T>::from_int(1) / mu);
2318 E2 = T(num_traits<T>::from_int(2) / (mu * mu));
2321 if (kind ==
"erlang") {
2322 const unsigned k = a.uinteger(
"lst_k");
2323 const T mu = a.number<T>(
"lst_mu");
2324 const T kk = num_traits<T>::from_int(
static_cast<int>(k));
2326 E2 = T(kk * (kk + num_traits<T>::from_int(1)) / (mu * mu));
2329 if (kind ==
"det") {
2330 const T d = a.number<T>(
"lst_d");
2336 const std::vector<T> alpha = a.vector<T>(
"lst_alpha");
2337 const Matrix<T> Tmat = a.matrix<T>(
"lst_T");
2342 E1 = a.number<T>(
"E_1");
2343 E2 = a.number<T>(
"E_2");
2346 throw InputError(
"'lst' must be one of exp, erlang, det, ph; got '" + kind +
"'");
2351Json aoi_results(
const aoi::AoiResult<T>& r) {
2361Json aoi_lst_results(
const aoi::AoiLstResult<T>& r) {
2365 out[
"has_lst"] = r.has_lst;
2369#define LINE_AOI_TWO(OpName, fn, k1, k2) \
2371 template <class T> \
2372 static Json run(Args& a) { \
2373 const T x = a.number<T>(k1); \
2374 const T y = a.number<T>(k2); \
2376 return aoi_results(aoi::fn(x, y)); \
2381LINE_AOI_TWO(OpAoiFcfsMd1, aoi_fcfs_md1,
"lambda",
"d");
2382LINE_AOI_TWO(OpAoiFcfsMm1, aoi_fcfs_mm1,
"lambda",
"mu");
2383LINE_AOI_TWO(OpAoiLcfsprDm1, aoi_lcfspr_dm1,
"tau",
"mu");
2384LINE_AOI_TWO(OpAoiLcfsprMd1, aoi_lcfspr_md1,
"lambda",
"d");
2385LINE_AOI_TWO(OpAoiLcfsprMm1, aoi_lcfspr_mm1,
"lambda",
"mu");
2389#define LINE_AOI_MGI1_TWO(OpName, fn) \
2391 template <class T> \
2392 static Json run(Args& a) { \
2393 const T lambda = a.number<T>("lambda"); \
2394 T E1 = num_traits<T>::from_int(0), E2 = num_traits<T>::from_int(0); \
2395 bool has_E2 = false; \
2396 const aoi::Lst<T> H = read_aoi_lst<T>(a, E1, E2, has_E2); \
2398 return aoi_lst_results(aoi::fn(lambda, H, E1, E2)); \
2404#undef LINE_AOI_MGI1_TWO
2406struct OpAoiFcfsMgi1 {
2408 static Json run(Args& a) {
2409 const T lambda = a.number<T>(
"lambda");
2410 T E1 = num_traits<T>::from_int(0), E2 = num_traits<T>::from_int(0);
2411 bool has_E2 =
false;
2412 const aoi::Lst<T> H = read_aoi_lst<T>(a, E1, E2, has_E2);
2418struct OpAoiLcfsprMgi1 {
2420 static Json run(Args& a) {
2421 const T lambda = a.number<T>(
"lambda");
2422 T E1 = num_traits<T>::from_int(0), E2 = num_traits<T>::from_int(0);
2423 bool has_E2 =
false;
2424 const aoi::Lst<T> H = read_aoi_lst<T>(a, E1, E2, has_E2);
2430struct OpAoiFcfsGim1 {
2432 static Json run(Args& a) {
2433 const T mu = a.number<T>(
"mu");
2434 T E1 = num_traits<T>::from_int(0), E2 = num_traits<T>::from_int(0);
2435 bool has_E2 =
false;
2436 const aoi::Lst<T> Y = read_aoi_lst<T>(a, E1, E2, has_E2);
2442#define LINE_AOI_GIM1_TWO(OpName, fn) \
2444 template <class T> \
2445 static Json run(Args& a) { \
2446 const T mu = a.number<T>("mu"); \
2447 T E1 = num_traits<T>::from_int(0), E2 = num_traits<T>::from_int(0); \
2448 bool has_E2 = false; \
2449 const aoi::Lst<T> Y = read_aoi_lst<T>(a, E1, E2, has_E2); \
2451 return aoi_lst_results(aoi::fn(Y, mu, E1, E2)); \
2457#undef LINE_AOI_GIM1_TWO
2459struct OpAoiLcfsprGim1 {
2461 static Json run(Args& a) {
2462 const T mu = a.number<T>(
"mu");
2463 T E1 = num_traits<T>::from_int(0), E2 = num_traits<T>::from_int(0);
2464 bool has_E2 =
false;
2465 const aoi::Lst<T> Y = read_aoi_lst<T>(a, E1, E2, has_E2);
2481#define LINE_FJ_K_LAMBDA_MU(OpName, fn, out_key) \
2483 template <class T> \
2484 static Json run(Args& a) { \
2485 const unsigned K = a.uinteger("K"); \
2486 const T lambda = a.number<T>("lambda"); \
2487 const T mu = a.number<T>("mu"); \
2490 out[out_key] = encode_scalar(fj::fn(K, lambda, mu)); \
2499#undef LINE_FJ_K_LAMBDA_MU
2501#define LINE_FJ_K_MU(OpName, fn, out_key) \
2503 template <class T> \
2504 static Json run(Args& a) { \
2505 const unsigned K = a.uinteger("K"); \
2506 const T mu = a.number<T>("mu"); \
2509 out[out_key] = encode_scalar(fj::fn(K, mu)); \
2519struct OpFjHarmonic {
2521 static Json run(Args& a) {
2522 const unsigned K = a.uinteger(
"K");
2530struct OpFjQuantile {
2532 static Json run(Args& a) {
2533 const unsigned K = a.uinteger(
"K");
2534 const T q = a.number<T>(
"q");
2542struct OpFjResptTwoway {
2544 static Json run(Args& a) {
2545 const T lambda = a.number<T>(
"lambda");
2546 const T mu = a.number<T>(
"mu");
2554struct OpFjSynchDelay {
2556 static Json run(Args& a) {
2557 const T lambda = a.number<T>(
"lambda");
2558 const T mu = a.number<T>(
"mu");
2568 static Json run(Args& a) {
2569 const T lambda1 = a.number<T>(
"lambda1");
2570 const T lambda2 = a.number<T>(
"lambda2");
2578struct OpFjXmaxErlang {
2580 static Json run(Args& a) {
2581 const unsigned K = a.uinteger(
"K");
2582 const unsigned k = a.uinteger(
"k");
2583 const T mu = a.number<T>(
"mu");
2591struct OpFjRmaxErlang {
2593 static Json run(Args& a) {
2594 const unsigned K = a.uinteger(
"K");
2595 const unsigned k = a.uinteger(
"k");
2596 const T lambda = a.number<T>(
"lambda");
2597 const T mu = a.number<T>(
"mu");
2605struct OpFjXmaxHyperexp {
2607 static Json run(Args& a) {
2608 const unsigned K = a.uinteger(
"K");
2609 const T p1 = a.number<T>(
"p1");
2610 const T mu1 = a.number<T>(
"mu1");
2611 const T mu2 = a.number<T>(
"mu2");
2627 static Json run(Args& a) {
2628 const unsigned K = a.uinteger(
"K");
2629 const T R = a.number<T>(
"R");
2630 const T sigma_R = a.number<T>(
"sigma_R");
2631 const bool calibrated = a.boolean(
"calibrated",
false);
2641 static Json run(Args& a) {
2642 const unsigned K = a.uinteger(
"K");
2643 const T lambda = a.number<T>(
"lambda");
2644 const T mu = a.number<T>(
"mu");
2646 const fj::FJBoundsResult<T> r =
fj::fj_bounds(K, lambda, mu);
2656 static Json run(Args& a) {
2657 const unsigned K = a.uinteger(
"K");
2658 const T mu = a.number<T>(
"mu");
2670 static Json run(Args& a) {
2671 const unsigned K = a.uinteger(
"K");
2684struct OpFjOrdstatExp {
2686 static Json run(Args& a) {
2687 const std::vector<T> ri = a.vector<T>(
"ri");
2688 const std::size_t k = a.count(
"k");
2696struct OpFjQuorumMoments {
2698 static Json run(Args& a) {
2699 const std::vector<T> branchMeans = a.vector<T>(
"branchMeans");
2700 const std::vector<T> branchVars = a.vector<T>(
"branchVars");
2701 const std::size_t k = a.count(
"k");
2703 const fj::FJQuorumMomentsResult<T> r =
2712struct OpFjXmaxApprox {
2714 static Json run(Args& a) {
2715 const unsigned K = a.uinteger(
"K");
2716 const T mu_X = a.number<T>(
"mu_X");
2717 const T sigma_X = a.number<T>(
"sigma_X");
2718 const std::string t = a.text(
"type",
"Exp");
2724 else throw InputError(
"'type' must be Exp, Uniform, Evd or Bound; got '" + t +
"'");
2734struct OpFjXmaxNormal {
2736 static Json run(Args& a) {
2737 const unsigned K = a.uinteger(
"K");
2738 const T mu = a.number<T>(
"mu");
2739 const T sigma = a.number<T>(
"sigma");
2740 const std::string m = a.text(
"method",
"Johnson");
2745 else throw InputError(
"'method' must be Johnson, Arnold or Corrected; got '" + m +
"'");
2755struct OpFjXmaxPareto {
2757 static Json run(Args& a) {
2758 const unsigned K = a.uinteger(
"K");
2759 const T beta = a.number<T>(
"beta");
2760 const T k = a.number<T>(
"k");
2776 return [](
const ArithSpec& s,
Args& a) {
return run_at<Op>(s, a); };
2779const std::map<std::string, Invoker>& dispatch_table() {
2780 static const std::map<std::string, Invoker>
table = {
2781 {
"pfqn_ca", make<OpPfqnCa>()},
2782 {
"pfqn_conv", make<OpPfqnConv>()},
2783 {
"pfqn_recal", make<OpPfqnRecal>()},
2784 {
"pfqn_gld", make<OpPfqnGld>()},
2785 {
"pfqn_mva", make<OpPfqnMva>()},
2786 {
"pfqn_comom", make<OpPfqnComom>()},
2787 {
"pfqn_comomrm", make<OpPfqnComomrm>()},
2788 {
"pfqn_comomrm_orig", make<OpPfqnComomrmOrig>()},
2789 {
"pfqn_comomrm_ms", make<OpPfqnComomrmMs>()},
2790 {
"pfqn_procomom", make<OpPfqnProcomom>()},
2791 {
"ctmc_solve", make<OpCtmcSolve>()},
2792 {
"dtmc_solve", make<OpDtmcSolve>()},
2793 {
"ctmc_makeinfgen", make<OpCtmcMakeinfgen>()},
2794 {
"sim_vonneumann", make<OpSimVonneumann>()},
2795 {
"sim_shapirowilk", make<OpSimShapirowilk>()},
2796 {
"sim_sts_quantile_areas", make<OpSimStsQuantileAreas>()},
2797 {
"sim_fquest", make<OpSimFquest>()},
2798 {
"sim_firquest", make<OpSimFirquest>()},
2799 {
"qsys_bmapphnn_retrial", make<OpQsysBmapphnnRetrial>()},
2800 {
"aoi_fcfs_dm1", make<NeedsTranscendental<OpAoiFcfsDm1>>()},
2801 {
"aoi_fcfs_gim1", make<NeedsTranscendental<OpAoiFcfsGim1>>()},
2802 {
"aoi_fcfs_md1", make<NeedsTranscendental<OpAoiFcfsMd1>>()},
2803 {
"aoi_fcfs_mgi1", make<NeedsTranscendental<OpAoiFcfsMgi1>>()},
2804 {
"aoi_fcfs_mm1", make<OpAoiFcfsMm1>()},
2805 {
"aoi_lcfsd_gim1", make<NeedsTranscendental<OpAoiLcfsdGim1>>()},
2806 {
"aoi_lcfsd_mgi1", make<NeedsTranscendental<OpAoiLcfsdMgi1>>()},
2807 {
"aoi_lcfspr_dm1", make<NeedsTranscendental<OpAoiLcfsprDm1>>()},
2808 {
"aoi_lcfspr_gim1", make<NeedsTranscendental<OpAoiLcfsprGim1>>()},
2809 {
"aoi_lcfspr_md1", make<NeedsTranscendental<OpAoiLcfsprMd1>>()},
2810 {
"aoi_lcfspr_mgi1", make<NeedsTranscendental<OpAoiLcfsprMgi1>>()},
2811 {
"aoi_lcfspr_mm1", make<OpAoiLcfsprMm1>()},
2812 {
"aoi_lcfss_gim1", make<NeedsTranscendental<OpAoiLcfssGim1>>()},
2813 {
"aoi_lcfss_mgi1", make<NeedsTranscendental<OpAoiLcfssMgi1>>()},
2814 {
"fj_bounds", make<OpFjBounds>()},
2815 {
"fj_char_max", make<NeedsTranscendental<OpFjCharMax>>()},
2816 {
"fj_gk_bound", make<NeedsTranscendental<OpFjGkBound>>()},
2817 {
"fj_harmonic", make<OpFjHarmonic>()},
2818 {
"fj_quantile", make<NeedsTranscendental<OpFjQuantile>>()},
2819 {
"fj_ordstat_exp", make<OpFjOrdstatExp>()},
2820 {
"fj_quorum_moments", make<NeedsTranscendental<OpFjQuorumMoments>>()},
2821 {
"fj_respt_2way", make<OpFjResptTwoway>()},
2822 {
"fj_respt_nt", make<OpFjResptNt>()},
2823 {
"fj_respt_varki", make<OpFjResptVarki>()},
2824 {
"fj_respt_vm", make<OpFjResptVm>()},
2825 {
"fj_rmax", make<OpFjRmax>()},
2826 {
"fj_rmax_erlang", make<NeedsTranscendental<OpFjRmaxErlang>>()},
2827 {
"fj_rmax_evd", make<NeedsTranscendental<OpFjRmaxEvd>>()},
2828 {
"fj_sm_tput", make<OpFjSmTput>()},
2829 {
"fj_synch_delay", make<OpFjSynchDelay>()},
2830 {
"fj_xmax_2", make<OpFjXmax2>()},
2831 {
"fj_xmax_approx", make<NeedsTranscendental<OpFjXmaxApprox>>()},
2832 {
"fj_xmax_emma", make<NeedsTranscendental<OpFjXmaxEmma>>()},
2833 {
"fj_xmax_erlang", make<NeedsTranscendental<OpFjXmaxErlang>>()},
2834 {
"fj_xmax_exp", make<OpFjXmaxExp>()},
2835 {
"fj_xmax_hyperexp", make<OpFjXmaxHyperexp>()},
2836 {
"fj_xmax_normal", make<NeedsTranscendental<OpFjXmaxNormal>>()},
2837 {
"fj_xmax_pareto", make<NeedsTranscendental<OpFjXmaxPareto>>()},
2838 {
"ctmc_courtois", make<NeedsTranscendental<OpCtmcCourtois>>()},
2839 {
"ctmc_fau", make<NeedsTranscendental<OpCtmcFau>>()},
2840 {
"ctmc_foxglynn", make<NeedsTranscendental<OpCtmcFoxglynn>>()},
2841 {
"ctmc_saddlepoint", make<NeedsTranscendental<OpCtmcSaddlepoint>>()},
2842 {
"ctmc_bicgstab", make<NeedsTranscendental<OpCtmcBicgstab>>()},
2843 {
"ctmc_bicgstab_multi", make<NeedsTranscendental<OpCtmcBicgstabMulti>>()},
2844 {
"ctmc_gmres", make<NeedsTranscendental<OpCtmcGmres>>()},
2845 {
"ctmc_gmres_multi", make<NeedsTranscendental<OpCtmcGmresMulti>>()},
2846 {
"ctmc_kms", make<NeedsTranscendental<OpCtmcKms>>()},
2847 {
"ctmc_multi", make<NeedsTranscendental<OpCtmcMulti>>()},
2848 {
"ctmc_randomization", make<OpCtmcRandomization>()},
2849 {
"ctmc_sens", make<OpCtmcSens>()},
2850 {
"ctmc_solve_reducible", make<OpCtmcSolveReducible>()},
2851 {
"ctmc_solve_reducible_blkdecomp", make<OpCtmcSolveReducibleBlkdecomp>()},
2852 {
"ctmc_takahashi", make<NeedsTranscendental<OpCtmcTakahashi>>()},
2853 {
"ctmc_transient", make<NeedsTranscendental<OpCtmcTransient>>()},
2854 {
"ctmc_transient_sens", make<NeedsTranscendental<OpCtmcTransientSens>>()},
2855 {
"dtmc_makestochastic", make<OpDtmcMakestochastic>()},
2856 {
"dtmc_solve_reducible", make<OpDtmcSolveReducible>()},
2857 {
"moment_binomial_from_factorial", make<OpMomentBinomialFromFactorial>()},
2858 {
"moment_binomial_from_negbinomial", make<OpMomentBinomialFromNegbinomial>()},
2859 {
"moment_binotrans", make<OpMomentBinotrans>()},
2860 {
"moment_binotransinv", make<OpMomentBinotransinv>()},
2861 {
"moment_central_from_raw", make<OpMomentCentralFromRaw>()},
2862 {
"moment_factorial_from_binomial", make<OpMomentFactorialFromBinomial>()},
2863 {
"moment_factorial_from_raw", make<OpMomentFactorialFromRaw>()},
2864 {
"moment_factorial_from_upfactorial", make<OpMomentFactorialFromUpfactorial>()},
2865 {
"moment_lah", make<OpMomentLah>()},
2866 {
"moment_negbinomial_from_binomial", make<OpMomentNegbinomialFromBinomial>()},
2867 {
"moment_negbinomial_from_upfactorial", make<OpMomentNegbinomialFromUpfactorial>()},
2868 {
"moment_raw_from_central", make<OpMomentRawFromCentral>()},
2869 {
"moment_raw_from_factorial", make<OpMomentRawFromFactorial>()},
2870 {
"moment_raw_from_upfactorial", make<OpMomentRawFromUpfactorial>()},
2871 {
"moment_stirling1", make<OpMomentStirling1>()},
2872 {
"moment_stirling2", make<OpMomentStirling2>()},
2873 {
"moment_stirlingcycle", make<OpMomentStirlingcycle>()},
2874 {
"moment_upfactorial_from_factorial", make<OpMomentUpfactorialFromFactorial>()},
2875 {
"moment_upfactorial_from_negbinomial", make<OpMomentUpfactorialFromNegbinomial>()},
2876 {
"moment_upfactorial_from_raw", make<OpMomentUpfactorialFromRaw>()},
2877 {
"stronglyconncomp", make<OpStronglyConnComp>()},
2878 {
"qsys_dmc", make<NeedsTranscendental<OpQsysDmc>>()},
2879 {
"dqsys_geogeo1", make<OpQsysGeoGeo1>()},
2880 {
"dqsys_geoxgeo1", make<OpQsysGeoxGeo1>()},
2881 {
"qsys_gg1", make<NeedsTranscendental<OpQsysGg1>>()},
2882 {
"qsys_gig1_approx_allencunneen", make<OpQsysGig1AllenCunneen>()},
2883 {
"qsys_gig1_approx_gelenbe", make<NeedsTranscendental<OpQsysGig1Gelenbe>>()},
2884 {
"qsys_gig1_approx_heyman", make<OpQsysGig1Heyman>()},
2885 {
"qsys_gig1_approx_kimura", make<OpQsysGig1Kimura>()},
2886 {
"qsys_gig1_approx_klb", make<NeedsTranscendental<OpQsysGig1Klb>>()},
2887 {
"qsys_gig1_approx_kobayashi", make<NeedsTranscendental<OpQsysGig1Kobayashi>>()},
2888 {
"qsys_gig1_approx_marchal", make<OpQsysGig1Marchal>()},
2889 {
"qsys_gig1_approx_myskja", make<NeedsTranscendental<OpQsysGig1Myskja>>()},
2890 {
"qsys_gig1_approx_myskja2", make<NeedsTranscendental<OpQsysGig1Myskja2>>()},
2891 {
"qsys_gig1_lbnd", make<OpQsysGig1Lbnd>()},
2892 {
"qsys_gig1_ubnd_kingman", make<OpQsysGig1UbndKingman>()},
2893 {
"qsys_gigk_approx", make<NeedsTranscendental<OpQsysGigkApprox>>()},
2894 {
"qsys_gigk_approx_cosmetatos", make<NeedsTranscendental<OpQsysGigkCosmetatos>>()},
2895 {
"qsys_gigk_approx_kingman", make<OpQsysGigkKingman>()},
2896 {
"qsys_gigk_approx_whitt", make<NeedsTranscendental<OpQsysGigkWhitt>>()},
2897 {
"qsys_erlanga", make<NeedsTranscendental<OpQsysErlangA>>()},
2898 {
"qsys_ggnm_diffusion", make<NeedsTranscendental<OpQsysGgnmDiffusion>>()},
2899 {
"qsys_gig1_bnds_extremal", make<NeedsTranscendental<OpQsysGig1BndsExtremal>>()},
2900 {
"qsys_mmk_qed", make<NeedsTranscendental<OpQsysMmkQed>>()},
2901 {
"qsys_mmk_qed_alpha", make<NeedsTranscendental<OpQsysMmkQedAlpha>>()},
2902 {
"qsys_mmk_qed_staffing", make<NeedsTranscendental<OpQsysMmkQedStaffing>>()},
2903 {
"qsys_gigk_rqt", make<NeedsTranscendental<OpQsysGigkRqt>>()},
2904 {
"qsys_gig1_rqt", make<NeedsTranscendental<OpQsysGig1Rqt>>()},
2905 {
"qsys_gigk_rqt_gamma", make<NeedsTranscendental<OpQsysGigkRqtGamma>>()},
2906 {
"qsys_gm1", make<OpQsysGm1>()},
2907 {
"qsys_mapd1", make<NeedsTranscendental<OpQsysMapd1>>()},
2908 {
"qsys_mapdc", make<NeedsTranscendental<OpQsysMapdc>>()},
2909 {
"qsys_mapg1", make<NeedsTranscendental<OpQsysMapg1>>()},
2910 {
"qsys_mapm1", make<NeedsTranscendental<OpQsysMapm1>>()},
2911 {
"qsys_mapmap1", make<NeedsTranscendental<OpQsysMapmap1>>()},
2912 {
"qsys_mapmc", make<NeedsTranscendental<OpQsysMapmc>>()},
2913 {
"qsys_mapph1", make<NeedsTranscendental<OpQsysMapph1>>()},
2914 {
"qsys_mapphc", make<NeedsTranscendental<OpQsysMapphc>>()},
2915 {
"qsys_mg1", make<OpQsysMg1>()},
2916 {
"qsys_mg1_fb", make<NeedsTranscendental<OpQsysMg1Fb>>()},
2917 {
"qsys_mg1_lrpt", make<NeedsTranscendental<OpQsysMg1Lrpt>>()},
2918 {
"qsys_mg1_prio", make<OpQsysMg1Prio>()},
2919 {
"qsys_mg1_psjf", make<NeedsTranscendental<OpQsysMg1Psjf>>()},
2920 {
"qsys_mg1_setf", make<NeedsTranscendental<OpQsysMg1Setf>>()},
2921 {
"qsys_mg1_srpt", make<NeedsTranscendental<OpQsysMg1Srpt>>()},
2922 {
"qsys_mg1k_loss_mgs", make<NeedsTranscendental<OpQsysMg1kLossMgs>>()},
2923 {
"qsys_mginf", make<NeedsTranscendental<OpQsysMginf>>()},
2924 {
"qsys_mm1", make<OpQsysMm1>()},
2925 {
"qsys_mm1_dps", make<NeedsTranscendental<OpQsysMm1Dps>>()},
2926 {
"qsys_mm1k_loss", make<OpQsysMm1kLoss>()},
2927 {
"qsys_mmcc_retrial_fp", make<NeedsTranscendental<OpQsysMmccRetrialFp>>()},
2928 {
"qsys_mgck_sync", make<NeedsTranscendental<OpQsysMgckSync>>()},
2929 {
"qsys_mmck", make<OpQsysMmck>()},
2930 {
"qsys_mmk", make<OpQsysMmk>()},
2931 {
"qsys_mxm1", make<OpQsysMxm1>()},
2932 {
"qsys_phm1", make<NeedsTranscendental<OpQsysPhm1>>()},
2933 {
"qsys_phmc", make<NeedsTranscendental<OpQsysPhmc>>()},
2934 {
"qsys_phph1", make<NeedsTranscendental<OpQsysPhph1>>()},
2939std::string
join(
const std::vector<std::string>& v,
const char* sep) {
2941 for (std::size_t i = 0; i < v.size(); ++i) {
2951 std::vector<std::string> names;
2952 for (
const auto& kv : dispatch_table()) names.push_back(kv.first);
2957 return dispatch_table().find(name) != dispatch_table().end();
2962 if (entry ==
nullptr)
2964 "' is not ported to C++ yet (--list-api shows what is).");
2970 std::vector<std::string> modes;
2973 spec.str() +
"; it supports: " + join(modes,
", ") +
".");
2976 auto it = dispatch_table().find(name);
2977 if (it == dispatch_table().end()) {
2984 "API function '" + name +
2985 "' takes a NetworkStruct or a LayeredNetworkStruct, not matrices, so it has no "
2986 "named-JSON-argument form and --api cannot carry it in any future version. Reach "
2987 "the model-level answer with -s <solver> -a <analysis>, or call it from the "
2990 "API function '" + name +
2991 "' is ported to C++ but not yet exposed over --api; it is reachable from the library "
2992 "and its tests only. Exposed over --api so far: " +
2996 Args reader(args, name);
2998 out[
"function"] = name;
2999 out[
"arith"] = spec.str();
3000 out[
"results"] = it->second(spec, reader);
3010void render_value(std::ostringstream& os,
const Json& v,
const std::string& indent) {
3012 if (v.is_object() && v.contains(
"double")) {
3013 os << v[
"double"].dump();
3014 if (v.contains(
"num"))
3015 os <<
" = " << v[
"num"].get<std::string>() <<
" / " << v[
"den"].get<std::string>();
3016 else if (v.contains(
"dec"))
3017 os <<
" = " << v[
"dec"].get<std::string>();
3022 if (!v.empty() && v[0].is_array()) {
3024 for (
const Json& row : v) {
3025 os << indent <<
" ";
3026 for (std::size_t k = 0; k < row.size(); ++k) {
3028 if (row[k].is_object() && row[k].contains(
"double"))
3029 os << row[k][
"double"].dump();
3031 os << row[k].dump();
3038 for (std::size_t k = 0; k < v.size(); ++k) {
3040 if (v[k].is_object() && v[k].contains(
"double"))
3041 os << v[k][
"double"].dump();
3048 os << v.dump() <<
"\n";
3054 std::ostringstream os;
3055 os << result[
"function"].get<std::string>() <<
" (arith: "
3056 << result[
"arith"].get<std::string>() <<
")\n";
3057 const Json& res = result[
"results"];
3058 for (
auto it = res.begin(); it != res.end(); ++it) {
3059 os <<
" " << it.key() <<
" = ";
3060 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 Age of Information, its transform and the peak age of a GI/M/1 non-preemptive LCFS queue with di...
Mean Age of Information, its transform and the peak age of an M/GI/1 non-preemptive LCFS queue with 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 Age of Information, its transform and the peak age of a GI/M/1 non-preemptive LCFS queue with se...
Mean Age of Information, its transform and the peak age of an M/GI/1 non-preemptive LCFS queue with 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_AOI_GIM1_TWO(OpName, fn)
#define LINE_QSYS_MG1_DISC(OpName, fn, ResultT)
The six M/G/1 disciplines, all {W per class, rhohat}.
#define LINE_FJ_K_LAMBDA_MU(OpName, fn, out_key)
The many members returning one bare number, under the reference's name.
#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_MGI1_TWO(OpName, fn)
The two non-preemptive LCFS M/GI/1 laws: transform at lambda plus both moments.
#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.
AoiLstResult< T > aoi_lcfspr_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 preemptive LCFS queue.
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.
std::string join(const std::vector< std::string > &v, const std::string &sep)
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.
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.
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, bool stiff=false)
Transient distribution of a CTMC over a time interval, by integrating the forward equations d pi/dt =...
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.
const std::map< std::string, std::vector< std::string > > & table()
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.
@ CONSTANT
the orbit retries at rate alpha whenever it is non-empty
@ LINEAR
each orbiting customer retries at rate alpha (orbit rate i*alpha)
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.
MapG1Result< T > qsys_mapg1(const mam::Map< T > &arrival, const std::vector< T > &moments, std::size_t dist_size, std::size_t numQLMoms, std::size_t numSTMoms)
The MAP/G/1 FCFS 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.
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...
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, std::size_t num_steps)
MAP/D/1 by the exact embedded M/G/1-type chain.
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.
MapMap1Result< T > qsys_mapmap1(const mam::Map< T > &arrival, const mam::Map< T > &service, std::size_t dist_size, std::size_t numQLMoms, std::size_t numSTMoms)
MAP/MAP/1 as the reference solves it: the service MAP collapsed to its PH marginal (mapToPh),...
MgckSyncResult< T > qsys_mgck_sync(const T &lambda, std::size_t c, std::size_t K, const ServiceLaw< T > &svc, const std::string &variant, std::size_t nphases, const T &tol, std::size_t nmaxCap)
Synchronous approximation of the M/G/c/K queue with dual bounds.
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.
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.
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, std::size_t num_steps)
MAP/D/c by Crommelin's exact embedded lattice chain.
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.
Conservation laws of a layered queueing network, enumerated from its structure.
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.
Synchronous approximation of the M/G/c/K queue with dual bounds (German, EPEW 2025).
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"
The <kind> part of a LINE:<category>:<kind> identifier (see _kb/17-error-vocabulary....
static double to_double(const double &v)
static ServiceLaw deterministic(const T &d)
Constant service time d.
static ServiceLaw phase_type(const std::vector< T > &alpha, const Matrix< T > &Tmat)
Phase type (alpha, Tmat).
static ServiceLaw gamma(const T &shape, const T &scale)
Gamma(shape, scale).
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