86Json encode_longs(
const std::vector<long>& v) {
87 Json a = Json::array();
88 for (
long x : v) a.push_back(
static_cast<long long>(x));
92Json encode_long_matrix(
const Matrix<long>& m) {
93 Json a = Json::array();
94 for (std::size_t i = 0; i < m.rows(); ++i) {
95 Json row = Json::array();
96 for (std::size_t k = 0; k < m.cols(); ++k) row.push_back(
static_cast<long long>(m(i, k)));
102Json encode_sizes(
const std::vector<std::size_t>& v) {
103 Json a = Json::array();
110Json encode_defined(
const T& v,
long count) {
115Json encode_vector_defined(
const std::vector<T>& v,
const std::vector<long>& count) {
116 Json a = Json::array();
117 for (std::size_t k = 0; k < v.size(); ++k) a.push_back(encode_defined(v[k], count[k]));
122Json encode_matrix_defined(
const Matrix<T>& m,
const Matrix<long>& count) {
123 Json a = Json::array();
124 for (std::size_t i = 0; i < m.rows(); ++i) {
125 Json row = Json::array();
126 for (std::size_t k = 0; k < m.cols(); ++k) row.push_back(encode_defined(m(i, k), count(i, k)));
132std::string where_of(
const std::string& fn,
const char* key) {
return fn +
": " + key; }
134std::vector<long> to_longs(
const std::vector<int>& v) {
return std::vector<long>(v.begin(), v.end()); }
137std::vector<std::size_t> nonneg_sizes(
const std::vector<int>& v,
const std::string& where) {
138 std::vector<std::size_t> out;
139 out.reserve(v.size());
141 if (x < 0)
throw InputError(where +
": entries must be nonnegative, got " + std::to_string(x));
142 out.push_back(
static_cast<std::size_t
>(x));
147std::vector<unsigned> nonneg_unsigned(
const std::vector<int>& v,
const std::string& where) {
148 const std::vector<std::size_t> s = nonneg_sizes(v, where);
149 return std::vector<unsigned>(s.begin(), s.end());
153std::vector<std::size_t> one_based_to_zero(
const std::vector<int>& v,
const std::string& where) {
154 std::vector<std::size_t> out;
155 out.reserve(v.size());
157 if (x < 1)
throw InputError(where +
": class labels are 1-based, got " + std::to_string(x));
158 out.push_back(
static_cast<std::size_t
>(x - 1));
163std::vector<std::size_t> one_based_sizes(
const std::vector<int>& v,
const std::string& where) {
164 std::vector<std::size_t> out;
165 out.reserve(v.size());
167 if (x < 1)
throw InputError(where +
": class labels are 1-based, got " + std::to_string(x));
168 out.push_back(
static_cast<std::size_t
>(x));
175T number_or_fill(
const Json& j,
const std::string& where,
const T& fill) {
185Matrix<T> matrix_or_fill(
const Json& j,
const std::string& where,
const T& fill) {
188 m(0, 0) = number_or_fill<T>(j, where, fill);
192 if (j[0].is_array()) {
193 const std::size_t rows = j.size(), cols = j[0].size();
194 for (std::size_t i = 0; i < rows; ++i)
195 if (!j[i].is_array() || j[i].size() != cols)
196 throw InputError(where +
": row " + std::to_string(i) +
" is not an array of " +
197 std::to_string(cols) +
" entries");
199 Matrix<T> m(rows, cols);
200 for (std::size_t i = 0; i < rows; ++i)
201 for (std::size_t k = 0; k < cols; ++k) m(i, k) = number_or_fill<T>(j[i][k], where, fill);
204 Matrix<T> m(1, j.size());
205 for (std::size_t k = 0; k < j.size(); ++k) m(0, k) = number_or_fill<T>(j[k], where, fill);
211std::vector<T> column_major(
const Matrix<T>& m) {
213 v.reserve(m.rows() * m.cols());
214 for (std::size_t c = 0; c < m.cols(); ++c)
215 for (std::size_t r = 0; r < m.rows(); ++r) v.push_back(m(r, c));
219std::string lower(std::string s) {
220 for (
char& c : s) c =
static_cast<char>(std::tolower(
static_cast<unsigned char>(c)));
224std::string string_of(
const Json& j,
const std::string& where) {
226 throw InputError(where +
": expected a string, got " + std::string(j.type_name()));
227 return j.get<std::string>();
230std::vector<std::string> strings_of(
const Json& j,
const std::string& where) {
231 if (!j.is_array())
throw InputError(where +
": expected a list of strings");
232 std::vector<std::string> out;
233 for (
const Json& e : j) out.push_back(string_of(e, where));
238bool flag_of(
const Json& j,
const std::string& where) {
239 if (j.is_boolean())
return j.get<
bool>();
241 if (v.size() != 1 || (v[0] != 0 && v[0] != 1))
242 throw InputError(where +
": expected true, false, 0 or 1");
252void read_trace_cells(
const Json& data,
const std::string& where, std::vector<std::vector<T>>& at_ms,
253 std::vector<std::vector<T>>& rt) {
254 if (!data.is_array() || data.size() < 4)
255 throw InputError(where +
": expected the 6 x (K+1) cell array, as a list of rows; rows 3 "
256 "(arrival times, ms) and 4 (response times) are read");
257 const std::size_t cols = data[0].is_array() ? data[0].size() : 0;
258 for (std::size_t r = 0; r < data.size(); ++r)
259 if (!data[r].is_array() || data[r].size() != cols)
260 throw InputError(where +
": row " + std::to_string(r + 1) +
" must have " +
261 std::to_string(cols) +
" cells, like row 1");
262 if (cols < 2)
throw InputError(where +
": at least one class column plus the trailing column");
263 const std::size_t K = cols - 1;
264 at_ms.assign(K, std::vector<T>());
265 rt.assign(K, std::vector<T>());
266 for (std::size_t k = 0; k < K; ++k) {
276#define LINE_TRACE_SCALAR_OP(Name, fn, outkey) \
279 static Json run(Args& a) { \
280 const std::vector<T> S = a.vector<T>("S"); \
283 out[outkey] = encode_scalar(line::trace::fn<T>(S)); \
293#undef LINE_TRACE_SCALAR_OP
297 static Json run(Args& a) {
298 const std::vector<T> S = a.vector<T>(
"S");
299 const bool has_lags = a.has(
"lags");
300 const std::vector<int> lags = a.ints_or_empty(
"lags");
311 static Json run(Args& a) {
312 const std::vector<T> S = a.vector<T>(
"S");
313 const std::vector<int> grid = a.ints(
"GRID");
316 Json lags = Json::array();
317 for (
const std::vector<int>& l : r.
lags) lags.push_back(
encode_ints(l));
320 out[
"BiCovLags"] = lags;
327 static Json run(Args& a) {
328 const std::vector<T> S = a.vector<T>(
"T");
329 const bool has_limit = a.has(
"limit");
330 const int limit = has_limit ? a.required_integer(
"limit") : 0;
333 const line::trace::TraceGammaResult<T> r =
344struct OpTraceIat2bins {
346 static Json run(Args& a) {
347 const std::vector<T> S = a.vector<T>(
"S");
348 const T scale = a.number<T>(
"scale");
352 out[
"C"] = encode_longs(r.
counts);
358struct OpTraceIat2counts {
360 static Json run(Args& a) {
361 const std::vector<T> S = a.vector<T>(
"S");
362 const T scale = a.number<T>(
"scale");
378 static Json run(Args& a) {
379 const std::vector<T> S = a.vector<T>(
"S");
380 const std::vector<long> kset = to_longs(a.ints(
"kset"));
381 const bool has_option = a.has(
"OPTION");
382 const std::string option = lower(a.text(
"OPTION", std::string()));
383 const bool has_n = a.has(
"n");
385 line::trace::TraceIdiResult<T> r;
388 throw InputError(
"trace_idi: 'n' is the aggregation count of OPTION 'aggregate'; "
392 }
else if (option ==
"aggregate") {
393 if (!has_n)
throw InputError(
"trace_idi: OPTION 'aggregate' needs 'n'");
394 const int n = a.required_integer(
"n");
395 if (n < 1)
throw InputError(
"trace_idi: 'n' must be a positive integer");
398 }
else if (option ==
"aggregate-mix") {
400 "trace_idi: OPTION 'aggregate-mix' is not ported; the reference branch keeps "
401 "only the statistic of its last partition (see trace_idi.h)");
403 throw InputError(
"trace_idi: OPTION must be 'aggregate', got '" + option +
"'");
407 out[
"support"] = encode_longs(r.
support);
414 static Json run(Args& a) {
415 const std::vector<T> S = a.vector<T>(
"S");
416 const std::vector<int> lag = a.ints(
"lag");
417 const std::vector<unsigned> order = nonneg_unsigned(a.ints(
"order"),
"trace_joint: order");
427 static Json run(Args& a) {
428 const std::vector<int> X = a.ints(
"X");
444struct OpTraceSummary {
446 static Json run(Args& a) {
447 const std::vector<T> S = a.vector<T>(
"m");
448 a.unsupported(
"fid",
"it is a MATLAB file identifier for the printed report; the API "
449 "returns the values instead of printing them");
472struct OpMtraceMoment {
474 static Json run(Args& a) {
475 const std::vector<T> Tv = a.vector<T>(
"T");
476 const std::vector<int> A = a.ints(
"A");
477 const std::vector<unsigned> orders = nonneg_unsigned(a.ints(
"ORDERS"),
"mtrace_moment: ORDERS");
478 const bool has_after = a.has(
"AFTER"), has_norm = a.has(
"NORM");
479 if (has_norm && !has_after)
480 throw InputError(
"mtrace_moment: NORM follows AFTER positionally; give AFTER too");
481 const bool after = has_after ? a.boolean(
"AFTER",
false) :
false;
482 const bool norm = has_norm ? a.boolean(
"NORM",
false) :
false;
499#define LINE_MTRACE_DIRECTED_MOMENT_OP(Name, fn) \
502 static Json run(Args& a) { \
503 const std::vector<T> Tv = a.vector<T>("T"); \
504 const std::vector<int> A = a.ints("A"); \
505 const std::vector<unsigned> orders = \
506 nonneg_unsigned(a.ints("ORDERS"), #fn ": ORDERS"); \
507 const bool has_norm = a.has("NORM"); \
508 const bool norm = has_norm ? a.boolean("NORM", false) : false; \
512 out["M"] = encode_matrix(has_norm ? line::trace::fn<T>(Tv, A, orders, norm) \
513 : line::trace::fn<T>(Tv, A, orders)); \
520#undef LINE_MTRACE_DIRECTED_MOMENT_OP
522#define LINE_MTRACE_CROSS_MOMENT_OP(Name, fn) \
525 static Json run(Args& a) { \
526 const std::vector<T> Tv = a.vector<T>("T"); \
527 const std::vector<int> L = a.ints("L"); \
528 const unsigned k = a.uinteger("k"); \
530 const line::trace::MtraceCrossMomentResult<T> r = \
531 line::trace::fn<T>(Tv, L, k); \
533 out["MC"] = encode_matrix_defined(r.mc, r.count); \
540#undef LINE_MTRACE_CROSS_MOMENT_OP
542struct OpMtraceCount {
544 static Json run(Args& a) {
545 const std::vector<T> Tv = a.vector<T>(
"T");
546 const std::vector<int> A = a.ints(
"A");
547 const T t = a.number<T>(
"t");
557 static Json run(Args& a) {
558 const std::vector<T> Tv = a.vector<T>(
"T");
559 const std::vector<int> A = a.ints(
"A");
562 Json c = Json::array();
563 for (
const std::vector<Matrix<T>>& row : cov) c.push_back(
encode_matrices(row));
570struct OpMtraceIat2counts {
572 static Json run(Args& a) {
573 const std::vector<T> Tv = a.vector<T>(
"T");
574 const std::vector<int> A = a.ints(
"A");
575 const T scale = a.number<T>(
"scale");
576 a.unsupported(
"no_mex",
"it selects between MATLAB's MEX and script implementations of "
577 "the same counts; the port has one implementation");
585struct OpMtraceJoint {
587 static Json run(Args& a) {
588 const std::vector<T> Tv = a.vector<T>(
"T");
589 const std::vector<int> A = a.ints(
"A");
590 const std::vector<unsigned> i = nonneg_unsigned(a.ints(
"i"),
"mtrace_joint: i");
591 if (i.size() != 2)
throw InputError(
"mtrace_joint: 'i' must hold the two orders [i1, i2]");
595 out[
"JM"] = encode_vector_defined(r.
jm, r.
count);
602 static Json run(Args& a) {
603 const std::vector<T> Tv = a.vector<T>(
"trace");
604 const int ntypes = a.required_integer(
"ntypes");
605 const std::vector<int> type = a.ints(
"type");
607 const line::trace::MtraceMeanResult<T> r =
610 out[
"m"] = encode_vector_defined(r.
mean, r.
count);
615struct OpMtraceMerge {
617 static Json run(Args& a) {
618 const std::vector<T> t1 = a.vector<T>(
"t1");
619 const std::vector<T> t2 = a.vector<T>(
"t2");
630void refuse_unused_times(
Args& a,
const char* fn) {
632 throw InputError(std::string(fn) +
": 'T' is not read by the reference, whose result "
633 "depends on the labels L alone; omit it");
639 static Json run(Args& a) {
640 const std::vector<int> C = a.ints(
"C");
648struct OpMtraceSigma {
650 static Json run(Args& a) {
651 refuse_unused_times(a,
"mtrace_sigma");
652 const std::vector<int> L = a.ints(
"L");
661struct OpMtraceSigma2 {
663 static Json run(Args& a) {
664 refuse_unused_times(a,
"mtrace_sigma2");
665 const std::vector<int> L = a.ints(
"L");
668 const std::size_t C = s.rows();
669 Json cube = Json::array();
670 for (std::size_t i = 0; i < C; ++i) {
671 Json plane = Json::array();
672 for (std::size_t j = 0; j < C; ++j) {
673 Json row = Json::array();
674 for (std::size_t h = 0; h < C; ++h) row.push_back(
encode_scalar(s(i, j * C + h)));
675 plane.push_back(row);
677 cube.push_back(plane);
685struct OpMtraceSplit {
687 static Json run(Args& a) {
688 const std::vector<T> Tv = a.vector<T>(
"T");
689 const std::vector<int> L = a.ints(
"L");
697struct OpMtraceSummary {
699 static Json run(Args& a) {
700 const std::vector<T> Tv = a.vector<T>(
"T");
701 const std::vector<int> C = a.ints(
"C");
725struct OpInferComputeQlAtArrival {
727 static Json run(Args& a) {
728 const std::vector<T> at = a.vector<T>(
"at");
729 const std::vector<long> at_jobid = to_longs(a.ints(
"at_jobid"));
730 const std::vector<T> rt = a.vector<T>(
"rt");
731 const std::vector<long> rt_jobid = to_longs(a.ints(
"rt_jobid"));
732 const std::vector<std::size_t> cls =
733 one_based_to_zero(a.ints(
"class"),
"infer_compute_ql_at_arrival: class");
734 const std::size_t R = a.count(
"R");
743struct OpInferGetQlenArrival {
745 static Json run(Args& a) {
746 std::vector<std::vector<T>> at_ms, rt;
747 read_trace_cells<T>(a.get(
"data"),
"infer_get_qlen_arrival: data", at_ms, rt);
755struct OpInferLqnFindbyname {
757 static Json run(Args& a) {
758 const Json& container = a.get(
"container");
759 const std::string
name = string_of(a.get(
"name"),
"infer_lqn_findbyname: name");
761 if (!container.is_array())
762 throw InputError(
"infer_lqn_findbyname: 'container' must be a list of elements");
763 std::vector<std::string> names;
764 for (std::size_t k = 0; k < container.size(); ++k) {
765 const Json& e = container[k];
766 if (!e.is_object() || e.find(
"name") == e.end())
767 throw InputError(
"infer_lqn_findbyname: container entry " + std::to_string(k + 1) +
768 " has no 'name' field");
769 names.push_back(string_of(e[
"name"],
"infer_lqn_findbyname: container.name"));
778struct OpInferLqnGetobs {
780 static Json run(Args& a) {
781 const std::vector<std::string> names = strings_of(a.get(
"names"),
"infer_lqn_getobs: names");
782 const Json& mj = a.get(
"metrics");
783 const Json& sj = a.get(
"obsSpec");
785 line::infer::LqnMetrics<T> m;
787 Args ma(mj,
"infer_lqn_getobs: metrics");
788 m.
QLen = ma.vector_or_empty<T>(
"QLen");
789 m.
Util = ma.vector_or_empty<T>(
"Util");
790 m.
RespT = ma.vector_or_empty<T>(
"RespT");
791 m.
Tput = ma.vector_or_empty<T>(
"Tput");
794 if (!sj.is_array())
throw InputError(
"infer_lqn_getobs: 'obsSpec' must be a list of {metric, name}");
795 std::vector<line::infer::LqnObsSpec> spec;
796 for (
const Json& e : sj) {
797 Args ea(e,
"infer_lqn_getobs: obsSpec");
798 const std::string metric = lower(string_of(ea.get(
"metric"),
"infer_lqn_getobs: obsSpec.metric"));
799 line::infer::LqnObsSpec s;
800 s.
name = string_of(ea.get(
"name"),
"infer_lqn_getobs: obsSpec.name");
802 if (metric ==
"respt")
804 else if (metric ==
"util")
806 else if (metric ==
"tput")
808 else if (metric ==
"qlen")
811 throw InputError(
"infer_lqn_getobs: Unknown metric '" + metric +
"'.");
822 static Json run(Args& a) {
823 const Matrix<T> Q = a.matrix<T>(
"Q");
824 const std::vector<T> N = a.vector<T>(
"N");
825 const std::vector<T> Z = a.vector<T>(
"Z");
835 static Json run(Args& a) {
836 const std::vector<T> rt = a.vector<T>(
"rt");
837 const std::vector<std::size_t> cls = one_based_to_zero(a.ints(
"class"),
"infer_rps: class");
838 const Matrix<T> ql = a.matrix<T>(
"ql");
839 const int V = a.required_integer(
"V");
852struct OpInferQuickModel {
854 static Json run(Args& a) {
855 const bool is_open = flag_of(a.get(
"open"),
"infer_quick_model: open");
856 std::vector<lang::SchedStrategy> stations;
857 for (
const std::string& s : strings_of(a.get(
"stations"),
"infer_quick_model: stations"))
858 stations.push_back(io::detail::sched_from_json(s));
859 const Matrix<T> demands = a.matrix<T>(
"classes");
860 const bool has_servers = a.has(
"servers"), has_jobs = a.has(
"jobs"),
861 has_routing = a.has(
"routing");
862 if (has_jobs && !has_servers)
863 throw InputError(
"infer_quick_model: 'jobs' follows 'servers' positionally; give servers too");
864 if (has_routing && !(has_servers && has_jobs))
865 throw InputError(
"infer_quick_model: 'routing' follows 'servers' and 'jobs' "
866 "positionally; give both");
867 if (has_routing && is_open)
868 throw InputError(
"infer_quick_model: 'routing' applies to a closed model; an open "
869 "model is routed serially from the source to the sink");
870 const std::vector<double> servers = a.vector_or_empty<
double>(
"servers");
871 const std::vector<double> jobs = a.vector_or_empty<
double>(
"jobs");
872 std::vector<Matrix<T>> routing;
874 const Json& rj = a.get(
"routing");
875 const bool cell_form = rj.is_array() && !rj.empty() && rj[0].is_array() &&
876 !rj[0].empty() && rj[0][0].is_array();
878 routing = a.matrices<T>(
"routing");
880 const Matrix<T>
P = a.matrix<T>(
"routing");
881 routing.assign(demands.rows(), P);
885 qn::Network<T> model =
887 : has_jobs ? line::infer::
infer_quick_model<T>(is_open, stations, demands, servers, jobs)
888 : has_servers ? line::infer::
infer_quick_model<T>(is_open, stations, demands, servers)
901struct OpInferNhppKs {
903 static Json run(Args& a) {
904 const std::vector<T> times = a.vector<T>(
"times");
905 const T Tend = a.number<T>(
"T");
906 a.unsupported(
"cumRate",
"it is a function handle; without it the rate is taken "
907 "constant over the interval");
908 const bool has_method = a.has(
"method"), has_t0 = a.has(
"T0");
909 const std::string m = lower(a.text(
"method", std::string()));
910 if (has_t0 && !has_method)
911 throw InputError(
"infer_nhpp_ks: the port takes T0 after method; give 'method' too");
912 line::infer::NhppKsResult<T> r;
920 else if (m ==
"lewis")
923 throw InputError(
"infer_nhpp_ks: method must be 'cu' or 'lewis'");
924 const std::function<T(
const T&)> constant;
926 const T t0 = a.number<T>(
"T0");
949Json encode_smp_fit(
const line::infer::SmpFit& f) {
950 Json arcs = Json::array();
951 for (
const line::infer::SmpArc& c : f.
arcs) {
976std::vector<double> doubles_nan(
const Json& j,
const std::string& where) {
977 const Matrix<double> m = matrix_or_fill<double>(j, where, std::numeric_limits<double>::quiet_NaN());
978 return column_major(m);
982line::infer::SmpFit read_smp_fit(
const Json& j) {
983 const std::string w =
"infer_smp_hazard: fit";
985 line::infer::SmpFit fit;
986 fit.
approach = string_of(f.get(
"approach"), w +
".approach");
987 fit.
nstates = f.count(
"nstates");
988 fit.
ncov = f.count(
"ncov");
989 fit.
loglik = number_or_fill<double>(f.get(
"loglik"), w +
".loglik",
990 std::numeric_limits<double>::quiet_NaN());
991 fit.
nparams = f.count(
"nparams");
992 fit.
aic = number_or_fill<double>(f.get(
"aic"), w +
".aic", std::numeric_limits<double>::quiet_NaN());
993 fit.
P = matrix_or_fill<double>(f.get(
"P"), w +
".P", std::numeric_limits<double>::quiet_NaN());
994 const Json& arcs = f.get(
"arcs");
996 if (!arcs.is_array())
throw InputError(w +
".arcs: expected a list of arcs");
997 for (
const Json& e : arcs) {
998 Args c(e, w +
".arcs");
999 line::infer::SmpArc arc;
1000 arc.
from = c.count(
"from");
1001 arc.
to = c.count(
"to");
1002 arc.
family = string_of(c.get(
"family"), w +
".arcs.family");
1003 arc.
theta = doubles_nan(c.get(
"theta"), w +
".arcs.theta");
1004 arc.
params = doubles_nan(c.get(
"params"), w +
".arcs.params");
1005 arc.
beta = doubles_nan(c.get(
"beta"), w +
".arcs.beta");
1006 arc.
se = doubles_nan(c.get(
"se"), w +
".arcs.se");
1007 arc.
prob = number_or_fill<double>(c.get(
"prob"), w +
".arcs.prob",
1008 std::numeric_limits<double>::quiet_NaN());
1009 arc.
nevents = c.count(
"nevents");
1011 fit.
arcs.push_back(arc);
1017 static Json run(Args& a) {
1018 const std::string w =
"infer_smp";
1019 const std::vector<std::size_t> from = nonneg_sizes(a.ints(
"from"), w +
": from");
1020 const std::vector<std::size_t> to = nonneg_sizes(a.ints(
"to"), w +
": to");
1021 const std::vector<double> dur = a.vector<
double>(
"dur");
1022 line::infer::SmpOptions opt;
1023 if (a.has(
"approach")) opt.approach = lower(a.text(
"approach", std::string()));
1024 if (
const Json* d = a.opt(
"dist")) {
1025 if (d->is_string()) {
1026 opt.dist = lower(d->get<std::string>());
1028 if (!d->is_array())
throw InputError(w +
": 'dist' must be a family name or an E x E table of them");
1029 for (
const Json& row : *d) {
1030 if (!row.is_array())
throw InputError(w +
": 'dist' table rows must be lists");
1031 std::vector<std::string> r;
1032 for (
const Json& e : row) r.push_back(e.is_null() ? std::string() : lower(string_of(e, w +
": dist")));
1033 opt.dist_table.push_back(r);
1037 if (a.has(
"covariates")) opt.covariates = a.matrix<
double>(
"covariates");
1038 if (
const Json* cm = a.opt(
"covmask")) {
1039 if (!cm->is_array())
throw InputError(w +
": 'covmask' must be an E x E x p array");
1040 for (
const Json& plane : *cm) {
1041 if (!plane.is_array())
throw InputError(w +
": 'covmask' must be an E x E x p array");
1042 std::vector<std::vector<bool>> p;
1043 for (
const Json& row : plane) {
1044 if (!row.is_array())
throw InputError(w +
": 'covmask' must be an E x E x p array");
1045 std::vector<bool> r;
1046 for (
const Json& e : row) r.push_back(flag_of(e, w +
": covmask"));
1049 opt.covmask.push_back(p);
1052 if (a.has(
"nstates")) opt.nstates = a.count(
"nstates");
1053 if (a.has(
"tolx")) opt.tolx = a.number<
double>(
"tolx");
1054 if (a.has(
"tolf")) opt.tolf = a.number<
double>(
"tolf");
1055 if (a.has(
"maxiter")) opt.maxiter = a.count(
"maxiter");
1057 a.opt(
"covariates");
1069struct OpInferSmpHazard {
1070 static Json run(Args& a) {
1071 const line::infer::SmpFit fit = read_smp_fit(a.get(
"fit"));
1072 const std::vector<double> t = a.vector<
double>(
"t");
1073 const bool has_z = a.has(
"z");
1074 const std::vector<double>
z = a.vector_or_empty<
double>(
"z");
1076 const std::vector<line::infer::SmpHazard> h =
1078 Json hz = Json::array();
1079 for (
const line::infer::SmpHazard& e : h) {
1095struct OpInferSmpNelsonAalen {
1096 static Json run(Args& a) {
1097 const std::string w =
"infer_smp_nelson_aalen";
1098 const std::vector<std::size_t> from = nonneg_sizes(a.ints(
"from"), w +
": from");
1099 const std::vector<std::size_t> to = nonneg_sizes(a.ints(
"to"), w +
": to");
1100 const std::vector<double> dur = a.vector<
double>(
"dur");
1101 const bool has_e = a.has(
"nstates");
1102 const std::size_t E = has_e ? a.count(
"nstates") : 0;
1105 const std::vector<line::infer::SmpNelsonAalen> r =
1108 Json na = Json::array();
1109 for (
const line::infer::SmpNelsonAalen& e : r) {
1128struct OpInferSmpFamily {
1129 static Json run(Args& a) {
1130 const std::string w =
"infer_smp_family";
1131 const std::string family = string_of(a.get(
"family"), w +
": family");
1132 const std::string mode = string_of(a.get(
"mode"), w +
": mode");
1135 auto theta = [&]() {
1136 const std::vector<double> th = a.vector<
double>(
"THETA");
1137 if (th.size() != npar)
1138 throw InputError(w +
": THETA must have " + std::to_string(npar) +
" entries for '" +
1143 if (mode ==
"npar") {
1146 }
else if (mode ==
"logfs") {
1147 const std::vector<double> th = theta();
1148 const std::vector<double> t = a.vector<
double>(
"T");
1149 const std::vector<double> eta = a.vector_or_empty<
double>(
"ETA");
1150 if (eta.size() > 1 && eta.size() != t.size())
1151 throw InputError(w +
": ETA must be a scalar or have one entry per instant of T");
1153 std::vector<double> logf, logS;
1157 }
else if (mode ==
"natural") {
1158 const std::vector<double> th = theta();
1161 }
else if (mode ==
"theta0") {
1162 const std::vector<double> tev = a.vector<
double>(
"TEV");
1163 const double texp = a.number<
double>(
"TEXP");
1166 }
else if (mode ==
"dist") {
1167 const std::vector<double> th = theta();
1168 const double eta = a.number<
double>(
"ETA");
1172 throw InputError(w +
": Unknown mode '" + mode +
1173 "': use 'npar', 'logfs', 'natural', 'theta0' or 'dist'.");
1187struct OpInferVariational {
1189 static Json run(Args& a) {
1190 const std::string w =
"infer_variational";
1191 const Json& sj = a.get(
"spec");
1192 const Json* oj = a.opt(
"options");
1194 const T nan = num_traits<T>::from_double(std::numeric_limits<double>::quiet_NaN());
1195 const T inf = num_traits<T>::from_double(std::numeric_limits<double>::infinity());
1197 line::infer::VariationalSpec<T> spec;
1199 Args s(sj, w +
": spec");
1200 const Matrix<T> arcs = s.matrix<T>(
"arcs");
1201 if (!arcs.empty() && arcs.cols() != 3)
1202 throw InputError(w +
": spec.arcs must have three columns [i j c].");
1204 const std::vector<std::size_t> arcsz = nonneg_sizes(arcint, w +
": spec.arcs");
1205 for (std::size_t e = 0; e < arcs.rows(); ++e)
1206 spec.
arcs.push_back(std::array<std::size_t, 3>{arcsz[3 * e], arcsz[3 * e + 1], arcsz[3 * e + 2]});
1207 spec.
x0 = s.matrix<T>(
"x0");
1208 spec.
sched = s.ints(
"sched");
1209 spec.
nservers = s.vector<T>(
"nservers");
1210 spec.
routeprob = s.vector<T>(
"routeprob");
1211 spec.
arcparam = nonneg_sizes(s.ints(
"arcparam"), w +
": spec.arcparam");
1212 spec.
arcrate = column_major(matrix_or_fill<T>(s.get(
"arcrate"), w +
": spec.arcrate", nan));
1213 spec.
alpha0 = s.vector<T>(
"alpha0");
1214 spec.
beta0 = s.vector<T>(
"beta0");
1215 spec.
obsTimes = s.vector<T>(
"obsTimes");
1216 spec.
obsData = matrix_or_fill<T>(s.get(
"obsData"), w +
": spec.obsData",
1218 spec.
obsRange = column_major(s.matrix<T>(
"obsRange"));
1219 spec.
epsilon = s.number<T>(
"epsilon");
1220 if (
const Json* c = s.opt(
"capacity"))
1221 spec.
capacity = column_major(matrix_or_fill<T>(*c, w +
": spec.capacity", inf));
1224 line::infer::VariationalOptions<T> opt;
1226 Args o(*oj, w +
": options");
1227 if (o.has(
"verbose")) opt.
verbose = o.required_integer(
"verbose");
1228 if (o.has(
"iter_max")) opt.
iter_max = o.count(
"iter_max");
1229 if (o.has(
"tol")) opt.
tol = o.number<
double>(
"tol");
1230 if (o.has(
"nsamples")) opt.
nsamples = o.count(
"nsamples");
1231 if (o.has(
"delta")) opt.
delta = o.number<
double>(
"delta");
1232 if (o.has(
"floor")) opt.
floor = o.number<
double>(
"floor");
1233 if (o.has(
"rate_max")) opt.
rate_max = o.number<
double>(
"rate_max");
1234 if (o.has(
"rate_cap_factor")) opt.
rate_cap_factor = o.number<
double>(
"rate_cap_factor");
1235 if (o.has(
"unifmax")) opt.
unifmax = o.number<
double>(
"unifmax");
1236 if (o.has(
"unif_tol")) opt.
unif_tol = o.number<
double>(
"unif_tol");
1237 if (o.has(
"unif_max_terms")) opt.
unif_max_terms = o.count(
"unif_max_terms");
1238 if (o.has(
"tmax")) opt.
tmax = o.number<
double>(
"tmax");
1239 if (o.has(
"dt")) opt.
dt = o.number<
double>(
"dt");
1240 if (o.has(
"ngrid")) opt.
ngrid =
static_cast<long>(o.count(
"ngrid"));
1241 if (o.has(
"ymax")) opt.
ymax =
static_cast<long>(o.count(
"ymax"));
1242 for (
const char* k : {
"verbose",
"iter_max",
"tol",
"nsamples",
"delta",
"floor",
1243 "rate_max",
"rate_cap_factor",
"unifmax",
"unif_tol",
1244 "unif_max_terms",
"tmax",
"dt",
"ngrid",
"ymax"})
1248 const line::infer::VariationalResult<T> r =
1273const char*
const kMlpsModelWhy =
1274 "the reference reads the delay rates and the server count off the model; pass them as "
1275 "'muZ' (per-class think rates) and 'nCores' instead";
1277std::vector<line::api::MlpsSample> read_mlps_samples(
Args& a,
const std::string& w) {
1278 const std::vector<double> rt = a.vector<
double>(
"rt");
1279 const std::vector<std::size_t> cls = one_based_sizes(a.ints(
"class"), w +
": class");
1280 const Matrix<double> ql = a.matrix<
double>(
"ql");
1281 if (cls.size() != rt.size() || ql.rows() != rt.size())
1282 throw InputError(w +
": rt, class and ql must have one row per sample");
1283 std::vector<line::api::MlpsSample> samples(rt.size());
1284 for (std::size_t i = 0; i < rt.size(); ++i) {
1285 samples[i].rt = rt[i];
1286 samples[i].cls = cls[i];
1287 samples[i].ql.resize(ql.cols());
1288 for (std::size_t c = 0; c < ql.cols(); ++c) samples[i].ql[c] = ql(i, c);
1294 static Json run(Args& a) {
1295 a.unsupported(
"model", kMlpsModelWhy);
1296 a.unsupported(
"node", kMlpsModelWhy);
1297 const std::vector<double> muZ = a.vector<
double>(
"muZ");
1298 const double nCores = a.number<
double>(
"nCores");
1299 const std::vector<line::api::MlpsSample> samples = read_mlps_samples(a,
"infer_mlps");
1312struct OpInferMinpsSetup {
1313 static Json run(Args& a) {
1314 const std::string w =
"infer_minps_setup";
1315 a.unsupported(
"model", kMlpsModelWhy);
1316 a.unsupported(
"node", kMlpsModelWhy);
1318 throw InputError(w +
": 'V' is not read by the reference, which takes the server count "
1319 "from the node; pass it as 'nCores'");
1321 std::vector<std::vector<double>> at_ms, rt;
1322 read_trace_cells<double>(a.get(
"data"), w +
": data", at_ms, rt);
1323 std::vector<line::api::MinpsClassTrace> traces(at_ms.size());
1324 for (std::size_t k = 0; k < at_ms.size(); ++k) {
1325 traces[k].arrival_ms = at_ms[k];
1326 traces[k].rt = rt[k];
1328 const std::size_t initSample = a.count(
"initSample");
1329 const std::size_t sampleSize = a.count(
"sampleSize");
1330 const std::vector<double> muZ = a.vector<
double>(
"muZ");
1331 const double nCores = a.number<
double>(
"nCores");
1334 if (muZ.size() != st.
classMap.size())
1335 throw InputError(w +
": 'muZ' must have one entry per class with samples (" +
1336 std::to_string(st.
classMap.size()) +
"), in the order of classMap");
1341 out[
"classMap"] = encode_sizes(st.
classMap);
1355struct OpInferGibbs {
1356 static Json run(Args& a) {
1357 const std::string w =
"infer_gibbs";
1358 const Json& data = a.get(
"data");
1359 std::vector<std::vector<double>> at_ms, rt;
1360 read_trace_cells<double>(data, w +
": data", at_ms, rt);
1361 if (data.size() < 6)
1362 throw InputError(w +
": data needs row 6 (the think-time observations) as well as "
1364 std::vector<line::infer::GibbsTrace<double>> traces(at_ms.size());
1365 for (std::size_t k = 0; k < at_ms.size(); ++k) {
1366 traces[k].arrival_ms = at_ms[k];
1367 traces[k].respt_s = rt[k];
1368 traces[k].think_obs =
1371 const double nbCores = a.number<
double>(
"nbCores");
1372 const double tol = a.scalar<
double>(
"tol", 1e-3);
1436 t[
"infer_lqn_jacobian"] =
1437 "its first argument hfun is a function handle (the LQN observation map), which JSON "
1439 t[
"infer_lqn_ekf"] =
1440 "its first argument hfun is a function handle (the LQN observation map), which JSON "
1443 "it calibrates a LayeredNetwork model in place through a solver callable; no line-cli "
1444 "analysis serves LQN inference yet.";
1445 t[
"infer_lqn_setparams"] =
1446 "it writes parameters into a LayeredNetwork model object in place; there is no data "
1447 "result to return.";
1449 "it reads the Network model and the station node (NetworkStruct), not a data argument; "
1450 "no line-cli analysis serves demand inference yet.";
1451 t[
"infer_smp_env"] =
1452 "it takes the per-stage Network models and returns an Environment model object; solve "
1453 "the resulting environment with line-cli -s env.";
Internal to the –api dispatcher: what a per-domain translation unit needs to add entries to the table...
#define LINE_MTRACE_DIRECTED_MOMENT_OP(Name, fn)
#define LINE_MTRACE_CROSS_MOMENT_OP(Name, fn)
#define LINE_TRACE_SCALAR_OP(Name, fn, outkey)
UnsupportedError(const std::string &what)
Named-argument reader over the parsed JSON object.
Per-class queue lengths seen by each arriving job, reconstructed from arrival and response time sampl...
Per-class queue lengths at arrival for the per-class sample format.
Gibbs sampling demand estimator for a closed delay-plus-queue model.
First element of a named LQN container matching a name.
Observation vector of a solved LQN, z = h(a).
Turn a raw per-class trace into the sample set MINPS estimates from.
Maximum-likelihood service-demand estimation at a processor-sharing queue.
Kolmogorov-Smirnov tests for a non-homogeneous Poisson arrival process.
Queue-length-based maximum-likelihood estimator of the service demands of a closed queueing network.
Convenience factory for the single-layer networks the inference estimators fit.
Regression for Processor Sharing (RPS) demand estimator.
Maximum-likelihood fit of a parametric semi-Markov multi-state model.
Variational inference for Markovian queueing networks.
Backward moments of a marked trace: the moments of the inter-arrival time that PRECEDES an event of e...
Per-class count process of a marked trace on a fixed resolution: the number of events of each class i...
Class-pair covariance matrices of a marked trace.
Class-pair cross moments of a marked trace: the k-th moment of the interval that separates an event o...
Forward moments of a marked trace: the moments of the inter-arrival time that FOLLOWS an event of eac...
Per-class counting processes of a marked trace: for each arrival, how many events of each class fall ...
Class-dependent joint moments of a marked trace,.
Per-type sample mean of a trace.
Superposes two single-class traces into one marked trace, labelling the events of the first stream 1 ...
Empirical class-dependent moments of a marked trace.
Class-pair cross moments of a marked trace.
Class probabilities of a marked trace, p_c = count_c / N.
Two-step class transition frequencies of a marked trace,.
One-step class transition frequencies of a marked trace,.
Splits a marked trace into its per-class traces: for each class, the inter-arrival times BETWEEN CONS...
Descriptor set of a marked trace: the first five raw moments of the inter-arrival times,...
std::vector< double > infer_minps(const std::vector< double > &muZ, double nCores, const std::vector< MlpsSample > &samples)
MINPS: run MLPS and RPS and keep whichever gives the smaller mean demand.
std::vector< double > infer_mlps(const std::vector< double > &muZ, double nCores, const std::vector< MlpsSample > &samples)
MLPS demand estimation at a PS queue.
MinpsSetup infer_minps_setup(const std::vector< MinpsClassTrace > &traces, std::size_t initSample, std::size_t sampleSize)
Turn a raw per-class trace into the sample set MINPS estimates from.
NhppKsResult< Tv > infer_nhpp_ks(const std::vector< Tv > ×, const Tv &T, const std::function< Tv(const Tv &)> &cumRate=std::function< Tv(const Tv &)>(), NhppKsMethod method=NhppKsMethod::Lewis, const Tv &T0=num_traits< Tv >::from_int(0))
Kolmogorov-Smirnov tests for a non-homogeneous Poisson arrival process.
static const std::size_t INFER_LQN_NOT_FOUND
Returned when no element carries the requested name, MATLAB's [].
std::size_t infer_smp_family_npar(const std::string &family)
infer_smp_family(F, 'npar'): the number of parameters, validating the name.
VariationalResult< T > infer_variational(VariationalSpec< T > spec, VariationalOptions< T > opt=VariationalOptions< T >())
Run the variational inference procedure.
std::vector< SmpHazard > infer_smp_hazard(const SmpFit &fit, const std::vector< double > &t, const std::vector< double > &zin=std::vector< double >())
infer_smp_hazard(fit, t, 'z', z): both hazard functions of every arc of a fit on the ascending instan...
std::vector< T > infer_rps(const std::vector< T > &rt, const std::vector< std::size_t > &cls, const Matrix< T > &ql, long V)
Regression for Processor Sharing (RPS) demand estimator.
std::vector< double > infer_smp_family_natural(const std::string &family, const std::vector< double > &th)
infer_smp_family(F, 'natural', THETA): rate | shape, scale | mu, sigma.
qn::Network< T > infer_quick_model(bool is_open, const std::vector< lang::SchedStrategy > &stations, const Matrix< T > &demands, const std::vector< double > &servers=std::vector< double >(), const std::vector< double > &jobs=std::vector< double >(), const std::vector< Matrix< T > > &routing=std::vector< Matrix< T > >())
Build a simple open or closed queueing network.
void infer_smp_family_logfs(const std::string &family, const std::vector< double > &th, const std::vector< double > &t, const std::vector< double > &eta, std::vector< double > &logf, std::vector< double > &logS)
infer_smp_family(F, 'logfs', THETA, T, ETA): log density and log survival at t under the proportional...
std::size_t infer_lqn_findbyname(const std::vector< std::string > &names, const std::string &name)
First element of a named LQN container matching a name.
std::vector< T > infer_gibbs(const std::vector< GibbsTrace< T > > &data, const T &nbCores, const GibbsOptions &opts, pfqn::McRng &rng)
Estimated per-class mean demands.
Matrix< T > infer_qmle(const Matrix< T > &Q, const std::vector< T > &N, const std::vector< T > &Z)
Queue-length-based maximum-likelihood estimator of the service demands of a closed queueing network.
lang::Distrib< double > infer_smp_family_dist(const std::string &family, const std::vector< double > &th, double eta)
infer_smp_family(F, 'dist', THETA, ETA): the LINE distribution of the law with hazard h0(t) exp(eta).
std::vector< double > infer_smp_family_theta0(const std::string &family, const std::vector< double > &tev, double texp)
infer_smp_family(F, 'theta0', TEV, TEXP): the starting point from the event times tev and the total e...
std::vector< Matrix< T > > infer_get_qlen_arrival(const std::vector< std::vector< T > > &at_ms, const std::vector< std::vector< T > > &rt)
Per-class queue lengths at arrival for the per-class sample format.
NhppKsMethod
Which test to run on the conditional-uniform data.
std::vector< T > infer_lqn_getobs(const std::vector< std::string > &names, const LqnMetrics< T > &metrics, const std::vector< LqnObsSpec > &spec)
Observation vector of a solved LQN, z = h(a).
Matrix< T > infer_compute_ql_at_arrival(const std::vector< T > &at, const std::vector< long > &at_jobid, const std::vector< T > &rt, const std::vector< long > &rt_jobid, const std::vector< std::size_t > &cls, std::size_t R)
Per-class queue lengths seen by each arriving job, reconstructed from arrival and response time sampl...
SmpFit infer_smp(const std::vector< std::size_t > &from, const std::vector< std::size_t > &to, const std::vector< double > &dur, const SmpOptions &opt=SmpOptions())
infer_smp(from, to, dur, ...): the fit, under opt.approach.
std::vector< SmpNelsonAalen > infer_smp_nelson_aalen(const std::vector< std::size_t > &from, const std::vector< std::size_t > &to, const std::vector< double > &dur, std::size_t nstates=0)
infer_smp_nelson_aalen(from, to, dur, 'nstates', E): the Nelson-Aalen estimate of the cumulative tran...
detail::json network_json_envelope(const qn::NetworkStruct< T > &sn)
The complete model.json envelope: {format, version, model}.
std::string name(const Element *el, const std::string &key="name")
std::mt19937_64 McRng
The generator type every Monte Carlo entry point in this tree accepts.
void register_library_only_trace(LibraryOnlyTable &t)
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.
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_api_trace(DispatchTable &t)
Json encode_scalar(const T &v)
Json encode_count(std::size_t n)
A count.
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
MtraceCountResult< T > mtrace_count(const std::vector< T > &Tv, const std::vector< int > &A, const T &t)
Per-class count process of a marked trace on a fixed resolution: the number of events of each class i...
MtraceJointResult< T > mtrace_joint(const std::vector< T > &Tv, const std::vector< int > &A, unsigned i1, unsigned i2)
Class-dependent joint moments of a marked trace, JM(a) = (1/N_a) sum_{j : A_{j+1} = a}...
MtraceMeanResult< T > mtrace_mean(const std::vector< T > &Tv, long ntypes, const std::vector< int > &type)
Per-type sample mean of a trace.
TraceBicovResult< T > trace_bicov(const std::vector< T > &S, const std::vector< int > &grid)
Bicovariance of a trace on a lag grid.
TraceSummary< T > trace_summary(const std::vector< T > &S)
Descriptive summary of a trace: moments, shape, order statistics, autocorrelation and burstiness.
std::vector< std::vector< Matrix< T > > > mtrace_cov(const std::vector< T > &Tv, const std::vector< int > &A)
Class-pair covariance matrices of a marked trace.
TracePmfResult< T > trace_pmf(const std::vector< int > &X)
Empirical probability mass function of a discrete trace (counts, batch sizes, queue-length samples).
TraceBinsResult trace_iat2bins(const std::vector< T > &S, const T &scale)
Bins a trace on a fixed time grid: the number of arrivals falling in each interval ((i-1)*scale,...
Matrix< T > mtrace_sigma2(const std::vector< int > &L)
Two-step class transition frequencies of a marked trace, sigma(i,j,h) = #{t : A_t = i,...
MtraceMergeResult< T > mtrace_merge(const std::vector< T > &t1, const std::vector< T > &t2)
Superposes two single-class traces into one marked trace, labelling the events of the first stream 1 ...
MtraceSummary< T > mtrace_summary(const std::vector< T > &Tv, const std::vector< int > &A, int max_lag=100)
Descriptor set of a marked trace: the first five raw moments of the inter-arrival times,...
MtraceCountsResult< T > mtrace_iat2counts(const std::vector< T > &Tv, const std::vector< int > &A, const T &scale)
Per-class counting processes of a marked trace: for each arrival, how many events of each class fall ...
TraceGammaResult< T > trace_gamma(const std::vector< T > &S, long limit=1000, const std::vector< T > &grid=std::vector< T >())
Autocorrelation decay rate of a trace: the gamma of the geometric model rho(k) = rho0 * gamma^k,...
MtraceSplitResult< T > mtrace_split(const std::vector< T > &Tv, const std::vector< int > &L)
Splits a marked trace into its per-class traces: for each class, the inter-arrival times BETWEEN CONS...
std::vector< T > mtrace_pc(const std::vector< int > &A)
Class probabilities of a marked trace, p_c = count_c / N.
Matrix< T > mtrace_moment(const std::vector< T > &Tv, const std::vector< int > &A, const std::vector< unsigned > &orders, bool after=false, bool norm=false)
Empirical class-dependent moments of a marked trace.
TraceIdiResult< T > trace_idi(const std::vector< T > &S, const std::vector< long > &k_set, long aggregate_n=0, bool drop_trailing_zero=false)
Index of dispersion for intervals, IDI(k) = k * var(S_t + ... + S_{t+k-1}) / mean(S_t + ....
T trace_joint(const std::vector< T > &S, const std::vector< int > &lag, const std::vector< unsigned > &order)
Joint moments of a trace, E[X_i^{k_1} X_{i+l_2}^{k_2} ...].
Matrix< T > mtrace_sigma(const std::vector< int > &L)
One-step class transition frequencies of a marked trace, sigma(i,j) = #{t : A_t = i,...
std::vector< T > trace_acf(const std::vector< T > &S, const std::vector< int > &lags)
Autocorrelation coefficients of a trace at the requested lags.
std::vector< long > trace_iat2counts(const std::vector< T > &S, const T &scale)
Counting process of a trace: the number of arrivals in the window of length scale that starts at each...
Conservation laws of a layered queueing network, enumerated from its structure.
Reader for the LINE model.json interchange (a Network model) into a qn::Network<T> built through the ...
qn::NetworkStruct -> model.json, the inverse of network_reader.h.
std::vector< double > lambda
per-surviving-class think-time rate
std::vector< MlpsSample > samples
sorted by arrival time, window applied
std::vector< std::size_t > classMap
Original 1-based class label of each surviving class, in the new order.
double threads
Wexp, the largest total queue length seen.
T statistic
the KS distance
std::vector< T > uniforms
after the conditional-uniform transformation
std::size_t n
number of arrivals used
T pvalue
asymptotic p-value
std::vector< T > transformed
after the Durbin step, for the Lewis test
std::vector< double > beta
p covariate effects, zero where masked out
std::vector< double > theta
unconstrained parameters
std::vector< double > se
standard errors of [theta; beta]
std::vector< double > params
natural parameters
double prob
Approach I: p_ij; Approach II: the embedded probability at z = 0.
Matrix< double > P
E x E embedded jump chain at z = 0.
std::vector< SmpArc > arcs
std::size_t unif_max_terms
double delta
rate added to every feasible transition by the space expansion.
double rate_max
cap on the variational rates; derived from ymax and tmax when negative.
std::vector< Matrix< T > > nu
std::vector< Matrix< T > > Y
std::vector< T > mean_service_time
std::vector< T > obsRange
(M*R) support size of the uniform contamination.
std::vector< T > arcrate
(T) known rate for transitions with arcparam == 0.
std::vector< T > capacity
(M*R) upper bound on the queue length, empty for none.
std::vector< std::size_t > arcparam
(T) index in 1..P of the rate governing the transition, 0 when known.
Matrix< T > x0
(M x R) initial queue lengths.
Matrix< T > obsData
(K x M*R) observed queue lengths; an unobserved entry is unobserved.
static T unobserved()
Sentinel marking an unobserved entry of obsData.
std::vector< std::array< std::size_t, 3 > > arcs
(T x 3) transitions [i j c]; i==0 external source, j==0 sink.
std::vector< int > sched
(M) discipline codes.
std::vector< T > obsTimes
(K) observation epochs.
std::vector< T > alpha0
(P) Gamma prior shapes and rates.
std::vector< T > nservers
(M) number of servers.
std::vector< T > routeprob
(T) routing probability of each transition.
T epsilon
probability that a reading is faulty.
std::vector< long > count
interior events of each label; 0 = undefined
std::vector< T > jm
one moment per label 1..max(A)
std::vector< T > mean
one mean per type; undefined where count = 0
std::vector< long > count
samples of each type
std::vector< int > labels
1 for the first stream, 2 for the second
std::vector< T > times
inter-arrival times of the merged process
Matrix< T > Pab
one-step class transition frequencies
std::vector< T > Pc
class probabilities
std::vector< T > M
raw moments of order 1..5
Matrix< T > C2
class-pair cross moments of order 1 and 2
Matrix< T > B2
backward moments of order 1 and 2
std::vector< T > acf
autocorrelation at the requested lags
Matrix< T > F2
forward moments of order 1 and 2
std::vector< std::vector< int > > lags
the [1,i,j] increment triples
std::vector< T > bicov
one moment per grid pair
std::vector< long > counts
arrivals per bin
std::vector< long > membership
1-based bin index of each binned arrival
T rho0
(1 - 1/scv)/2, the GE-type lag-0 amplitude
T gamma
best decay rate on the grid
T residuals
sum of squared deviations from the fitted model
std::vector< T > idi
one value per requested k
std::vector< long > support
the number of points each value rests on
std::vector< T > pmf
relative frequency of each distinct value
std::vector< int > values
the distinct values, in increasing order
T mad
median absolute deviation about the median
T kurt_excess
population kurtosis minus 3
std::vector< T > acf
lags 1..4
T skew
bias-corrected skewness, see trace_skew
Autocorrelation coefficients of a trace at the requested lags.
Bicovariance of a trace on a lag grid.
Autocorrelation decay rate of a trace: the gamma of the geometric model rho(k) = rho0 * gamma^k,...
Bins a trace on a fixed time grid: the number of arrivals falling in each interval ((i-1)*scale,...
Counting process of a trace: the number of arrivals in the window of length scale that starts at each...
Index of dispersion for counts, estimated by its asymptotic equality with the index of dispersion for...
Index of dispersion for intervals,.
Joint moments of a trace, E[X_i^{k_1} X_{i+l_2}^{k_2} ...].
Empirical probability mass function of a discrete trace (counts, batch sizes, queue-length samples).
Squared coefficient of variation of a trace, var/mean^2.
Bias-corrected sample skewness (MATLAB's skewness(S,0), equivalently the G1 estimator).
Descriptive summary of a trace: moments, shape, order statistics, autocorrelation and burstiness.
Sample variance of a trace.