35#include <initializer_list>
122std::vector<int> ints_with_inf(
const Json& j,
const std::string& where) {
123 std::vector<Json> flat;
127 for (
const Json& e : j) {
129 for (
const Json& f : e) flat.push_back(f);
134 std::vector<int> out;
135 out.reserve(flat.size());
136 for (
const Json& e : flat) {
138 std::string s = e.get<std::string>();
139 for (
char& c : s) c =
static_cast<char>(std::tolower(
static_cast<unsigned char>(c)));
140 if (s ==
"inf" || s ==
"+inf" || s ==
"infinity") {
146 if (one.size() != 1)
throw InputError(where +
": expected an integer or \"Inf\"");
148 throw InputError(where +
": a negative entry other than -1 has no meaning, got " +
149 std::to_string(one[0]));
150 out.push_back(one[0]);
155std::vector<int> pop_with_open(
Args& a,
const char* key) {
156 return ints_with_inf(a.get(key), std::string(
"'") + key +
"'");
159std::vector<int> pop_with_open_or_empty(
Args& a,
const char* key) {
160 const Json* v = a.opt(key);
161 return v ? ints_with_inf(*v, std::string(
"'") + key +
"'") : std::vector<int>();
165Matrix<int> int_matrix(
Args& a,
const char* key) {
166 const Json& j = a.get(key);
167 const std::string where = std::string(
"'") + key +
"'";
168 std::vector<std::vector<int> > rows;
169 if (j.is_array() && !j.empty() && j[0].is_array()) {
171 }
else if (!(j.is_array() && j.empty())) {
174 const std::size_t m = rows.size(), n = m ? rows[0].size() : 0;
176 for (std::size_t i = 0; i < m; ++i) {
177 if (rows[i].size() != n)
throw InputError(where +
": rows have different lengths");
178 for (std::size_t k = 0; k < n; ++k) M(i, k) = rows[i][k];
184std::vector<std::size_t> indices(
Args& a,
const char* key) {
185 const std::vector<int> v = a.ints(key);
186 std::vector<std::size_t> out;
187 out.reserve(v.size());
190 throw InputError(std::string(
"'") + key +
"' holds 0-based indices and cannot be "
191 "negative, got " + std::to_string(x));
192 out.push_back(
static_cast<std::size_t
>(x));
197std::vector<long> longs(
Args& a,
const char* key) {
198 const std::vector<int> v = a.ints(key);
199 return std::vector<long>(v.begin(), v.end());
202long a_long(
Args& a,
const char* key) {
return static_cast<long>(a.required_integer(key)); }
205std::vector<double> doubles(
Args& a,
const char* key) {
return a.vector<
double>(key); }
207std::vector<bool> bools(
Args& a,
const char* key) {
208 const Json& j = a.get(key);
209 std::vector<bool> out;
210 auto push = [&](
const Json& e) {
211 if (e.is_boolean()) {
212 out.push_back(e.get<
bool>());
217 if (x != 0 && x != 1)
218 throw InputError(std::string(
"'") + key +
"' entries must be true, false, 0 or 1");
219 out.push_back(x != 0);
223 for (
const Json& e : j) push(e);
234std::size_t given_prefix(
Args& a,
const char* fn, std::initializer_list<const char*> keys) {
238 for (
const char* key : keys) {
241 throw InputError(std::string(fn) +
": '" + key +
"' is positional after " +
242 missing +
", which must then be given as well");
245 if (!gap) missing = std::string(
"'") + key +
"'";
253bool all_or_none(
Args& a,
const char* fn, std::initializer_list<const char*> keys) {
255 std::string names, missing;
256 for (
const char* key : keys) {
257 names += (names.empty() ?
"'" :
", '") + std::string(key) +
"'";
261 missing += (missing.empty() ?
"'" :
", '") + std::string(key) +
"'";
263 if (n == 0)
return false;
264 if (n == keys.size())
return true;
265 throw InputError(std::string(fn) +
": arguments " + names +
266 " are taken together by the port's long form; missing " + missing);
272 OptObj(Args& a,
const char* key,
const char* fn) : j_(a.opt(key)), fn_(fn), key_(key) {
273 if (j_ && !j_->is_object())
274 throw InputError(fn_ +
": '" + key_ +
"' must be an object");
276 OptObj(
const Json* j, std::string fn, std::string key) : j_(j), fn_(std::move(fn)), key_(std::move(key)) {
277 if (j_ && !j_->is_object())
278 throw InputError(fn_ +
": '" + key_ +
"' must be an object");
280 bool given()
const {
return j_ !=
nullptr; }
281 bool has(
const char* k)
const {
return j_ && j_->find(k) != j_->end(); }
282 const Json&
get(
const char* k) {
284 if (!has(k))
throw InputError(fn_ +
": missing required field '" + key_ +
"." + k +
"'");
287 const Json* sub(
const char* k) {
289 return has(k) ? &*j_->find(k) :
nullptr;
291 std::string where(
const char* k)
const {
return fn_ +
": " + key_ +
"." + k; }
293 T number(
const char* k) {
296 std::string text(
const char* k) {
298 if (!v.is_string())
throw InputError(where(k) +
" must be a string");
299 return v.get<std::string>();
301 std::size_t count(
const char* k) {
303 if (v.size() != 1 || v[0] < 0)
304 throw InputError(where(k) +
" must be a single non-negative integer");
305 return static_cast<std::size_t
>(v[0]);
309 for (
auto it = j_->begin(); it != j_->end(); ++it)
310 if (seen_.find(it.key()) == seen_.end())
311 throw InputError(fn_ +
": unknown field '" + key_ +
"." + it.key() +
"'");
318 std::set<std::string> seen_;
326pfqn::NcOptions nc_options(OptObj& o,
const char* fn) {
328 if (o.has(
"samples")) n.samples = o.count(
"samples");
329 if (o.has(
"seed")) n.seed =
static_cast<unsigned long>(o.count(
"seed"));
330 OptObj cfg(o.sub(
"config"), fn,
"options.config");
331 if (cfg.has(
"aghq_nodes")) n.aghq_nodes = cfg.count(
"aghq_nodes");
332 if (cfg.has(
"mcmc_batches")) n.mcmc_batches = cfg.count(
"mcmc_batches");
333 if (cfg.has(
"mcmc_burnin")) n.mcmc_burnin = cfg.number<
double>(
"mcmc_burnin");
339E enum_of(
const std::string& fn,
const char* key,
const std::string& value,
340 std::initializer_list<std::pair<const char*, E>> table) {
341 std::string low = value;
342 for (
char& c : low) c =
static_cast<char>(std::tolower(
static_cast<unsigned char>(c)));
343 std::string accepted;
344 for (
const auto& p : table) {
345 if (low == p.first)
return p.second;
346 accepted += (accepted.empty() ?
"" :
", ") + std::string(p.first);
348 throw InputError(fn +
": unknown " + key +
" '" + value +
"'; accepted: " + accepted);
351std::vector<std::string> strings(
Args& a,
const char* key) {
352 const Json& j = a.get(key);
353 std::vector<std::string> out;
355 out.push_back(j.get<std::string>());
358 if (!j.is_array())
throw InputError(std::string(
"'") + key +
"' must be a list of strings");
359 for (
const Json& e : j) {
360 if (!e.is_string())
throw InputError(std::string(
"'") + key +
"' must be a list of strings");
361 out.push_back(e.get<std::string>());
367std::vector<pfqn::SchedStrategy> sched_list(
Args& a,
const char* key,
const char* fn) {
368 std::vector<pfqn::SchedStrategy> out;
369 for (
const std::string& s : strings(a, key))
370 out.push_back(enum_of<pfqn::SchedStrategy>(fn, key, s,
377std::vector<pfqn::AmvaSched> amva_sched_list(
Args& a,
const char* key,
const char* fn) {
378 std::vector<pfqn::AmvaSched> out;
379 for (
const std::string& s : strings(a, key))
380 out.push_back(enum_of<pfqn::AmvaSched>(fn, key, s,
387Json enc_idx(
const std::vector<std::size_t>& v) {
388 Json j = Json::array();
389 for (std::size_t x : v) j.push_back(
static_cast<std::uint64_t
>(x));
393Json enc_bools(
const std::vector<bool>& v) {
394 Json j = Json::array();
395 for (
bool b : v) j.push_back(b);
401Json enc_tensor(
const moment::MomentTensor<T>& t) {
403 j[
"sz"] = enc_idx(t.sz);
414Json mva_out(
const pfqn::MvaResult<T>& r,
const char* lgkey) {
426Json amva_out(
const pfqn::AmvaResult<T>& r,
const char* itkey) {
433 out[
"converged"] = r.converged;
438Json linearizer_out(
const pfqn::LinearizerResult<T>& r) {
445 out[
"totiter"] = r.totiter;
450Json schmidt_out(
const R& r) {
465 static Json run(Args& a) {
466 const Matrix<T> L = a.matrix<T>(
"L");
467 const std::vector<int> N = a.ints(
"N");
468 pfqn::PfqnManjunathOptions opt;
471 if (a.has(
"stats")) opt.stats = a.boolean(
"stats", opt.stats);
472 const std::size_t k = given_prefix(a,
"pfqn_manjunath", {
"Z",
"A",
"b",
"sense"});
473 pfqn::PfqnManjunathResult<T> r;
478 const Matrix<T> Z = a.matrix<T>(
"Z");
483 throw InputError(
"pfqn_manjunath: 'A', 'b' and 'sense' describe the constraint "
484 "rows together; give all three");
485 const Matrix<T> Z = a.matrix<T>(
"Z");
486 const Matrix<T> A = a.matrix<T>(
"A");
487 const std::vector<long> b = longs(a,
"b");
488 const std::string sense = a.text(
"sense",
"");
518 static Json run(Args& a) {
519 const std::vector<T> lambda = a.vector_or_empty<T>(
"lambda");
520 const Matrix<T> L = a.matrix<T>(
"L");
521 const std::vector<int> N = pop_with_open(a,
"N");
522 const Matrix<T> Z = a.matrix_or_empty<T>(
"Z");
523 OptObj o(a,
"options",
"pfqn_nc");
524 if (!o.given())
throw InputError(
"pfqn_nc: missing required argument 'options' (with field 'method')");
526 const bool longform = !lambda.empty() || o.has(
"tol") || o.has(
"samples") ||
527 o.has(
"seed") || o.has(
"config");
528 pfqn::NcDispatchResult<T> r;
535 throw InputError(
"pfqn_nc: the port's long form (open classes or sampling "
536 "options) takes the absolute tolerance options.tol explicitly");
537 const T atol = o.number<T>(
"tol");
538 pfqn::NcOptions nopt = nc_options(o,
"pfqn_nc");
539 nopt.tol = num_traits<T>::to_double(atol);
549 out[
"method"] = r.method;
550 out[
"valid"] = r.valid;
557 static Json run(Args& a) {
558 const bool lng = all_or_none(a,
"pfqn_nc_sanitize", {
"lambda",
"atol"});
559 pfqn::NcSanitizeResult<T> r;
561 const std::vector<T> lambda = a.vector_or_empty<T>(
"lambda");
562 const Matrix<T> L = a.matrix<T>(
"L");
563 const std::vector<int> N = pop_with_open(a,
"N");
564 const Matrix<T> Z = a.matrix_or_empty<T>(
"Z");
565 const T atol = a.number<T>(
"atol");
569 const Matrix<T> L = a.matrix<T>(
"L");
570 const std::vector<int> N = pop_with_open(a,
"N");
571 const Matrix<T> Z = a.matrix_or_empty<T>(
"Z");
580 out[
"lGremaind"] = r.lGremaind;
582 out[
"classIndex"] = enc_idx(r.classIndex);
589 static Json run(Args& a) {
590 const Matrix<T> L = a.matrix<T>(
"L");
591 const std::vector<int> N = a.ints(
"N");
592 const Matrix<T> Z = a.matrix_or_empty<T>(
"Z");
593 const Matrix<T> mu = a.matrix<T>(
"mu");
594 OptObj o(a,
"options",
"pfqn_ncld");
595 pfqn::NcldResult<T> r;
600 const std::string method = o.text(
"method");
601 const T atol = o.number<T>(
"tol");
602 pfqn::NcOptions nopt = nc_options(o,
"pfqn_ncld");
603 nopt.tol = num_traits<T>::to_double(atol);
611 out[
"method"] = r.method;
618 static Json run(Args& a) {
619 const std::vector<T> lambda = a.vector<T>(
"lambda");
620 const Matrix<T> D = a.matrix<T>(
"D");
621 const std::vector<int> N = pop_with_open(a,
"N");
622 const Matrix<T> Z = a.matrix_or_empty<T>(
"Z");
623 const Matrix<T> mu = a.matrix<T>(
"mu");
624 OptObj o(a,
"options",
"pfqn_ncldmx");
625 pfqn::NcldmxResult<T> r;
630 const std::string method = o.text(
"method");
631 const T atol = o.number<T>(
"tol");
632 pfqn::NcOptions nopt = nc_options(o,
"pfqn_ncldmx");
633 nopt.tol = num_traits<T>::to_double(atol);
641 out[
"lGopen"] = r.lGopen;
652 static Json run(Args& a) {
653 const Matrix<T> A = a.matrix<T>(
"A");
654 const std::vector<int> m = a.ints(
"m");
664 static Json run(Args& a) {
665 const std::vector<T> L = a.vector<T>(
"L");
666 const std::vector<T> N = a.vector<T>(
"N");
667 const std::vector<T> Z = a.vector<T>(
"Z");
679using NrFn = T (*)(
const Matrix<T>&,
const std::vector<T>&,
const std::vector<T>&,
682template <
template <
class>
class F>
685 static Json run(Args& a) {
686 const Matrix<T> L = a.matrix<T>(
"L");
687 const std::vector<T> N = a.vector<T>(
"N");
688 const std::vector<T> Z = a.vector<T>(
"Z");
689 const Matrix<T> alpha = a.matrix<T>(
"alpha");
698 static T call(
const Matrix<T>& L,
const std::vector<T>& N,
const std::vector<T>& Z,
699 const Matrix<T>& al) {
705 static T call(
const Matrix<T>& L,
const std::vector<T>& N,
const std::vector<T>& Z,
706 const Matrix<T>& al) {
712 static T call(
const Matrix<T>& L,
const std::vector<T>& N,
const std::vector<T>& Z,
713 const Matrix<T>& al) {
720 static Json run(Args& a) {
721 const std::vector<T> Phi = a.vector<T>(
"Phi");
722 const std::vector<int> N = a.ints(
"N");
723 a.unsupported(
"f",
"the per-state function f is a callable, which has no JSON "
724 "representation; call pfqn_oi_fnc from the library for that case");
730 out[
"stride"] = enc_idx(r.stride);
737 static Json run(Args& a) {
738 const Matrix<T> L = a.matrix<T>(
"L");
739 const std::vector<int> N = a.ints(
"N");
740 const std::vector<T> Z = a.vector<T>(
"Z");
741 pfqn::PanaceaResult<T> r;
742 if (a.has(
"terms")) {
743 const int terms = a.required_integer(
"terms");
753 out[
"normalUsage"] = r.normalUsage;
760 static Json run(Args& a) {
761 const Matrix<T> L = a.matrix<T>(
"L");
762 const std::vector<int> N = a.ints(
"N");
763 const std::vector<T> Z = a.vector<T>(
"Z");
764 const Matrix<T> mu = a.matrix<T>(
"mu");
765 pfqn::PanaceaLdResult<T> r;
766 if (a.has(
"terms")) {
767 const int terms = a.required_integer(
"terms");
777 out[
"normalUsage"] = r.normalUsage;
778 out[
"reason"] = r.reason ? std::string(r.reason) : std::string();
785 static Json run(Args& a) {
786 const Matrix<T> L = a.matrix<T>(
"L");
787 const std::vector<T> N = a.vector<T>(
"N");
788 const std::vector<T> Z = a.vector<T>(
"Z");
801 static Json run(Args& a) {
802 const Matrix<T> L = a.matrix<T>(
"L");
803 const std::vector<int> N = a.ints(
"N");
804 const Matrix<T> Z = a.matrix_or_empty<T>(
"Z");
805 const Matrix<T> mu = a.matrix<T>(
"mu");
806 OptObj o(a,
"options",
"pfqn_rd");
812 const double tol = o.number<
double>(
"tol");
827 static Json run(Args& a) {
828 const std::vector<T> L = a.vector<T>(
"L");
829 const int N = a.required_integer(
"N");
830 pfqn::RgfResult<T> r;
832 const T Z = a.number<T>(
"Z");
849 static Json run(Args& a) {
850 const Matrix<T> L = a.matrix<T>(
"L");
851 const std::vector<int> N = a.ints(
"N");
852 const std::vector<T> Z = a.vector<T>(
"Z");
853 OptObj o(a,
"options",
"pfqn_rgfmc");
854 pfqn::RgfmcResult<T> r;
859 const T tol = o.number<T>(
"tol");
860 const std::size_t maxterms = o.count(
"maxterms");
861 const T maxcancel = o.number<T>(
"maxcancel");
875 static Json run(Args& a) {
876 const std::vector<T> L = a.vector<T>(
"L");
877 const int N = a.required_integer(
"N");
878 const std::vector<T> s = a.vector<T>(
"s");
892 static Json run(Args& a) {
893 const std::vector<T> lambda = a.vector<T>(
"lambda");
894 const Matrix<T> L = a.matrix<T>(
"L");
895 const std::vector<int> N = pop_with_open(a,
"N");
896 const Matrix<T> Z = a.matrix_or_empty<T>(
"Z");
897 pfqn::MvaResult<T> r;
899 const std::vector<int> mi = a.ints(
"mi");
901 throw InputError(
"pfqn_mvams: the port's form with 'mi' also takes 'S'");
902 const std::vector<int> S = pop_with_open(a,
"S");
905 }
else if (a.has(
"S")) {
906 const std::vector<int> S = pop_with_open(a,
"S");
913 return mva_out(r,
"lG");
919 static Json run(Args& a) {
920 const std::vector<T> lambda = a.vector<T>(
"lambda");
921 const Matrix<T> D = a.matrix<T>(
"D");
922 const std::vector<int> N = pop_with_open(a,
"N");
923 const Matrix<T> Z = a.matrix_or_empty<T>(
"Z");
924 const std::vector<int> mi = a.ints_or_empty(
"mi");
932 static Json run(Args& a) {
933 const std::vector<T> lambda = a.vector<T>(
"lambda");
934 const Matrix<T> D = a.matrix<T>(
"D");
935 const std::vector<int> N = pop_with_open(a,
"N");
936 const Matrix<T> Z = a.matrix_or_empty<T>(
"Z");
937 const Matrix<T> mu = a.matrix<T>(
"mu");
945 static Json run(Args& a) {
946 const std::vector<T> lambda = a.vector<T>(
"lambda");
947 const Matrix<T> D = a.matrix<T>(
"D");
948 const std::vector<int> N = pop_with_open(a,
"N");
949 const Matrix<T> Z = a.matrix_or_empty<T>(
"Z");
950 const std::vector<int> S = pop_with_open(a,
"S");
958 static Json run(Args& a) {
959 const Matrix<T> L = a.matrix<T>(
"L");
960 const std::vector<int> N = a.ints(
"N");
961 const Matrix<T> Z = a.matrix_or_empty<T>(
"Z");
962 const Matrix<T> mu = a.matrix<T>(
"mu");
963 pfqn::MvaLdResult<T> r;
964 if (a.has(
"stabilize")) {
965 const bool st = a.boolean(
"stabilize",
false);
979 out[
"isNumStable"] = r.isNumStable;
988 static Json run(Args& a) {
989 const long N = a_long(a,
"N");
990 const std::vector<T> S = a.vector<T>(
"S");
991 const Matrix<T>
P = a.matrix<T>(
"P");
992 const std::vector<double> K = doubles(a,
"K");
993 const std::vector<bool> isdelay = bools(a,
"isdelay");
994 const std::size_t k = given_prefix(a,
"pfqn_debemva", {
"tol",
"iter_max"});
995 pfqn::DebemvaResult<T> r;
1000 const double tol = a.number<
double>(
"tol");
1004 const double tol = a.number<
double>(
"tol");
1005 const long iter_max = a_long(a,
"iter_max");
1016 out[
"theta"] = r.theta;
1017 out[
"iter"] = r.iter;
1018 out[
"converged"] = r.converged;
1024 static Json run(Args& a) {
1025 const std::vector<double> lam = a.vector<
double>(
"lam");
1026 const Matrix<double> A = a.matrix<
double>(
"A");
1027 const Matrix<double> S = a.matrix<
double>(
"S");
1028 const Matrix<double> SCV = a.matrix<
double>(
"SCV");
1029 const std::vector<double> nservers = doubles(a,
"nservers");
1030 const std::vector<bool> isps = bools(a,
"isps");
1031 const std::vector<double> poolv = doubles(a,
"pool");
1032 const std::vector<double> Ncapv = doubles(a,
"Ncap");
1033 const bool waitq = a.boolean(
"waitq",
true);
1034 const double tol = a.has(
"tol") ? a.number<
double>(
"tol") : 1e-8;
1035 const long iter_max = a.has(
"iter_max") ? a_long(a,
"iter_max") : 1000L;
1037 std::vector<int> pool, Ncap;
1038 for (
double v : poolv) pool.push_back(
static_cast<int>(v) - 1);
1039 for (
double v : Ncapv) Ncap.push_back(
static_cast<int>(v));
1040 const pfqn::OqnrcResult r =
1041 pfqn::pfqn_oqnrc(lam, A, S, SCV, nservers, isps, pool, Ncap, waitq, tol,
static_cast<int>(iter_max));
1050 out[
"iter"] = r.iter;
1057 static Json run(Args& a) {
1058 const long N = a_long(a,
"N");
1059 const std::vector<T> S = a.vector<T>(
"S");
1060 const Matrix<T>
P = a.matrix<T>(
"P");
1061 const std::vector<double> K = doubles(a,
"K");
1062 const std::vector<bool> isdelay = bools(a,
"isdelay");
1063 const std::size_t k = given_prefix(a,
"pfqn_mvablo", {
"tol",
"iter_max"});
1064 pfqn::MvabloResult<T> r;
1068 }
else if (k == 1) {
1069 const double tol = a.number<
double>(
"tol");
1073 const double tol = a.number<
double>(
"tol");
1074 const int iter_max = a.required_integer(
"iter_max");
1084 out[
"iter"] = r.iter;
1085 out[
"converged"] = r.converged;
1092 static Json run(Args& a) {
1093 const Matrix<T> L = a.matrix<T>(
"L");
1094 const std::vector<int> N = a.ints(
"N");
1095 pfqn::MvacResult<T> r;
1097 const Matrix<T> Z = a.matrix<T>(
"Z");
1115 static Json run(Args& a) {
1116 const Matrix<T> L = a.matrix<T>(
"L");
1117 const std::vector<int> N = a.ints(
"N");
1118 const Matrix<T> Z = a.matrix<T>(
"Z");
1119 pfqn::MvacldResult<T> r;
1121 const Matrix<T> mu = a.matrix<T>(
"mu");
1140 static Json run(Args& a) {
1141 const std::vector<T> L = a.vector<T>(
"L");
1142 const T N = a.number<T>(
"N");
1143 pfqn::NintMvaResult<T> r;
1145 const T Z = a.number<T>(
"Z");
1161struct OpMvaInterval {
1163 static Json run(Args& a) {
1164 const Matrix<T> L = a.matrix<T>(
"L");
1165 const std::vector<int> N = a.ints(
"N");
1166 const std::vector<T> Z = a.vector<T>(
"Z");
1169 if (N.size() != 1 && N.size() != 2)
1170 throw InputError(
"pfqn_mva_interval: 'N' must be [nlo nup] or a scalar");
1171 if (Z.size() != 1 && Z.size() != 2)
1172 throw InputError(
"pfqn_mva_interval: 'Z' must be [zlo zup] or a scalar");
1173 const pfqn::MvaIntervalResult<T> r =
1188 static Json run(Args& a) {
1189 const Matrix<T> L = a.matrix<T>(
"L");
1190 const std::vector<int> N = a.ints(
"N");
1191 const std::vector<T> Z = a.vector<T>(
"Z");
1192 pfqn::MomlinResult<T> r;
1193 if (all_or_none(a,
"pfqn_momlin", {
"tol",
"maxiter"})) {
1194 const T tol = a.number<T>(
"tol");
1195 const int maxiter = a.required_integer(
"maxiter");
1210 qc[
"sz"] = Json::array({r.M, r.Rc, r.M, r.Rc});
1224 static Json run(Args& a) {
1225 const Matrix<T> L = a.matrix<T>(
"L");
1226 const std::vector<T> N = a.vector<T>(
"N");
1227 const std::size_t k =
1228 given_prefix(a,
"pfqn_qsa", {
"Z",
"type",
"tol",
"maxiter",
"levels"});
1229 pfqn::AmvaResult<T> r;
1233 }
else if (k == 1) {
1234 const std::vector<T> Z = a.vector<T>(
"Z");
1238 const std::vector<T> Z = a.vector<T>(
"Z");
1239 const std::vector<pfqn::AmvaSched> type = amva_sched_list(a,
"type",
"pfqn_qsa");
1243 }
else if (k == 3) {
1244 const double tol = a.number<
double>(
"tol");
1247 }
else if (k == 4) {
1248 const double tol = a.number<
double>(
"tol");
1249 const std::size_t maxiter = a.count(
"maxiter");
1253 const double tol = a.number<
double>(
"tol");
1254 const std::size_t maxiter = a.count(
"maxiter");
1255 const int levels = a.required_integer(
"levels");
1266 out[
"converged"] = r.converged;
1273 static Json run(Args& a) {
1274 const Matrix<T> L = a.matrix<T>(
"L");
1275 const std::vector<T> N = a.vector<T>(
"N");
1276 const std::vector<T> Z = a.vector<T>(
"Z");
1277 const Matrix<T> mu = a.matrix<T>(
"mu");
1278 const Matrix<T> Q0 = a.matrix<T>(
"Q0");
1279 const std::size_t k = given_prefix(a,
"pfqn_qdamva", {
"tol",
"maxiter"});
1280 pfqn::QdAmvaResult<T> r;
1284 }
else if (k == 1) {
1285 const double tol = a.number<
double>(
"tol");
1289 const double tol = a.number<
double>(
"tol");
1290 const std::size_t maxiter = a.count(
"maxiter");
1306 static Json run(Args& a) {
1307 const Matrix<T> L = a.matrix<T>(
"L");
1308 const std::vector<T> N = a.vector<T>(
"N");
1309 const std::vector<T> Z = a.vector<T>(
"Z");
1310 pfqn::QdLinResult<T> r;
1311 const bool ld = all_or_none(a,
"pfqn_qdlin", {
"mu",
"nservers"});
1312 const std::size_t k = given_prefix(a,
"pfqn_qdlin", {
"tol",
"maxiter",
"wtol"});
1314 std::vector<double> ns;
1316 mu = a.matrix<T>(
"mu");
1317 ns = doubles(a,
"nservers");
1319 double tol = 0, wtol = 0;
1320 std::size_t maxiter = 0;
1321 if (k >= 1) tol = a.number<
double>(
"tol");
1322 if (k >= 2) maxiter = a.count(
"maxiter");
1323 if (k >= 3) wtol = a.number<
double>(
"wtol");
1349 static Json run(Args& a) {
1350 const Matrix<T> L = a.matrix<T>(
"L");
1351 const std::vector<T> N = a.vector<T>(
"N");
1352 const std::size_t k = given_prefix(a,
"pfqn_pam", {
"Z",
"variant"});
1353 pfqn::AmvaResult<T> r;
1358 const std::vector<T> Z = a.vector<T>(
"Z");
1364 "pfqn_pam",
"variant", a.text(
"variant",
""),
1365 {{
"pamb", pfqn::PamVariant::Basic},
1366 {
"pami", pfqn::PamVariant::Improved},
1367 {
"pamt", pfqn::PamVariant::Two}});
1372 return amva_out(r,
"iterations");
1378 static Json run(Args& a) {
1379 const Matrix<T> L = a.matrix<T>(
"L");
1380 const std::vector<T> N = a.vector<T>(
"N");
1381 const std::size_t k = given_prefix(a,
"pfqn_tay", {
"Z",
"tol",
"maxiter",
"QN0"});
1382 pfqn::AmvaResult<T> r;
1387 const std::vector<T> Z = a.vector<T>(
"Z");
1391 }
else if (k == 2) {
1392 const double tol = a.number<
double>(
"tol");
1395 }
else if (k == 3) {
1396 const double tol = a.number<
double>(
"tol");
1397 const std::size_t maxiter = a.count(
"maxiter");
1401 const double tol = a.number<
double>(
"tol");
1402 const std::size_t maxiter = a.count(
"maxiter");
1403 const Matrix<T> QN0 = a.matrix<T>(
"QN0");
1408 return amva_out(r,
"it");
1414 static Json run(Args& a) {
1415 const Matrix<T> L = a.matrix<T>(
"L");
1416 const std::vector<int> N = a.ints(
"N");
1417 const bool lng = all_or_none(a,
"pfqn_scat", {
"type",
"tol",
"maxiter",
"QN0"});
1418 pfqn::LinearizerResult<T> r;
1420 const Matrix<T> Z = a.matrix<T>(
"Z");
1421 const std::vector<pfqn::SchedStrategy> type = sched_list(a,
"type",
"pfqn_scat");
1422 const double tol = a.number<
double>(
"tol");
1423 const int maxiter = a.required_integer(
"maxiter");
1424 const Matrix<T> QN0 = a.matrix_or_empty<T>(
"QN0");
1427 }
else if (a.has(
"Z")) {
1428 const Matrix<T> Z = a.matrix<T>(
"Z");
1435 return linearizer_out(r);
1441 static Json run(Args& a) {
1442 const Matrix<T> D = a.matrix<T>(
"D");
1443 const std::vector<int> N = a.ints(
"N");
1444 const Matrix<int> S = int_matrix(a,
"S");
1445 const std::vector<pfqn::SchedStrategy> sched = sched_list(a,
"sched",
"pfqn_schmidt");
1446 pfqn::SchmidtResult<T> r;
1448 const Matrix<T> v = a.matrix<T>(
"v");
1455 return schmidt_out(r);
1459struct OpSchmidtExt {
1461 static Json run(Args& a) {
1462 const Matrix<T> D = a.matrix<T>(
"D");
1463 const std::vector<int> N = a.ints(
"N");
1464 const Matrix<int> S = int_matrix(a,
"S");
1465 const std::vector<pfqn::SchedStrategy> sched = sched_list(a,
"sched",
"pfqn_schmidt_ext");
1473 static Json run(Args& a) {
1474 const Matrix<T> L = a.matrix<T>(
"L");
1475 const std::vector<int> N = a.ints(
"N");
1476 const std::vector<T> Z = a.vector<T>(
"Z");
1477 const Matrix<T> scv = a.matrix<T>(
"scv");
1478 pfqn::MarieResult<T> r;
1479 if (all_or_none(a,
"pfqn_marie", {
"tol",
"maxiter",
"nservers"})) {
1480 const double tol = a.number<
double>(
"tol");
1481 const int maxiter = a.required_integer(
"maxiter");
1482 const std::vector<int> ns = a.ints(
"nservers");
1495 if (r.cds.empty()) {
1498 Json mu = Json::array();
1499 for (
const auto& c : r.cds) {
1516 static Json run(Args& a) {
1517 const Matrix<T> L = a.matrix<T>(
"L");
1518 const std::vector<int> N = a.ints(
"N");
1519 const Matrix<T> Z = a.matrix_or_empty<T>(
"Z");
1520 const std::vector<int> S = a.ints(
"S");
1521 const std::vector<std::size_t> fcfs = indices(a,
"fcfsNodes");
1522 const Matrix<T> rates = a.matrix<T>(
"rates");
1523 const std::vector<T> tset = a.vector<T>(
"tset");
1525 const pfqn::StdfResult<T> r = Heur
1527 : pfqn::
pfqn_stdf(L, N, Z, S, fcfs, rates, tset);
1528 Json rd = Json::array();
1533 out[
"isNumStable"] = r.isNumStable;
1540 static Json run(Args& a) {
1541 const std::vector<T> N = a.vector<T>(
"N");
1542 const std::vector<T> L = a.vector<T>(
"L");
1543 const std::vector<T> Z = a.vector<T>(
"Z");
1556 static Json run(Args& a) {
1557 const Matrix<T> S = a.matrix<T>(
"S");
1558 const Matrix<T> xi = a.matrix<T>(
"xi");
1559 const std::vector<std::size_t> N = indices(a,
"N");
1560 OptObj o(a,
"sdr",
"pfqn_sdr");
1561 if (!o.given())
throw InputError(
"pfqn_sdr: missing required argument 'sdr'");
1562 pfqn::SdrStruct sdr;
1563 auto idx = [&](
const char* k) {
1565 std::vector<std::size_t> out;
1567 if (x < 0)
throw InputError(o.where(k) +
" cannot be negative");
1568 out.push_back(
static_cast<std::size_t
>(x));
1572 sdr.entry = o.count(
"entry");
1573 sdr.departure = o.count(
"departure");
1575 const Json& br = o.get(
"branch");
1576 if (!br.is_array())
throw InputError(o.where(
"branch") +
" must be a list of index lists");
1577 for (std::size_t b = 0; b < br.size(); ++b) {
1578 std::vector<std::size_t> blk;
1579 if (!br[b].is_null())
1581 if (x < 0)
throw InputError(o.where(
"branch") +
" cannot be negative");
1582 blk.push_back(
static_cast<std::size_t
>(x));
1584 sdr.branch.push_back(blk);
1587 sdr.entryOf = idx(
"entryOf");
1588 sdr.departureOf = idx(
"departureOf");
1589 sdr.level = idx(
"level");
1593 pfqn::SdrResult<T> r;
1594 if (a.has(
"alpha")) {
1595 const Matrix<T> alpha = a.matrix<T>(
"alpha");
1617template <
template <
class>
class F>
1620 static Json run(Args& a) {
1621 const std::vector<T> L = a.vector<T>(
"L");
1622 const T N = a.number<T>(
"N");
1623 const T Z = a.number<T>(
"Z");
1632 static constexpr const char* key =
"XN";
1633 static T call(
const std::vector<T>& L,
const T& N,
const T& Z) {
return pfqn::pfqn_xzabalow(L, N, Z); }
1637 static constexpr const char* key =
"XN";
1638 static T call(
const std::vector<T>& L,
const T& N,
const T& Z) {
return pfqn::pfqn_xzabaup(L, N, Z); }
1642 static constexpr const char* key =
"X";
1643 static T call(
const std::vector<T>& L,
const T& N,
const T& Z) {
return pfqn::pfqn_xzgsblow(L, N, Z); }
1647 static constexpr const char* key =
"X";
1648 static T call(
const std::vector<T>& L,
const T& N,
const T& Z) {
return pfqn::pfqn_xzgsbup(L, N, Z); }
1654 static Json run(Args& a) {
1655 const std::vector<T> L = a.vector<T>(
"L");
1656 const T N = a.number<T>(
"N");
1657 const T Z = a.number<T>(
"Z");
1658 const std::size_t i = a.count(
"i");
1669 static Json run(Args& a) {
1670 const std::vector<T> L = a.vector<T>(
"L");
1671 const T N = a.number<T>(
"N");
1672 const T Z = a.number<T>(
"Z");
1673 pfqn::SsdBounds<T> r;
1674 if (a.has(
"nservers")) {
1675 const std::vector<T> ns = a.vector<T>(
"nservers");
1691 static Json run(Args& a) {
1692 const Matrix<T> L = a.matrix<T>(
"L");
1693 const std::vector<T> N = a.vector<T>(
"N");
1694 pfqn::McubBounds<T> r;
1696 const std::vector<T> Z = a.vector<T>(
"Z");
1712 static Json run(Args& a) {
1713 const Matrix<T> V = a.matrix<T>(
"V");
1714 const Matrix<T> S = a.matrix<T>(
"S");
1715 const std::vector<T> N = a.vector<T>(
"N");
1716 const std::vector<T> Z = a.vector<T>(
"Z");
1717 pfqn::MwrbbBounds<T> r;
1718 if (all_or_none(a,
"pfqn_mwrbb", {
"sched",
"prio"})) {
1719 std::vector<pfqn::MwrbbSched> sched;
1720 for (
int c : a.ints(
"sched")) {
1722 throw InputError(
"pfqn_mwrbb: 'sched' codes are 0=FIFO, 1=PS, 2=non-preemptive "
1723 "priority, 3=preemptive priority, 4=ABA; got " +
1727 const std::vector<int> prio = a.ints(
"prio");
1744 static Json run(Args& a) {
1745 const std::vector<T> L = a.vector<T>(
"L");
1746 const int N = a.required_integer(
"N");
1747 const T Z = a.number<T>(
"Z");
1748 pfqn::PbhBounds<T> r;
1749 if (a.has(
"level")) {
1750 const int level = a.required_integer(
"level");
1768 static Json run(Args& a) {
1769 const std::vector<T> L = a.vector<T>(
"L");
1770 const int N = a.required_integer(
"N");
1771 const T Z = a.number<T>(
"Z");
1772 pfqn::SibBounds<T> r;
1773 if (a.has(
"level")) {
1774 const int level = a.required_integer(
"level");
1792 static Json run(Args& a) {
1793 const std::vector<T> L = a.vector<T>(
"L");
1794 const long N = a_long(a,
"N");
1808 static Json run(Args& a) {
1809 const long N = a_long(a,
"N");
1810 const long K = a_long(a,
"K");
1812 if (all_or_none(a,
"pfqn_scbgap", {
"r",
"undominated"})) {
1813 const long r = a_long(a,
"r");
1814 const bool und = a.boolean(
"undominated",
false);
1829 static Json run(Args& a) {
1830 const long R = a_long(a,
"R");
1831 const long K = a_long(a,
"K");
1832 const long N = a_long(a,
"N");
1840struct OpMinclasses {
1842 static Json run(Args& a) {
1843 const T Usum = a.number<T>(
"Usum");
1844 const long K = a_long(a,
"K");
1845 const long N = a_long(a,
"N");
1859 static Json run(Args& a) {
1860 const Matrix<T> L = a.matrix<T>(
"L");
1861 pfqn::UniqueResult<T> r;
1862 if (all_or_none(a,
"pfqn_unique", {
"mu",
"gamma"})) {
1863 const Matrix<T> mu = a.matrix_or_empty<T>(
"mu");
1864 const Matrix<T> gamma = a.matrix_or_empty<T>(
"gamma");
1876 out[
"mapping"] = enc_idx(r.mapping);
1883 static Json run(Args& a) {
1884 const Matrix<T> mu = a.matrix<T>(
"mu");
1885 const std::vector<std::size_t> iset = indices(a,
"iset");
1895 static Json run(Args& a) {
1896 const int N = a.required_integer(
"N");
1897 const int m = a.required_integer(
"m");
1898 const int c = a.required_integer(
"c");
1912 static Json run(Args& a) {
1913 const Matrix<T> L = a.matrix<T>(
"L");
1914 const std::vector<int> N = a.ints(
"N");
1915 const std::vector<T> Z = a.vector<T>(
"Z");
1916 pfqn::SensResult<T> r;
1918 const std::vector<int> mi = a.ints(
"mi");
1930 Json ps = Json::array();
1931 for (
const auto& p : r.params) {
1933 e[
"type"] = std::string(1, p.type);
1934 e[
"station"] = p.station;
1935 e[
"class"] =
static_cast<std::uint64_t
>(p.cls);
1953struct OpSensLdmxEc {
1955 static Json run(Args& a) {
1956 const std::vector<T> lambda = a.vector<T>(
"lambda");
1957 const Matrix<T> D = a.matrix<T>(
"D");
1958 const Matrix<T> mu = a.matrix<T>(
"mu");
1973struct OpSensLinearizer {
1975 static Json run(Args& a) {
1976 const Matrix<T> L = a.matrix<T>(
"L");
1977 const std::vector<int> N = a.ints(
"N");
1978 const std::vector<T> Z = a.vector<T>(
"Z");
1979 pfqn::SensLinearizerResult<T> r;
1980 if (all_or_none(a,
"pfqn_sens_linearizer", {
"tol",
"maxiter"})) {
1981 const T tol = a.number<T>(
"tol");
1982 const unsigned maxiter = a.uinteger(
"maxiter");
2012 static Json run(Args& a) {
2013 const Matrix<T> L = a.matrix<T>(
"L");
2014 const std::vector<int> N = a.ints(
"N");
2015 const std::vector<T> Z = a.vector<T>(
"Z");
2016 pfqn::SensMomResult<T> r;
2017 if (all_or_none(a,
"pfqn_sens_mom", {
"mi",
"groups"})) {
2018 const std::vector<int> mi = a.ints_or_empty(
"mi");
2019 const std::vector<int> groups = a.ints_or_empty(
"groups");
2048 static Json run(Args& a) {
2049 const Matrix<T> L = a.matrix<T>(
"L");
2050 const std::vector<int> N = a.ints(
"N");
2051 const std::vector<T> Z = a.vector<T>(
"Z");
2052 pfqn::SensMvaResult<T> r;
2054 const std::vector<int> mi = a.ints(
"mi");
2076struct OpSensMvaldmx {
2078 static Json run(Args& a) {
2079 const std::vector<T> lambda = a.vector<T>(
"lambda");
2080 const Matrix<T> D = a.matrix<T>(
"D");
2081 const std::vector<int> N = pop_with_open(a,
"N");
2082 const std::vector<T> Z = a.vector<T>(
"Z");
2083 const Matrix<T> mu = a.matrix<T>(
"mu");
2102struct OpSensMomldmx {
2104 static Json run(Args& a) {
2105 const std::vector<T> lambda = a.vector<T>(
"lambda");
2106 const Matrix<T> D = a.matrix<T>(
"D");
2107 const std::vector<int> N = pop_with_open(a,
"N");
2108 const std::vector<T> Z = a.vector<T>(
"Z");
2109 const Matrix<T> mu = a.matrix<T>(
"mu");
2110 const std::vector<int> groups = a.ints_or_empty(
"groups");
2135 static Json run(Args& a) {
2136 const std::vector<T> S = a.vector<T>(
"S");
2137 const Matrix<T> V = a.matrix<T>(
"V");
2138 const std::vector<int> N = a.ints(
"N");
2139 const std::vector<T> Z = a.vector<T>(
"Z");
2140 pfqn::SensResptResult<T> r;
2141 if (all_or_none(a,
"pfqn_sens_respt", {
"b",
"tmax"})) {
2142 const std::vector<int> b = a.ints(
"b");
2143 const int tmax = a.required_integer(
"tmax");
2168struct OpQlenJointMoments {
2170 static Json run(Args& a) {
2171 const Matrix<T> L = a.matrix<T>(
"L");
2172 const std::vector<int> N = a.ints(
"N");
2173 const std::vector<T> Z = a.vector<T>(
"Z");
2174 a.unsupported(
"lGsrc",
"the injected log G source is a callable, which has no JSON "
2175 "representation; omit it to have pfqn_nc supply log G");
2176 std::vector<std::pair<std::size_t, std::size_t> > pairs;
2177 if (a.has(
"pairs")) {
2178 const Matrix<int>
P = int_matrix(a,
"pairs");
2179 if (!
P.empty() &&
P.cols() != 2)
2180 throw InputError(
"pfqn_qlen_joint_moments: 'pairs' must be a P x 2 matrix of "
2181 "0-based (station, class) indices");
2182 for (std::size_t p = 0; p <
P.rows(); ++p) {
2183 if (
P(p, 0) < 0 ||
P(p, 1) < 0)
2184 throw InputError(
"pfqn_qlen_joint_moments: 'pairs' holds 0-based indices");
2185 pairs.emplace_back(
static_cast<std::size_t
>(
P(p, 0)),
2186 static_cast<std::size_t
>(
P(p, 1)));
2189 const bool lng = all_or_none(a,
"pfqn_qlen_joint_moments", {
"route",
"options"});
2190 pfqn::QlenJointMomentsResult<T> r;
2193 "pfqn_qlen_joint_moments",
"route", a.text(
"route",
""),
2194 {{
"auto", pfqn::QlenJointRoute::Auto},
2195 {
"tail", pfqn::QlenJointRoute::Tail},
2196 {
"pmf", pfqn::QlenJointRoute::Pmf}});
2197 OptObj o(a,
"options",
"pfqn_qlen_joint_moments");
2199 pfqn::NcOptions nopt = nc_options(o,
"pfqn_qlen_joint_moments");
2200 if (o.has(
"tol")) nopt.tol = o.number<
double>(
"tol");
2211 out[
"tail"] = enc_tensor(r.tail);
2212 out[
"binomial"] = enc_tensor(r.binomial);
2213 out[
"factorial"] = enc_tensor(r.factorial);
2214 out[
"raw"] = enc_tensor(r.raw);
2215 out[
"central"] = enc_tensor(r.central);
2216 out[
"cumulant"] = enc_tensor(r.cumulant);
2220 info[
"route"] = r.route;
2224 info[
"exact"] = r.exact;
2225 Json pj = Json::array();
2226 for (
const auto& p : r.pairs)
2227 pj.push_back(Json::array({
static_cast<std::uint64_t
>(p.first),
2228 static_cast<std::uint64_t
>(p.second)}));
2230 info[
"dims"] = enc_idx(r.dims);
2236struct OpResptPsMoments {
2238 static Json run(Args& a) {
2239 const std::vector<T> S = a.vector<T>(
"S");
2240 const std::vector<long> N = longs(a,
"N");
2241 const std::vector<T> Z = a.vector<T>(
"Z");
2242 pfqn::ResptPsMomentsResult<T> r;
2243 if (a.has(
"method")) {
2244 const pfqn::ResptPsRoute m = enum_of<pfqn::ResptPsRoute>(
2245 "pfqn_respt_ps_moments",
"method", a.text(
"method",
""),
2246 {{
"auto", pfqn::ResptPsRoute::Auto},
2247 {
"exact", pfqn::ResptPsRoute::Exact},
2248 {
"asymptotic", pfqn::ResptPsRoute::Asymptotic}});
2250 r = pfqn::pfqn_respt_ps_moments(S, N, Z, m);
2253 r = pfqn::pfqn_respt_ps_moments(S, N, Z);
2256 Json ms = Json::array();
2257 for (pfqn::ResptPsMethod m : r.method) {
2259 case pfqn::ResptPsMethod::None: ms.push_back(
"none");
break;
2260 case pfqn::ResptPsMethod::Exact: ms.push_back(
"exact");
break;
2261 case pfqn::ResptPsMethod::Asymptotic: ms.push_back(
"asymptotic");
break;
2262 case pfqn::ResptPsMethod::Unavailable: ms.push_back(
"unavailable");
break;
2292 static Json run(Args& a) {
2293 const Matrix<T> L = a.matrix<T>(
"L");
2294 const std::vector<int> N = a.ints(
"N");
2295 const std::vector<T> Z = a.vector_or_empty<T>(
"Z");
2296 const std::vector<double> sv = a.vector_or_empty<
double>(
"s");
2297 const Json* oj = a.opt(
"options");
2300 throw InputError(
"pfqn_mcmc: options.seed is required; the port draws from a seeded "
2301 "generator and has no session RNG to fall back on");
2302 Args op(*oj,
"pfqn_mcmc options");
2303 const std::size_t samples = op.count(
"samples", 100000);
2304 std::size_t nbatches = pfqn::MCMC_DEFAULT_BATCHES;
2305 double burnin = pfqn::MCMC_DEFAULT_BURNIN;
2306 if (
const Json* cj = op.opt(
"config")) {
2307 Args cfg(*cj,
"pfqn_mcmc options.config");
2308 nbatches = cfg.count(
"mcmc_batches", nbatches);
2309 burnin = cfg.scalar<
double>(
"mcmc_burnin", burnin);
2312 const std::uint64_t seed =
required_seed(op,
"pfqn_mcmc",
"options.seed");
2314 pfqn::McRng rng(seed);
2315 const pfqn::McmcResult<T> r = pfqn::pfqn_mcmc(L, N, Z, sv, samples, nbatches, burnin, rng);
2341 static Json run(Args& a) {
2342 const Matrix<T> D = a.matrix<T>(
"D");
2343 const std::vector<int> N = a.ints(
"N");
2344 const std::vector<T> Z = a.vector_or_empty<T>(
"Z");
2345 const std::size_t I = a.count(
"I", 100000);
2346 std::string v = a.text(
"variant",
"imci");
2347 for (
char& c : v) c =
static_cast<char>(std::tolower(
static_cast<unsigned char>(c)));
2348 pfqn::MciVariant variant;
2349 if (v ==
"imci") variant = pfqn::MciVariant::Imci;
2350 else if (v ==
"mci") variant = pfqn::MciVariant::Mci;
2351 else if (v ==
"rm") variant = pfqn::MciVariant::Rm;
2352 else if (v ==
"amci") variant = pfqn::MciVariant::Amci;
2353 else if (v ==
"lhsmci") variant = pfqn::MciVariant::Lhsmci;
2354 else throw InputError(
"pfqn_mci: variant must be one of imci, mci, rm, amci, lhsmci; got '" +
2358 const pfqn::NcResult<T> r = pfqn::pfqn_mci(D, N, Z, I, variant, rng);
2369 static Json run(Args& a) {
2370 const Matrix<T> L = a.matrix<T>(
"L");
2371 const std::vector<int> N = a.ints(
"N");
2372 const std::vector<T> Z = a.vector_or_empty<T>(
"Z");
2373 const std::size_t samples = a.count(
"samples", 100000);
2376 const pfqn::NcResult<T> r = pfqn::pfqn_mmsample2(L, N, Z, samples, rng);
2465 const std::string oirate =
2466 "the per-station service rates are callables of the station state "
2467 "(std::function), which have no JSON representation.";
2468 t[
"pfqn_oi_insvc"] =
"the in-service rate oirate is a callable of the station state "
2469 "(std::function), which has no JSON representation.";
2470 t[
"pfqn_mvajd"] = oirate;
2471 t[
"pfqn_mvaoi"] = oirate;
2472 t[
"pfqn_mvaoi_marg"] = oirate;
2473 t[
"pfqn_ncoi"] = oirate;
2474 t[
"pfqn_ncjd"] = oirate;
2475 t[
"pfqn_pas_nc"] = oirate;
2476 t[
"pfqn_oi_is"] =
"the per-station rates are callables (std::function), which have no JSON "
2478 t[
"pfqn_pas_is"] = t[
"pfqn_oi_is"];
Internal to the –api dispatcher: what a per-domain translation unit needs to add entries to the table...
Named-argument reader over the parsed JSON object.
const std::string * get(const Element *el, const std::string &key)
el.get(key), with Python's None as a null pointer.
SqniResult< T > pfqn_sqni(const std::vector< T > &N, const std::vector< T > &L, const std::vector< T > &Z)
Square-root non-iterative (SQNI) approximation for a single queueing station with per-class delay.
RgfmcResult< T > pfqn_rgfmc(const Matrix< T > &L, const std::vector< int > &N, const std::vector< T > &Z, const T &tol, std::size_t maxterms, const T &maxcancel)
Multiclass Recursion by Generating Functions (RGF), with think times.
RdResult< T > pfqn_rd(const Matrix< T > &L0, const std::vector< int > &N, const Matrix< T > &Z, const Matrix< T > &mu0, double tol, NcMethod method)
Reduction heuristic (RD) for the normalizing constant of a closed LOAD-DEPENDENT product-form network...
MvaIntervalResult< T > pfqn_mva_interval(const Matrix< T > &L, int nlo, int nup, const T &zlo, const T &zup)
Exact interval-valued MVA for single-class closed product-form networks.
QlenJointMomentsResult< T > pfqn_qlen_joint_moments(const Matrix< T > &L, const std::vector< int > &N, const std::vector< T > &Z, const std::vector< std::pair< std::size_t, std::size_t > > &pairs, QlenJointRoute route, const QlenJointLgSource< T > &lGsrc, NcMethod method, const NcOptions &nopt)
Joint moments of the queue-length vector of a closed product-form network, obtained from normalizing ...
T pfqn_xia(const std::vector< T > &L, int N, const std::vector< T > &s)
Xia's asymptotic approximation of the normalizing constant of a load-dependent (multiserver) closed n...
PanaceaLdResult< T > pfqn_panaceald(const Matrix< T > &L, const std::vector< int > &N, const std::vector< T > &Z, const Matrix< T > &mu, int terms)
PANACEA normal-usage asymptotic expansion for LOAD-DEPENDENT closed networks (Mitra and McKenna,...
SchmidtExtResult< T > pfqn_schmidt_ext(const Matrix< T > &D, const std::vector< int > &N, const Matrix< int > &S, const std::vector< SchedStrategy > &sched)
Extended Schmidt MVA with queue-aware alpha corrections.
SensResptResult< T > pfqn_sens_respt(const std::vector< T > &S, const Matrix< T > &V, const std::vector< int > &N, const std::vector< T > &Z, const std::vector< int > &b, int tmax)
Exact raw moments E[W^t], t = 1..3, of the sojourn time of a job at an FCFS b-server center of a clos...
LinearizerResult< T > pfqn_scat(const Matrix< T > &L, const std::vector< int > &N, const Matrix< T > &Z, const std::vector< SchedStrategy > &type, double tol, int maxiter, const Matrix< T > &QN0)
Neuse-Chandy SCAT (Self-Correcting Approximation Technique) approximate MVA.
OqnrcResult pfqn_oqnrc(const std::vector< double > &lam, const Matrix< double > &A, const Matrix< double > &S, const Matrix< double > &SCV, const std::vector< double > &nservers, const std::vector< bool > &isps, const std::vector< int > &pool, const std::vector< int > &Ncap, bool waitq, double tol, int iter_max)
Runs OQNRC.
StdfResult< T > pfqn_stdf(const Matrix< T > &L, const std::vector< int > &N, const Matrix< T > &Z, const std::vector< int > &S, const std::vector< std::size_t > &fcfsNodes, const Matrix< T > &rates, const std::vector< T > &tset)
Sojourn-time distribution at the listed FCFS stations.
AmvaResult< T > pfqn_pam(const Matrix< T > &L, const std::vector< T > &N, const std::vector< T > &Z, PamVariant variant=PamVariant::Basic)
Hsieh-Lam Proportional Approximation Methods (PAMB / PAMI / PAMT).
NcldmxResult< T > pfqn_ncldmx(const std::vector< T > &lambda, const Matrix< T > &D, const std::vector< int > &N, const Matrix< T > &Z, const Matrix< T > &mu, const std::string &method, const T &atol, const NcOptions &nopt)
Normalizing constant of a MIXED open/closed network with limited load dependence.
ScbBounds< T > pfqn_scb(const std::vector< T > &L, long N)
Bracket on the throughput and the per-device utilizations of the UNKNOWN multiclass system whose sing...
NcSanitizeResult< T > pfqn_nc_sanitize(const std::vector< T > &lambda, const Matrix< T > &L, const std::vector< int > &N, const Matrix< T > &Z, const T &atol)
Preprocessing shared by the normalizing-constant solvers: drop the classes that cannot contribute,...
MarieResult< T > pfqn_marie(const Matrix< T > &L, const std::vector< int > &N, const std::vector< T > &Z, const Matrix< T > &scv, double tol, int maxiter, const std::vector< int > &nservers)
Marie's method for a closed network with FCFS Coxian service.
SensMvaResult< T > pfqn_sens_mva(const Matrix< T > &L, const std::vector< int > &N, const std::vector< T > &Z, const std::vector< int > &mi)
Exact per-station queue-length variances and covariances of a closed product-form network,...
SensLinearizerResult< T > pfqn_sens_linearizer(const Matrix< T > &L, const std::vector< int > &N, const std::vector< T > &Z, const T *tol, unsigned maxiter)
Approximate moments E[Q_i], Var[Q_i], Cov[Q_i,Q_j], E[Q_i^2] and E[Q_i^3] of the per-station total qu...
long pfqn_minclasses(const T &Usum, long K, long N)
Smallest number of customer classes R consistent with an observed sum of device utilizations,...
MvaResult< T > pfqn_mvams(const std::vector< T > &lambda, const Matrix< T > &L, const std::vector< int > &N, const Matrix< T > &Z, const std::vector< int > &mi, const std::vector< int > &S)
General-purpose exact MVA for mixed networks with multiserver stations.
UniqueResult< T > pfqn_unique(const Matrix< T > &L, const Matrix< T > &mu, const Matrix< T > &gamma)
Merge stations whose (L, mu, gamma) rows are exactly equal.
McubBounds< T > pfqn_mcub(const Matrix< T > &L, const std::vector< T > &N, const std::vector< T > &Z)
Kerola's multiclass composite bound (Perf.
PropfairResult< T > pfqn_propfair(const Matrix< T > &L, const std::vector< T > &N, const std::vector< T > &Z)
Proportionally fair allocation estimate of the normalizing constant (Schweitzer 1979; Walton,...
NcldResult< T > pfqn_ncld(const Matrix< T > &L, const std::vector< int > &N, const Matrix< T > &Z, const Matrix< T > &mu, const std::string &method_name, const T &atol, const NcOptions &nopt)
Normalizing constant of a LOAD-DEPENDENT closed network: the dispatcher.
std::function< std::vector< double >(const Matrix< T > &, const std::vector< std::vector< int > > &)> QlenJointLgSource
Injected source of log G.
MvaResult< T > pfqn_mvamx(const std::vector< T > &lambda, const Matrix< T > &D, const std::vector< int > &N, const Matrix< T > &Z, const std::vector< int > &mi)
Exact MVA for a mixed open/closed network of single-server stations.
T pfqn_xzabaup(const std::vector< T > &L, const T &N, const T &Z)
X <= min(1/Lmax, N/(sum(L)+Z)): capacity bound and population bound.
NcMethod nc_method_of(const std::string &s)
Map a method name to its enum; throws UnsupportedError on an unknown one.
QlenJointRoute
Which survival-array identity is used.
MvabloResult< T > pfqn_mvablo(long N, const std::vector< T > &S, const Matrix< T > &P, const std::vector< double > &K, std::vector< bool > isdelay, double tol=1e-4, int iter_max=1000)
Runs MVABLO.
T pfqn_xzabalow(const std::vector< T > &L, const T &N, const T &Z)
X >= N / (Z + N sum(L)), the ABA population bound.
MvaLdResult< T > pfqn_mvald(const Matrix< T > &L, const std::vector< int > &N, const Matrix< T > &Z, const Matrix< T > &mu, bool stabilize=true)
Exact MVA for a closed network of load-dependent stations.
StdfResult< T > pfqn_stdf_heur(const Matrix< T > &L, const std::vector< int > &N, const Matrix< T > &Z, const std::vector< int > &S, const std::vector< std::size_t > &fcfsNodes, const Matrix< T > &rates, const std::vector< T > &tset)
Heuristic sojourn-time distribution at the listed FCFS stations.
T pfqn_nre(const Matrix< T > &L0, const std::vector< T > &N, const std::vector< T > &Z, const Matrix< T > &alpha0)
Saddle-tilted Edgeworth approximation of log G for a limited load-dependent model.
MwrbbSched
Station discipline codes, matching the MATLAB sched argument.
AmvaResult< T > pfqn_tay(const Matrix< T > &L, const std::vector< T > &N, const std::vector< T > &Z, double tol=1e-6, std::size_t maxiter=1000, const Matrix< T > &QN0=Matrix< T >())
Tay's arrival-instant approximate MVA.
T pfqn_xzgsbup(const std::vector< T > &L, const T &N, const T &Z)
X = 2N / (R + sqrt(R^2 - 4 Z Lmax N)), R from the geometric queue bound.
MvaResult< T > pfqn_mvaldms(const std::vector< T > &lambda, const Matrix< T > &D, const std::vector< int > &N, const Matrix< T > &Z, const std::vector< int > &S)
Exact MVA for mixed open/closed networks with multiserver stations.
DebemvaResult< T > pfqn_debemva(long N, const std::vector< T > &S, const Matrix< T > &P, const std::vector< double > &K, std::vector< bool > isdelay, double tol=0.0, long iter_max=100000)
Runs debeMVA.
QdAmvaResult< T > pfqn_qdamva(const Matrix< T > &L, const std::vector< T > &N, const std::vector< T > &Z, const Matrix< T > &mu, const Matrix< T > &Q0, double tol=1e-6, std::size_t maxiter=10000)
QD-AMVA: queue-dependent approximate mean value analysis.
AmvaResult< T > pfqn_qsa(const Matrix< T > &L, const std::vector< T > &N, const std::vector< T > &Z, const std::vector< AmvaSched > &type, double tol=1e-10, std::size_t maxiter=100, int levels=3)
Queue-Shift Approximation (QSA) for closed product-form networks.
T pfqn_usumbound(long R, long K, long N)
Largest value the sum of device utilizations can take in any closed product-form network with R class...
SibBounds< T > pfqn_sib(const std::vector< T > &L, int N, const T &Z, int level)
Successively Improving Bounds (Srinivasan 1985/1987) on the cycle time and throughput of a single-cla...
SchmidtResult< T > pfqn_schmidt(const Matrix< T > &D, const std::vector< int > &N, const Matrix< int > &S, const std::vector< SchedStrategy > &sched, const Matrix< T > &v)
Schmidt's MVA for closed networks with general scheduling disciplines and class-dependent multiserver...
SdrResult< T > pfqn_sdr(const Matrix< T > &S, const Matrix< T > &xi, const std::vector< std::size_t > &N, const SdrStruct &sdr, const Matrix< T > &alpha=Matrix< T >())
Exact product form of eq.
T pfqn_qzgbup(const std::vector< T > &L, const T &N, const T &Z, std::size_t i)
As the lower bound, with Y from the ABA upper bound and the sigma term.
MvaResult< T > pfqn_mvaldmx(const std::vector< T > &lambda, const Matrix< T > &D, const std::vector< int > &N, const Matrix< T > &Z, const Matrix< T > &mu)
Exact MVA for mixed open/closed networks with limited load dependence.
MmintResult< T > pfqn_mmint2(const std::vector< T > &L, const std::vector< T > &N, const std::vector< T > &Z)
Adaptive form (MATLAB pfqn_mmint2): Gauss-Kronrod on [0, 27.63] with absolute tolerance 1e-12.
OiFncResult< T > pfqn_oi_fnc(const std::vector< T > &Phi, const std::vector< int > &N, const std::function< T(const std::vector< int > &)> &f)
Order-independent (OI) functional server: the balance function Psi and the rate mu_f of an auxiliary ...
PanaceaResult< T > pfqn_panacea(const Matrix< T > &L, const std::vector< int > &N, const std::vector< T > &Z, int terms)
PANACEA normal-usage asymptotic expansion of the normalizing constant (Ramakrishnan and Mitra,...
T pfqn_scbgap(long N, long K, long r, bool undominated)
Demand-free bound on the relative throughput error incurred when r of the N single-customer classes a...
T pfqn_nrp(const Matrix< T > &L, const std::vector< T > &N, const std::vector< T > &Z, const Matrix< T > &alpha)
Norlund-Rice probit approximation of log G.
RgfResult< T > pfqn_rgf(const std::vector< T > &L, int N, const T &Z)
Recursion by Generating Functions (RGF) for the normalizing constant of a SINGLE-CLASS closed product...
MwrbbBounds< T > pfqn_mwrbb(const Matrix< T > &V, const Matrix< T > &S, const std::vector< T > &N, const std::vector< T > &Z, const std::vector< MwrbbSched > &sched, const std::vector< int > &prio)
Majumdar-Woodside robust box bounds on the per-class throughput of a closed multiclass network with m...
NintMvaResult< T > pfqn_nintmva(const std::vector< T > &L, const T &N, const T &Z)
Mean value analysis at a nonintegral population (fractional-base aMVA).
SensMomResult< T > pfqn_sens_mom(const Matrix< T > &L, const std::vector< int > &N, const std::vector< T > &Z, const std::vector< int > &mi, const std::vector< int > &groups)
Exact moments E[Q], Var[Q], E[Q^2] and E[Q^3] of the grouped queue lengths of a closed product-form n...
PbhBounds< T > pfqn_pbh(const std::vector< T > &L, int N, const T &Z, int level)
Performance Bound Hierarchy (Eager and Sevcik 1983, ACM TOCS 1(2):99-115) for single-class closed pro...
Matrix< T > pfqn_mushift(const Matrix< T > &mu, const std::vector< std::size_t > &iset)
Shift the load-dependent service-rate lattice of selected stations.
NcMethod
The methods this port dispatches, one per compute_norm_const case.
SensLdmxEcResult< T > pfqn_sens_ldmx_ec(const std::vector< T > &lambda, const Matrix< T > &D, const Matrix< T > &mu)
Effective capacity terms of the mixed load-dependent MVA of Bruell-Balbo-Afshari, together with their...
QdLinResult< T > pfqn_qdlin(const Matrix< T > &L, const std::vector< T > &N, const std::vector< T > &Z, const Matrix< T > &mu, const std::vector< double > &nservers, double tol=1e-6, std::size_t maxiter=1000, double wtol=1e-4)
QD-LIN: the Linearizer arm of AMVA-LD, on a plain demand matrix.
SensMvaldmxResult< T > pfqn_sens_mvaldmx(const std::vector< T > &lambda, const Matrix< T > &D, const std::vector< int > &N, const std::vector< T > &Z, const Matrix< T > &mu)
Exact queue-length variances and covariances of a mixed open/closed product-form network with limited...
std::vector< T > pfqn_mu_ms(int N, int m, int c)
Aggregate load-dependent rate of m identical c-server FCFS stations.
PamVariant
Which of the three proportional approximations to run.
T pfqn_nrl(const Matrix< T > &L, const std::vector< T > &N, const std::vector< T > &Z, const Matrix< T > &alpha)
Norlund-Rice logit approximation of log G.
T pfqn_qzgblow(const std::vector< T > &L, const T &N, const T &Z, std::size_t i)
Qgb = y/(1-y) - y^(N+1)/(1-y) with y = N L_i / (Z + sum(L) + Lmax N).
T pfqn_perm(const Matrix< T > &A, const std::vector< int > &m)
Permanent of a matrix with repeated columns, by Ryser's formula.
SensMomResult< T > pfqn_sens_momldmx(const std::vector< T > &lambda, const Matrix< T > &D, const std::vector< int > &N, const std::vector< T > &Z, const Matrix< T > &mu, const std::vector< int > &groups)
Exact moments E[Q], Var[Q], E[Q^2], E[Q^3] and covariances of the grouped queue lengths of a mixed lo...
MomlinResult< T > pfqn_momlin(const Matrix< T > &L, const std::vector< int > &N, const std::vector< T > &Z, const T &tol, int maxiter)
Moment linearizer: approximate first and second queue-length moments of a large closed product-form n...
SensResult< T > pfqn_sens(const Matrix< T > &L, const std::vector< int > &N, const std::vector< T > &Z, const std::vector< int > &mi)
Exact analytic derivatives of the mean performance measures {X,Q,U,R} of a closed product-form (BCMP)...
T pfqn_xzgsblow(const std::vector< T > &L, const T &N, const T &Z)
X = 2N / (R + sqrt(R^2 - 4 Z Lmax (N-1))), R from the geometric queue bound.
MvacldResult< T > pfqn_mvacld(const Matrix< T > &L, const std::vector< int > &N, const Matrix< T > &Z, const Matrix< T > &mu)
MVAC for networks with queue-length dependent (QLD) service centers, the Section V extension of Conwa...
NcDispatchResult< T > pfqn_nc(const std::vector< T > &lambda, const Matrix< T > &L, const std::vector< int > &N, const Matrix< T > &Z, NcMethod method, const T &atol, const NcOptions &nopt)
Normalizing constant of a product-form queueing network: the dispatcher.
MvacResult< T > pfqn_mvac(const Matrix< T > &L, const std::vector< int > &N, const Matrix< T > &Z)
MVAC: exact mean value analysis BY CHAIN of a closed multichain product-form network (Conway,...
PfqnManjunathResult< T > pfqn_manjunath(const Matrix< T > &L, const std::vector< int > &N, const Matrix< T > &Z, const Matrix< T > &A, const std::vector< long > &b, const std::string &sense, const PfqnManjunathOptions &options={})
Exact normalizing constant of a closed multiclass product-form network whose state space carries arbi...
SsdBounds< T > pfqn_ssd(const std::vector< T > &L, const T &N, const T &Z, const std::vector< T > &nservers)
Server-Station Disaggregation bounds for a multiserver closed network (Dallery and Suri,...
std::uint64_t required_seed(Args &a, const std::string &fn, const char *spelled="seed")
The seed of a function whose port draws from a caller-owned generator.
Json encode_vectors(const std::vector< std::vector< T > > &v)
A list of vectors, the shape a per-class or per-segment result returns.
Matrix< T > matrix_from_json(const Json &j, const std::string &where)
A matrix from a JSON value: 2-D array as rows, 1-D array as a row vector, scalar as 1x1,...
std::vector< int > int_vector_from_json(const Json &j, const std::string &where)
An integer vector; a non-integral entry is an error, never a truncation.
Json encode_matrices(const std::vector< Matrix< T > > &v)
A list of matrices, the shape the MMAP/BMAP families return as {D0,D1,...}.
T number_from_json(const Json &j, const std::string &where)
std::vector< T > vector_from_json(const Json &j, const std::string &where)
A flat numeric vector: 1-D array, or a 1-row / 1-column 2-D array.
Json encode_vector(const std::vector< T > &v)
Json encode_matrix(const Matrix< T > &m)
void register_library_only_pfqn_b(LibraryOnlyTable &t)
Json encode_scalar(const T &v)
Json encode_count(std::size_t n)
A count.
void register_api_pfqn_b(DispatchTable &t)
std::map< std::string, std::string > LibraryOnlyTable
name -> why the function has no named-JSON-argument form.
Json encode_ints(const std::vector< int > &v)
std::map< std::string, Invoker > DispatchTable
Conservation laws of a layered queueing network, enumerated from its structure.
debeMVA: MVA-based approximation of closed networks with finite (BAS) buffers.
Exact normalizing constant of a closed multiclass product-form network whose state space carries arbi...
Marie's iterative aggregation-decomposition for closed networks with FCFS general (Coxian) service.
Monte Carlo Integration estimate of the normalizing constant of a closed product-form network (Ross,...
Chen-O'Cinneide REGULARIZATION: a Markov chain Monte Carlo estimator of the class throughputs X(r) = ...
Kerola's multiclass composite bound (Perf.
McKenna-Mitra integral form of the normalizing constant of a repairman model (one queueing station,...
Sampled McKenna-Mitra integral form of the normalizing constant of a repairman (single-queue plus del...
Moment linearizer: approximate first and second queue-length moments of a large closed product-form n...
Aggregate load-dependent rate of m identical c-server FCFS stations.
Shift the load-dependent service-rate lattice of selected stations.
Exact interval-valued MVA for single-class closed product-form networks.
MVABLO: approximate MVA for closed networks with Blocking-After-Service (BAS).
MVAC: exact mean value analysis BY CHAIN of a closed multichain product-form network (Conway,...
MVAC for networks with queue-length dependent (QLD) service centers, the Section V extension of Conwa...
Exact Mean Value Analysis for mixed open/closed networks with multiserver stations.
Majumdar-Woodside robust box bounds on the per-class throughput of a closed multiclass network with m...
Normalizing constant of a product-form queueing network: the dispatcher.
Preprocessing shared by the normalizing-constant solvers: drop the classes that cannot contribute,...
Normalizing constant of a LOAD-DEPENDENT closed network: the dispatcher.
Normalizing constant of a MIXED open/closed network with limited load dependence.
Mean value analysis at a nonintegral population (fractional-base aMVA).
Norlund-Rice inversion of the normalizing constant on a SADDLE-TILTED contour, with a second-order Ed...
Norlund-Rice inversion of the normalizing constant, in its logistic (NRL) and probit (NRP) substituti...
Order-independent (OI) functional server: the balance function Psi and the rate mu_f of an auxiliary ...
OQNRC: approximate MVA for open queueing networks with restricted capacity.
Hsieh-Lam Proportional Approximation Methods (PAMB / PAMI / PAMT).
PANACEA normal-usage asymptotic expansion of the normalizing constant (Ramakrishnan and Mitra,...
PANACEA normal-usage asymptotic expansion for LOAD-DEPENDENT closed networks (Mitra and McKenna,...
Performance Bound Hierarchy (Eager and Sevcik 1983, ACM TOCS 1(2):99-115) for single-class closed pro...
Permanent of a matrix with repeated columns, by Ryser's formula.
Proportionally fair allocation estimate of the normalizing constant (Schweitzer 1979; Walton,...
QD-AMVA: queue-dependent approximate mean value analysis.
QD-LIN: the Linearizer arm of AMVA-LD, on a plain demand matrix.
Joint moments of the queue-length vector of a closed product-form network, obtained from normalizing ...
Queue-Shift Approximation (QSA) for closed product-form networks.
Geometric-bound lower bound on the queue length at station i.
Geometric-bound upper bound on the queue length at station i.
Reduction heuristic (RD) for the normalizing constant of a closed LOAD-DEPENDENT product-form network...
Sojourn-time moments at the processor-sharing station of a closed terminal-driven system (Mitra and M...
Recursion by Generating Functions (RGF) for the normalizing constant of a SINGLE-CLASS closed product...
Multiclass Recursion by Generating Functions (RGF), with think times.
Neuse-Chandy SCAT (Self-Correcting Approximation Technique) approximate MVA.
Dowdy-Carlson-Krantz-Tripathi (1992) single-class bounds of multi-class queueing networks,...
Schmidt's MVA for closed networks with general scheduling disciplines and class-dependent multiserver...
Extended Schmidt MVA with queue-aware alpha corrections.
Product-form state-dependent routing.
Exact analytic derivatives of the mean performance measures {X,Q,U,R} of a closed product-form (BCMP)...
Effective capacity terms of the mixed load-dependent MVA of Bruell-Balbo-Afshari, together with their...
Approximate moments E[Q_i], Var[Q_i], Cov[Q_i,Q_j], E[Q_i^2] and E[Q_i^3] of the per-station total qu...
Exact moments E[Q], Var[Q], E[Q^2] and E[Q^3] of the grouped queue lengths of a closed product-form n...
Exact higher queue-length moments (up to order three) of mixed open/closed product-form networks with...
Exact per-station queue-length variances and covariances of a closed product-form network,...
Exact queue-length variances and covariances of a mixed open/closed product-form network with limited...
Exact raw moments E[W^t], t = 1..3, of the sojourn time of a job at an FCFS b-server center of a clos...
Successively Improving Bounds (Srinivasan 1985/1987) on the cycle time and throughput of a single-cla...
Square-root non-iterative (SQNI) approximation for a single queueing station with per-class delay.
Server-Station Disaggregation bounds for a multiserver closed network (Dallery and Suri,...
Sojourn-time distribution at multiserver FCFS stations of a closed product-form network (J.
Heuristic sojourn-time distribution at multiserver FCFS stations, a variant of J.
Tay's arrival-instant approximate MVA.
Station consolidation and its inverse: merge identical demand rows into one station with a multiplici...
Xia's asymptotic approximation of the normalizing constant of a load-dependent (multiserver) closed n...
Asymptotic-bound-analysis lower bound on throughput.
Asymptotic-bound-analysis upper bound on throughput.
Geometric-square-root bound, lower bound on throughput.
Geometric-square-root bound, upper bound on throughput.