5#ifndef LINE_API_MAM_MAMAP2M_FIT_H
6#define LINE_API_MAM_MAMAP2M_FIT_H
94namespace mamapdetail {
101template <
class T,
class QFun>
102std::vector<T> solve_split(
const std::vector<T>& target,
const std::vector<T>& w,
103 std::size_t nflows, std::size_t k, QFun qof) {
105 const std::size_t nv = target.size();
107 auto fobj = [&](
const std::vector<T>& x) {
109 for (std::size_t v = 0; v < nv; ++v) {
110 const T r = T(x[v] / target[v] - one);
115 auto heq = [&](
const std::vector<T>& x) {
116 std::vector<T> v(nflows, zero);
117 for (std::size_t j = 0; j < nflows; ++j) {
119 for (std::size_t c = 0; c < k; ++c) s += qof(x, j, c);
124 auto gineq = [&](
const std::vector<T>& x) {
126 v.reserve(2 * nflows * k);
127 for (std::size_t c = 0; c < k; ++c)
128 for (std::size_t j = 0; j < nflows; ++j) {
129 const T qq = qof(x, j, c);
130 v.push_back(T(qq - one));
136 std::vector<T> x0 = target;
137 std::vector<Bound<T>> bounds(nv);
138 for (std::size_t v = 0; v < nv; ++v) {
141 if (x0[v] < bounds[v].lo) x0[v] = bounds[v].lo;
142 if (x0[v] > bounds[v].hi) x0[v] = bounds[v].hi;
144 return auglag(fobj, heq, gineq, x0, bounds).x;
149void fix_split(std::vector<std::vector<T>>& q, std::size_t k) {
151 for (std::size_t j = 0; j < q.size(); ++j) {
153 for (std::size_t c = 0; c < k; ++c) {
154 if (q[j][c] < zero) q[j][c] = zero;
157 if (!(num_traits<T>::to_double(s) > 0.0))
158 throw NumericError(
"mamap2m_fit: a flow split lost all its mass");
159 for (std::size_t c = 0; c < k; ++c) q[j][c] = T(q[j][c] / s);
178 const std::vector<T>& F,
const std::vector<T>& B,
179 const std::vector<T>& classWeights = std::vector<T>(),
180 const std::vector<T>& fbWeights = std::vector<T>()) {
182 "mamap2m_fit_fb_multiclass solves a quadratic program");
185 if (map.
D0.rows() != 2)
186 throw InputError(
"mamap2m_fit_fb_multiclass: the underlying MAP must be second order");
188 throw InputError(
"mamap2m_fit_fb_multiclass: the underlying MAP must be acyclic");
191 if (map.
D1(0, 1) == zero)
193 else if (map.
D1(0, 0) == zero)
197 "mamap2m_fit_fb_multiclass: the underlying MAP must be in canonical acyclic form "
198 "(D1(1,2) = 0 for a positive decay, D1(1,1) = 0 for a negative one)");
200 const std::size_t k = p.size();
201 if (k == 0)
throw InputError(
"mamap2m_fit_fb_multiclass: no classes given");
202 if (F.size() != k || B.size() != k)
204 "mamap2m_fit_fb_multiclass: one forward and one backward moment per class is required");
205 std::vector<T> cw = classWeights;
206 if (cw.empty()) cw.assign(k, one);
207 std::vector<T> fbw = fbWeights;
208 if (fbw.empty()) fbw.assign(2, one);
210 const T h1 = T(-one / map.
D0(0, 0));
211 const T h2 = T(-one / map.
D0(1, 1));
212 const T r1 = T(map.
D0(0, 1) * h1);
213 const T r2 = T(map.
D1(1, 1) * h2);
214 const double dt = 1e-8;
223 auto finish = [&](std::vector<std::vector<T>>& q) {
224 mamapdetail::fix_split(q, k);
225 for (std::size_t c = 0; c < k; ++c) {
227 out.
mmap.Dc[c](0, 0) = T(out.
mmap.D1(0, 0) * q[0][c]);
228 out.
mmap.Dc[c](1, 0) = T(out.
mmap.D1(1, 0) * q[1][c]);
229 out.
mmap.Dc[c](1, 1) = T(out.
mmap.D1(1, 1) * q[2][c]);
231 out.
mmap.Dc[c](0, 1) = T(out.
mmap.D1(0, 1) * q[0][c]);
232 out.
mmap.Dc[c](1, 0) = T(out.
mmap.D1(1, 0) * q[1][c]);
233 out.
mmap.Dc[c](1, 1) = T(out.
mmap.D1(1, 1) * q[2][c]);
236 const std::vector<unsigned> one_order(1, 1u);
239 out.
fF.assign(k, zero);
240 out.
fB.assign(k, zero);
241 for (std::size_t c = 0; c < k; ++c) {
242 out.
fF[c] = fm(c, 0);
243 out.
fB[c] = bm[c][0];
249 const bool poisson1 =
250 form == 1 && (dr1 < dt || dr2 > 1.0 - dt || std::fabs(dh2 - dh1 * dr2) < dt ||
251 std::fabs(dh1 - dh2 + dh2 * dr1) < dt);
252 const bool poisson2 =
253 form == 2 && (dr2 > 1.0 - dt || std::fabs(dh1 - dh2 + dh2 * dr1) < dt ||
254 std::fabs(dh1 - dh2 - dh1 * dr1 + dh1 * dr1 * dr2) < dt);
255 if (poisson1 || poisson2) {
256 out.
mmap = mamapdetail::marked_poisson(
map_mean(map), p);
257 const std::vector<unsigned> one_order(1, 1u);
260 out.
fF.assign(k, zero);
261 out.
fB.assign(k, zero);
262 for (std::size_t c = 0; c < k; ++c) {
263 out.
fF[c] = fm(c, 0);
264 out.
fB[c] = bm[c][0];
270 if (form == 2 && dr2 < dt && std::fabs(1.0 - dr1) < dt) {
271 std::vector<std::vector<T>> q(3, std::vector<T>(k, zero));
272 for (std::size_t c = 0; c < k; ++c) q[0][c] = q[1][c] = q[2][c] = p[c];
278 if (form == 1 && dr2 < dt) {
284 const std::vector<unsigned> one_order(1, 1u);
287 out.
fF.assign(k, zero);
288 out.
fB.assign(k, zero);
289 for (std::size_t c = 0; c < k; ++c) {
290 out.
fF[c] = fm(c, 0);
291 out.
fB[c] = bm[c][0];
297 if (std::fabs(1.0 - dr1) < dt) {
298 std::vector<std::vector<T>> qf(2, std::vector<T>(k, zero)),
299 q0(2, std::vector<T>(k, zero));
300 for (std::size_t c = 0; c < k; ++c) {
301 qf[0][c] = T(p[c] * (-one / ((h1 + h2 * (r1 - one)) * (r2 - one) *
302 (r1 + r2 - r1 * r2))));
303 q0[0][c] = T(p[c] * (h2 / ((r2 - one) * (r1 + r2 - r1 * r2) *
304 (h1 - h2 + h2 * r1))));
305 qf[1][c] = T(p[c] * (-one / (r2 * (h1 + h2 * (r1 - one)) * (r1 + r2 - r1 * r2))));
306 q0[1][c] = T(p[c] * ((h1 + h2 * r1) /
307 (r2 * (r1 + r2 - r1 * r2) * (h1 - h2 + h2 * r1))));
309 std::vector<T> w(k, zero);
310 for (std::size_t c = 0; c < k; ++c) w[c] = T(cw[c] * fbw[0]);
311 auto qof = [&](
const std::vector<T>& x, std::size_t j, std::size_t c) {
312 return T(x[c] * qf[j][c] + q0[j][c]);
314 const std::vector<T> x = mamapdetail::solve_split(F, w, 2, k, qof);
315 std::vector<std::vector<T>> q(3, std::vector<T>(k, zero));
317 for (std::size_t c = 0; c < k; ++c) {
319 q[1][c] = T(x[c] * qf[0][c] + q0[0][c]);
320 q[2][c] = T(x[c] * qf[1][c] + q0[1][c]);
327 if (form == 2 && dr2 < dt) {
328 const bool doForward = !(fbw[0] < fbw[1]);
329 std::vector<std::vector<T>> qc(2, std::vector<T>(k, zero)),
330 q0(2, std::vector<T>(k, zero));
331 for (std::size_t c = 0; c < k; ++c) {
333 qc[0][c] = T(p[c] * (-(r1 - two) / ((h1 + h2 * (r1 - one)) * (r1 - one))));
334 q0[0][c] = T(p[c] * (one - (h1 + h2) / ((r1 - one) * (h1 - h2 + h2 * r1))));
335 qc[1][c] = T(p[c] * (-(r1 - two) / (h1 + h2 * (r1 - one))));
336 q0[1][c] = T(p[c] * ((h2 * (r1 - two)) / (h1 - h2 + h2 * r1)));
338 qc[0][c] = T(p[c] * (-(r1 - two) / ((h2 + h1 * (r1 - one)) * (r1 - one))));
339 q0[0][c] = T(p[c] * (one - (h1 + h2) / ((r1 - one) * (h2 - h1 + h1 * r1))));
340 qc[1][c] = T(p[c] * (-(r1 - two) / (h2 + h1 * (r1 - one))));
341 q0[1][c] = T(p[c] * ((h1 * (r1 - two)) / (h2 - h1 + h1 * r1)));
344 std::vector<T> w(k, zero);
345 for (std::size_t c = 0; c < k; ++c) w[c] = T(cw[c] * (doForward ? fbw[0] : fbw[1]));
346 auto qof = [&](
const std::vector<T>& x, std::size_t j, std::size_t c) {
347 return T(x[c] * qc[j][c] + q0[j][c]);
349 const std::vector<T> x = mamapdetail::solve_split(doForward ? F : B, w, 2, k, qof);
350 std::vector<std::vector<T>> q(3, std::vector<T>(k, zero));
352 for (std::size_t c = 0; c < k; ++c) {
353 q[0][c] = T(x[c] * qc[0][c] + q0[0][c]);
354 q[1][c] = T(x[c] * qc[1][c] + q0[1][c]);
362 std::vector<std::vector<T>> qf(3, std::vector<T>(k, zero)), qb(3, std::vector<T>(k, zero)),
363 q0(3, std::vector<T>(k, zero));
364 for (std::size_t c = 0; c < k; ++c) {
366 const T z = T(r1 * r2 - r2 + one);
368 qb[0][c] = T(-(p[c] * z) / ((h2 - h1 * r2) * (r1 - one) * (r2 - one)));
369 q0[0][c] = T((p[c] * (h1 + h2 - h1 * r2) * z) /
370 ((h2 - h1 * r2) * (r1 - one) * (r2 - one)));
371 qf[1][c] = T(-(p[c] * z) / (r1 * (h1 + h2 * (r1 - one)) * (r2 - one)));
372 qb[1][c] = T(-(p[c] * z) / (r1 * (h2 - h1 * r2) * (r2 - one)));
373 q0[1][c] = T((p[c] * z) / ((r1 - one) * (r2 - one)) +
374 (h1 * p[c] * z) / (r1 * (h2 - h1 * r2) * (r2 - one)) -
375 (h1 * p[c] * z) / (r1 * (h1 + h2 * (r1 - one)) * (r1 - one) * (r2 - one)));
376 qf[2][c] = T(-(p[c] * z) / (r1 * r2 * (h1 - h2 + h2 * r1)));
378 q0[2][c] = T((p[c] * (h1 + h2 * r1) * z) / (r1 * r2 * (h1 - h2 + h2 * r1)));
380 const T z = T(r1 + r2 - r1 * r2 - two);
381 const T d2 = T(h1 - h2 - h1 * r1 + h1 * r1 * r2);
383 qb[0][c] = T(-(p[c] * z) / ((r1 - one) * (r2 - one) * d2));
384 q0[0][c] = T((p[c] * (h2 + h1 * r1 - h1 * r1 * r2) * z) /
385 ((r1 - one) * (r2 - one) * d2));
386 qf[1][c] = T((p[c] * z) / ((r2 - one) * (h1 - h2 + h2 * r1)));
388 q0[1][c] = T(-(h2 * p[c] * z) / ((r2 - one) * (h1 - h2 + h2 * r1)));
389 qf[2][c] = T((p[c] * z) / (r2 * (h1 + h2 * (r1 - one))));
390 qb[2][c] = T((p[c] * z) / (r2 * d2));
391 q0[2][c] = T((h1 * p[c] * z) / (r2 * (h1 + h2 * (r1 - one)) * (r1 - one)) -
392 (h1 * p[c] * z) / (r2 * d2) - (p[c] * z) / (r2 * (r1 - one)));
397 std::vector<T> target(2 * k, zero), w(2 * k, zero);
398 for (std::size_t c = 0; c < k; ++c) {
399 target[2 * c] = F[c];
400 target[2 * c + 1] = B[c];
401 w[2 * c] = T(cw[c] * fbw[0]);
402 w[2 * c + 1] = T(cw[c] * fbw[1]);
404 auto qof = [&](
const std::vector<T>& x, std::size_t j, std::size_t c) {
405 return T(x[2 * c] * qf[j][c] + x[2 * c + 1] * qb[j][c] + q0[j][c]);
407 const std::vector<T> x = mamapdetail::solve_split(target, w, 3, k, qof);
408 std::vector<std::vector<T>> q(3, std::vector<T>(k, zero));
409 for (std::size_t c = 0; c < k; ++c)
410 for (std::size_t j = 0; j < 3; ++j) q[j][c] = qof(x, j, c);
421 const std::vector<T>& p,
const std::vector<T>& F,
422 const std::vector<T>& B) {
424 if (a.
amaps.empty() || (a.
amaps.size() == 1 && a.
amaps[0].order() == 1))
425 return mamapdetail::marked_poisson(M1, p);
428 double bestErr = 0.0;
430 for (std::size_t j = 0; j < a.
amaps.size(); ++j) {
434 }
catch (
const Error&) {
438 for (std::size_t c = 0; c < p.size(); ++c) {
441 err += df * df + db * db;
443 if (!have || err < bestErr) {
451 "mamap2m_fit_gamma_fb: no AMAP(2) form admits a valid class split for the requested "
452 "class probabilities and forward/backward moments");
479 const std::vector<T>& p,
const std::vector<T>& F,
const std::vector<T>& B,
480 const Matrix<T>& S,
const std::vector<T>& fbsWeights = std::vector<T>()) {
482 std::vector<T> w = fbsWeights;
483 if (w.empty()) w.assign(3, one);
484 if (w.size() != 3)
throw InputError(
"mamap2m_fit: three (F, B, S) weights are required");
487 const double gammatol = 1e-4, degentol = 1e-8;
492 if (a.
amaps.empty() || (a.
amaps.size() == 1 && a.
amaps[0].order() == 1))
493 return mamapdetail::marked_poisson(M1, p);
495 const bool preferFB = !(w[0] < w[2]) && !(w[1] < w[2]);
496 const bool preferFS = !preferFB && !(w[0] < w[1]);
499 double bestErr = 0.0;
501 for (std::size_t j = 0; j < a.
amaps.size(); ++j) {
503 if (mp.
order() != 2)
continue;
504 const T h1 = T(-one / mp.
D0(0, 0)), h2 = T(-one / mp.
D0(1, 1));
505 const T r1 = T(h1 * mp.
D0(0, 1)), r2 = T(h2 * mp.
D1(1, 1));
512 bool needsFs =
false, needsBs =
false;
514 if (std::fabs(dh2 - dh1 * dr2) < degentol) needsFs =
true;
515 else if (std::fabs(dh1 - dh2 + dh2 * dr1) < degentol) needsBs =
true;
516 else if (1.0 - dr1 < degentol) needsFs =
true;
518 if (std::fabs(dh1 - dh2 - dh1 * dr1 + dh1 * dr1 * dr2) < degentol) needsFs =
true;
519 else if (std::fabs(dh1 - dh2 + dh2 * dr1) < degentol) needsBs =
true;
522 if (!needsFs && !needsBs && !preferFB) {
523 if (preferFS) needsFs =
true;
528 std::vector<T> cF, cB;
533 }
else if (needsBs) {
540 }
catch (
const Error&) {
544 const std::vector<unsigned> ord1(1, 1u);
549 for (std::size_t c = 0; c < p.size(); ++c) {
555 if (S_or_empty.
rows() > 0 && fsc.
rows() > 0) {
559 if (!have || err < bestErr) {
567 "mamap2m_fit: no AMAP(2) form admits a valid class split for the requested "
572namespace mamapdetail {
576struct MmapDescriptors {
578 std::vector<T> p, F, B;
582MmapDescriptors<T> mmap_descriptors(
const Mmap<T>& mm) {
583 MmapDescriptors<T> d;
584 const Map<T> agg = mm.map();
590 const std::vector<unsigned> ord1(1, 1u);
593 for (std::size_t c = 0; c < mm.classes(); ++c) {
594 d.F.push_back(Fm(c, 0));
595 d.B.push_back(Bm[c][0]);
611 if (mm.
classes() == 0)
throw InputError(
"mamap2m_fit_mmap: the MMAP has no classes");
612 const mamapdetail::MmapDescriptors<T> d = mamapdetail::mmap_descriptors(mm);
623 if (mm.
classes() == 0)
throw InputError(
"mamap2m_fit_gamma_fb_mmap: the MMAP has no classes");
624 const mamapdetail::MmapDescriptors<T> d = mamapdetail::mmap_descriptors(mm);
641 if (Tv.empty() || Tv.size() != A.size())
643 "mamap2m_fit_gamma_fb_trace: the trace and its labels must agree in length");
645 T m1 = zero, m2 = zero, m3 = zero;
646 for (std::size_t i = 0; i < Tv.size(); ++i) {
653 const std::vector<unsigned> one_order(1, 1u);
657 std::vector<T> F(p.size(), zero), B(p.size(), zero);
658 for (std::size_t c = 0; c < p.size(); ++c) {
684 const std::vector<T>& fbsWeights = std::vector<T>()) {
685 if (Tv.empty() || Tv.size() != A.size())
686 throw InputError(
"mamap2m_fit_trace: the trace and its labels must agree in length");
688 T m1 = zero, m2 = zero, m3 = zero;
689 for (std::size_t i = 0; i < Tv.size(); ++i) {
696 const std::vector<unsigned> one_order(1, 1u);
700 std::vector<T> F(p.size(), zero), B(p.size(), zero);
701 for (std::size_t c = 0; c < p.size(); ++c) {
707 F, B, S, fbsWeights);
AMAP(2) fit of three moments and the autocorrelation decay rate (matlab/lib/m3a/m3a/amap2/amap2_fit_g...
Augmented Lagrangian method for equality- and inequality-constrained minimization,...
Base error for the multiprecision C++ port.
NumericError(const std::string &what)
The exception types the port throws.
Fit a MAMAP(2,2) matching the FORWARD moment and the class TRANSITION probability sigma.
The marked Poisson process every MAMAP fitter falls back to.
Autocorrelation decay rate of a MAP: the gamma of the geometric model rho(k) = rho0 * gamma^k with rh...
Markovian arrival process descriptors: stationary vectors, rate, moments, autocorrelation and the ind...
Fit a MAPH(2,m): a second-order acyclic phase-type marked with m classes.
Dense matrix and non-owning view.
Class-conditional backward moments of an MMAP (matlab/lib/m3a/m3a/mmap/mmap_backward_moment....
Marked MAP (MMAP) algebra: per-class rates, class probabilities, superposition, normalization and sca...
Marked MAP statistics: embedded chains, class-transition probabilities, forward and cross moments,...
Backward moments of a marked trace: the moments of the inter-arrival time that PRECEDES an event of e...
Forward moments of a marked trace: the moments of the inter-arrival time that FOLLOWS an event of eac...
Class probabilities of a marked trace, p_c = count_c / N.
One-step class transition frequencies of a marked trace,.
Mmap< T > maph2m_fit(const T &M1, const T &M2, const T &M3, const std::vector< T > &p, const std::vector< T > &B)
Fit a MAPH(2,m) to three moments, the class probabilities and the per-class backward moments,...
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).
Mmap< T > mamap2m_fit_trace(const std::vector< T > &Tv, const std::vector< int > &A, const std::vector< T > &fbsWeights=std::vector< T >())
Fit a MAPH(2,m) or MAMAP(2,m) matching the characteristics of a marked trace.
Matrix< T > mmap_forward_moment(const Mmap< T > &mm, const std::vector< unsigned > &orders, bool normalize)
Forward moments: MOMENTS(a,h) is the order-orders[h] moment of the interval ENDING with a class-a arr...
Mmap< T > mamap2m_fit(const T &M1, const T &M2, const T &M3, const T &GAMMA, const std::vector< T > &p, const std::vector< T > &F, const std::vector< T > &B, const Matrix< T > &S, const std::vector< T > &fbsWeights=std::vector< T >())
The full mamap2m_fit dispatcher.
T map_mean(const Map< T > &m)
Mean inter-arrival time, 1/lambda.
Mmap< T > mamap2m_fit_gamma_fb_mmap(const Mmap< T > &mm)
Fit a MAMAP(2,m) to an MMAP through the (F, B) pair alone (mamap2m_fit_gamma_fb_mmap....
std::vector< std::vector< T > > mmap_backward_moment(const Mmap< T > &m, const std::vector< unsigned > &orders, bool normalized)
Class-conditional backward moments of an MMAP (mmap_backward_moment.m).
Mamap22FsFitResult< T > mamap22_fit_fs_multiclass(const Map< T > &map, const std::vector< T > &p, const std::vector< T > &F, const Matrix< T > &S, const std::vector< T > &classWeights=std::vector< T >(), const std::vector< T > &fsWeights=std::vector< T >(), bool adjust=true)
Mamap22FitResult< T > mamap22_fit_bs_multiclass(const Map< T > &map, const std::vector< T > &p, const std::vector< T > &B, const Matrix< T > &S, const std::vector< T > &classWeights=std::vector< T >(), const std::vector< T > &bsWeights=std::vector< T >(), bool adjust=true)
Matrix< T > mmap_sigma(const Mmap< T > &mm)
sigma(i,j) = pie E_i E_j 1, the probability that two consecutive marks are (i,j).
Mmap< T > mamap2m_fit_gamma_fb(const T &M1, const T &M2, const T &M3, const T &GAMMA, const std::vector< T > &p, const std::vector< T > &F, const std::vector< T > &B)
Fit a MAMAP(2,m) to three moments, the decay rate, the class probabilities and the forward and backwa...
Mmap< T > mamap2m_fit_mmap(const Mmap< T > &mm, const std::vector< T > &fbsWeights=std::vector< T >())
Fit a MAMAP(2,m) to the characteristics of an MMAP (mamap2m_fit_mmap.m): its three moments,...
Mamap2mFitResult< T > mamap2m_fit_fb_multiclass(const Map< T > &map, const std::vector< T > &p, const std::vector< T > &F, const std::vector< T > &B, const std::vector< T > &classWeights=std::vector< T >(), const std::vector< T > &fbWeights=std::vector< T >())
Mark a canonical acyclic AMAP(2) with m classes, matching the forward and backward moments.
std::vector< T > mmap_pc(const Mmap< T > &m)
Class probabilities seen by an arriving job, pc = pie (-D0)^-1 D1^(c) e.
Map< T > map_normalize(const Map< T > &in)
Clamp negative off-diagonal entries of D0 and negative entries of D1 to zero, then rebuild the diagon...
T map_moment(const Map< T > &m, unsigned k)
Raw moment of order k of the inter-arrival time: k!
Mmap< T > mamap2m_fit_gamma_fb_trace(const std::vector< T > &Tv, const std::vector< int > &A)
Fit a MAMAP(2,m) from a marked trace through the (F, B) pair alone.
Maph2mFitResult< T > maph2m_fit_multiclass(const Map< T > &aph, const std::vector< T > &p, const std::vector< T > &B, const std::vector< T > &classWeights=std::vector< T >())
Mark a canonical acyclic APH(2) with m classes.
T map_gamma(const Map< T > &m, long limit=1000)
Autocorrelation decay rate of a MAP (map_gamma.m).
Matrix< T > mtrace_forward_moment(const std::vector< T > &Tv, const std::vector< int > &A, const std::vector< unsigned > &orders, bool norm=true)
Forward moments of a marked trace: the moments of the inter-arrival time that FOLLOWS an event of eac...
Matrix< T > mtrace_backward_moment(const std::vector< T > &Tv, const std::vector< int > &A, const std::vector< unsigned > &orders, bool norm=true)
Backward moments of a marked trace: the moments of the inter-arrival time that PRECEDES an event of e...
TraceGammaResult< T > trace_gamma(const std::vector< T > &S, long limit=1000, const std::vector< T > &grid=std::vector< T >())
Autocorrelation decay rate of a trace: the gamma of the geometric model rho(k) = rho0 * gamma^k,...
std::vector< T > mtrace_pc(const std::vector< int > &A)
Class probabilities of a marked trace, p_c = count_c / N.
Matrix< T > mtrace_sigma(const std::vector< int > &L)
One-step class transition frequencies of a marked trace, sigma(i,j) = #{t : A_t = i,...
Conservation laws of a layered queueing network, enumerated from its structure.
AugLagResult< T > auglag(F f, H h, G g, const std::vector< T > &x0, const std::vector< Bound< T > > &bounds, const AugLagOptions< T > &opt)
Augmented Lagrangian with a scalar objective and a simplex inner solver.
Number-type abstraction for the templated API port.
Result of amap2_fit_gamma.
std::vector< Map< T > > amaps
every exact solution found
The fitted MAMAP(2,2), what it achieved, and whether the fit was exact.
The forward-plus-sigma result; warning carries the reference's diagnostic.
The fitted MAMAP and the moments it achieved.
std::vector< T > fF
achieved per-class forward moments
std::vector< T > fB
achieved per-class backward moments
A MAP as the pair of matrices (D0, D1).
std::size_t order() const
The fitted MAPH and the backward moments it actually achieved.
An MMAP: the underlying MAP plus the per-class arrival matrices.
std::size_t classes() const
Autocorrelation decay rate of a trace: the gamma of the geometric model rho(k) = rho0 * gamma^k,...