LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
api_dispatch_mam.cpp
Go to the documentation of this file.
1/*
2 * Copyright (c) 2012-2026, QORE Lab, Imperial College London
3 * All rights reserved.
4 *
5 * --api dispatch entries for the 'mam' group (see api_dispatch_detail.h).
6 *
7 * Conventions shared by every entry below:
8 * - argument keys are the MATLAB parameter names of the reference .m file
9 * (matlab/lib/kpctoolbox/, matlab/lib/m3a/, matlab/src/api/{mam,me,mc}/),
10 * output keys its output names. A function with no MATLAB reference uses
11 * the parameter names of its C++ port;
12 * - a MAP is the list [D0, D1] and an MMAP the list [D0, D1, D11, ..., D1K],
13 * exactly the MATLAB cell arrays; a list of MAPs is a list of such lists;
14 * - an ABSENT optional argument selects the port's own shorter overload, or
15 * leaves a field of an options struct at the port's value. No default is
16 * restated here. Where the port only has a long form that takes several
17 * optionals together, giving one of them requires giving the others, and
18 * the refusal names the missing one;
19 * - indices that are 1-based in MATLAB (map_stochcomp retain_idx,
20 * smp_passage_moments target, me_* refstat) are 1-based here as well;
21 * - an infinite server count or buffer is the string "Inf", as MATLAB's Inf.
22 */
23
24#include <cmath>
25#include <cstdint>
26#include <initializer_list>
27#include <random>
28#include <string>
29#include <utility>
30#include <vector>
31
32#include "api_dispatch_detail.h"
33
42#include "line/api/mam/ldqbd.h"
81#include "line/api/mam/qbd_r.h"
86#include "line/api/me/me_cqn.h"
90#include "line/api/me/me_mqn.h"
91#include "line/api/me/me_oqn.h"
93
94namespace line {
95namespace reg {
96
97namespace {
98
99// ---------------------------------------------------------------------------
100// Shared helpers
101// ---------------------------------------------------------------------------
102
103std::string quoted(const char* key) { return std::string("'") + key + "'"; }
104
105/**
106 * The long form of a port whose short overload fixes some arguments itself:
107 * selected as soon as any of `triggers` is given, and then every one of
108 * `needed` must be given too, because the long form has no default for it.
109 */
110bool long_form(const Args& a, const char* fn, std::initializer_list<const char*> triggers,
111 std::initializer_list<const char*> needed) {
112 std::string trig;
113 for (const char* t : triggers)
114 if (a.has(t)) {
115 trig = t;
116 break;
117 }
118 if (trig.empty()) return false;
119 for (const char* n : needed)
120 if (!a.has(n))
121 throw InputError(std::string(fn) + ": '" + trig + "' selects the long form of the C++ "
122 "port, which has no default for '" + n + "'; give '" + n +
123 "' as well, or drop '" + trig + "' to use the port's own defaults.");
124 return true;
125}
126
127template <class T>
128mam::Map<T> map_from_json(const Json& j, const std::string& where) {
129 if (!j.is_array() || j.size() != 2)
130 throw InputError(where + ": a MAP is a list [D0, D1] of two square matrices");
131 mam::Map<T> m;
132 m.D0 = matrix_from_json<T>(j[0], where + "[0]");
133 m.D1 = matrix_from_json<T>(j[1], where + "[1]");
134 if (m.D0.rows() != m.D0.cols() || m.D1.rows() != m.D0.rows() || m.D1.cols() != m.D0.cols())
135 throw InputError(where + ": D0 and D1 must be square matrices of the same order");
136 return m;
137}
138
139template <class T>
140mam::Mmap<T> mmap_from_json(const Json& j, const std::string& where) {
141 if (!j.is_array() || j.size() < 3)
142 throw InputError(where + ": an MMAP is a list [D0, D1, D11, ..., D1K] of at least three "
143 "square matrices");
144 mam::Mmap<T> m;
145 m.D0 = matrix_from_json<T>(j[0], where + "[0]");
146 m.D1 = matrix_from_json<T>(j[1], where + "[1]");
147 for (std::size_t k = 2; k < j.size(); ++k)
148 m.Dc.push_back(matrix_from_json<T>(j[k], where + "[" + std::to_string(k) + "]"));
149 const std::size_t n = m.D0.rows();
150 bool ok = m.D0.cols() == n && m.D1.rows() == n && m.D1.cols() == n;
151 for (const Matrix<T>& D : m.Dc) ok = ok && D.rows() == n && D.cols() == n;
152 if (!ok) throw InputError(where + ": every matrix of an MMAP must be square of the same order");
153 return m;
154}
155
156template <class T>
157mam::Map<T> read_map(Args& a, const char* key) {
158 return map_from_json<T>(a.get(key), quoted(key));
159}
160
161template <class T>
162mam::Mmap<T> read_mmap(Args& a, const char* key) {
163 return mmap_from_json<T>(a.get(key), quoted(key));
164}
165
166template <class T>
167std::vector<mam::Map<T> > read_maps(Args& a, const char* key) {
168 const Json& j = a.get(key);
169 if (!j.is_array() || j.empty())
170 throw InputError(quoted(key) + ": expected a non-empty list of MAPs, each [D0, D1]");
171 std::vector<mam::Map<T> > out;
172 for (std::size_t i = 0; i < j.size(); ++i)
173 out.push_back(map_from_json<T>(j[i], quoted(key) + "[" + std::to_string(i) + "]"));
174 return out;
175}
176
177template <class T>
178Json encode_map(const mam::Map<T>& m) {
179 Json o = Json::array();
180 o.push_back(encode_matrix(m.D0));
181 o.push_back(encode_matrix(m.D1));
182 return o;
183}
184
185template <class T>
186Json encode_mmap(const mam::Mmap<T>& m) {
187 Json o = Json::array();
188 o.push_back(encode_matrix(m.D0));
189 o.push_back(encode_matrix(m.D1));
190 for (const Matrix<T>& D : m.Dc) o.push_back(encode_matrix(D));
191 return o;
192}
193
194template <class T>
195Json encode_maps(const std::vector<mam::Map<T> >& v) {
196 Json o = Json::array();
197 for (const mam::Map<T>& m : v) o.push_back(encode_map(m));
198 return o;
199}
200
201template <class T>
202Json encode_mmaps(const std::vector<mam::Mmap<T> >& v) {
203 Json o = Json::array();
204 for (const mam::Mmap<T>& m : v) o.push_back(encode_mmap(m));
205 return o;
206}
207
208/** Non-negative integers, for lags, orders and powers. */
209std::vector<unsigned> unsigneds(Args& a, const char* key) {
210 std::vector<unsigned> out;
211 for (int v : a.ints(key)) {
212 if (v < 0)
213 throw InputError(quoted(key) + ": entries must be non-negative integers, got " +
214 std::to_string(v));
215 out.push_back(static_cast<unsigned>(v));
216 }
217 return out;
218}
219
220/** MATLAB 1-based indices, returned 0-based. */
221std::vector<std::size_t> one_based(const Json& j, const std::string& where) {
222 std::vector<std::size_t> out;
223 for (int v : int_vector_from_json(j, where)) {
224 if (v < 1)
225 throw InputError(where + ": indices are 1-based, as in MATLAB; got " + std::to_string(v));
226 out.push_back(static_cast<std::size_t>(v - 1));
227 }
228 return out;
229}
230
231/** A list of numeric vectors. */
232template <class T>
233std::vector<std::vector<T> > vectors_from_json(const Json& j, const std::string& where) {
234 if (!j.is_array()) throw InputError(where + ": expected a list of vectors");
235 std::vector<std::vector<T> > out;
236 for (std::size_t i = 0; i < j.size(); ++i)
237 out.push_back(vector_from_json<T>(j[i], where + "[" + std::to_string(i) + "]"));
238 return out;
239}
240
241template <class T>
242std::vector<std::vector<T> > read_vectors(Args& a, const char* key) {
243 return vectors_from_json<T>(a.get(key), quoted(key));
244}
245
246/**
247 * A count per station in which MATLAB's Inf marks "unbounded" (an infinite
248 * server, an infinite buffer); api/me spells that 0. A finite entry must be a
249 * positive integer, so a literal 0 cannot be mistaken for either meaning.
250 */
251std::vector<long> counts_with_inf(Args& a, const char* key) {
252 std::vector<long> out;
253 for (double d : a.vector<double>(key)) {
254 if (std::isinf(d) && d > 0) {
255 out.push_back(0);
256 continue;
257 }
258 if (d != std::floor(d) || d < 1)
259 throw InputError(quoted(key) + ": entries must be positive integers or \"Inf\", got " +
261 out.push_back(static_cast<long>(d));
262 }
263 return out;
264}
265
266/** Class populations; with `open_inf` an Inf entry (an open class) reads as 0. */
267std::vector<long> populations(Args& a, const char* key, bool open_inf) {
268 std::vector<long> out;
269 for (double d : a.vector<double>(key)) {
270 if (open_inf && std::isinf(d) && d > 0) {
271 out.push_back(0);
272 continue;
273 }
274 if (d != std::floor(d) || d < 0)
275 throw InputError(quoted(key) + ": a population must be a non-negative integer, got " +
277 out.push_back(static_cast<long>(d));
278 }
279 return out;
280}
281
282/** A per-entry flag vector (true/false or 0/1), as std::vector<char>. */
283std::vector<char> flags(Args& a, const char* key) {
284 const Json& j = a.get(key);
285 std::vector<char> out;
286 std::vector<Json> flat;
287 if (j.is_array())
288 for (const Json& e : j) flat.push_back(e);
289 else
290 flat.push_back(j);
291 for (const Json& e : flat) {
292 if (e.is_boolean()) {
293 out.push_back(e.get<bool>() ? 1 : 0);
294 continue;
295 }
296 const std::vector<int> v = int_vector_from_json(e, quoted(key));
297 if (v.size() != 1 || (v[0] != 0 && v[0] != 1))
298 throw InputError(quoted(key) + ": entries must be true, false, 0 or 1");
299 out.push_back(static_cast<char>(v[0]));
300 }
301 return out;
302}
303
304/** Per-class routing: R matrices (M x M), or a single matrix when R == 1. */
305template <class T>
306std::vector<Matrix<T> > per_class_routing(Args& a, const char* key, std::size_t R) {
307 const Json& j = a.get(key);
308 const bool single = j.is_array() && !j.empty() && j[0].is_array() && !j[0].empty() &&
309 !j[0][0].is_array();
310 if (single) {
311 if (R != 1)
312 throw InputError(quoted(key) + ": with R = " + std::to_string(R) +
313 " classes, give a list of R routing matrices (one M x M matrix per "
314 "class, P{r}(i,j) = MATLAB P(i,j,r))");
315 return std::vector<Matrix<T> >(1, matrix_from_json<T>(j, quoted(key)));
316 }
317 return a.matrices<T>(key);
318}
319
320/** MATLAB refstat: 1-based per class, 0 for the default; api/me spells the default -1. */
321std::vector<long> reference_stations(Args& a, const char* key, std::size_t R) {
322 if (!a.has(key)) {
323 a.opt(key);
324 return std::vector<long>(R, -1);
325 }
326 std::vector<long> out;
327 for (int v : a.ints(key)) {
328 if (v < 0) throw InputError(quoted(key) + ": station indices are 1-based, 0 for the default");
329 out.push_back(v == 0 ? -1L : static_cast<long>(v - 1));
330 }
331 return out;
332}
333
334/** The MATLAB options struct of me_cqn/me_mqn/me_oqn. */
335me::MeOptions me_options(Args& a) {
336 me::MeOptions o;
337 const Json* j = a.opt("options");
338 if (!j) return o;
339 if (!j->is_object()) throw InputError("'options' must be an object {tol, maxiter, verbose}");
340 for (auto it = j->begin(); it != j->end(); ++it) {
341 const std::string k = it.key();
342 if (k == "tol") {
343 o.tol = number_from_json<double>(*it, "'options.tol'");
344 } else if (k == "maxiter") {
345 const std::vector<int> v = int_vector_from_json(*it, "'options.maxiter'");
346 if (v.size() != 1 || v[0] < 1)
347 throw InputError("'options.maxiter' must be a positive integer");
348 o.maxiter = v[0];
349 } else if (k == "verbose") {
350 const bool on = it->is_boolean() ? it->get<bool>()
351 : number_from_json<double>(*it, "'options.verbose'") != 0;
352 if (on)
353 throw UnsupportedError(ErrorKind{"JsonApi"},
354 "'options.verbose' = true prints iteration traces to the "
355 "console, which the JSON API has no channel for; omit it.");
356 } else {
357 throw InputError("'options': unknown field '" + k + "'; accepted: tol, maxiter, verbose");
358 }
359 }
360 return o;
361}
362
363me::MeBlkOptions me_blk_options(Args& a) {
364 me::MeBlkOptions o;
365 const Json* j = a.opt("options");
366 if (!j) return o;
367 if (!j->is_object())
368 throw InputError("'options' must be an object {tol, maxiter, verbose, damping}");
369 for (auto it = j->begin(); it != j->end(); ++it) {
370 const std::string k = it.key();
371 if (k == "tol") {
372 o.tol = number_from_json<double>(*it, "'options.tol'");
373 } else if (k == "damping") {
374 o.damping = number_from_json<double>(*it, "'options.damping'");
375 } else if (k == "maxiter") {
376 const std::vector<int> v = int_vector_from_json(*it, "'options.maxiter'");
377 if (v.size() != 1 || v[0] < 1)
378 throw InputError("'options.maxiter' must be a positive integer");
379 o.maxiter = v[0];
380 } else if (k == "verbose") {
381 const bool on = it->is_boolean() ? it->get<bool>()
382 : number_from_json<double>(*it, "'options.verbose'") != 0;
383 if (on)
384 throw UnsupportedError(ErrorKind{"JsonApi"},
385 "'options.verbose' = true prints iteration traces to the "
386 "console, which the JSON API has no channel for; omit it.");
387 } else {
388 throw InputError("'options': unknown field '" + k +
389 "'; accepted: tol, maxiter, verbose, damping");
390 }
391 }
392 return o;
393}
394
395template <class T>
396Json encode_me_result(const me::MeResult<T>& r, bool with_X) {
397 Json o;
398 o["L"] = encode_matrix(r.L);
399 o["W"] = encode_matrix(r.W);
400 o["Ca"] = encode_matrix(r.Ca);
401 o["Cd"] = encode_matrix(r.Cd);
402 o["lambda"] = encode_matrix(r.lambda);
403 o["rho"] = encode_matrix(r.rho);
404 if (with_X) o["X"] = encode_vector(r.X);
405 o["iter"] = static_cast<std::int64_t>(r.iter);
406 o["converged"] = r.converged;
407 return o;
408}
409
410/** The building blocks returned by mfq_ld_solve, as mfq_ld_mean/distr take them. */
411template <class T>
412mam::LevelDependentFluidBlocks<T> read_ld_blocks(Args& a) {
413 mam::LevelDependentFluidBlocks<T> b;
414 b.masses = read_vectors<T>(a, "masses");
415 b.iniF = read_vectors<T>(a, "iniF");
416 b.KF = a.matrices<T>("KF");
417 b.cloF = a.matrices<T>("cloF");
418 b.iniB = read_vectors<T>(a, "iniB");
419 b.KB = a.matrices<T>("KB");
420 b.cloB = a.matrices<T>("cloB");
421 b.Thr = a.vector<T>("T");
422 return b;
423}
424
425/** A rate vector, given as MATLAB's diagonal matrix or as the vector itself. */
426std::vector<double> diagonal_rates(const Json& j, const std::string& where) {
427 const Matrix<double> m = matrix_from_json<double>(j, where);
428 if (m.empty()) return std::vector<double>();
429 if (m.rows() == 1 || m.cols() == 1) return vector_from_json<double>(j, where);
430 if (m.rows() != m.cols())
431 throw InputError(where + ": a drift-rate matrix must be square and diagonal");
432 std::vector<double> d(m.rows());
433 for (std::size_t i = 0; i < m.rows(); ++i)
434 for (std::size_t k = 0; k < m.cols(); ++k) {
435 if (i == k) {
436 d[i] = m(i, i);
437 } else if (m(i, k) != 0.0) {
438 throw InputError(where + ": a drift-rate matrix must be diagonal (entry (" +
439 std::to_string(i + 1) + "," + std::to_string(k + 1) +
440 ") is nonzero)");
441 }
442 }
443 return d;
444}
445
446std::vector<std::vector<double> > diagonal_rate_list(Args& a, const char* key, bool optional) {
447 const Json* j = optional ? a.opt(key) : &a.get(key);
448 std::vector<std::vector<double> > out;
449 if (!j) return out;
450 if (!j->is_array()) throw InputError(quoted(key) + ": expected a list of drift-rate matrices");
451 for (std::size_t i = 0; i < j->size(); ++i)
452 out.push_back(diagonal_rates((*j)[i], quoted(key) + "[" + std::to_string(i) + "]"));
453 return out;
454}
455
456std::vector<mam::FluidBoundary> boundaries(Args& a, const char* key) {
457 std::vector<mam::FluidBoundary> out;
458 for (int v : a.ints_or_empty(key)) {
459 if (v != 0 && v != 1)
460 throw InputError(quoted(key) + ": entries are 0 (reflective) or 1 (absorbing)");
462 }
463 return out;
464}
465
466mam::FluidDistrKind distr_kind(Args& a) {
467 const std::string w = a.text("what", "");
468 if (!a.has("what")) a.get("what");
469 if (w == "pdf") return mam::FluidDistrKind::Pdf;
470 if (w == "pdfd") return mam::FluidDistrKind::Pdfd;
471 if (w == "cdf") return mam::FluidDistrKind::Cdf;
472 if (w == "cdfm") return mam::FluidDistrKind::Cdfm;
473 throw InputError("'what' must be one of \"pdf\", \"pdfd\", \"cdf\" or \"cdfm\", got \"" + w + "\"");
474}
475
476mam::MmapCompressMethod compress_method(const std::string& s) {
477 if (s == "default" || s == "mixture" || s == "mixture.order1")
479 if (s == "mixture.order2") return mam::MmapCompressMethod::MixtureOrder2;
480 if (s == "mamap2") return mam::MmapCompressMethod::Mamap2;
481 if (s == "mamap2.fb") return mam::MmapCompressMethod::Mamap2Fb;
482 if (s == "m3pp.approx_cov") return mam::MmapCompressMethod::M3ppApproxCov;
483 if (s == "m3pp.approx_ag") return mam::MmapCompressMethod::M3ppApproxAg;
484 if (s == "m3pp.exact_delta") return mam::MmapCompressMethod::M3ppExactDelta;
485 if (s == "m3pp.approx_delta") return mam::MmapCompressMethod::M3ppApproxDelta;
486 throw InputError("'config.method': unknown compression method '" + s +
487 "'; accepted: default, mixture, mixture.order1, mixture.order2, mamap2, "
488 "mamap2.fb, m3pp.approx_cov, m3pp.approx_ag, m3pp.exact_delta, "
489 "m3pp.approx_delta");
490}
491
492// ---------------------------------------------------------------------------
493// MAP descriptors (kpctoolbox/map)
494// ---------------------------------------------------------------------------
495
496#define LINE_MAM_MAP_UNARY(OpName, fn, outkey, enc) \
497 struct OpName { \
498 template <class T> \
499 static Json run(Args& a) { \
500 const mam::Map<T> m = read_map<T>(a, "MAP"); \
501 a.done(); \
502 Json o; \
503 o[outkey] = enc(mam::fn(m)); \
504 return o; \
505 } \
506 };
507
508LINE_MAM_MAP_UNARY(OpMapInfgen, map_infgen, "Q", encode_matrix)
509LINE_MAM_MAP_UNARY(OpMapProb, map_prob, "PIQ", encode_vector)
510LINE_MAM_MAP_UNARY(OpMapLambda, map_lambda, "LAMBDA", encode_scalar)
511LINE_MAM_MAP_UNARY(OpMapPie, map_pie, "PIE", encode_vector)
512LINE_MAM_MAP_UNARY(OpMapMean, map_mean, "MEAN", encode_scalar)
513LINE_MAM_MAP_UNARY(OpMapEmbedded, map_embedded, "P", encode_matrix)
514LINE_MAM_MAP_UNARY(OpMapVar, map_var, "VAR", encode_scalar)
515LINE_MAM_MAP_UNARY(OpMapScv, map_scv, "SCV", encode_scalar)
516LINE_MAM_MAP_UNARY(OpMapIdc, map_idc, "I", encode_scalar)
517LINE_MAM_MAP_UNARY(OpMapKurt, map_kurt, "KURT", encode_scalar)
518LINE_MAM_MAP_UNARY(OpMapSkew, map_skew, "SKEWNESS", encode_scalar)
519LINE_MAM_MAP_UNARY(OpMapNormalize, map_normalize, "MAP", encode_map)
520#undef LINE_MAM_MAP_UNARY
521
522struct OpMapMoment {
523 template <class T>
524 static Json run(Args& a) {
525 const mam::Map<T> m = read_map<T>(a, "MAP");
526 const std::vector<unsigned> orders = unsigneds(a, "ORDERS");
527 a.done();
528 std::vector<T> out;
529 for (unsigned k : orders) out.push_back(mam::map_moment(m, k));
530 Json o;
531 o["MOMENTS"] = encode_vector(out);
532 return o;
533 }
534};
535
536struct OpMapAcf {
537 template <class T>
538 static Json run(Args& a) {
539 const mam::Map<T> m = read_map<T>(a, "MAP");
540 const std::vector<unsigned> lags = unsigneds(a, "LAGS");
541 a.done();
542 Json o;
543 o["ACFCOEFFS"] = encode_vector(mam::map_acf(m, lags));
544 return o;
545 }
546};
547
548struct OpMapScale {
549 template <class T>
550 static Json run(Args& a) {
551 const mam::Map<T> m = read_map<T>(a, "MAPIN");
552 const T mean = a.number<T>("NEWMEAN");
553 a.done();
554 Json o;
555 o["MAPOUT"] = encode_map(mam::map_scale(m, mean));
556 return o;
557 }
558};
559
560struct OpMapRenewal {
561 template <class T>
562 static Json run(Args& a) {
563 const mam::Map<T> m = read_map<T>(a, "MAPIN");
564 a.done();
565 Json o;
566 o["MAPOUT"] = encode_map(mam::map_renewal(m));
567 return o;
568 }
569};
570
571struct OpMapExponentialMean {
572 template <class T>
573 static Json run(Args& a) {
574 const T mean = a.number<T>("mean");
575 a.done();
576 Json o;
577 o["MAP"] = encode_map(mam::map_exponential_mean(mean));
578 return o;
579 }
580};
581
582struct OpMapErlang {
583 template <class T>
584 static Json run(Args& a) {
585 const T mean = a.number<T>("MEAN");
586 const unsigned k = a.uinteger("k");
587 a.done();
588 Json o;
589 o["MAP"] = encode_map(mam::map_erlang(mean, k));
590 return o;
591 }
592};
593
594struct OpMapSum {
595 template <class T>
596 static Json run(Args& a) {
597 const mam::Map<T> m = read_map<T>(a, "MAP");
598 const unsigned n = a.uinteger("n");
599 a.done();
600 Json o;
601 o["MAP"] = encode_map(mam::map_sum(m, n));
602 return o;
603 }
604};
605
606struct OpMapSumind {
607 template <class T>
608 static Json run(Args& a) {
609 const std::vector<mam::Map<T> > maps = read_maps<T>(a, "MAPs");
610 a.done();
611 Json o;
612 o["MAP"] = encode_map(mam::map_sumind(maps));
613 return o;
614 }
615};
616
617struct OpMapMixture {
618 template <class T>
619 static Json run(Args& a) {
620 const std::vector<T> alpha = a.vector<T>("alpha");
621 const std::vector<mam::Map<T> > maps = read_maps<T>(a, "MAPs");
622 a.done();
623 Json o;
624 o["MAP"] = encode_map(mam::map_mixture(alpha, maps));
625 return o;
626 }
627};
628
629struct OpPh2map {
630 template <class T>
631 static Json run(Args& a) {
632 const Json& j = a.get("ph");
633 if (!j.is_object())
634 throw InputError("'ph' must be an object {\"alpha\": entry vector, \"subgen\": "
635 "sub-generator}");
636 mam::PhType<T> ph;
637 bool has_alpha = false, has_sub = false;
638 for (auto it = j.begin(); it != j.end(); ++it) {
639 if (it.key() == "alpha") {
640 ph.alpha = vector_from_json<T>(*it, "'ph.alpha'");
641 has_alpha = true;
642 } else if (it.key() == "subgen") {
643 ph.subgen = matrix_from_json<T>(*it, "'ph.subgen'");
644 has_sub = true;
645 } else {
646 throw InputError("'ph': unknown field '" + it.key() + "'; accepted: alpha, subgen");
647 }
648 }
649 if (!has_alpha || !has_sub) throw InputError("'ph' needs both 'alpha' and 'subgen'");
650 a.done();
651 Json o;
652 o["MAP"] = encode_map(mam::ph2map(ph));
653 return o;
654 }
655};
656
657struct OpMapStochcomp {
658 template <class T>
659 static Json run(Args& a) {
660 const mam::Map<T> m = read_map<T>(a, "MAP");
661 const std::vector<std::size_t> retain = one_based(a.get("retain_idx"), "'retain_idx'");
662 a.done();
663 Json o;
664 o["MAPnew"] = encode_map(mam::map_stochcomp(m, retain));
665 return o;
666 }
667};
668
669struct OpMapJoint {
670 template <class T>
671 static Json run(Args& a) {
672 const mam::Map<T> m = read_map<T>(a, "MAP");
673 const std::vector<unsigned> lags = unsigneds(a, "a");
674 const std::vector<unsigned> pw = unsigneds(a, "i");
675 a.done();
676 Json o;
677 o["JM"] = encode_scalar(mam::map_joint(m, lags, pw));
678 return o;
679 }
680};
681
682struct OpMapIsfeasible {
683 template <class T>
684 static Json run(Args& a) {
685 const mam::Map<T> m = read_map<T>(a, "MAP");
686 const bool tol = a.has("TOL");
687 const T t = tol ? a.number<T>("TOL") : T();
688 a.opt("TOL");
689 a.done();
690 Json o;
691 o["ISFEAS"] = tol ? mam::map_isfeasible(m, t) : mam::map_isfeasible(m);
692 return o;
693 }
694};
695
696struct OpMapHyperexp {
697 template <class T>
698 static Json run(Args& a) {
699 const T mean = a.number<T>("MEAN");
700 const T scv = a.number<T>("SCV");
701 const bool hp = a.has("p");
702 const T p = hp ? a.number<T>("p") : T();
703 a.opt("p");
704 a.done();
705 Json o;
706 o["MAP"] = encode_map(hp ? mam::map_hyperexp(mean, scv, p) : mam::map_hyperexp(mean, scv));
707 return o;
708 }
709};
710
711struct OpMapMark {
712 template <class T>
713 static Json run(Args& a) {
714 const mam::Map<T> m = read_map<T>(a, "MAP");
715 const std::vector<T> prob = a.vector<T>("prob");
716 a.done();
717 Json o;
718 o["MMAP"] = encode_mmap(mam::map_mark(m, prob));
719 return o;
720 }
721};
722
723struct OpMapAcfc {
724 template <class T>
725 static Json run(Args& a) {
726 const mam::Map<T> m = read_map<T>(a, "MAP");
727 const std::vector<unsigned> kset = unsigneds(a, "kset");
728 const T u = a.number<T>("u");
729 a.done();
730 Json o;
731 o["acfc"] = encode_vector(mam::map_acfc(m, kset, u));
732 return o;
733 }
734};
735
736#define LINE_MAM_MAP_POINTS(OpName, fn, mapkey, ptkey, outkey) \
737 struct OpName { \
738 template <class T> \
739 static Json run(Args& a) { \
740 const mam::Map<T> m = read_map<T>(a, mapkey); \
741 const std::vector<T> pts = a.vector<T>(ptkey); \
742 a.done(); \
743 Json o; \
744 o[outkey] = encode_vector(mam::fn(m, pts)); \
745 return o; \
746 } \
747 };
748
749LINE_MAM_MAP_POINTS(OpMapCdf, map_cdf, "MAP", "POINTS", "CDFVALS")
750LINE_MAM_MAP_POINTS(OpMapPdf, map_pdf, "MAP", "tset", "f")
751LINE_MAM_MAP_POINTS(OpMapVarcount, map_varcount, "MAP", "tset", "varc")
752LINE_MAM_MAP_POINTS(OpMapCountMean, map_count_mean, "map", "t", "m")
753LINE_MAM_MAP_POINTS(OpMapCountVar, map_count_var, "map", "t", "v")
754#undef LINE_MAM_MAP_POINTS
755
756struct OpMapCountMoment {
757 template <class T>
758 static Json run(Args& a) {
759 const mam::Map<T> m = read_map<T>(a, "MAP");
760 const T t = a.number<T>("t");
761 const std::vector<unsigned> orders = unsigneds(a, "order");
762 a.done();
763 Json o;
764 o["M"] = encode_vector(mam::map_count_moment(m, t, orders));
765 return o;
766 }
767};
768
769// ---------------------------------------------------------------------------
770// MMAP algebra (m3a/mmap)
771// ---------------------------------------------------------------------------
772
773struct OpMmapLambda {
774 template <class T>
775 static Json run(Args& a) {
776 const mam::Mmap<T> m = read_mmap<T>(a, "MMAP");
777 a.done();
778 Json o;
779 o["lambda"] = encode_vector(mam::mmap_lambda(m));
780 return o;
781 }
782};
783
784struct OpMmapCountLambda {
785 template <class T>
786 static Json run(Args& a) {
787 const mam::Mmap<T> m = read_mmap<T>(a, "mmap");
788 a.done();
789 Json o;
791 return o;
792 }
793};
794
795struct OpMmapPc {
796 template <class T>
797 static Json run(Args& a) {
798 const mam::Mmap<T> m = read_mmap<T>(a, "MMAP");
799 a.done();
800 Json o;
801 o["pc"] = encode_vector(mam::mmap_pc(m));
802 return o;
803 }
804};
805
806struct OpMmapIsfeasible {
807 template <class T>
808 static Json run(Args& a) {
809 const mam::Mmap<T> m = read_mmap<T>(a, "MMAP");
810 const bool tol = a.has("TOL");
811 const T t = tol ? a.number<T>("TOL") : T();
812 a.opt("TOL");
813 a.done();
814 Json o;
815 o["TF"] = tol ? mam::mmap_isfeasible_tol(m, t) : mam::mmap_isfeasible(m);
816 return o;
817 }
818};
819
820struct OpMmapNormalize {
821 template <class T>
822 static Json run(Args& a) {
823 const mam::Mmap<T> m = read_mmap<T>(a, "MMAP");
824 a.done();
825 Json o;
826 o["MMAP"] = encode_mmap(mam::mmap_normalize(m));
827 return o;
828 }
829};
830
831struct OpMmapScale {
832 template <class T>
833 static Json run(Args& a) {
834 const mam::Mmap<T> m = read_mmap<T>(a, "MMAP");
835 const Json& jm = a.get("M");
836 const std::vector<T> M = vector_from_json<T>(jm, "'M'");
837 if (M.size() != 1)
838 throw UnsupportedError(ErrorKind{"JsonApi"},
839 "mmap_scale: the C++ port scales to a single aggregate mean; "
840 "the per-class form (M a vector of class means) is not ported.");
841 a.unsupported("maxIter", "the MATLAB reference declares it but never reads it, so it "
842 "has no effect to reproduce.");
843 a.done();
844 Json o;
845 o["SCALED"] = encode_mmap(mam::mmap_scale(m, M[0]));
846 return o;
847 }
848};
849
850struct OpMmapSuper {
851 template <class T>
852 static Json run(Args& a) {
853 const mam::Mmap<T> x = read_mmap<T>(a, "MMAPa");
854 const mam::Mmap<T> y = read_mmap<T>(a, "MMAPb");
855 const std::string opt = a.text("opt", "default");
856 if (a.has("opt") && opt != "default")
857 throw UnsupportedError(ErrorKind{"JsonApi"},
858 "mmap_super: only opt = \"default\" is ported to C++; got \"" +
859 opt + "\".");
860 a.done();
861 Json o;
862 o["SUP"] = encode_mmap(mam::mmap_super(x, y));
863 return o;
864 }
865};
866
867struct OpMmapCountVar {
868 template <class T>
869 static Json run(Args& a) {
870 const mam::Mmap<T> m = read_mmap<T>(a, "mmap");
871 const T t = a.number<T>("t");
872 a.done();
873 Json o;
874 o["vk"] = encode_vector(mam::mmap_count_var(m, t));
875 return o;
876 }
877};
878
879struct OpMmapCompress {
880 template <class T>
881 static Json run(Args& a) {
882 const mam::Mmap<T> m = read_mmap<T>(a, "MMAP");
883 const Json* c = a.opt("config");
884 bool has_method = false;
886 if (c) {
887 if (!c->is_object()) throw InputError("'config' must be an object {method}");
888 for (auto it = c->begin(); it != c->end(); ++it) {
889 if (it.key() != "method")
890 throw InputError("'config': unknown field '" + it.key() + "'; accepted: method");
891 if (!it->is_string()) throw InputError("'config.method' must be a string");
892 meth = compress_method(it->get<std::string>());
893 has_method = true;
894 }
895 }
896 a.done();
897 Json o;
898 o["MMAP"] = encode_mmap(has_method ? mam::mmap_compress(m, meth) : mam::mmap_compress(m));
899 return o;
900 }
901};
902
903// ---------------------------------------------------------------------------
904// QBD
905// ---------------------------------------------------------------------------
906
907/** qbd_R and qbd_R_logred: MATLAB iter_max, plus the port's tol alongside it. */
908template <bool Logred>
909struct OpQbdR {
910 template <class T>
911 static Json run(Args& a) {
912 const char* fn = Logred ? "qbd_R_logred" : "qbd_R";
913 const Matrix<T> B = a.matrix<T>("B");
914 const Matrix<T> L = a.matrix<T>("L");
915 const Matrix<T> F = a.matrix<T>("F");
916 const bool lf = long_form(a, fn, {"iter_max", "tol"}, {"iter_max", "tol"});
917 const unsigned it = lf ? a.uinteger("iter_max") : 0u;
918 const T tol = lf ? a.number<T>("tol") : T();
919 a.opt("iter_max");
920 a.opt("tol");
921 a.done();
922 Json o;
923 if (Logred)
924 o["R"] = encode_matrix(lf ? mam::qbd_R_logred(B, L, F, it, tol) : mam::qbd_R_logred(B, L, F));
925 else
926 o["R"] = encode_matrix(lf ? mam::qbd_R(B, L, F, it, tol) : mam::qbd_R(B, L, F));
927 return o;
928 }
929};
930
931struct OpQbdFundmat {
932 template <class T>
933 static Json run(Args& a) {
934 const Matrix<T> B = a.matrix<T>("B");
935 const Matrix<T> L = a.matrix<T>("L");
936 const Matrix<T> F = a.matrix<T>("F");
937 const std::string which = a.text("matrices", "GR");
938 if (which != "G" && which != "R" && which != "GR" && which != "RG")
939 throw InputError("qbd_fundmat: 'matrices' must be \"G\", \"R\", \"GR\" or \"RG\"");
940 const bool lf = long_form(a, "qbd_fundmat", {"precision", "maxNumIt"}, {"precision", "maxNumIt"});
941 const T tol = lf ? a.number<T>("precision") : T();
942 const unsigned it = lf ? a.uinteger("maxNumIt") : 0u;
943 a.opt("precision");
944 a.opt("maxNumIt");
945 a.done();
946 const mam::QbdFundMat<T> r = lf ? mam::qbd_fundmat(B, L, F, it, tol) : mam::qbd_fundmat(B, L, F);
947 Json o;
948 if (which.find('G') != std::string::npos) o["G"] = encode_matrix(r.G);
949 if (which.find('R') != std::string::npos) o["R"] = encode_matrix(r.R);
950 return o;
951 }
952};
953
954struct OpQbdCaudal {
955 template <class T>
956 static Json run(Args& a) {
957 const Matrix<T> R = a.matrix<T>("R");
958 const bool lf = long_form(a, "qbd_caudal", {"iter_max", "tol"}, {"iter_max", "tol"});
959 const unsigned it = lf ? a.uinteger("iter_max") : 0u;
960 const T tol = lf ? a.number<T>("tol") : T();
961 a.opt("iter_max");
962 a.opt("tol");
963 a.done();
964 Json o;
965 o["eta"] = encode_scalar(lf ? mam::qbd_caudal(R, it, tol) : mam::qbd_caudal(R));
966 return o;
967 }
968};
969
970struct OpQbdPi {
971 template <class T>
972 static Json run(Args& a) {
973 const Matrix<T> B = a.matrix<T>("B");
974 const Matrix<T> Lbar = a.matrix<T>("Lbar");
975 const Matrix<T> R = a.matrix<T>("R");
976 const bool lf = long_form(a, "qbd_pi", {"max_levels", "mass_tol"}, {"max_levels", "mass_tol"});
977 const std::size_t ml = lf ? a.count("max_levels") : 0u;
978 const T mt = lf ? a.number<T>("mass_tol") : T();
979 a.opt("max_levels");
980 a.opt("mass_tol");
981 a.done();
982 Json o;
983 o["pi"] = encode_matrix(lf ? mam::qbd_pi(B, Lbar, R, ml, mt) : mam::qbd_pi(B, Lbar, R));
984 return o;
985 }
986};
987
988template <bool G>
989struct OpQbdResidual {
990 template <class T>
991 static Json run(Args& a) {
992 const Matrix<T> B = a.matrix<T>("B");
993 const Matrix<T> L = a.matrix<T>("L");
994 const Matrix<T> F = a.matrix<T>("F");
995 const Matrix<T> X = a.matrix<T>(G ? "G" : "R");
996 a.done();
997 Json o;
998 o["residual"] = encode_scalar(G ? mam::qbd_G_residual(B, L, F, X) : mam::qbd_R_residual(B, L, F, X));
999 return o;
1000 }
1001};
1002
1003struct OpQbdMapmap1Blocks {
1004 template <class T>
1005 static Json run(Args& a) {
1006 const mam::Map<T> arr = read_map<T>(a, "arrival");
1007 const mam::Map<T> srv = read_map<T>(a, "service");
1008 a.done();
1009 const mam::QbdMapMap1Blocks<T> r = mam::qbd_mapmap1_blocks(arr, srv);
1010 Json o;
1011 o["B"] = encode_matrix(r.B);
1012 o["L"] = encode_matrix(r.L);
1013 o["F"] = encode_matrix(r.F);
1014 o["Lbar"] = encode_matrix(r.Lbar);
1015 return o;
1016 }
1017};
1018
1019template <bool Fact>
1020struct OpQbdQlenMoment {
1021 template <class T>
1022 static Json run(Args& a) {
1023 const std::vector<T> pi0 = a.vector<T>("pi0");
1024 const Matrix<T> R = a.matrix<T>("R");
1025 const unsigned m = a.uinteger("m");
1026 a.done();
1027 Json o;
1028 if (Fact)
1029 o["factmoment"] = encode_scalar(mam::qbd_qlen_factmoment(pi0, R, m));
1030 else
1031 o["moment"] = encode_scalar(mam::qbd_qlen_moment(pi0, R, m));
1032 return o;
1033 }
1034};
1035
1036struct OpQbdRg {
1037 template <class T>
1038 static Json run(Args& a) {
1039 const mam::Map<T> arr = read_map<T>(a, "MAPa");
1040 const mam::Map<T> srv = read_map<T>(a, "MAPs");
1041 const bool hu = a.has("util");
1042 const T util = hu ? a.number<T>("util") : T();
1043 a.opt("util");
1044 a.done();
1045 const mam::QbdRg<T> r = hu ? mam::qbd_rg(arr, srv, util) : mam::qbd_rg(arr, srv);
1046 Json o;
1047 o["R"] = encode_matrix(r.R);
1048 o["G"] = encode_matrix(r.G);
1049 o["B"] = encode_matrix(r.B);
1050 o["L"] = encode_matrix(r.L);
1051 o["F"] = encode_matrix(r.F);
1052 o["U"] = encode_matrix(r.U);
1053 return o;
1054 }
1055};
1056
1057struct OpQbdMapmap1 {
1058 template <class T>
1059 static Json run(Args& a) {
1060 const mam::Map<T> arr = read_map<T>(a, "MAPa");
1061 const mam::Map<T> srv = read_map<T>(a, "MAPs");
1062 const bool lf = long_form(a, "qbd_mapmap1", {"util", "max_levels"}, {"util", "max_levels"});
1063 const T util = lf ? a.number<T>("util") : T();
1064 const std::size_t ml = lf ? a.count("max_levels") : 0u;
1065 a.opt("util");
1066 a.opt("max_levels");
1067 a.done();
1068 const mam::QbdMapMap1Result<T> r = lf ? mam::qbd_mapmap1(arr, srv, util, ml) : mam::qbd_mapmap1(arr, srv);
1069 Json o;
1070 o["XN"] = encode_scalar(r.XN);
1071 o["QN"] = encode_scalar(r.QN);
1072 o["UN"] = encode_scalar(r.UN);
1073 o["pqueue"] = encode_matrix(r.pqueue);
1074 o["R"] = encode_matrix(r.R);
1075 o["eta"] = encode_scalar(r.eta);
1076 o["G"] = encode_matrix(r.G);
1077 o["A_1"] = encode_matrix(r.B);
1078 o["A0"] = encode_matrix(r.L);
1079 o["A1"] = encode_matrix(r.F);
1080 o["U"] = encode_matrix(r.U);
1081 o["MAPs"] = encode_map(r.service);
1082 return o;
1083 }
1084};
1085
1086struct OpQbdMapmap1QlenTruncated {
1087 template <class T>
1088 static Json run(Args& a) {
1089 const Json& j = a.get("res");
1090 if (!j.is_object() || j.find("pqueue") == j.end())
1091 throw InputError("'res' must be the result object of qbd_mapmap1, carrying at least "
1092 "'pqueue' (the only field this function reads)");
1093 mam::QbdMapMap1Result<T> r;
1094 r.pqueue = matrix_from_json<T>(j["pqueue"], "'res.pqueue'");
1095 a.done();
1096 Json o;
1098 return o;
1099 }
1100};
1101
1102struct OpQbdRap {
1103 template <class T>
1104 static Json run(Args& a) {
1105 const Matrix<T> A0 = a.matrix<T>("A0");
1106 const Matrix<T> A1 = a.matrix<T>("A1");
1107 const Matrix<T> A2 = a.matrix<T>("A2");
1108 const bool lf = long_form(a, "qbd_rap", {"B0", "B1", "numLevels"}, {"B0", "B1", "numLevels"});
1109 const Matrix<T> B0 = lf ? a.matrix<T>("B0") : Matrix<T>();
1110 const Matrix<T> B1 = lf ? a.matrix<T>("B1") : Matrix<T>();
1111 const std::size_t nl = lf ? a.count("numLevels") : 0u;
1112 a.opt("B0");
1113 a.opt("B1");
1114 a.opt("numLevels");
1115 a.done();
1116 const mam::QbdRapResult<T> r = lf ? mam::qbd_rap(A0, A1, A2, B0, B1, nl) : mam::qbd_rap(A0, A1, A2);
1117 Json o;
1118 o["levelProb"] = encode_vector(r.levelProb);
1119 o["QN"] = encode_scalar(r.QN);
1120 o["R"] = encode_matrix(r.R);
1121 o["G"] = encode_matrix(r.G);
1122 o["U"] = encode_matrix(r.U);
1123 o["spr"] = r.spr;
1124 o["pqueue"] = encode_matrix(r.pqueue);
1125 o["pi0"] = encode_vector(r.pi0);
1126 return o;
1127 }
1128};
1129
1130struct OpQbdBmapbmap1 {
1131 template <class T>
1132 static Json run(Args& a) {
1133 const mam::Map<T> arr = read_map<T>(a, "MAPa");
1134 const std::vector<T> pb = a.vector<T>("pbatcha");
1135 const mam::Map<T> srv = read_map<T>(a, "MAPs");
1136 a.done();
1137 const mam::QbdBmapBmap1Blocks<T> r = mam::qbd_bmapbmap1(arr, pb, srv);
1138 Json o;
1139 o["A1"] = encode_matrices(r.A1);
1140 o["A0"] = encode_matrix(r.A0);
1141 o["A_1"] = encode_matrix(r.Am1);
1142 o["A0bar"] = encode_matrix(r.A0bar);
1143 o["B0"] = encode_matrix(r.B0);
1144 o["B1"] = encode_matrices(r.B1);
1145 return o;
1146 }
1147};
1148
1149struct OpLdqbd {
1150 template <class T>
1151 static Json run(Args& a) {
1152 const std::vector<Matrix<T> > q0 = a.matrices<T>("Q0");
1153 const std::vector<Matrix<T> > q1 = a.matrices<T>("Q1");
1154 // MATLAB holds Q2{1..N} = the down-blocks of levels 1..N; the port indexes
1155 // them by level, 0..N, with slot 0 unused.
1156 std::vector<Matrix<T> > q2(1, Matrix<T>());
1157 for (const Matrix<T>& m : a.matrices<T>("Q2")) q2.push_back(m);
1158 a.unsupported("options", "its fields (epsilon, maxIter, verbose) are only printed by the "
1159 "MATLAB reference under verbose and never change the result; the "
1160 "recursion is exact and takes no tolerance.");
1161 a.done();
1162 const mam::LdqbdResult<T> r = mam::ldqbd(q0, q1, q2);
1163 std::vector<Matrix<T> > Rout;
1164 for (std::size_t n = 1; n < r.R.size(); ++n) Rout.push_back(r.R[n]);
1165 Json o;
1166 o["R"] = encode_matrices(Rout);
1167 o["pi"] = encode_vector(r.pi.pi);
1168 return o;
1169 }
1170};
1171
1172struct OpLdqbdCensor {
1173 template <class T>
1174 static Json run(Args& a) {
1175 const Matrix<T> Q = a.matrix<T>("Q");
1176 // phases: one vector of per-level phase counts per set (a MATLAB cell).
1177 std::vector<std::vector<std::size_t> > phases;
1178 for (const Matrix<double>& m : a.matrices<double>("phases")) {
1179 std::vector<std::size_t> P;
1180 for (std::size_t i = 0; i < m.rows(); ++i)
1181 for (std::size_t j = 0; j < m.cols(); ++j) {
1182 const double v = m(i, j);
1183 if (!(v >= 1) || v != static_cast<double>(static_cast<std::size_t>(v)))
1184 throw InputError(ErrorKind{"Argument"},
1185 "ldqbd_censor: phases must hold positive integers");
1186 P.push_back(static_cast<std::size_t>(v));
1187 }
1188 phases.push_back(P);
1189 }
1190 double tol = 1e-10;
1191 a.unsupported("options", "only options.tol is read by the reference and it is passed as 'tol'.");
1192 if (a.has("tol")) tol = a.number<double>("tol");
1193 a.done();
1194 const mam::LdqbdCensorResult<T> r = mam::ldqbd_censor(Q, phases, tol);
1195 Json cells = Json::array();
1196 for (const auto& set : r.pi_cells) cells.push_back(encode_vectors(set));
1197 Json o;
1198 o["pi"] = encode_vector(r.pi);
1199 o["pi_cell"] = cells;
1200 return o;
1201 }
1202};
1203
1204struct OpLdqbdMphc {
1205 template <class T>
1206 static Json run(Args& a) {
1207 const Matrix<T> D0 = a.matrix<T>("D0");
1208 const Matrix<T> D1 = a.matrix<T>("D1");
1209 const std::vector<T> alpha = a.vector<T>("alpha");
1210 const double c = a.number<double>("c");
1211 const std::vector<T> arr = a.vector<T>("arrRate");
1212 const std::vector<T> sf = a.vector_or_empty<T>("sf");
1213 const bool hc = a.has("carry");
1214 const bool carry = a.boolean("carry", false);
1215 a.done();
1216 const mam::LdqbdMphcBlocks<T> r =
1217 hc ? mam::ldqbd_mphc(D0, D1, alpha, c, arr, sf, carry) : mam::ldqbd_mphc(D0, D1, alpha, c, arr, sf);
1218 // MATLAB's Q2 holds the down-blocks of levels 1..Nlev; the port's slot 0 is unused.
1219 std::vector<Matrix<T> > q2;
1220 for (std::size_t n = 1; n < r.Q2.size(); ++n) q2.push_back(r.Q2[n]);
1221 Json o;
1222 o["Q0"] = encode_matrices(r.Q0);
1223 o["Q1"] = encode_matrices(r.Q1);
1224 o["Q2"] = encode_matrices(q2);
1225 return o;
1226 }
1227};
1228
1229// ---------------------------------------------------------------------------
1230// Setup / delay-off queues
1231// ---------------------------------------------------------------------------
1232
1233struct OpQbdSetupdelayoff {
1234 template <class T>
1235 static Json run(Args& a) {
1236 const T lambda = a.number<T>("lambda");
1237 const T mu = a.number<T>("mu");
1238 const T ar = a.number<T>("alpharate");
1239 const T as = a.number<T>("alphascv");
1240 const T br = a.number<T>("betarate");
1241 const T bs = a.number<T>("betascv");
1242 a.done();
1243 Json o;
1244 o["QN"] = encode_scalar(mam::qbd_setupdelayoff(lambda, mu, ar, as, br, bs));
1245 return o;
1246 }
1247};
1248
1249struct OpQbdSetupdelayoffClosed {
1250 template <class T>
1251 static Json run(Args& a) {
1252 const T N = a.number<T>("N");
1253 const T Z = a.number<T>("Z");
1254 const T mu = a.number<T>("mu");
1255 const T ar = a.number<T>("alpharate");
1256 const T as = a.number<T>("alphascv");
1257 const T br = a.number<T>("betarate");
1258 const T bs = a.number<T>("betascv");
1259 a.done();
1260 const mam::SetupDelayoffClosed<T> r = mam::qbd_setupdelayoff_closed(N, Z, mu, ar, as, br, bs);
1261 Json o;
1262 o["QN"] = encode_scalar(r.QN);
1263 o["XN"] = encode_scalar(r.XN);
1264 return o;
1265 }
1266};
1267
1268struct OpQbdSetupdelayoffMmk {
1269 template <class T>
1270 static Json run(Args& a) {
1271 const int k = a.required_integer("k");
1272 const double N = a.number<double>("N");
1273 const T arv = a.number<T>("arv");
1274 const T mu = a.number<T>("mu");
1275 const T ar = a.number<T>("alpharate");
1276 const T as = a.number<T>("alphascv");
1277 const T br = a.number<T>("betarate");
1278 const T bs = a.number<T>("betascv");
1279 a.done();
1280 const mam::SetupDelayoffMMk<T> r = mam::qbd_setupdelayoff_mmk(k, N, arv, mu, ar, as, br, bs);
1281 Json o;
1282 o["QN"] = encode_scalar(r.QN);
1283 o["XN"] = encode_scalar(r.XN);
1284 return o;
1285 }
1286};
1287
1288// ---------------------------------------------------------------------------
1289// AMAP(2) / APH(2)
1290// ---------------------------------------------------------------------------
1291
1292struct OpAmap2AdjustGamma {
1293 template <class T>
1294 static Json run(Args& a) {
1295 const T M1 = a.number<T>("M1");
1296 const T M2 = a.number<T>("M2");
1297 const T M3 = a.number<T>("M3");
1298 const T G = a.number<T>("GAMMA");
1299 const bool full = long_form(a, "amap2_adjust_gamma", {"weights", "constraints", "tol"},
1300 {"weights", "method", "constraints", "tol"});
1301 const bool hm = a.has("method");
1302 mam::Amap2AdjustGammaResult<T> r;
1303 if (full) {
1304 const std::vector<T> w = a.vector<T>("weights");
1305 const int method = a.required_integer("method");
1306 const int cons = a.required_integer("constraints");
1307 const T tol = a.number<T>("tol");
1308 a.done();
1309 r = mam::amap2_adjust_gamma(M1, M2, M3, G, w, method, cons, tol);
1310 } else if (hm) {
1311 const int method = a.required_integer("method");
1312 a.opt("weights");
1313 a.opt("constraints");
1314 a.opt("tol");
1315 a.done();
1316 r = mam::amap2_adjust_gamma(M1, M2, M3, G, method);
1317 } else {
1318 a.opt("weights");
1319 a.opt("method");
1320 a.opt("constraints");
1321 a.opt("tol");
1322 a.done();
1323 r = mam::amap2_adjust_gamma(M1, M2, M3, G);
1324 }
1325 Json o;
1326 o["M2a"] = encode_scalar(r.M2a);
1327 o["M3a"] = encode_scalar(r.M3a);
1328 o["GAMMAa"] = encode_scalar(r.GAMMAa);
1329 o["objective"] = encode_scalar(r.objective);
1330 o["feasible"] = r.feasible;
1331 return o;
1332 }
1333};
1334
1335struct OpAmap2Assemble {
1336 template <class T>
1337 static Json run(Args& a) {
1338 const T l1 = a.number<T>("l1");
1339 const T l2 = a.number<T>("l2");
1340 const T p1 = a.number<T>("p1");
1341 const T p2 = a.number<T>("p2");
1342 const int form = a.required_integer("form");
1343 a.done();
1344 Json o;
1345 o["AMAP"] = encode_map(mam::amap2_assemble(l1, l2, p1, p2, form));
1346 return o;
1347 }
1348};
1349
1350struct OpAmap2FitGamma {
1351 template <class T>
1352 static Json run(Args& a) {
1353 const T M1 = a.number<T>("M1");
1354 const T M2 = a.number<T>("M2");
1355 const T M3 = a.number<T>("M3");
1356 const T G = a.number<T>("GAMMA");
1357 const bool ht = a.has("cvtol");
1358 const T cvtol = ht ? a.number<T>("cvtol") : T();
1359 a.opt("cvtol");
1360 a.done();
1361 const mam::Amap2FitGammaResult<T> r =
1362 ht ? mam::amap2_fit_gamma(M1, M2, M3, G, cvtol) : mam::amap2_fit_gamma(M1, M2, M3, G);
1363 Json o;
1364 o["AMAP"] = encode_map(r.amap);
1365 o["AMAPS"] = encode_maps(r.amaps);
1366 o["adjusted"] = r.adjusted;
1367 o["poisson_fallback"] = r.poisson_fallback;
1368 return o;
1369 }
1370};
1371
1372struct OpAmap2FitallGamma {
1373 template <class T>
1374 static Json run(Args& a) {
1375 const T M1 = a.number<T>("M1");
1376 const T M2 = a.number<T>("M2");
1377 const T M3 = a.number<T>("M3");
1378 const T G = a.number<T>("GAMMA");
1379 const bool lf = long_form(a, "amap2_fitall_gamma", {"degentol", "r12tol"}, {"degentol", "r12tol"});
1380 const T dt = lf ? a.number<T>("degentol") : T();
1381 const T rt = lf ? a.number<T>("r12tol") : T();
1382 a.opt("degentol");
1383 a.opt("r12tol");
1384 a.done();
1385 Json o;
1386 o["AMAPS"] = encode_maps(lf ? mam::amap2_fitall_gamma(M1, M2, M3, G, dt, rt)
1387 : mam::amap2_fitall_gamma(M1, M2, M3, G));
1388 return o;
1389 }
1390};
1391
1392struct OpAph2Adjust {
1393 template <class T>
1394 static Json run(Args& a) {
1395 const T M1 = a.number<T>("M1");
1396 const T M2 = a.number<T>("M2");
1397 const T M3 = a.number<T>("M3");
1398 const std::string method = a.text("method", "simple");
1399 if (a.has("method") && method != "simple")
1400 throw UnsupportedError(ErrorKind{"JsonApi"},
1401 "aph2_adjust: only method \"simple\" is ported to C++; got \"" +
1402 method + "\".");
1403 const bool ht = a.has("tol");
1404 const T tol = ht ? a.number<T>("tol") : T();
1405 a.opt("tol");
1406 a.done();
1407 const mam::Aph2AdjustResult<T> r = ht ? mam::aph2_adjust(M1, M2, M3, tol) : mam::aph2_adjust(M1, M2, M3);
1408 Json o;
1409 o["M2a"] = encode_scalar(r.M2a);
1410 o["M3a"] = encode_scalar(r.M3a);
1411 return o;
1412 }
1413};
1414
1415struct OpAph2Assemble {
1416 template <class T>
1417 static Json run(Args& a) {
1418 const T l1 = a.number<T>("l1");
1419 const T l2 = a.number<T>("l2");
1420 const T p1 = a.number<T>("p1");
1421 a.done();
1422 Json o;
1423 o["APH"] = encode_map(mam::aph2_assemble(l1, l2, p1));
1424 return o;
1425 }
1426};
1427
1428struct OpAph2Fit {
1429 template <class T>
1430 static Json run(Args& a) {
1431 const T M1 = a.number<T>("M1");
1432 const T M2 = a.number<T>("M2");
1433 const T M3 = a.number<T>("M3");
1434 a.done();
1435 const mam::Aph2FitResult<T> r = mam::aph2_fit(M1, M2, M3);
1436 Json o;
1437 o["APH"] = encode_map(r.aph);
1438 o["APHS"] = encode_maps(r.aphs);
1439 o["adjusted"] = r.adjusted;
1440 return o;
1441 }
1442};
1443
1444struct OpAph2Fitall {
1445 template <class T>
1446 static Json run(Args& a) {
1447 const T M1 = a.number<T>("M1");
1448 const T M2 = a.number<T>("M2");
1449 const T M3 = a.number<T>("M3");
1450 const bool ht = a.has("degentol");
1451 const T dt = ht ? a.number<T>("degentol") : T();
1452 a.opt("degentol");
1453 a.done();
1454 Json o;
1455 o["APHS"] = encode_maps(ht ? mam::aph2_fitall(M1, M2, M3, dt) : mam::aph2_fitall(M1, M2, M3));
1456 return o;
1457 }
1458};
1459
1460// ---------------------------------------------------------------------------
1461// MAP(2) / MMPP(2) fitting
1462// ---------------------------------------------------------------------------
1463
1464struct OpMap2Fit {
1465 template <class T>
1466 static Json run(Args& a) {
1467 const T e1 = a.number<T>("e1");
1468 const T e2 = a.number<T>("e2");
1469 const bool h3 = a.has("e3");
1470 const T e3 = h3 ? a.number<T>("e3") : T();
1471 a.opt("e3");
1472 const T g2 = a.number<T>("g2");
1473 a.done();
1474 const mam::Map2FitResult<T> r = h3 ? mam::map2_fit(e1, e2, e3, g2) : mam::map2_fit(e1, e2, g2);
1475 Json o;
1476 o["MAP"] = r.has_map ? encode_map(r.map) : Json::array();
1477 o["ERR"] = r.err;
1478 return o;
1479 }
1480};
1481
1482struct OpMap2FitIdc {
1483 template <class T>
1484 static Json run(Args& a) {
1485 const T e1 = a.number<T>("e1");
1486 const T e2 = a.number<T>("e2");
1487 const T e3 = a.number<T>("e3");
1488 const T I = a.number<T>("I");
1489 a.done();
1490 const mam::Map2FitIdcResult<T> r = mam::map2_fit_idc(e1, e2, e3, I);
1491 Json o;
1492 o["MAP"] = encode_map(r.map);
1493 o["status"] = r.status;
1494 return o;
1495 }
1496};
1497
1498struct OpMmpp2Fit {
1499 template <class T>
1500 static Json run(Args& a) {
1501 const T E1 = a.number<T>("E1");
1502 const T E2 = a.number<T>("E2");
1503 const T E3 = a.number<T>("E3");
1504 const T g = a.number<T>("ACFLAG1");
1505 a.done();
1506 Json o;
1507 o["MAP"] = encode_map(mam::mmpp2_fit(E1, E2, E3, g));
1508 return o;
1509 }
1510};
1511
1512struct OpMmpp2Fit1 {
1513 template <class T>
1514 static Json run(Args& a) {
1515 const T mean = a.number<T>("mean");
1516 const T scv = a.number<T>("scv");
1517 const T skew = a.number<T>("skew");
1518 const T idc = a.number<T>("idc");
1519 a.done();
1520 const mam::Map2FitResult<T> r = mam::mmpp2_fit1(mean, scv, skew, idc);
1521 Json o;
1522 o["MAP"] = r.has_map ? encode_map(r.map) : Json::array();
1523 return o;
1524 }
1525};
1526
1527template <bool Four>
1528struct OpMmpp2Fit24 {
1529 template <class T>
1530 static Json run(Args& a) {
1531 const T mean = a.number<T>("mean");
1532 const T scv = a.number<T>("scv");
1533 const T skew = a.number<T>("skew");
1534 const T g = a.number<T>(Four ? "acf1" : "g2");
1535 a.done();
1536 const mam::Mmpp2FitResult<T> r = Four ? mam::mmpp2_fit4(mean, scv, skew, g) : mam::mmpp2_fit2(mean, scv, skew, g);
1537 Json o;
1538 o["MAP"] = encode_map(r.map);
1539 o["feasible"] = r.feasible;
1540 return o;
1541 }
1542};
1543
1544struct OpMmpp2Fit3 {
1545 template <class T>
1546 static Json run(Args& a) {
1547 const T E1 = a.number<T>("E1");
1548 const T E2 = a.number<T>("E2");
1549 const T E3 = a.number<T>("E3");
1550 const T G2 = a.number<T>("G2");
1551 const bool ht = a.has("g2tol");
1552 const T tol = ht ? a.number<T>("g2tol") : T();
1553 a.opt("g2tol");
1554 a.done();
1555 Json o;
1556 o["MAP"] = encode_map(ht ? mam::mmpp2_fit3(E1, E2, E3, G2, tol) : mam::mmpp2_fit3(E1, E2, E3, G2));
1557 return o;
1558 }
1559};
1560
1561struct OpMmpp2Fitc {
1562 template <class T>
1563 static Json run(Args& a) {
1564 const T mu = a.number<T>("mu");
1565 const T bt1 = a.number<T>("bt1");
1566 const T bt2 = a.number<T>("bt2");
1567 const T binf = a.number<T>("binf");
1568 const T m3t2 = a.number<T>("m3t2");
1569 const T t1 = a.number<T>("t1");
1570 const T t2 = a.number<T>("t2");
1571 a.done();
1572 const mam::Mmpp2FitcResult<T> r = mam::mmpp2_fitc(mu, bt1, bt2, binf, m3t2, t1, t2);
1573 Json o;
1574 o["mmpp"] = encode_map(r.map);
1575 o["degenerate"] = r.degenerate;
1576 o["third_moment_ok"] = r.third_moment_ok;
1577 return o;
1578 }
1579};
1580
1581struct OpMmpp2FitcApprox {
1582 template <class T>
1583 static Json run(Args& a) {
1584 const T x = a.number<T>("a");
1585 const T bt1 = a.number<T>("bt1");
1586 const T bt2 = a.number<T>("bt2");
1587 const T binf = a.number<T>("binf");
1588 const T m3t2 = a.number<T>("m3t2");
1589 const T t1 = a.number<T>("t1");
1590 const T t2 = a.number<T>("t2");
1591 a.done();
1592 const mam::Mmpp2FitcApproxResult<T> r = mam::mmpp2_fitc_approx(x, bt1, bt2, binf, m3t2, t1, t2);
1593 Json o;
1594 o["FIT"] = encode_map(r.map);
1595 o["objective"] = encode_scalar(r.objective);
1596 o["violation"] = encode_scalar(r.violation);
1597 o["converged"] = r.converged;
1598 return o;
1599 }
1600};
1601
1602struct OpMmpp2FitcTheoretical {
1603 template <class T>
1604 static Json run(Args& a) {
1605 const mam::Map<T> m = read_map<T>(a, "map");
1606 const bool lf = long_form(a, "mmpp2_fitc_theoretical", {"t1", "t2", "tinf"}, {"t1", "t2", "tinf"});
1607 const T t1 = lf ? a.number<T>("t1") : T();
1608 const T t2 = lf ? a.number<T>("t2") : T();
1609 const T ti = lf ? a.number<T>("tinf") : T();
1610 a.opt("t1");
1611 a.opt("t2");
1612 a.opt("tinf");
1613 a.done();
1614 const mam::Mmpp2FitcResult<T> r = lf ? mam::mmpp2_fitc_theoretical(m, t1, t2, ti) : mam::mmpp2_fitc_theoretical(m);
1615 Json o;
1616 o["fit"] = encode_map(r.map);
1617 o["degenerate"] = r.degenerate;
1618 o["third_moment_ok"] = r.third_moment_ok;
1619 return o;
1620 }
1621};
1622
1623// ---------------------------------------------------------------------------
1624// M3PP
1625// ---------------------------------------------------------------------------
1626
1627struct OpM3ppSuperposFitc {
1628 template <class T>
1629 static Json run(Args& a) {
1630 const std::vector<T> av = a.vector<T>("av");
1631 const std::vector<T> btv = a.vector<T>("btv");
1632 const std::vector<T> binfv = a.vector<T>("binfv");
1633 const std::vector<T> m3tv = a.vector<T>("m3tv");
1634 const T t = a.number<T>("t");
1635 const T tinf = a.number<T>("tinf");
1636 a.done();
1637 const mam::M3ppSuperposResult<T> r = mam::m3pp_superpos_fitc(av, btv, binfv, m3tv, t, tinf);
1638 Json o;
1639 o["fit"] = encode_mmap(r.mmap);
1640 o["m3pps"] = encode_mmaps(r.parts);
1641 return o;
1642 }
1643};
1644
1645/** The ten characteristics m3pp2m_fitc and its approximate variants share. */
1646template <class T>
1647struct M3pp2mChars {
1648 T a, bt1, bt2, binf, m3t2, t1, t2, t3;
1649 std::vector<T> ai, third;
1650};
1651
1652template <class T>
1653M3pp2mChars<T> read_m3pp2m(Args& a, const char* third) {
1654 M3pp2mChars<T> c;
1655 c.a = a.number<T>("a");
1656 c.bt1 = a.number<T>("bt1");
1657 c.bt2 = a.number<T>("bt2");
1658 c.binf = a.number<T>("binf");
1659 c.m3t2 = a.number<T>("m3t2");
1660 c.t1 = a.number<T>("t1");
1661 c.t2 = a.number<T>("t2");
1662 c.ai = a.vector<T>("ai");
1663 c.third = a.vector<T>(third);
1664 c.t3 = a.number<T>("t3");
1665 a.done();
1666 return c;
1667}
1668
1669struct OpM3pp2mFitc {
1670 template <class T>
1671 static Json run(Args& a) {
1672 const M3pp2mChars<T> c = read_m3pp2m<T>(a, "dvt3");
1673 const mam::M3pp2mFitcResult<T> r =
1674 mam::m3pp2m_fitc(c.a, c.bt1, c.bt2, c.binf, c.m3t2, c.t1, c.t2, c.ai, c.third, c.t3);
1675 Json o;
1676 o["mmmpp"] = encode_mmap(r.mmap);
1677 o["degenerate"] = r.degenerate;
1678 return o;
1679 }
1680};
1681
1682template <bool Ag>
1683struct OpM3pp2mFitcApprox {
1684 template <class T>
1685 static Json run(Args& a) {
1686 const M3pp2mChars<T> c = read_m3pp2m<T>(a, Ag ? "gt3" : "dvt3");
1687 const mam::M3pp2mFitcApproxResult<T> r =
1688 Ag ? mam::m3pp2m_fitc_approx_ag(c.a, c.bt1, c.bt2, c.binf, c.m3t2, c.t1, c.t2, c.ai, c.third, c.t3)
1689 : mam::m3pp2m_fitc_approx(c.a, c.bt1, c.bt2, c.binf, c.m3t2, c.t1, c.t2, c.ai, c.third, c.t3);
1690 Json o;
1691 o["FIT"] = encode_mmap(r.mmap);
1692 o["mmpp_objective"] = encode_scalar(r.mmpp_objective);
1693 o["class_objective"] = encode_scalar(r.class_objective);
1694 o["class_violation"] = encode_scalar(r.class_violation);
1695 o["degenerate"] = r.degenerate;
1696 o["feasible"] = r.feasible;
1697 return o;
1698 }
1699};
1700
1701struct OpM3pp2mFitcTrace {
1702 template <class T>
1703 static Json run(Args& a) {
1704 const std::vector<T> Tv = a.vector<T>("T");
1705 const std::vector<int> A = a.ints("A");
1706 const Json& jm = a.get("method");
1707 if (!jm.is_string()) throw InputError("'method' must be a string");
1708 const std::string method = jm.get<std::string>();
1709 const bool lf = long_form(a, "m3pp2m_fitc_trace", {"t1", "tinf"}, {"t1", "tinf"});
1710 const T t1 = lf ? a.number<T>("t1") : T();
1711 const T ti = lf ? a.number<T>("tinf") : T();
1712 a.opt("t1");
1713 a.opt("tinf");
1714 a.done();
1715 const mam::M3pp2mFitcTraceResult<T> r =
1716 lf ? mam::m3pp2m_fitc_trace(Tv, A, method, t1, ti) : mam::m3pp2m_fitc_trace(Tv, A, method);
1717 Json o;
1718 o["fit"] = encode_mmap(r.mmap);
1719 return o;
1720 }
1721};
1722
1723// ---------------------------------------------------------------------------
1724// Fluid queues
1725// ---------------------------------------------------------------------------
1726
1727struct OpMfqSojourn {
1728 template <class T>
1729 static Json run(Args& a) {
1730 const Matrix<T> Q = a.matrix<T>("Q");
1731 const Matrix<T> Rin = a.matrix<T>("Rin");
1732 const Matrix<T> Rout = a.matrix<T>("Rout");
1733 const bool lf = long_form(a, "mfq_sojourn", {"Q0", "transToPH", "prec"}, {"transToPH", "prec"});
1734 const Matrix<T> Q0 = a.matrix_or_empty<T>("Q0");
1735 const bool tp = a.boolean("transToPH", false);
1736 const T prec = lf ? a.number<T>("prec") : T();
1737 a.opt("prec");
1738 a.done();
1739 const mam::MeRepresentation<T> r = lf ? mam::mfq_sojourn(Q, Rin, Rout, Q0, tp, prec) : mam::mfq_sojourn(Q, Rin, Rout);
1740 Json o;
1741 o["alpha"] = encode_vector(r.alpha);
1742 o["A"] = encode_matrix(r.A);
1743 return o;
1744 }
1745};
1746
1747struct OpMfqFlufluSojourn {
1748 template <class T>
1749 static Json run(Args& a) {
1750 const Matrix<T> Qin = a.matrix<T>("Qin");
1751 const Matrix<T> Rin = a.matrix<T>("Rin");
1752 const Matrix<T> Qout = a.matrix<T>("Qout");
1753 const Matrix<T> Rout = a.matrix<T>("Rout");
1754 if (!a.has("srv0stop")) a.get("srv0stop");
1755 const bool s0 = a.boolean("srv0stop", false);
1756 const bool lf = long_form(a, "mfq_fluflu_sojourn", {"transToPH", "prec"}, {"transToPH", "prec"});
1757 const bool tp = a.boolean("transToPH", false);
1758 const T prec = lf ? a.number<T>("prec") : T();
1759 a.opt("prec");
1760 a.done();
1761 const mam::MeRepresentation<T> r = lf ? mam::mfq_fluflu_sojourn(Qin, Rin, Qout, Rout, s0, tp, prec)
1762 : mam::mfq_fluflu_sojourn(Qin, Rin, Qout, Rout, s0);
1763 Json o;
1764 o["alpha"] = encode_vector(r.alpha);
1765 o["A"] = encode_matrix(r.A);
1766 return o;
1767 }
1768};
1769
1770struct OpMfqLdMean {
1771 template <class T>
1772 static Json run(Args& a) {
1773 const mam::LevelDependentFluidBlocks<T> b = read_ld_blocks<T>(a);
1774 a.done();
1775 Json o;
1776 o["res"] = encode_scalar(mam::mfq_ld_mean(b));
1777 return o;
1778 }
1779};
1780
1781struct OpMfqLdDistr {
1782 template <class T>
1783 static Json run(Args& a) {
1784 const mam::LevelDependentFluidBlocks<T> b = read_ld_blocks<T>(a);
1785 const mam::FluidDistrKind what = distr_kind(a);
1786 const std::vector<T> pts = a.vector<T>("points");
1787 a.done();
1788 Json o;
1789 o["res"] = encode_vectors(mam::mfq_ld_distr(b, what, pts));
1790 return o;
1791 }
1792};
1793
1794struct OpMfqLdSolve {
1795 template <class T>
1796 static Json run(Args& a) {
1797 const std::vector<Matrix<T> > Q = a.matrices<T>("Q");
1798 const std::vector<Matrix<T> > R = a.matrices<T>("R");
1799 const std::vector<Matrix<T> > S = a.matrices<T>("S");
1800 const std::vector<T> Thr = a.vector<T>("T");
1801 const bool lf = long_form(a, "mfq_ld_solve", {"boundaryL", "boundaryU", "Qt", "prec"}, {"prec"});
1802 const std::vector<mam::FluidBoundary> bL = boundaries(a, "boundaryL");
1803 const std::vector<mam::FluidBoundary> bU = boundaries(a, "boundaryU");
1804 const std::vector<Matrix<T> > Qt = a.matrices_or_empty<T>("Qt");
1805 const T prec = lf ? a.number<T>("prec") : T();
1806 a.opt("prec");
1807 a.done();
1808 const mam::LevelDependentFluidBlocks<T> r =
1809 lf ? mam::mfq_ld_solve(Q, R, S, Thr, bL, bU, Qt, prec) : mam::mfq_ld_solve(Q, R, S, Thr);
1810 Json o;
1811 o["masses"] = encode_vectors(r.masses);
1812 o["iniF"] = encode_vectors(r.iniF);
1813 o["KF"] = encode_matrices(r.KF);
1814 o["cloF"] = encode_matrices(r.cloF);
1815 o["iniB"] = encode_vectors(r.iniB);
1816 o["KB"] = encode_matrices(r.KB);
1817 o["cloB"] = encode_matrices(r.cloB);
1818 return o;
1819 }
1820};
1821
1822struct OpMfqMultiregime {
1823 static Json run(Args& a) {
1824 const std::vector<Matrix<double> > Q = a.matrices<double>("Q");
1825 const std::vector<std::vector<double> > R = diagonal_rate_list(a, "R", false);
1826 const std::vector<Matrix<double> > Qt = a.matrices_or_empty<double>("Qt");
1827 const std::vector<std::vector<double> > Rt = diagonal_rate_list(a, "Rt", true);
1828 const std::vector<double> Thr = a.vector<double>("T");
1829 const std::vector<double> pdfp = a.vector_or_empty<double>("pdfpoints");
1830 const std::vector<double> cdfp = a.vector_or_empty<double>("cdfpoints");
1831 a.done();
1832 const mam::MultiRegimeResult r = mam::mfq_multiregime(Q, R, Qt, Rt, Thr, pdfp, cdfp);
1833 Json o;
1834 o["pdf"] = encode_vectors(r.pdf);
1835 o["pdfd"] = encode_vectors(r.pdfd);
1836 o["cdf"] = encode_vectors(r.cdf);
1837 o["cdfm"] = encode_vectors(r.cdfm);
1838 return o;
1839 }
1840};
1841
1842struct OpMfqPrioQueue {
1843 static Json run(Args& a) {
1844 const Matrix<double> Q = a.matrix<double>("Q");
1845 const Matrix<double> R = a.matrix<double>("R");
1846 const double d = a.number<double>("d");
1847 mam::FluidPrioOptions opt;
1848 const bool fm = a.has("flMoms"), fd = a.has("flDistr"), sm = a.has("stMoms"), sd = a.has("stDistr");
1849 if (fm) opt.flMoms = a.count("flMoms");
1850 if (fd) opt.flDistr = a.vector<double>("flDistr");
1851 if (sm) opt.stMoms = a.count("stMoms");
1852 if (sd) opt.stDistr = a.vector<double>("stDistr");
1853 a.opt("flMoms");
1854 a.opt("flDistr");
1855 a.opt("stMoms");
1856 a.opt("stDistr");
1857 if (a.has("prec")) opt.prec = a.number<double>("prec");
1858 a.opt("prec");
1859 if (a.has("erlMaxOrder")) opt.erlMaxOrder = a.count("erlMaxOrder");
1860 a.opt("erlMaxOrder");
1861 if (a.has("classes")) {
1862 for (int c : a.ints("classes")) {
1863 if (c < 1) throw InputError("'classes' are 1-based, as in MATLAB");
1864 opt.classes.push_back(static_cast<std::size_t>(c));
1865 }
1866 }
1867 a.opt("classes");
1868 a.done();
1869 if (!fm && !fd && !sm && !sd)
1870 throw InputError("mfq_prio_queue: ask for at least one measure: flMoms, flDistr, "
1871 "stMoms or stDistr");
1872 const mam::FluidPrioResult r = mam::mfq_prio_queue(Q, R, d, opt);
1873 Json o;
1874 Json cls = Json::array();
1875 for (std::size_t c : r.classes) cls.push_back(static_cast<std::uint64_t>(c));
1876 o["classes"] = cls;
1877 if (fm) o["flMoms"] = encode_vectors(r.flMoms);
1878 if (fd) o["flDistr"] = encode_vectors(r.flDistr);
1879 if (sm) o["stMoms"] = encode_vectors(r.stMoms);
1880 if (sd) o["stDistr"] = encode_vectors(r.stDistr);
1881 return o;
1882 }
1883};
1884
1885// ---------------------------------------------------------------------------
1886// Semi-Markov passage times
1887// ---------------------------------------------------------------------------
1888
1889struct OpSmpPassageMoments {
1890 template <class T>
1891 static Json run(Args& a) {
1892 const Matrix<T> P = a.matrix<T>("P");
1893 const Json& jh = a.get("hmom");
1894 const std::vector<T> pi0 = a.vector_or_empty<T>("pi0");
1895 const std::vector<std::size_t> target = one_based(a.get("target"), "'target'");
1896 const bool hn = a.has("nmax");
1897 const std::size_t nmax = a.count("nmax", 1);
1898 a.done();
1899 // hmom is either (nstates x nmax), or the per-pair cell {i,k} of moment vectors.
1900 const bool cell = jh.is_array() && !jh.empty() && jh[0].is_array() && !jh[0].empty() &&
1901 jh[0][0].is_array();
1902 mc::PassageMoments<T> r;
1903 if (cell) {
1904 std::vector<std::vector<std::vector<T> > > h;
1905 for (std::size_t i = 0; i < jh.size(); ++i)
1906 h.push_back(vectors_from_json<T>(jh[i], "'hmom'[" + std::to_string(i) + "]"));
1907 r = hn ? mc::smp_passage_moments(P, h, pi0, target, nmax) : mc::smp_passage_moments(P, h, pi0, target);
1908 } else {
1909 const Matrix<T> h = matrix_from_json<T>(jh, "'hmom'");
1910 r = hn ? mc::smp_passage_moments(P, h, pi0, target, nmax) : mc::smp_passage_moments(P, h, pi0, target);
1911 }
1912 Json o;
1913 o["Mall"] = encode_matrix(r.mall);
1914 o["m"] = encode_vector(r.m);
1915 return o;
1916 }
1917};
1918
1919// ---------------------------------------------------------------------------
1920// Maximum entropy (api/me)
1921// ---------------------------------------------------------------------------
1922
1923struct OpMeCqn {
1924 template <class T>
1925 static Json run(Args& a) {
1926 const std::size_t M = a.count("M");
1927 const std::size_t R = a.count("R");
1928 const std::vector<long> N = populations(a, "N", false);
1929 const Matrix<T> mu = a.matrix<T>("mu");
1930 const Matrix<T> Cs = a.matrix<T>("Cs");
1931 const std::vector<Matrix<T> > P = per_class_routing<T>(a, "P", R);
1932 const std::vector<long> c = counts_with_inf(a, "c");
1933 const std::vector<long> ref = reference_stations(a, "refstat", R);
1934 const std::vector<char> ins = flags(a, "insens");
1935 const bool ho = a.has("options");
1936 const me::MeOptions opt = me_options(a);
1937 a.done();
1938 const me::MeResult<T> r = ho ? me::me_cqn(M, R, N, mu, Cs, P, c, ref, ins, opt)
1939 : me::me_cqn(M, R, N, mu, Cs, P, c, ref, ins);
1940 return encode_me_result(r, true);
1941 }
1942};
1943
1944struct OpMeMqn {
1945 template <class T>
1946 static Json run(Args& a) {
1947 const std::size_t M = a.count("M");
1948 const std::size_t R = a.count("R");
1949 const std::vector<char> oc = flags(a, "openClasses");
1950 const Matrix<T> lambda0 = a.matrix<T>("lambda0");
1951 const Matrix<T> Ca0 = a.matrix<T>("Ca0");
1952 const std::vector<long> N = populations(a, "N", true);
1953 const Matrix<T> mu = a.matrix<T>("mu");
1954 const Matrix<T> Cs = a.matrix<T>("Cs");
1955 const std::vector<Matrix<T> > P = per_class_routing<T>(a, "P", R);
1956 const std::vector<long> c = counts_with_inf(a, "c");
1957 const std::vector<long> ref = reference_stations(a, "refstat", R);
1958 const std::vector<char> ins = flags(a, "insens");
1959 const bool ho = a.has("options");
1960 const me::MeOptions opt = me_options(a);
1961 a.done();
1962 const me::MeResult<T> r = ho ? me::me_mqn(M, R, oc, lambda0, Ca0, N, mu, Cs, P, c, ref, ins, opt)
1963 : me::me_mqn(M, R, oc, lambda0, Ca0, N, mu, Cs, P, c, ref, ins);
1964 return encode_me_result(r, true);
1965 }
1966};
1967
1968struct OpMeOqn {
1969 template <class T>
1970 static Json run(Args& a) {
1971 const std::size_t M = a.count("M");
1972 const std::size_t R = a.count("R");
1973 const Matrix<T> lambda0 = a.matrix<T>("lambda0");
1974 const Matrix<T> Ca0 = a.matrix<T>("Ca0");
1975 const Matrix<T> mu = a.matrix<T>("mu");
1976 const Matrix<T> Cs = a.matrix<T>("Cs");
1977 const std::vector<Matrix<T> > P = per_class_routing<T>(a, "P", R);
1978 const std::vector<long> c = counts_with_inf(a, "c");
1979 const std::vector<char> ins = flags(a, "insens");
1980 const bool ho = a.has("options");
1981 const me::MeOptions opt = me_options(a);
1982 a.done();
1983 const me::MeResult<T> r = ho ? me::me_oqn(M, R, lambda0, Ca0, mu, Cs, P, c, ins, opt)
1984 : me::me_oqn(M, R, lambda0, Ca0, mu, Cs, P, c, ins);
1985 return encode_me_result(r, false);
1986 }
1987};
1988
1989struct OpMeOqnBlk {
1990 template <class T>
1991 static Json run(Args& a) {
1992 const std::size_t M = a.count("M");
1993 const std::vector<T> lambda0 = a.vector<T>("lambda0");
1994 const std::vector<T> Ca0 = a.vector<T>("Ca0");
1995 const std::vector<T> mu = a.vector<T>("mu");
1996 const std::vector<T> Cs = a.vector<T>("Cs");
1997 const Matrix<T> P = a.matrix<T>("P");
1998 const std::vector<long> c = counts_with_inf(a, "c");
1999 const std::vector<long> N = counts_with_inf(a, "N");
2000 const std::vector<int> br = a.ints("blockrule");
2001 const bool ho = a.has("options");
2002 const me::MeBlkOptions opt = me_blk_options(a);
2003 a.done();
2004 const me::MeBlkResult<T> r = ho ? me::me_oqn_blk(M, lambda0, Ca0, mu, Cs, P, c, N, br, opt)
2005 : me::me_oqn_blk(M, lambda0, Ca0, mu, Cs, P, c, N, br);
2006 Json o;
2007 o["Q"] = encode_vector(r.Q);
2008 o["W"] = encode_vector(r.W);
2009 o["T"] = encode_vector(r.T_);
2010 o["U"] = encode_vector(r.U);
2011 o["Ca"] = encode_vector(r.Ca);
2012 o["Cd"] = encode_vector(r.Cd);
2013 o["PBa"] = encode_vector(r.PBa);
2014 o["lambda"] = encode_vector(r.lambda);
2015 o["iter"] = static_cast<std::int64_t>(r.iter);
2016 o["converged"] = r.converged;
2017 return o;
2018 }
2019};
2020
2021struct OpMeGegecMql {
2022 template <class T>
2023 static Json run(Args& a) {
2024 const T lambda = a.number<T>("lambda");
2025 const T Ca = a.number<T>("Ca");
2026 const T mu = a.number<T>("mu");
2027 const T Cs = a.number<T>("Cs");
2028 const long c = a.required_integer("c");
2029 a.done();
2030 Json o;
2031 o["L"] = encode_scalar(me::me_gegec_mql(lambda, Ca, mu, Cs, c));
2032 return o;
2033 }
2034};
2035
2036struct OpMeGegecn {
2037 template <class T>
2038 static Json run(Args& a) {
2039 const T lambda = a.number<T>("lambda");
2040 const T Ca = a.number<T>("Ca");
2041 const T mu = a.number<T>("mu");
2042 const T Cs = a.number<T>("Cs");
2043 const long c = a.required_integer("c");
2044 const long K = a.required_integer("K");
2045 const long N = a.required_integer("N");
2046 a.done();
2047 const me::GegecnResult<T> r = me::me_gegecn(lambda, Ca, mu, Cs, c, K, N);
2048 Json o;
2049 o["p"] = encode_vector(r.p);
2050 o["L"] = encode_scalar(r.L);
2051 o["U"] = encode_scalar(r.U);
2052 o["PB"] = encode_scalar(r.PB);
2053 o["Lq"] = encode_scalar(r.Lq);
2054 return o;
2055 }
2056};
2057
2058struct OpMeGegecnPb {
2059 template <class T>
2060 static Json run(Args& a) {
2061 const std::vector<T> p = a.vector<T>("p");
2062 const long K = a.required_integer("K");
2063 const long N = a.required_integer("N");
2064 const long c = a.required_integer("c");
2065 const T Cs = a.number<T>("Cs");
2066 const T Ca = a.number<T>("Ca");
2067 a.done();
2068 Json o;
2069 o["PB"] = encode_scalar(me::me_gegecn_pb(p, K, N, c, Cs, Ca));
2070 return o;
2071 }
2072};
2073
2074
2075/**
2076 * MMAP = m3pp_rand(order, classes, seed): a random M3PP. MATLAB's signature
2077 * has no seed and draws from the session RNG; the port takes its engine by
2078 * reference, so the JSON form requires the seed of a std::mt19937_64. The
2079 * result is the [D0, D1, D1_1, ..., D1_C] cell the other mam entries return.
2080 */
2081struct OpM3ppRand {
2082 template <class T>
2083 static Json run(Args& a) {
2084 const std::size_t K = a.count("order");
2085 const std::size_t classes = a.count("classes");
2086 std::mt19937_64 gen(required_seed(a, "m3pp_rand"));
2087 a.done();
2088 Json out;
2089 out["MMAP"] = encode_mmap(mam::m3pp_rand<T>(K, classes, gen));
2090 return out;
2091 }
2092};
2093
2094} // namespace
2095
2097 t["m3pp_rand"] = make<NeedsTranscendental<OpM3ppRand> >();
2098 // Double, Exact and Real.
2099 t["map_infgen"] = make<OpMapInfgen>();
2100 t["map_prob"] = make<OpMapProb>();
2101 t["map_lambda"] = make<OpMapLambda>();
2102 t["map_pie"] = make<OpMapPie>();
2103 t["map_mean"] = make<OpMapMean>();
2104 t["map_embedded"] = make<OpMapEmbedded>();
2105 t["map_moment"] = make<OpMapMoment>();
2106 t["map_var"] = make<OpMapVar>();
2107 t["map_scv"] = make<OpMapScv>();
2108 t["map_acf"] = make<OpMapAcf>();
2109 t["map_idc"] = make<OpMapIdc>();
2110 t["mmap_lambda"] = make<OpMmapLambda>();
2111 t["mmap_count_lambda"] = make<OpMmapCountLambda>();
2112 t["mmap_pc"] = make<OpMmapPc>();
2113 t["mmap_isfeasible"] = make<OpMmapIsfeasible>();
2114 t["mmap_normalize"] = make<OpMmapNormalize>();
2115 t["mmap_scale"] = make<OpMmapScale>();
2116 t["mmap_super"] = make<OpMmapSuper>();
2117 t["map_normalize"] = make<OpMapNormalize>();
2118 t["map_scale"] = make<OpMapScale>();
2119 t["map_exponential_mean"] = make<OpMapExponentialMean>();
2120 t["map_erlang"] = make<OpMapErlang>();
2121 t["map_sum"] = make<OpMapSum>();
2122 t["map_sumind"] = make<OpMapSumind>();
2123 t["map_mixture"] = make<OpMapMixture>();
2124 t["map_renewal"] = make<OpMapRenewal>();
2125 t["ph2map"] = make<OpPh2map>();
2126 t["map_stochcomp"] = make<OpMapStochcomp>();
2127 t["map_kurt"] = make<OpMapKurt>();
2128 t["map_joint"] = make<OpMapJoint>();
2129 t["map_isfeasible"] = make<OpMapIsfeasible>();
2130 t["qbd_pi"] = make<OpQbdPi>();
2131 t["qbd_R_residual"] = make<OpQbdResidual<false> >();
2132 t["qbd_G_residual"] = make<OpQbdResidual<true> >();
2133 t["qbd_mapmap1_blocks"] = make<OpQbdMapmap1Blocks>();
2134 t["qbd_qlen_factmoment"] = make<OpQbdQlenMoment<true> >();
2135 t["qbd_qlen_moment"] = make<OpQbdQlenMoment<false> >();
2136 t["amap2_assemble"] = make<OpAmap2Assemble>();
2137 t["aph2_assemble"] = make<OpAph2Assemble>();
2138 t["map_mark"] = make<OpMapMark>();
2139 t["map_count_mean"] = make<OpMapCountMean>();
2140 t["smp_passage_moments"] = make<OpSmpPassageMoments>();
2141 t["ldqbd"] = make<OpLdqbd>();
2142 t["ldqbd_censor"] = make<OpLdqbdCensor>();
2143 t["ldqbd_mphc"] = make<OpLdqbdMphc>();
2144 t["qbd_bmapbmap1"] = make<OpQbdBmapbmap1>();
2145
2146 // Double and Real.
2147 t["me_cqn"] = make<NeedsTranscendental<OpMeCqn> >();
2148 t["me_mqn"] = make<NeedsTranscendental<OpMeMqn> >();
2149 t["me_oqn"] = make<NeedsTranscendental<OpMeOqn> >();
2150 t["qbd_R"] = make<NeedsTranscendental<OpQbdR<false> > >();
2151 t["qbd_R_logred"] = make<NeedsTranscendental<OpQbdR<true> > >();
2152 t["qbd_fundmat"] = make<NeedsTranscendental<OpQbdFundmat> >();
2153 t["qbd_caudal"] = make<NeedsTranscendental<OpQbdCaudal> >();
2154 t["qbd_rg"] = make<NeedsTranscendental<OpQbdRg> >();
2155 t["qbd_mapmap1"] = make<NeedsTranscendental<OpQbdMapmap1> >();
2156 t["qbd_mapmap1_qlen_truncated"] = make<NeedsTranscendental<OpQbdMapmap1QlenTruncated> >();
2157 t["map_hyperexp"] = make<NeedsTranscendental<OpMapHyperexp> >();
2158 t["map_skew"] = make<NeedsTranscendental<OpMapSkew> >();
2159 t["amap2_adjust_gamma"] = make<NeedsTranscendental<OpAmap2AdjustGamma> >();
2160 t["amap2_fit_gamma"] = make<NeedsTranscendental<OpAmap2FitGamma> >();
2161 t["amap2_fitall_gamma"] = make<NeedsTranscendental<OpAmap2FitallGamma> >();
2162 t["aph2_adjust"] = make<NeedsTranscendental<OpAph2Adjust> >();
2163 t["aph2_fit"] = make<NeedsTranscendental<OpAph2Fit> >();
2164 t["aph2_fitall"] = make<NeedsTranscendental<OpAph2Fitall> >();
2165 t["m3pp_superpos_fitc"] = make<NeedsTranscendental<OpM3ppSuperposFitc> >();
2166 t["m3pp2m_fitc"] = make<NeedsTranscendental<OpM3pp2mFitc> >();
2167 t["m3pp2m_fitc_approx"] = make<NeedsTranscendental<OpM3pp2mFitcApprox<false> > >();
2168 t["m3pp2m_fitc_approx_ag"] = make<NeedsTranscendental<OpM3pp2mFitcApprox<true> > >();
2169 t["m3pp2m_fitc_trace"] = make<NeedsTranscendental<OpM3pp2mFitcTrace> >();
2170 t["map2_fit"] = make<NeedsTranscendental<OpMap2Fit> >();
2171 t["mmpp2_fit"] = make<NeedsTranscendental<OpMmpp2Fit> >();
2172 t["mmpp2_fit1"] = make<NeedsTranscendental<OpMmpp2Fit1> >();
2173 t["mmpp2_fit2"] = make<NeedsTranscendental<OpMmpp2Fit24<false> > >();
2174 t["mmpp2_fit3"] = make<NeedsTranscendental<OpMmpp2Fit3> >();
2175 t["mmpp2_fit4"] = make<NeedsTranscendental<OpMmpp2Fit24<true> > >();
2176 t["mmpp2_fitc"] = make<NeedsTranscendental<OpMmpp2Fitc> >();
2177 t["mmpp2_fitc_approx"] = make<NeedsTranscendental<OpMmpp2FitcApprox> >();
2178 t["mmpp2_fitc_theoretical"] = make<NeedsTranscendental<OpMmpp2FitcTheoretical> >();
2179 t["map_acfc"] = make<NeedsTranscendental<OpMapAcfc> >();
2180 t["map_cdf"] = make<NeedsTranscendental<OpMapCdf> >();
2181 t["map_count_moment"] = make<NeedsTranscendental<OpMapCountMoment> >();
2182 t["map_count_var"] = make<NeedsTranscendental<OpMapCountVar> >();
2183 t["map_pdf"] = make<NeedsTranscendental<OpMapPdf> >();
2184 t["map_varcount"] = make<NeedsTranscendental<OpMapVarcount> >();
2185 t["mmap_count_var"] = make<NeedsTranscendental<OpMmapCountVar> >();
2186 t["mfq_sojourn"] = make<NeedsTranscendental<OpMfqSojourn> >();
2187 t["mfq_fluflu_sojourn"] = make<NeedsTranscendental<OpMfqFlufluSojourn> >();
2188 t["mfq_ld_mean"] = make<NeedsTranscendental<OpMfqLdMean> >();
2189 t["mfq_ld_distr"] = make<NeedsTranscendental<OpMfqLdDistr> >();
2190 t["map2_fit_idc"] = make<NeedsTranscendental<OpMap2FitIdc> >();
2191 t["me_gegec_mql"] = make<NeedsTranscendental<OpMeGegecMql> >();
2192 t["me_gegecn"] = make<NeedsTranscendental<OpMeGegecn> >();
2193 t["me_gegecn_pb"] = make<NeedsTranscendental<OpMeGegecnPb> >();
2194 t["me_oqn_blk"] = make<NeedsTranscendental<OpMeOqnBlk> >();
2195 t["mfq_ld_solve"] = make<NeedsTranscendental<OpMfqLdSolve> >();
2196 t["mmap_compress"] = make<NeedsTranscendental<OpMmapCompress> >();
2197 t["qbd_rap"] = make<NeedsTranscendental<OpQbdRap> >();
2198 t["qbd_setupdelayoff"] = make<NeedsTranscendental<OpQbdSetupdelayoff> >();
2199 t["qbd_setupdelayoff_closed"] = make<NeedsTranscendental<OpQbdSetupdelayoffClosed> >();
2200 t["qbd_setupdelayoff_mmk"] = make<NeedsTranscendental<OpQbdSetupdelayoffMmk> >();
2201
2202 // Double only.
2203 t["mfq_multiregime"] = make<DoubleOnly<OpMfqMultiregime> >();
2204 t["mfq_prio_queue"] = make<DoubleOnly<OpMfqPrioQueue> >();
2205}
2206
2208 const std::string callables =
2209 "its holding-time transforms hlst are callables (std::function of a complex argument, "
2210 "one per state or per state pair), which have no JSON representation.";
2211 t["smp_passage_lst"] = "smp_passage_lst: " + callables;
2212 t["smp_passage_time"] = "smp_passage_time: " + callables;
2213 const std::string distribs =
2214 "its arcs are lang::Distrib objects (arbitrary distribution instances with their own "
2215 "sampling and transform methods), which have no JSON representation in the --api "
2216 "argument vocabulary.";
2217 t["smp_stage_cif"] = "smp_stage_cif: " + distribs;
2218 t["smp_stage_quad"] = "smp_stage_quad: " + distribs;
2219 t["mmap_mark"] =
2220 "mmap_mark: the C++ port mmap_mark(Map base, weights n x C) is a different function from "
2221 "the MATLAB reference mmap_mark(MMAP, prob K x R): it marks the arrivals of a MAP by "
2222 "phase-dependent weights, whereas the reference re-marks the K classes of an MMAP into R "
2223 "classes. Neither signature can be served from the other, so the MATLAB name is not "
2224 "exposed rather than returning a different quantity under it.";
2225 t["map_transform"] =
2226 "map_transform: the C++ library has no function of this name; it is the header "
2227 "map_transform.h, whose functions (map_normalize, map_scale, map_erlang, map_sum, "
2228 "map_sumind, map_mixture, map_renewal, map_stochcomp, map_hyperexp, ...) are exposed "
2229 "under their own names.";
2230 t["qbd_r"] =
2231 "qbd_r: the C++ library has no function of this name; it is the header qbd_r.h, whose "
2232 "functions (qbd_R, qbd_R_logred, qbd_fundmat, qbd_caudal, qbd_pi, qbd_R_residual, "
2233 "qbd_G_residual) are exposed under their own names.";
2234}
2235
2236} // namespace reg
2237} // namespace line
Nearest AMAP(2)-feasible (M2, M3, GAMMA) (matlab/lib/m3a/m3a/amap2/amap2_adjust_gamma....
Assemble an AMAP(2) in one of the two canonical forms (matlab/lib/m3a/m3a/amap2/amap2_assemble....
AMAP(2) fit of three moments and the autocorrelation decay rate (matlab/lib/m3a/m3a/amap2/amap2_fit_g...
All AMAP(2) representations matching three moments and the autocorrelation decay rate (matlab/lib/m3a...
Nearest APH(2)-feasible values of the second and third moments (matlab/lib/m3a/m3a/aph2/aph2_adjust....
Assemble an APH(2) from its canonical parameters (matlab/lib/m3a/m3a/aph2/aph2_assemble....
APH(2) fit of three moments, with a fallback to adjusted moments (matlab/lib/m3a/m3a/aph2/aph2_fit....
All APH(2) representations matching three moments (matlab/lib/m3a/m3a/aph2/aph2_fitall....
Internal to the –api dispatcher: what a per-domain translation unit needs to add entries to the table...
#define LINE_MAM_MAP_POINTS(OpName, fn, mapkey, ptkey, outkey)
#define LINE_MAM_MAP_UNARY(OpName, fn, outkey, enc)
InputError(const std::string &what)
Definition error.h:105
UnsupportedError(const std::string &what)
Definition error.h:119
Named-argument reader over the parsed JSON object.
Definition api_json.h:391
First passage times into a target STATE SET, for Markov and semi-Markov chains.
Level-dependent QBD processes with finitely many levels: the rate matrices R^(n) by the backward matr...
Stationary distribution of a chain of connected LDQBDs by successive censoring.
Port of ldqbd_mphc.m and ph_multisets.m: the exact level-dependent QBD blocks of an M/PH/c queue.
Marked MMPP(2) with m classes, fitted to counting-process characteristics (matlab/lib/m3a/m3a/m3pp/m3...
M3PP(2, m) fitted to counting-process characteristics with an optimized per-class split (matlab/lib/m...
M3PP(2, m) fitted to the counting process of a multi-class TRACE (matlab/lib/m3a/m3a/m3pp/m3pp2m_fitc...
M3PP obtained by SUPERPOSING one second-order process per class (matlab/lib/m3a/m3a/m3pp/m3pp_superpo...
Explicit inverse characterization of a second-order acyclic MAP (matlab/lib/kpctoolbox/map/map2_fit....
Fit a MAP(2) to three moments and an asymptotic index of dispersion.
Autocorrelation of the counting process of a MAP at a given timescale.
Cumulative distribution of the inter-arrival time of a MAP.
Mean of the counting process of a MAP at resolution t.
Power moments of the counts of a MAP in a window of length t.
Variance of the counting process of a MAP at resolution t.
Mark the arrivals of a MAP with class probabilities (matlab/lib/kpctoolbox/map/map_mark....
Markovian arrival process descriptors: stationary vectors, rate, moments, autocorrelation and the ind...
Probability density of the inter-arrival time of a MAP.
Random MAP, MMPP, MMAP, acyclic-PH and hyperexponential generators, plus the hyperexponential reader.
MAP constructors and structural transformations.
Variance of the counts of a MAP over windows of length t, in the spelling of matlab/lib/kpctoolbox/ma...
Maximum-entropy algorithm for closed multiclass queueing networks.
Mean queue length of a stable infinite-capacity GE/GE/c/FCFS queue.
Censored GE/GE/c/K;N queue by entropy maximisation.
Blocking probability seen by ONE arrival stream of a censored GE/GE/c/K;N queue.
Maximum-entropy algorithm for mixed open/closed multiclass networks.
Maximum-entropy algorithm for open multiclass queueing networks.
Maximum Entropy algorithm for single-class OPEN networks with FINITE BUFFERS, under loss or transfer ...
Sojourn-time distribution of a fluid queue whose SERVICE is itself a Markov-modulated fluid flow,...
Stationary density and distribution of a first- or second-order level-dependent (multi-regime) Markov...
Stationary mean fluid level E[X] of a first- or second-order level-dependent (multi-regime) Markovian...
First- and second-order level-dependent (multi-regime) Markovian fluid queues: the matrix-exponential...
Multi-regime FEEDBACK Markovian fluid queue: density, density derivative and distribution of the flui...
Fluid priority queue: per-class fluid level and sojourn time of an MMAP[K]/PH[K]/1-type continuous fl...
Sojourn-time distribution of a Markov-modulated fluid queue, as a matrix-exponential or phase-type re...
Compression of a marked MAP into a smaller representation, and the two M3A primitives it is built fro...
Per-class variance of the counting process of a marked MAP.
Marked MAP (MMAP) algebra: per-class rates, class probabilities, superposition, normalization and sca...
MAP(2) matching mean, SCV, skewness and the index of dispersion for counts (matlab/lib/kpctoolbox/mmp...
MMPP(2) matching mean, SCV, skewness and the autocorrelation decay rate (matlab/lib/kpctoolbox/mmpp/m...
MMPP(2) matching three moments and the autocorrelation decay rate (matlab/lib/kpctoolbox/mmpp/mmpp2_f...
MMPP(2) matching mean, SCV, skewness and the lag-1 autocorrelation (matlab/lib/kpctoolbox/mmpp/mmpp2_...
MMPP(2) matching three moments and the lag-1 autocorrelation (matlab/lib/kpctoolbox/mmpp/mmpp2_fit....
MMPP(2) matching counting-process characteristics (matlab/lib/kpctoolbox/mmpp/mmpp2_fitc....
MMPP(2) fitted to counting-process characteristics by optimization (matlab/lib/kpctoolbox/mmpp/mmpp2_...
Map2FitResult< T > mmpp2_fit1(const T &mean, const T &scv, const T &skew, const T &idc)
MAP(2) with the given mean, SCV, skewness and IDC.
Definition mmpp2_fit1.h:36
std::vector< T > map_acf(const Map< T > &m, const std::vector< unsigned > &lags)
Autocorrelation coefficients of the inter-arrival times at the given lags,.
Definition map_moment.h:168
Mmap< T > mmap_normalize(const Mmap< T > &in)
Clamp negative off-diagonal and per-class entries to zero and rebuild D1 and the diagonal of D0 from ...
Map2FitResult< T > map2_fit(const T &e1, const T &e2, const T &e3_in, const T &g2)
Fit an AMAP(2) to (e1, e2, e3, g2); see the header comment for e3 sentinels.
Definition map2_fit.h:117
MultiRegimeResult mfq_multiregime(const std::vector< Matrix< double > > &Q, const std::vector< std::vector< double > > &R, const std::vector< Matrix< double > > &Qt, const std::vector< std::vector< double > > &Rt, const std::vector< double > &Thr, const std::vector< double > &pdfpoints, const std::vector< double > &cdfpoints)
Multi-regime feedback fluid queue.
M3pp2mFitcApproxResult< T > m3pp2m_fitc_approx_ag(const T &a, const T &bt1, const T &bt2, const T &binf, const T &m3t2, const T &t1, const T &t2, const std::vector< T > &ai, const std::vector< T > &gt3, const T &t3, const std::vector< Bound< T > > &bounds, const AugLagOptions< T > &opt)
m3pp2m_fitc_approx_ag: fit the underlying MMPP(2) by optimization, then apply the 'ag' per-class spli...
MmapCompressMethod
The compression methods of mmap_compress.m.
@ M3ppApproxDelta
'm3pp.approx_delta'
@ MixtureOrder1
'default', 'mixture', 'mixture.order1'
@ MixtureOrder2
'mixture.order2'
@ M3ppExactDelta
'm3pp.exact_delta'
@ M3ppApproxCov
'm3pp.approx_cov'
T map_joint(const Map< T > &m, const std::vector< unsigned > &a, const std::vector< unsigned > &i)
Joint moment of K consecutive inter-arrival times observed at the cumulative lags a,...
Aph2FitResult< T > aph2_fit(const T &M1, const T &M2, const T &M3)
Fit an APH(2) to (M1, M2, M3), relaxing the moments if necessary.
Definition aph2_fit.h:42
Mmap< T > mmap_scale(const Mmap< T > &in, const T &M)
Rescale time so that the mean inter-arrival time becomes M.
Mmpp2FitcResult< T > mmpp2_fitc(const T &mu, const T &bt1, const T &bt2, const T &binf, const T &m3t2, const T &t1, const T &t2)
MMPP(2) from the arrival rate, the IDC at t1, t2 and infinity, and the third central moment of the co...
Definition mmpp2_fitc.h:102
Map< T > map_hyperexp(const T &mean, const T &scv, const T &p_in)
Two-phase hyperexponential renewal MAP matching a mean and an SCV >= 1, with branching probability p ...
Amap2FitGammaResult< T > amap2_fit_gamma(const T &M1, const T &M2, const T &M3, const T &GAMMA, const T &cvtol)
Fit an AMAP(2) to (M1, M2, M3, GAMMA).
std::vector< Map< T > > aph2_fitall(const T &M1, const T &M2, const T &M3, const T &degentol)
All feasible APH(2) fits of (M1, M2, M3).
Definition aph2_fitall.h:46
QbdMapMap1Blocks< T > qbd_mapmap1_blocks(const Map< T > &arrival, const Map< T > &service)
Level blocks of the MAP/MAP/1 QBD from the arrival and service MAPs.
Definition qbd_mapmap1.h:72
M3ppSuperposResult< T > m3pp_superpos_fitc(const std::vector< T > &av, const std::vector< T > &btv, const std::vector< T > &binfv, const std::vector< T > &m3tv, const T &t, const T &tinf)
Fit one second-order M3PP per class from its counting characteristics and superpose them.
Map< T > mmpp2_fit3(const T &E1, const T &E2, const T &E3, const T &G2, const T &g2tol)
MMPP(2) with moments (E1, E2, E3) and autocorrelation decay rate G2.
Definition mmpp2_fit3.h:51
std::vector< T > mmap_lambda(const Mmap< T > &m)
Alias kept for parity with the MATLAB name.
T qbd_G_residual(const Matrix< T > &B, const Matrix< T > &L, const Matrix< T > &F, const Matrix< T > &G)
Residual of the defining equation of G, ||B + L G + F G^2||_inf.
Definition qbd_r.h:162
Amap2AdjustGammaResult< T > amap2_adjust_gamma(const T &M1, const T &M2, const T &M3, const T &GAMMA, const std::vector< T > &weights, int method, int constraints, const T &tol)
Nearest AMAP(2)-feasible characteristics.
bool mmap_isfeasible_tol(const Mmap< T > &m, const T &tol)
Feasibility of a marked MAP WITHIN A TOLERANCE, the semantics of matlab/lib/m3a/m3a/mmap/mmap_isfeasi...
std::vector< T > map_acfc(const Map< T > &m, const std::vector< unsigned > &kset, const T &u)
Autocorrelation of the counting process of a MAP at a given timescale.
Definition map_acfc.h:57
M3pp2mFitcResult< T > m3pp2m_fitc(const T &a, const T &bt1, const T &bt2, const T &binf, const T &m3t2, const T &t1, const T &t2, const std::vector< T > &ai, const std::vector< T > &dvt3, const T &t3)
Fit an M3PP(2, m).
Definition m3pp2m_fitc.h:60
T qbd_caudal(const Matrix< T > &R, unsigned iter_max, const T &tol)
Caudal characteristic eta = sp(R), the decay rate of the queue-length tail.
Definition qbd_r.h:360
T mfq_ld_mean(const LevelDependentFluidBlocks< T > &b)
Stationary mean fluid level of a level-dependent fluid queue.
Map2FitIdcResult< T > map2_fit_idc(const T &e1, const T &e2, const T &e3, const T &I)
Fit a MAP(2) to three moments and an asymptotic index of dispersion.
LdqbdMphcBlocks< T > ldqbd_mphc(const Matrix< T > &D0, const Matrix< T > &D1, const std::vector< T > &alpha, double c, const std::vector< T > &arrRate, const std::vector< T > &sf, bool carry=false)
Block-tridiagonal generator of an M/PH/c queue with level-dependent arrivals.
Definition ldqbd_mphc.h:272
Aph2AdjustResult< T > aph2_adjust(const T &M1, const T &M2, const T &M3, const T &tol)
Feasible (M2, M3) closest to the input, holding M1 fixed.
Definition aph2_adjust.h:46
MeRepresentation< T > mfq_fluflu_sojourn(const Matrix< T > &Qin, const Matrix< T > &Rin, const Matrix< T > &Qout, const Matrix< T > &Rout, bool srv0stop, bool transToPH, const T &prec)
Sojourn time of a drop in a fluid queue with fluid-modulated service.
Mmpp2FitResult< T > mmpp2_fit4(const T &mean, const T &scv, const T &skew, const T &acf1)
MMPP(2) with the given mean, SCV, skewness and lag-1 autocorrelation.
Definition mmpp2_fit4.h:37
QbdMapMap1Result< T > qbd_mapmap1(const Map< T > &arrival, const Map< T > &service_in, const T &util, std::size_t max_levels)
MAP/MAP/1 queue (qbd_mapmap1.m).
Mmpp2FitcResult< T > mmpp2_fitc_theoretical(const Map< T > &mp, const T &t1, const T &t2, const T &tinf)
MMPP(2) fitted to the counting characteristics of a GIVEN MAP (matlab/lib/kpctoolbox/mmpp/mmpp2_fitc_...
T qbd_mapmap1_qlen_truncated(const QbdMapMap1Result< T > &res)
The mean number in system computed the way MATLAB's qbd_mapmap1 does it, by summing k over the materi...
T qbd_setupdelayoff(const T &lambda, const T &mu, const T &alpharate, const T &alphascv, const T &betarate, const T &betascv)
Mean queue length of the M/M/1 queue with setup delay and delay-off (qbd_setupdelayoff....
Map< T > aph2_assemble(const T &l1, const T &l2, const T &p1)
APH(2) with phase means l1, l2 and continuation probability p1.
T qbd_qlen_moment(const std::vector< T > &pi0, const Matrix< T > &R, unsigned m)
Raw moment of order m of the number in system, E[N^m], assembled from the factorial moments with the ...
Map< T > map_renewal(const Map< T > &in)
Renewal process with the same inter-arrival distribution: D1 is replaced by (D1 e) pie,...
SetupDelayoffMMk< T > qbd_setupdelayoff_mmk(int k, double N, const T &arv, const T &mu, const T &alpharate, const T &alphascv, const T &betarate, const T &betascv)
Mean number present and throughput of a k-SERVER queue whose servers each pay a setup when woken from...
FluidPrioResult mfq_prio_queue(const Matrix< double > &Q, const Matrix< double > &R, double d, const FluidPrioOptions &opt)
Fluid priority queue.
Mmap< T > m3pp_rand(std::size_t K, std::size_t classes, Gen &gen)
Random M3PP of order K with classes marks (m3a/m3pp/m3pp_rand.m).
Definition map_rand.h:98
LdqbdResult< T > ldqbd(const std::vector< Matrix< T > > &q0, const std::vector< Matrix< T > > &q1, const std::vector< Matrix< T > > &q2)
Solve a level-dependent QBD: rate matrices and stationary law (ldqbd.m).
Definition ldqbd.h:246
Map< T > map_erlang(const T &mean, unsigned k)
Erlang-k renewal MAP with the given mean (map_erlang.m).
MeRepresentation< T > mfq_sojourn(const Matrix< T > &Q, const Matrix< T > &Rin, const Matrix< T > &Rout, const Matrix< T > &Q0, bool transToPH, const T &prec)
Sojourn time of a drop in a Markov-modulated fluid queue.
Definition mfq_sojourn.h:86
Mmpp2FitcApproxResult< T > mmpp2_fitc_approx(const T &a, const T &bt1, const T &bt2, const T &binf, const T &m3t2, const T &t1, const T &t2, const AugLagOptions< T > &opt)
Fit an MMPP(2) to counting characteristics.
std::vector< std::vector< T > > mfq_ld_distr(const LevelDependentFluidBlocks< T > &b, FluidDistrKind what, const std::vector< T > &points)
Stationary density or distribution of a level-dependent fluid queue.
bool map_isfeasible(const Map< T > &m, const T &tol)
Structural feasibility of a MAP within a tolerance (map_isfeasible.m): off-diagonal D0 and all of D1 ...
LdqbdCensorResult< T > ldqbd_censor(const Matrix< T > &Q, const std::vector< std::vector< std::size_t > > &phases, double tol=1e-10)
Stationary distribution of a chain of connected LDQBDs (ldqbd_censor.m).
Mmap< T > mmap_compress(const Mmap< T > &in, MmapCompressMethod method)
Compress an MMAP (mmap_compress.m).
Map< T > map_exponential_mean(const T &mean)
Poisson process with the given mean inter-arrival time (map_exponential.m).
Map< T > map_sumind(const std::vector< Map< T > > &maps)
Sum of independent, not necessarily identical MAPs: after each component completes,...
Map< T > map_mixture(const std::vector< T > &alpha, const std::vector< Map< T > > &maps)
Probabilistic mixture of MAPs with weights alpha: after an arrival from component i the process jumps...
Map< T > map_sum(const Map< T > &in, unsigned n)
n-fold convolution of a MAP with itself: the inter-arrival time of the result is the sum of n consecu...
QbdFundMat< T > qbd_fundmat(const Matrix< T > &B, const Matrix< T > &L, const Matrix< T > &F, unsigned iter_max, const T &tol)
G and R by cyclic reduction (qbd_fundmat.m, the Bini-Meini logarithmic reduction on the raw level blo...
Definition qbd_r.h:285
Map< T > ph2map(const PhType< T > &ph)
MAP whose inter-arrival time is the PH (alpha, T): the renewal MAP with D1 = (-T e) alpha.
QbdRapResult< T > qbd_rap(const Matrix< T > &A0, const Matrix< T > &A1, const Matrix< T > &A2, const Matrix< T > &B0, const Matrix< T > &B1, std::size_t numLevels)
Equilibrium analysis of a QBD with RAP components (qbd_rap.m).
Definition qbd_rap.h:274
Map< T > amap2_assemble(const T &l1, const T &l2, const T &p1, const T &p2, int form)
AMAP(2) in canonical form 1 (gamma >= 0) or 2 (gamma < 0).
Map< T > map_scale(const Map< T > &in, const T &new_mean)
Rescale time so that the mean inter-arrival time becomes new_mean.
M3pp2mFitcApproxResult< T > m3pp2m_fitc_approx(const T &a, const T &bt1, const T &bt2, const T &binf, const T &m3t2, const T &t1, const T &t2, const std::vector< T > &ai, const std::vector< T > &dvt3, const T &t3, const std::vector< Bound< T > > &bounds, const AugLagOptions< T > &opt)
m3pp2m_fitc_approx: fit the underlying MMPP(2) by optimization, then split the classes on their varia...
Map< T > mmpp2_fit(const T &E1, const T &E2, const T &E3, const T &ACFLAG1)
MMPP(2) with moments (E1, E2, E3) and lag-1 autocorrelation ACFLAG1.
Definition mmpp2_fit.h:34
Matrix< T > qbd_R_logred(const Matrix< T > &B, const Matrix< T > &L, const Matrix< T > &F, unsigned iter_max, const T &tol)
R by logarithmic reduction (qbd_R_logred.m).
Definition qbd_r.h:217
M3pp2mFitcTraceResult< T > m3pp2m_fitc_trace(const std::vector< T > &Tv, const std::vector< int > &A, const std::string &method, const T &t1, const T &tinf)
Fit a multi-class trace with an M3PP(2, m) on its counting process.
Map< T > map_stochcomp(const Map< T > &in, const std::vector< std::size_t > &retain)
Stochastic complement of a MAP on the retained phases (map_stochcomp.m): the eliminated phases are ce...
std::vector< T > map_count_moment(const Map< T > &m, const T &t, const std::vector< unsigned > &orders)
Power moments of the counts of a MAP in a window of length t.
Matrix< T > qbd_R(const Matrix< T > &B, const Matrix< T > &L, const Matrix< T > &F, unsigned iter_max, const T &tol)
R by successive substitutions (qbd_R.m): iterate R <- -(F + R^2 B) L^-1.
Definition qbd_r.h:184
SetupDelayoffClosed< T > qbd_setupdelayoff_closed(const T &N, const T &Z, const T &mu, const T &alpharate, const T &alphascv, const T &betarate, const T &betascv)
Mean queue length and throughput of a FINITE-POPULATION queue with setup delay and delay-off,...
Mmap< T > mmap_super(const Mmap< T > &a, const Mmap< T > &b)
Superposition of two MMAPs: the phase process is the product chain, and the class list of the result ...
Definition mmap_lambda.h:88
bool mmap_isfeasible(const Mmap< T > &m)
True when the per-class matrices partition D1 exactly and D0 is a generator.
std::vector< T > mmap_pc(const Mmap< T > &m)
Class probabilities seen by an arriving job, pc = pie (-D0)^-1 D1^(c) e.
std::vector< Map< T > > amap2_fitall_gamma(const T &M1, const T &M2, const T &M3, const T &GAMMA, const T &degentol, const T &r12tol)
Every AMAP(2) matching (M1, M2, M3, GAMMA).
Matrix< T > qbd_pi(const Matrix< T > &B, const Matrix< T > &Lbar, const Matrix< T > &R, std::size_t max_levels, const T &mass_tol)
Stationary distribution of a QBD given R (QBD_pi.m, continuous-time branch, default boundary).
Definition qbd_r.h:417
T map_moment(const Map< T > &m, unsigned k)
Raw moment of order k of the inter-arrival time: k!
Definition map_moment.h:118
T qbd_qlen_factmoment(const std::vector< T > &pi0, const Matrix< T > &R, unsigned m)
Factorial moment of order m of the number in system, computed in closed form from the boundary vector...
QbdRg< T > qbd_rg(const Map< T > &arrival, const Map< T > &service_in, const T &util)
R and G of the MAP/MAP/1 QBD (qbd_rg.m).
Mmap< T > map_mark(const Map< T > &m, const std::vector< T > &prob)
MMAP with the same inter-arrival process and arrivals marked by prob.
Definition map_mark.h:38
T qbd_R_residual(const Matrix< T > &B, const Matrix< T > &L, const Matrix< T > &F, const Matrix< T > &R)
Residual of the defining equation of R, ||F + R L + R^2 B||_inf.
Definition qbd_r.h:154
Mmpp2FitResult< T > mmpp2_fit2(const T &mean, const T &scv, const T &skew, const T &g2)
MMPP(2) with the given mean, SCV, skewness and decay rate g2.
Definition mmpp2_fit2.h:43
std::vector< T > mmap_count_lambda(const Mmap< T > &m)
Per-class arrival rates, lambda_c = theta D1^(c) e.
std::vector< T > mmap_count_var(const Mmap< T > &mm, const T &t)
Per-class variance of the counting process of a marked MAP.
LevelDependentFluidBlocks< T > mfq_ld_solve(const std::vector< Matrix< T > > &Q, const std::vector< Matrix< T > > &R, const std::vector< Matrix< T > > &S, const std::vector< T > &Thr, const std::vector< FluidBoundary > &boundaryL, const std::vector< FluidBoundary > &boundaryU, const std::vector< Matrix< T > > &Qt, const T &prec)
Solve a first- or second-order level-dependent fluid queue.
FluidDistrKind
Which functional of the stationary level law to evaluate.
@ Pdfd
derivative of the density
@ Cdf
P(X < p), excluding an atom sitting exactly at p.
@ Pdf
per-state density
@ Cdfm
P(X <= p), including it.
QbdBmapBmap1Blocks< T > qbd_bmapbmap1(const Map< T > &arrival, const std::vector< T > &pbatch, const Map< T > &service)
Level blocks of a BMAP/MAP/1 queue.
PassageMoments< T > smp_passage_moments(const Matrix< T > &P, const Matrix< T > &hmom, const std::vector< T > &pi0, const std::vector< std::size_t > &target, std::size_t nmax=1)
Moments of the semi-Markov first passage time from the per-state holding moments m_i(r),...
GegecnResult< T > me_gegecn(const T &lambda, const T &Ca, const T &mu, const T &Cs, long c, long K, long N)
Port of me_gegecn.
Definition me_gegecn.h:75
MeResult< T > me_mqn(std::size_t M, std::size_t R, const std::vector< char > &open_classes, const Matrix< T > &lambda0, const Matrix< T > &Ca0, const std::vector< long > &N, const Matrix< T > &mu, const Matrix< T > &Cs, const std::vector< Matrix< T > > &P, const std::vector< long > &c, const std::vector< long > &refstat, const std::vector< char > &insens, const MeOptions &opt=MeOptions())
Maximum-entropy algorithm for mixed open/closed multiclass networks.
Definition me_mqn.h:78
T me_gegecn_pb(const std::vector< T > &p, long K, long N, long c, const T &Cs, const T &Ca)
Port of me_gegecn_pb.
MeResult< T > me_cqn(std::size_t M, std::size_t R, const std::vector< long > &N, const Matrix< T > &mu, const Matrix< T > &Cs, const std::vector< Matrix< T > > &P, const std::vector< long > &c, const std::vector< long > &refstat_in, const std::vector< char > &insens, const MeOptions &opt=MeOptions())
Maximum-entropy algorithm for closed multiclass queueing networks.
Definition me_cqn.h:463
T me_gegec_mql(const T &lambda, const T &Ca, const T &mu, const T &Cs, long c)
Port of me_gegec_mql.
MeBlkResult< T > me_oqn_blk(std::size_t M, const std::vector< T > &lambda0, const std::vector< T > &Ca0, const std::vector< T > &mu, const std::vector< T > &Cs, const Matrix< T > &P, const std::vector< long > &c, const std::vector< long > &N, const std::vector< int > &blockrule, const MeBlkOptions &opt=MeBlkOptions())
Port of me_oqn_blk.
Definition me_oqn_blk.h:113
MeResult< T > me_oqn(std::size_t M, std::size_t R, const Matrix< T > &lambda0, const Matrix< T > &Ca0, const Matrix< T > &mu, const Matrix< T > &Cs, const std::vector< Matrix< T > > &P, const std::vector< long > &c, const std::vector< char > &insens, const MeOptions &opt=MeOptions())
Maximum-entropy algorithm for open multiclass queueing networks.
Definition me_oqn.h:121
nlohmann::json Json
Definition api_json.h:63
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.
Definition api_json.h:366
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,...
Definition api_json.h:223
void register_library_only_mam(LibraryOnlyTable &t)
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.
Definition api_json.h:267
Json encode_matrices(const std::vector< Matrix< T > > &v)
A list of matrices, the shape the MMAP/BMAP families return as {D0,D1,...}.
Definition api_json.h:358
void register_api_mam(DispatchTable &t)
T number_from_json(const Json &j, const std::string &where)
Definition api_json.h:210
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.
Definition api_json.h:255
Json encode_vector(const std::vector< T > &v)
Definition api_json.h:333
Json encode_matrix(const Matrix< T > &m)
Definition api_json.h:340
std::string shortest_decimal(double v)
The shortest decimal literal that round-trips to v.
Definition api_json.h:76
Json encode_scalar(const T &v)
Definition api_json.h:328
std::map< std::string, std::string > LibraryOnlyTable
name -> why the function has no named-JSON-argument form.
std::map< std::string, Invoker > DispatchTable
Conservation laws of a layered queueing network, enumerated from its structure.
Definition aoi_dist2ph.h:52
Level blocks of a BMAP/MAP/1 queue: batch Markovian arrivals against a single-departure MAP service p...
The MAP/MAP/1 queue solved as a quasi-birth-death process.
Quasi-birth-death processes: the rate matrix R, the fundamental matrix G, the caudal characteristic,...
Quasi-birth-death processes with rational arrival process components, and the RAP/RAP/1 queue built o...
Mean queue length of an M/M/1 queue with a setup delay and a delayed-off period, solved as a QBD.
Multi-server queue with setup and delayed-off servers.