5#ifndef LINE_LANG_LANG_TYPES_H
6#define LINE_LANG_LANG_TYPES_H
98 default:
return "Unknown Metric";
156 default:
return "INIT";
272 default:
return "none";
294 throw UnsupportedError(
"lqn reader: unsupported scheduling discipline '" + s +
"'");
320 std::string(
"the LQN XML schema has no spelling for scheduling discipline '") +
321 sched_to_text(s) +
"'; it carries inf, fcfs, ps, ref, hol, pri, rand, sjf, ljf and lcfs");
414 default:
return "disabled";
466enum class LqnElement { HOST = 0, TASK = 1, ENTRY = 2, ACTIVITY = 3, CALL = 4 };
638 default:
return "none";
670 default:
return false;
731using CdScaling = std::function<std::vector<T>(
const std::vector<T>&)>;
744using GdScaling = std::function<std::vector<T>(
const std::vector<T>&)>;
762 static constexpr double Zero = 1e-14;
771 static constexpr double MaxInt = 2147483647.0;
877 std::shared_ptr<PriorSpec<T>>
prior;
940 d.
params.push_back(lambda);
1006 if (r == 0)
throw InputError(
"Erlang: the number of phases must be positive");
1007 if (!(phase_rate > zero))
throw InputError(
"Erlang: the phase rate must be positive");
1011 d.
params.push_back(phase_rate);
1017 for (std::size_t i = 0; i < r; ++i) {
1018 d.
D0(i, i) = T(-phase_rate);
1019 if (i + 1 < r) d.
D0(i, i + 1) = phase_rate;
1021 d.
D1(r - 1, 0) = phase_rate;
1037 if (!(c2 > zero))
throw InputError(
"Erlang.fitMeanAndSCV: the SCV must be positive");
1040 "Erlang.fitMeanAndSCV: the Erlang distribution requires a squared coefficient "
1041 "of variation <= 1; use HyperExp, Coxian or APH above 1");
1044 const std::size_t r =
static_cast<std::size_t
>(r_d < 1.0 ? 1.0 : r_d);
1064 const std::size_t n = p.size();
1065 if (n == 0 || lambda.size() != n)
1066 throw InputError(
"HyperExp: p and lambda must be non-empty and of equal length");
1070 for (
const T& v : p) d.
params.push_back(v);
1071 for (
const T& v : lambda) d.
params.push_back(v);
1074 T m1 = zero, m2 = zero;
1075 for (std::size_t i = 0; i < n; ++i) {
1076 if (!(lambda[i] > zero))
throw InputError(
"HyperExp: the phase rates must be positive");
1077 d.
D0(i, i) = T(-lambda[i]);
1078 for (std::size_t j = 0; j < n; ++j) d.
D1(i, j) = T(lambda[i] * p[j]);
1079 m1 += T(p[i] / lambda[i]);
1080 m2 += T(two * p[i] / (lambda[i] * lambda[i]));
1083 d.
scv = T((m2 - m1 * m1) / (m1 * m1));
1089 if (!(lambda1 > zero) || !(lambda2 > zero))
1090 throw InputError(
"HyperExp: the phase rates must be positive");
1091 if (p < zero || p > one)
throw InputError(
"HyperExp: p is not a probability");
1096 d.
params.push_back(lambda1);
1097 d.
params.push_back(lambda2);
1098 const T q = T(one - p);
1099 d.
mean = T(p / lambda1 + q / lambda2);
1101 (p / (lambda1 * lambda1) + q / (lambda2 * lambda2)));
1105 d.
D0(0, 0) = T(-lambda1);
1106 d.
D0(1, 1) = T(-lambda2);
1107 d.
D1(0, 0) = T(lambda1 * p);
1108 d.
D1(0, 1) = T(lambda1 * q);
1109 d.
D1(1, 0) = T(lambda2 * p);
1110 d.
D1(1, 1) = T(lambda2 * q);
1120 const std::size_t n = mu.size();
1121 if (n == 0 || phi.size() != n)
1122 throw InputError(
"Coxian: mu and phi must be non-empty and of equal length");
1126 for (
const T& v : mu) d.
params.push_back(v);
1127 for (
const T& v : phi) d.
params.push_back(v);
1130 for (std::size_t i = 0; i < n; ++i) {
1131 if (!(mu[i] > zero))
throw InputError(
"Coxian: the phase rates must be positive");
1132 d.
D0(i, i) = T(-mu[i]);
1133 if (i + 1 < n) d.
D0(i, i + 1) = T(mu[i] * (one - phi[i]));
1134 d.
D1(i, 0) = T(mu[i] * phi[i]);
1145 std::vector<T> mu, phi;
1148 phi.push_back(phi1);
1163 const std::size_t n = alpha.size();
1164 if (n == 0 || A.
rows() != n || A.
cols() != n)
1165 throw InputError(
"PH: alpha and the subgenerator have inconsistent sizes");
1169 for (
const T& v : alpha) d.
params.push_back(v);
1172 for (std::size_t i = 0; i < n; ++i) {
1174 for (std::size_t j = 0; j < n; ++j) out += A(i, j);
1175 for (std::size_t j = 0; j < n; ++j) d.
D1(i, j) = T(-out * alpha[j]);
1186 throw InputError(
"MAP: D0 and D1 must be square and of the same order");
1214 const std::vector<std::vector<
Matrix<T>>>& blocks) {
1216 for (std::size_t k = 0; k < D0segs.size(); ++k) {
1218 for (std::size_t i = 0; i < A.
rows(); ++i) {
1220 for (std::size_t j = 0; j < A.
cols(); ++j) {
1222 throw InputError(who +
": off-diagonal D0 entries must be non-negative; "
1223 "segment " + std::to_string(k + 1) +
" entry (" +
1224 std::to_string(i) +
"," + std::to_string(j) +
") is not");
1227 for (
const std::vector<
Matrix<T>>& blk : blocks) {
1228 for (std::size_t j = 0; j < blk[k].
cols(); ++j) {
1230 throw InputError(who +
": every arrival block must be non-negative; "
1231 "segment " + std::to_string(k + 1) +
" entry (" +
1232 std::to_string(i) +
"," + std::to_string(j) +
1234 rowsum += blk[k](i, j);
1238 throw InputError(who +
": D0 plus every arrival block must have zero row sums "
1239 "(generator); segment " + std::to_string(k + 1) +
" row " +
1240 std::to_string(i) +
" sums to " +
1254 const std::vector<
Matrix<T>>& mats,
bool ignore_diagonal) {
1255 if (mats.empty())
return;
1256 for (std::size_t k = 1; k < mats.size(); ++k) {
1257 for (std::size_t i = 0; i < mats[0].rows(); ++i)
1258 for (std::size_t j = 0; j < mats[0].cols(); ++j) {
1259 if (ignore_diagonal && i == j)
continue;
1263 throw InputError(who +
": the " + label +
" sparsity pattern must be "
1264 "identical across segments; segment " +
1265 std::to_string(k + 1) +
" differs from segment 1 at (" +
1266 std::to_string(i) +
"," + std::to_string(j) +
"). A "
1267 "schedule that switches a transition on or off cannot be "
1268 "expressed as a per-entry multiplier on the time-averaged "
1269 "process. Keep the entry present with a small positive "
1281 const std::size_t n = D0segs.size();
1282 if (n == 0 || D1segs.size() != n)
1283 throw InputError(who +
": the two segment lists must be non-empty and equally long");
1284 if (breakpoints.size() != n + 1)
1286 ": breakpoints is the BOUNDARY vector and must hold one more entry "
1287 "than there are segments");
1288 for (std::size_t k = 0; k + 1 < breakpoints.size(); ++k)
1289 if (!(breakpoints[k + 1] > breakpoints[k]))
1290 throw InputError(who +
": breakpoints must be strictly increasing");
1291 const std::size_t order = D0segs[0].rows();
1292 for (std::size_t k = 0; k < n; ++k)
1293 if (D0segs[k].rows() != order || D0segs[k].cols() != order ||
1294 D1segs[k].rows() != order || D1segs[k].cols() != order)
1296 ": every segment must have the same order; the schedule "
1297 "modulates one phase structure and does not switch between them");
1302 std::vector<std::vector<Matrix<T>>> one;
1303 one.push_back(D1segs);
1317 for (std::size_t k = 0; k < n; ++k) total += T(breakpoints[k + 1] - breakpoints[k]);
1320 for (std::size_t k = 0; k < n; ++k) {
1321 const T w = T(T(breakpoints[k + 1] - breakpoints[k]) / total);
1322 for (std::size_t a = 0; a < order; ++a)
1323 for (std::size_t b = 0; b < order; ++b) {
1324 d.
D0(a, b) += w * D0segs[k](a, b);
1325 d.
D1(a, b) += w * D1segs[k](a, b);
1353 const std::vector<
Matrix<T>>& D1segs,
bool cyclic) {
1364 static Distrib pht(
const std::vector<T>& breakpoints,
const std::vector<std::vector<T>>& alphas,
1365 const std::vector<
Matrix<T>>& Ssegs,
bool cyclic) {
1367 if (alphas.size() != Ssegs.size() || alphas.empty())
1368 throw InputError(
"PHt: alpha and S must have the same, non-zero number of segments");
1369 std::vector<Matrix<T>> D0segs, D1segs;
1370 for (std::size_t k = 0; k < Ssegs.size(); ++k) {
1372 const std::vector<T>& a = alphas[k];
1374 throw InputError(
"PHt: alpha and the sub-generator disagree in order");
1376 for (std::size_t i = 0; i < S.
rows(); ++i) {
1378 for (std::size_t j = 0; j < S.
cols(); ++j) s += S(i, j);
1379 for (std::size_t j = 0; j < S.
cols(); ++j)
D1(i, j) = T(-s * a[j]);
1381 D0segs.push_back(S);
1382 D1segs.push_back(
D1);
1397 const std::vector<std::vector<
Matrix<T>>>& Dmarksegs,
bool cyclic) {
1399 if (Dmarksegs.empty())
throw InputError(
"MMAPt: no marked arrival block was given");
1400 const std::size_t n = D0segs.size();
1401 for (
const std::vector<
Matrix<T>>& blk : Dmarksegs)
1402 if (blk.
size() != n)
1403 throw InputError(
"MMAPt: every mark must be defined on the whole schedule; one "
1404 "carries " + std::to_string(blk.
size()) +
" segments against " +
1405 std::to_string(n) +
" in D0");
1406 std::vector<Matrix<T>> D1segs;
1407 for (std::size_t k = 0; k < n; ++k) {
1408 Matrix<T> agg(D0segs[k].rows(), D0segs[k].cols(), zero);
1409 for (
const std::vector<
Matrix<T>>& blk : Dmarksegs) {
1410 if (blk[k].rows() != D0segs[k].rows() || blk[k].cols() != D0segs[k].cols())
1411 throw InputError(
"MMAPt: a mark block and D0 disagree in order in segment " +
1412 std::to_string(k + 1));
1413 for (std::size_t a = 0; a < agg.
rows(); ++a)
1414 for (std::size_t b = 0; b < agg.
cols(); ++b) agg(a, b) += blk[k](a, b);
1416 D1segs.push_back(agg);
1419 for (std::size_t c = 0; c < Dmarksegs.size(); ++c)
1427 for (std::size_t k = 0; k < n; ++k) total += T(breakpoints[k + 1] - breakpoints[k]);
1428 const std::size_t order = D0segs[0].rows();
1429 for (
const std::vector<
Matrix<T>>& blk : Dmarksegs) {
1431 for (std::size_t k = 0; k < n; ++k) {
1432 const T w = T(T(breakpoints[k + 1] - breakpoints[k]) / total);
1433 for (std::size_t a = 0; a < order; ++a)
1434 for (std::size_t b = 0; b < order; ++b) nom(a, b) += w * blk[k](a, b);
1436 d.
Dmark.push_back(nom);
1461 const std::vector<std::vector<std::vector<
Matrix<T>>>>& Dbatchsegs,
1464 if (Dbatchsegs.empty())
throw InputError(
"BMMAPt: no marked batch block was given");
1465 const std::size_t n = D0segs.size();
1466 if (n == 0)
throw InputError(
"BMMAPt: D0 must carry at least one segment");
1467 const std::size_t B = Dbatchsegs[0].size();
1468 if (B == 0)
throw InputError(
"BMMAPt: mark 1 declares no batch size");
1469 for (std::size_t c = 0; c < Dbatchsegs.size(); ++c) {
1470 if (Dbatchsegs[c].size() != B)
1471 throw InputError(
"BMMAPt: mark " + std::to_string(c + 1) +
" declares " +
1472 std::to_string(Dbatchsegs[c].size()) +
" batch sizes against " +
1473 std::to_string(B) +
" in mark 1; the batch axis is dense and "
1474 "every mark must span it (use a zero block for an unused size)");
1475 for (std::size_t b = 0; b < B; ++b)
1476 if (Dbatchsegs[c][b].size() != n)
1477 throw InputError(
"BMMAPt: block (mark " + std::to_string(c + 1) +
", batch " +
1478 std::to_string(b + 1) +
") carries " +
1479 std::to_string(Dbatchsegs[c][b].size()) +
1480 " segments against " + std::to_string(n) +
" in D0; every "
1481 "block must be defined on the whole schedule");
1484 std::vector<std::vector<Matrix<T>>> Dmarksegs;
1485 for (std::size_t c = 0; c < Dbatchsegs.size(); ++c) {
1486 std::vector<Matrix<T>> permark;
1487 for (std::size_t k = 0; k < n; ++k) {
1488 Matrix<T> acc(D0segs[k].rows(), D0segs[k].cols(), zero);
1489 for (std::size_t b = 0; b < B; ++b) {
1490 const Matrix<T>& M = Dbatchsegs[c][b][k];
1491 if (M.
rows() != D0segs[k].rows() || M.
cols() != D0segs[k].cols())
1492 throw InputError(
"BMMAPt: block (mark " + std::to_string(c + 1) +
1493 ", batch " + std::to_string(b + 1) +
") and D0 disagree "
1494 "in order in segment " + std::to_string(k + 1));
1495 for (std::size_t a = 0; a < acc.
rows(); ++a)
1496 for (std::size_t d = 0; d < acc.
cols(); ++d) acc(a, d) += M(a, d);
1498 permark.push_back(acc);
1500 Dmarksegs.push_back(permark);
1505 Distrib d =
mmapt(breakpoints, D0segs, Dmarksegs, cyclic);
1520 const std::vector<std::vector<T>>& alphas,
1522 const std::vector<std::vector<std::vector<T>>>& exits,
bool cyclic) {
1524 if (alphas.size() != Ssegs.size() || alphas.empty())
1525 throw InputError(
"MPHt: alpha and S must have the same, non-zero number of segments");
1526 if (exits.empty())
throw InputError(
"MPHt: no marked exit vector was given");
1527 const std::size_t n = Ssegs.size();
1528 for (
const std::vector<std::vector<T>>& ex : exits)
1530 throw InputError(
"MPHt: every mark must be defined on the whole schedule");
1531 std::vector<std::vector<Matrix<T>>> Dmarksegs;
1532 for (
const std::vector<std::vector<T>>& ex : exits) {
1533 std::vector<Matrix<T>> blocks;
1534 for (std::size_t k = 0; k < n; ++k) {
1536 const std::vector<T>& a = alphas[k];
1537 if (S.
rows() != S.
cols() || S.
rows() != a.size() || ex[k].size() != S.
rows())
1538 throw InputError(
"MPHt: alpha, S and the exit vector disagree in order in "
1539 "segment " + std::to_string(k + 1));
1541 for (std::size_t i = 0; i < S.
rows(); ++i)
1542 for (std::size_t j = 0; j < S.
cols(); ++j) block(i, j) = T(ex[k][i] * a[j]);
1543 blocks.push_back(block);
1545 Dmarksegs.push_back(blocks);
1548 for (std::size_t k = 0; k < n; ++k) {
1550 for (std::size_t i = 0; i < S.
rows(); ++i) {
1551 T rowsum = zero, marked = zero;
1552 for (std::size_t j = 0; j < S.
cols(); ++j) rowsum += S(i, j);
1553 for (
const std::vector<std::vector<T>>& ex : exits) marked += ex[k][i];
1555 if (std::fabs(slack) > 1e-10)
1556 throw InputError(
"MPHt: the exit vectors must partition the absorption rate "
1557 "of S; in segment " + std::to_string(k + 1) +
" phase " +
1558 std::to_string(i) +
" they miss it by " +
1559 std::to_string(slack));
1562 Distrib d =
mmapt(breakpoints, Ssegs, Dmarksegs, cyclic);
1572 static Distrib nhpp(
const std::vector<T>& breakpoints,
const std::vector<T>& rates,
1574 std::vector<Matrix<T>> D0segs, D1segs;
1575 for (std::size_t k = 0; k < rates.size(); ++k) {
1576 Matrix<T> a(1, 1, T(-rates[k])), b(1, 1, rates[k]);
1577 D0segs.push_back(a);
1578 D1segs.push_back(b);
1589 if (!(b > a))
throw InputError(
"Uniform: the upper bound must exceed the lower bound");
1596 const T w = T(b - a);
1605 throw InputError(
"Pareto: the shape must exceed 2 for a finite variance");
1609 d.
params.push_back(shape);
1610 d.
params.push_back(scale);
1611 d.
mean = T(shape * scale / (shape - one));
1612 const T var = T(scale * scale * shape / ((shape - one) * (shape - one)) / (shape - two));
1631 d.
params.push_back(shape);
1632 d.
params.push_back(scale);
1633 d.
mean = T(shape * scale);
1634 d.
scv = T(one / shape);
1641 "Weibull: its moments are values of the gamma function, which exact arithmetic "
1642 "has no representation for; use the double or real backend");
1646 if (!(a > 0.0) || !(r > 0.0))
1647 throw InputError(
"Weibull: the scale and the shape must be positive");
1648 const double g1 = std::tgamma(1.0 + 1.0 / r);
1649 const double g2 = std::tgamma(1.0 + 2.0 / r);
1653 d.
params.push_back(scale);
1654 d.
params.push_back(shape);
1664 "Lognormal: its moments are values of exp, which exact arithmetic has no "
1665 "representation for; use the double or real backend");
1669 if (!(sg > 0.0))
throw InputError(
"Lognormal: sigma must be positive");
1673 d.
params.push_back(logmean);
1674 d.
params.push_back(logsigma);
1691 throw InputError(
"Normal: sigma must be positive");
1696 d.
params.push_back(sigma);
1721 if (samples.empty())
throw InputError(
"Replayer: the trace is empty");
1728 for (
const T& x : samples) {
1750 if (!(b >= a))
throw InputError(
"DiscreteUniform: the upper bound must not be below the lower");
1756 d.
mean = T((a + b) / two);
1757 const T w = T(b - a + one);
1771 d.
scv = T((one - p) / p);
1784 d.
scv = T((one - p) / (n * p));
1797 d.
params.push_back(lambda);
1799 d.
scv = T(one / lambda);
1813 d.
mean = T(one / p);
1830 "Zipf: its moments are generalized harmonic sums of a real exponent, which exact "
1831 "arithmetic has no representation for; use the double or real backend");
1833 if (n == 0)
throw InputError(
"Zipf: the item count must be positive");
1835 auto harmonic = [n](
double e) {
1837 for (std::size_t k = 1; k <= n; ++k) acc += std::pow(
double(k), -e);
1840 const double h0 = harmonic(sv), h1 = harmonic(sv - 1.0), h2 = harmonic(sv - 2.0);
1846 const double m1 = h1 / h0;
1864 if (p.empty())
throw InputError(
"DiscreteSampler: the probability vector is empty");
1865 if (!x.empty() && x.size() != p.size())
1866 throw InputError(
"DiscreteSampler: p and x must have the same length");
1874 for (std::size_t k = 0; k < p.size(); ++k) {
1878 m2 += T(p[k] * pt * pt);
1884 d.
scv = T((m2 - m1 * m1) / (m1 * m1));
1895 if (x.size() != F.size() || x.size() < 2)
1896 throw InputError(
"EmpiricalCDF: x and F must be equally long and hold at least two points");
1904 for (std::size_t i = 0; i + 1 < x.size(); ++i) {
1905 const T mid = T((x[i + 1] - x[i]) / two + x[i]);
1906 const T w = T(F[i + 1] - F[i]);
1908 m2 += T(mid * mid * w);
1953 if (D1k.empty())
throw InputError(
"MMAP: no marked arrival block was given");
1957 throw InputError(
"MMAP: every marked block must have the order of D0");
1958 for (std::size_t i = 0; i < agg.
rows(); ++i)
1959 for (std::size_t j = 0; j < agg.
cols(); ++j) agg(i, j) += Dk(i, j);
1972 if (D.size() < 2)
throw InputError(
"BMAP: the block list must carry D0 and at least one batch block");
1973 const std::vector<Matrix<T>> batches(D.begin() + 1, D.end());
1994 v.push_back(
rate());
1997 for (std::size_t i = 0; i <
D0.
rows(); ++i) v.push_back(T(-
D0(i, i)));
2010 for (std::size_t i = 0; i <
D1.
rows(); ++i) {
2012 for (std::size_t j = 0; j <
D1.
cols(); ++j) s +=
D1(i, j);
2013 const T out = T(-
D0(i, i));
2033 const std::size_t n = alpha.size();
2035 for (
unsigned i = 0; i < k; ++i) x = solve_neg(A, x);
2037 for (std::size_t i = 0; i < n; ++i) acc += alpha[i] * x[i];
2039 for (
unsigned i = 2; i <= k; ++i) fact *= num_traits<T>::from_int(
static_cast<long>(i));
2040 return T(fact * acc);
2052 static std::vector<T> solve_neg(
const Matrix<T>& A,
const std::vector<T>& b) {
2054 const std::size_t n = A.
rows();
2055 if (A.
cols() != n || b.size() != n)
2056 throw InputError(
"phase-type moment: the subgenerator is not square");
2058 std::vector<T> x = b;
2059 for (std::size_t i = 0; i < n; ++i)
2060 for (std::size_t j = 0; j < n; ++j) M(i, j) = T(-A(i, j));
2061 for (std::size_t col = 0; col < n; ++col) {
2062 std::size_t best = col;
2064 for (std::size_t r = col + 1; r < n; ++r) {
2072 for (std::size_t j = 0; j < n; ++j) std::swap(M(col, j), M(best, j));
2073 std::swap(x[col], x[best]);
2075 if (M(col, col) == zero)
2076 throw NumericError(
"phase-type moment: the subgenerator is singular");
2077 for (std::size_t r = 0; r < n; ++r) {
2078 if (r == col)
continue;
2079 const T f = T(M(r, col) / M(col, col));
2080 if (f == zero)
continue;
2081 for (std::size_t j = 0; j < n; ++j) M(r, j) = T(M(r, j) - f * M(col, j));
2082 x[r] = T(x[r] - f * x[col]);
2085 for (std::size_t i = 0; i < n; ++i) x[i] = T(x[i] / M(i, i));
Cache(model, name, params).
ClassSwitch(model, name, C).
Delay(model, name): the infinite-server station.
NumericError(const std::string &what)
Place(model, name): a Petri-net place.
Queue(model, name, strategy).
Router(model, name): a stateless routing node.
Sink(model, name): the external departure node, which holds no jobs.
Source(model, name): the external arrival station.
Transition(model, name): a Petri-net transition, with its modes declared after it as MATLAB,...
UnsupportedError(const std::string &what)
The exception types the port throws.
Dense matrix and non-owning view.
SchedStrategy
Scheduling disciplines, with the values of MATLAB SchedStrategy.
DropStrategy
Blocking and loss rules, with the values of MATLAB DropStrategy.
TimingStrategy
SPN transition timing, with the values of MATLAB TimingStrategy.
@ IMMEDIATE
fires with zero delay, resolved by weight and priority
@ TIMED
fires after its firing distribution elapses
BalkingStrategy
Balking rules, with the values of MATLAB BalkingStrategy.
SignalType
G-network signal classes, with the values of MATLAB SignalType.
@ REPLY
completes a synchronous call, releasing a held server
@ NEGATIVE
removes a batch of jobs (Gelenbe's negative customer)
@ CATASTROPHE
removes EVERY job at the station
bool process_is_batch(ProcessType p)
True when an EVENT of this process releases (or, as a service process, completes) a BATCH of jobs who...
JoinStrategy
Join rules, with the values of MATLAB JoinStrategy.
PrecedenceType
Activity precedence kinds, with the values of MATLAB ActivityPrecedenceType.
LqnElement
LQN element kinds, with the values of MATLAB LayeredNetworkElement.
RoutingStrategy
Routing strategies, with the values of MATLAB RoutingStrategy.
@ SDR
Krzesinski (1987) product-form state-dependent routing.
SchedStrategy sched_from_lqnx(const std::string &s)
Parse the scheduling attribute of an .lqnx processor or task.
DepartureDiscipline
When a Place releases a served token, MATLAB DepartureDiscipline.
bool process_is_marked(ProcessType p)
True for every marked family.
CallType
Call kinds, with the values of MATLAB CallType.
const char * metric_to_text(MetricType metric)
Port of MetricType.toText.
RemovalPolicy
Which job a negative signal removes, with the values of MATLAB RemovalPolicy.
@ LCFS
the newest waiting job; servers only once nobody waits
@ RANDOM
uniform over waiting AND in-service jobs
EventType
The events a state can undergo, with the values of MATLAB EventType.
@ PHASE
service advances a phase WITHOUT departing
@ READ
a cache item is read
@ FAILURE
the server breaks down, going from up to down
@ STAGE
a random environment changes stage
@ SWITCH
a polling server advances its switchover timer
@ LOCAL
dummy event, no state change outside the node
@ RENEGE
a waiting job abandons the queue (impatience)
@ POST
produce to a place or queue buffer
@ START
a job begins or resumes holding a server
@ ENABLE
an SPN mode becomes enabled
@ RETRY
an orbiting job retries entry at a retrial station
@ REPAIR
the server is repaired, going from down to up, resuming the held job, which is why it emits no START
@ PRE
consume from a place or queue buffer, no server effect
@ INIT
the model is initialized, t = 0
@ PREEMPT
a job holding a server is pushed back into the buffer
MetricType
Solver output metrics, with the numeric values of MATLAB MetricType.
HeteroSchedPolicy
How a heterogeneous station picks among its server types, MATLAB HeteroSchedPolicy.
PollingType
Polling service disciplines, with the values of MATLAB PollingType.
@ KLIMITED
serve at most K per visit (K in pollingPar)
@ EXHAUSTIVE
serve until the queue empties
@ GATED
serve exactly the jobs present at the polling instant
@ DECREMENTING
serve until the queue is one shorter than at arrival
JobClassType
Job class kinds, with the values of MATLAB JobClassType.
std::string sched_to_lqnx(SchedStrategy s)
The scheduling attribute an .lqnx processor or task carries for a strategy.
bool process_is_marked_schedule(ProcessType p)
True when sn.proc holds the MARKED SCHEDULE slot.
const char * node_type_to_text(NodeType t)
Name of a node kind, for diagnostics.
ProcessType
Distribution kinds, with the values of MATLAB ProcessType.
@ NORMAL
A Gaussian, and the ONE family whose value is not MATLAB's, because MATLAB has none to copy: ProcessT...
@ BMMAPT
BMMAPT crosses the BATCH axis with the two above: a block is indexed by segment, mark and batch size,...
@ MPH
The MARKED families, MATLAB's ProcessType.m:36-38.
@ NHPP
The time-INHOMOGENEOUS families of Ko and Pender (ORL 45, 2017): an NHPP is a rate schedule lambda(t)...
@ PRIOR
A Prior: a weighted set of ALTERNATIVE distributions, or a density over a scalar parameter plus a fac...
std::function< std::vector< T >(const std::vector< T > &)> GdScaling
A globally state-dependent scaling, sn.gdscaling.
const char * sched_to_text(SchedStrategy s)
const char * process_to_text(ProcessType p)
The MATLAB ProcessType name, as sn.procid prints it.
bool process_is_markovian(ProcessType p)
ProcessType.isMarkovian: true when sn.proc carries an exact matrix representation of the law,...
bool process_is_marked_stationary(ProcessType p)
True when the type carries PER-MARK arrival blocks, i.e.
std::function< std::vector< T >(const std::vector< T > &)> CdScaling
A class-dependent scaling map, sn.cdscaling.
const char * routing_to_text(RoutingStrategy r)
NodeType
Node kinds, with the values of MATLAB NodeType.
const char * event_to_text(EventType e)
ReplacementStrategy
Cache replacement policies, with the values of MATLAB ReplacementStrategy.
@ HLRU
h-LRU / LRU(m): h lists, promote i -> i+1 on a hit
@ CLIMB
move up one position on a hit (transposition rule)
@ QLRU
q-LRU: LRU with probabilistic admission on a miss
@ FIFO
first in, first out
ImpatienceType
Impatience kinds, with the values of MATLAB ImpatienceType.
Conservation laws of a layered queueing network, enumerated from its structure.
Number-type abstraction for the templated API port.
bool is_immediate() const
static Distrib sched_dist(const std::vector< T > &breakpoints, const std::vector< Matrix< T > > &D0segs, const std::vector< Matrix< T > > &D1segs, bool cyclic, ProcessType tag)
The shared constructor of the three schedule families.
static Distrib empirical_cdf(const std::vector< T > &x, const std::vector< T > &F)
EmpiricalCDF(x, F): the moments of the MIDPOINT rule over the CDF bins, which is what MATLAB Empirica...
std::vector< std::vector< std::vector< Matrix< double > > > > sched_Dbatch
static Distrib nhpp(const std::vector< T > &breakpoints, const std::vector< T > &rates, bool cyclic)
NHPP(breakpoints, rates, cyclic): a MAPt of ORDER ONE, which is what an inhomogeneous Poisson process...
std::vector< T > mu_vec() const
Phase rates, MATLAB's getMu: the total outgoing rate of each phase.
static void check_common_support(const std::string &who, const std::string &label, const std::vector< Matrix< T > > &mats, bool ignore_diagonal)
Reject a schedule whose matrices do not share one sparsity pattern, the twin of MATLAB's MAPt....
bool has_map() const
True when the type carries a (D0,D1) pair of its own.
static Distrib mmapt(const std::vector< T > &breakpoints, const std::vector< Matrix< T > > &D0segs, const std::vector< std::vector< Matrix< T > > > &Dmarksegs, bool cyclic)
MMAPt(breakpoints, {D0_k}, {{D1^(c)_k}}, cyclic): the marked schedule.
std::vector< std::vector< Matrix< double > > > sched_Dmark
static Distrib replayer(const std::vector< double > &samples)
std::vector< double > sched_bp
static Distrib normal(const T &mu, const T &sigma)
Normal(mu, sigma): the Gaussian, for use as a continuous Prior's parameter density.
static Distrib dmap(const Matrix< T > &D0, const Matrix< T > &D1)
DMAP(D0, D1): a DISCRETE-time MAP, where D0 + D1 is stochastic rather than a generator.
static Distrib exp_rate(const T &r)
static Distrib phase_type(const std::vector< T > &alpha, const Matrix< T > &A, bool acyclic)
PH / APH given by (alpha, A): D0 = A and D1 = (-A e) alpha.
std::vector< Matrix< double > > Dmark
static Distrib mapt(const std::vector< T > &breakpoints, const std::vector< Matrix< T > > &D0segs, const std::vector< Matrix< T > > &D1segs, bool cyclic)
MAPt(breakpoints, {D0_k}, {D1_k}, cyclic): a piecewise-constant (D0(t), D1(t)).
std::shared_ptr< Distrib< double > > declared
static Distrib weibull(const T &scale, const T &shape)
static Distrib replayer_from(const std::vector< T > &samples, const std::string &path)
Replayer / Trace read FROM A FILE, which keeps the path beside the samples.
bool has_schedule() const
static Distrib bmap(const std::vector< Matrix< T > > &D)
BMAP: the batch-size blocks D0, D1, ..., Dk, where Dj carries an arrival of batch size j.
static Distrib mmap(const Matrix< T > &D0, const std::vector< Matrix< T > > &D1k)
MMAP: D0 plus one D1 block per mark.
static Distrib disabled_dist()
static Distrib pht(const std::vector< T > &breakpoints, const std::vector< std::vector< T > > &alphas, const std::vector< Matrix< T > > &Ssegs, bool cyclic)
PHt(breakpoints, {alpha_k}, {S_k}, cyclic), stored as its equivalent MAP schedule: D0 = S and D1 = (-...
static double ph_moment(const std::vector< double > &alpha, const Matrix< double > &A, unsigned k)
static Distrib erlang_fit(const T &m, const T &c2)
Erlang fitted to a mean and an SCV, as MATLAB's Erlang.fitMeanAndSCV.
static Distrib pareto(const T &shape, const T &scale)
Pareto(shape, scale), with the MATLAB parameter order (alpha, k).
std::vector< double > params
static Distrib gamma_dist(const T &shape, const T &scale)
Gamma(shape, scale), Weibull(scale, shape) and Lognormal(mu, sigma).
static Distrib cox2(const T &mu1, const T &mu2, const T &phi1)
Cox2(mu1, mu2, phi1), MATLAB's two-phase Coxian constructor.
static Distrib map_dist(const Matrix< T > &D0, const Matrix< T > &D1, ProcessType tag)
A MAP given by its two matrices; the moments are those of its stationary phase.
static Distrib poisson(const T &lambda)
Poisson(lambda), whose SCV is 1/lambda – the count's variance is lambda and its mean is lambda,...
std::vector< double > trace
static Distrib bernoulli(const T &p)
Bernoulli(p): one trial, mean p and variance p(1-p).
static double ph_moment_from(const Matrix< double > &A, std::size_t start, unsigned k)
static Distrib hyperexp_n(const std::vector< T > &p, const std::vector< T > &lambda)
HyperExp(p, lambda1, lambda2): phase i chosen with probability p_i.
static Distrib discrete_uniform(const T &a, const T &b)
DiscreteUniform(a, b) over the integers a..b inclusive.
std::shared_ptr< PriorSpec< double > > prior
static Distrib geometric(const T &p)
Geometric(p) on the MATLAB convention: the NUMBER OF TRIALS to the first success, support {1,...
static Distrib det(const T &m)
static Distrib bmmapt(const std::vector< T > &breakpoints, const std::vector< Matrix< T > > &D0segs, const std::vector< std::vector< std::vector< Matrix< T > > > > &Dbatchsegs, bool cyclic)
BMMAPt(breakpoints, {D0_k}, {{{D^(c,b)_k}}}, cyclic): the BATCH marked schedule.
static Distrib rap(const Matrix< T > &H0, const Matrix< T > &H1)
RAP(H0, H1): a rational arrival process, whose moments are the MAP ones.
bool has_batch_schedule() const
static Distrib uniform(const T &a, const T &b)
Uniform(a, b).
std::vector< Matrix< double > > sched_D1
static Distrib lognormal(const T &logmean, const T &logsigma)
static Distrib hyperexp(const T &p, const T &lambda1, const T &lambda2)
std::vector< Matrix< double > > sched_D0
static Distrib me(const std::vector< T > &alpha, const Matrix< T > &A)
ME(alpha, A): the matrix-exponential distribution, whose moments are the phase-type ones – k!
static Distrib immediate()
The Immediate singleton.
std::vector< T > phi_vec() const
Completion probabilities, MATLAB's getPhi: (D1 e) .
static Distrib erlang(const T &phase_rate, std::size_t r)
Erlang(alpha, r): r phases of rate alpha, as MATLAB's Erlang(phaseRate, nphases).
bool has_marked_schedule() const
static Distrib exp_mean(const T &m)
std::size_t max_batch_size() const
Largest batch size the schedule declares, or 1 when it carries no batch axis.
static Distrib mpht(const std::vector< T > &breakpoints, const std::vector< std::vector< T > > &alphas, const std::vector< Matrix< T > > &Ssegs, const std::vector< std::vector< std::vector< T > > > &exits, bool cyclic)
MPHt(breakpoints, {alpha_k}, {S_k}, {{s^(c)_k}}, cyclic), stored LOWERED to MMAPt form segment by seg...
std::size_t phases() const
The order of the representation, MATLAB's sn.phases.
static void check_sched_generator(const std::string &who, const std::vector< Matrix< T > > &D0segs, const std::vector< std::vector< Matrix< T > > > &blocks)
Reject a schedule segment that is not a generator, the check MATLAB, the JAR and Python all apply and...
static Distrib coxian(const std::vector< T > &mu, const std::vector< T > &phi)
Coxian(mu, phi): phase i completes with probability phi(i) and otherwise moves to phase i+1.
static Distrib discrete_sampler(const std::vector< T > &p, const std::vector< T > &x)
DiscreteSampler(p, x): the pmf p over the points x.
static Distrib binomial(const T &n, const T &p)
Binomial(n, p).
static Distrib zipf(const T &s, std::size_t n)
Zipf(s, n) over the ranks 1..n, with the generalized harmonic moments H(s-1,n)/H(s,...
The MATLAB GlobalConstants, as reported by lineStart at its defaults.
static constexpr double Immediate
Rate of an Immediate distribution; its mean is 1/Immediate = 1e-8.
static constexpr double FineTol
static constexpr double ArcTol
Below this an off-diagonal entry is NO ARC of the phase / state graph.
static constexpr double Zero
static constexpr double CoarseTol
static constexpr double MaxInt
Stand-in for an unbounded COUNT, MATLAB GlobalConstants.MaxInt.
A LINE Distribution, as the model layer and sn carry it.
std::function< Distrib< T >(const T &)> factory
theta -> Distribution; the continuous form only.
bool continuous
True for the parameter-density form, false for the alternative-set form.
Distrib< T > param_dist
The law of the scalar parameter; the continuous form only.
std::vector< T > probabilities
std::vector< Distrib< T > > alternatives
The alternatives and their weights; the discrete form only.