LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
mamap22_fit_bs.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2012-2026, QORE Lab, Imperial College London
3 * All rights reserved.
4 */
5#ifndef LINE_API_MAM_MAMAP22_FIT_BS_H
6#define LINE_API_MAM_MAMAP22_FIT_BS_H
7
8/**
9 * @file
10 * @ingroup api_mam
11 * Fit a MAMAP(2,2) matching the BACKWARD moment and the class TRANSITION
12 * probability sigma.
13 *
14 * Templated port of matlab/lib/m3a/m3a/mamap22/mamap22_fit_bs_multiclass.m.
15 *
16 * TWO CLASSES ONLY, by construction: sigma is a class-to-class transition
17 * probability, and the closed forms below invert it for the (1,1) entry alone.
18 * The reference says so and refuses otherwise, and so does this.
19 *
20 * Unlike the F+B fitter, which is affine in the marking and therefore a
21 * quadratic program, the B+S relation is a RATIO: q2 (form 1) or q3 (form 2) is
22 * a quadratic in the backward moment over a linear denominator, and the other
23 * two follow linearly from it. That inverse is closed form -- `fit_can1` and
24 * `fit_can2` here -- and it is EXACT whenever its answer lands in the unit box.
25 * The coefficient tables it reads are `mamap2m_coefficients.h`.
26 *
27 * WHAT IS NOT PORTED, and is refused by name rather than approximated. When the
28 * closed form lands outside the box and the caller asked for `adjust`, the
29 * reference repairs it by solving a NONCONVEX program -- the marking equality
30 * q2 * den(B1) = num(B1, S11) is bilinear in the unknowns -- with YALMIP's
31 * `bmibnb`, a spatial branch-and-bound that returns a GLOBAL optimum, over two
32 * sides (B1 below and above the mean) and keeps the better. `line/util/auglag.h`
33 * finds a local KKT point, which on a nonconvex feasible set is a different
34 * answer, not a slower one; substituting it would report a fit the reference
35 * would not have chosen. Every other branch IS ported, including all four
36 * degeneracies and the one-variable quadratic repair of the degenerate MMAP
37 * form, so the exact path and the degenerate paths are complete.
38 *
39 * ARITHMETIC: transcendental, through the fitters it delegates to.
40 */
41
42#include <cmath>
43#include <cstddef>
44#include <vector>
45
61#include "line/num/number.h"
62#include "line/util/error.h"
63#include "line/util/matrix.h"
64
65namespace line {
66namespace mam {
67
68/** The fitted MAMAP(2,2), what it achieved, and whether the fit was exact. */
69template <class T>
72 std::vector<T> fB; ///< achieved per-class backward moments
73 Matrix<T> fS; ///< achieved class transition probabilities
74 bool exact = false;
75};
76
77namespace bsdetail {
78
79/** The closed-form B+S inverse of the first canonical form. */
80template <class T>
81void fit_can1(const Mamap2mCoefficients<T>& c, const T& p1, const T& vB1, const T& vS11,
82 double denumtol, T* q1, T* q2, T* q3) {
83 const T den = T(c.U[10] * vB1 * p1 + c.U[11] * p1);
84 if (std::fabs(num_traits<T>::to_double(den)) < denumtol) {
85 *q1 = *q2 = *q3 = p1; // the inverse degenerates; only p is identifiable
86 return;
87 }
88 *q2 = T((c.U[6] * vB1 * vB1 * p1 * p1 + c.U[7] * vB1 * p1 * p1 + c.U[8] * vS11 +
89 c.U[9] * p1 * p1) /
90 den);
91 *q1 = T(-(c.G[11] * p1 - vB1 * c.G[2] * p1 +
92 (c.G[2] * c.G[10] - c.G[1] * c.G[11]) * (*q2)) /
93 c.Y[2]);
94 *q3 = T((c.G[9] * p1 - vB1 * c.G[0] * p1 +
95 (c.G[0] * c.G[10] - c.G[1] * c.G[9]) * (*q2)) /
96 c.Y[2]);
97}
98
99/** The closed-form B+S inverse of the second canonical form. */
100template <class T>
101void fit_can2(const Mamap2mCoefficients<T>& c, const T& p1, const T& vB1, const T& vS11,
102 double denumtol, T* q1, T* q2, T* q3) {
103 const T den = T(c.U[10] * vB1 * p1 + c.U[11] * p1);
104 if (std::fabs(num_traits<T>::to_double(den)) < denumtol) {
105 *q1 = *q2 = *q3 = p1;
106 return;
107 }
108 *q3 = T((c.U[6] * vB1 * vB1 * p1 * p1 + c.U[7] * vB1 * p1 * p1 + c.U[8] * p1 * p1 +
109 c.U[9] * vS11) /
110 den);
111 *q1 = T((c.G[9] * p1 - vB1 * c.G[1] * p1 +
112 (c.G[1] * c.G[10] - c.G[2] * c.G[9]) * (*q3)) /
113 c.Y[2]);
114 *q2 = T(-(c.G[8] * p1 - vB1 * c.G[0] * p1 +
115 (c.G[0] * c.G[10] - c.G[2] * c.G[8]) * (*q3)) /
116 c.Y[2]);
117}
118
119} // namespace bsdetail
120
121/**
122 * @param map the AMAP(2), in one of the two canonical acyclic forms
123 * @param p the two class probabilities
124 * @param B the two target backward moments
125 * @param S the target class transition matrix; only S(0,0) is used
126 * @param classWeights per-class weights; empty means uniform
127 * @param bsWeights the (backward, sigma) weights; empty means (1, 1)
128 * @param adjust repair an infeasible closed form; the repair is unported
129 */
130template <class T>
131Mamap22FitResult<T> mamap22_fit_bs_multiclass(const Map<T>& map, const std::vector<T>& p,
132 const std::vector<T>& B, const Matrix<T>& S,
133 const std::vector<T>& classWeights = std::vector<T>(),
134 const std::vector<T>& bsWeights = std::vector<T>(),
135 bool adjust = true) {
137 "mamap22_fit_bs_multiclass inverts a moment system");
138 const T zero = num_traits<T>::from_int(0), one = num_traits<T>::from_int(1);
139 const T two = num_traits<T>::from_int(2);
140 if (map.D0.rows() != 2)
141 throw InputError("mamap22_fit_bs_multiclass: the underlying MAP must be second order");
142 if (!(num_abs(T(map.D0(1, 0))) <= zero))
143 throw InputError("mamap22_fit_bs_multiclass: the underlying MAP must be acyclic");
144 int form;
145 if (map.D1(0, 1) == zero) form = 1;
146 else if (map.D1(0, 0) == zero) form = 2;
147 else
148 throw InputError(
149 "mamap22_fit_bs_multiclass: the underlying MAP must be in canonical acyclic form");
150 if (p.size() != 2)
151 throw InputError(
152 "mamap22_fit_bs_multiclass: fitting the backward moment and the transition "
153 "probabilities supports two classes only");
154 if (B.size() != 2)
155 throw InputError("mamap22_fit_bs_multiclass: one backward moment per class is required");
156 if (S.rows() < 1 || S.cols() < 1)
157 throw InputError("mamap22_fit_bs_multiclass: the transition matrix is empty");
158
159 std::vector<T> cw = classWeights;
160 if (cw.empty()) cw.assign(2, one);
161 std::vector<T> bw = bsWeights;
162 if (bw.empty()) bw.assign(2, one);
163
164 const double degentol = 1e-6, feastol = 1e-4, denumtol = 1e-12;
165 Map<T> mp = map;
166 T h1 = T(-one / mp.D0(0, 0)), h2 = T(-one / mp.D0(1, 1));
167 T r1 = T(mp.D0(0, 1) * h1), r2 = T(mp.D1(1, 1) * h2);
168 auto dv = [](const T& v) { return num_traits<T>::to_double(v); };
169
171 out.mmap.D0 = mp.D0;
172 out.mmap.D1 = mp.D1;
173 out.mmap.Dc.assign(2, Matrix<T>(2, 2, zero));
174
175 auto finish = [&](T q1, T q2, T q3) {
176 auto fix = [&](const T& q) {
177 T v = q;
178 if (v < zero) v = zero;
179 if (v > one) v = one;
180 return v;
181 };
182 q1 = fix(q1);
183 q2 = fix(q2);
184 q3 = fix(q3);
185 if (form == 1) {
186 out.mmap.Dc[0](0, 0) = T(out.mmap.D1(0, 0) * q1);
187 out.mmap.Dc[0](1, 0) = T(out.mmap.D1(1, 0) * q2);
188 out.mmap.Dc[0](1, 1) = T(out.mmap.D1(1, 1) * q3);
189 out.mmap.Dc[1](0, 0) = T(out.mmap.D1(0, 0) * (one - q1));
190 out.mmap.Dc[1](1, 0) = T(out.mmap.D1(1, 0) * (one - q2));
191 out.mmap.Dc[1](1, 1) = T(out.mmap.D1(1, 1) * (one - q3));
192 } else {
193 out.mmap.Dc[0](0, 1) = T(out.mmap.D1(0, 1) * q1);
194 out.mmap.Dc[0](1, 0) = T(out.mmap.D1(1, 0) * q2);
195 out.mmap.Dc[0](1, 1) = T(out.mmap.D1(1, 1) * q3);
196 out.mmap.Dc[1](0, 1) = T(out.mmap.D1(0, 1) * (one - q1));
197 out.mmap.Dc[1](1, 0) = T(out.mmap.D1(1, 0) * (one - q2));
198 out.mmap.Dc[1](1, 1) = T(out.mmap.D1(1, 1) * (one - q3));
199 }
200 const std::vector<unsigned> ord(1, 1u);
201 const std::vector<std::vector<T>> bm = mmap_backward_moment(out.mmap, ord, true);
202 out.fB.assign(2, zero);
203 for (std::size_t c = 0; c < 2; ++c) out.fB[c] = bm[c][0];
204 out.fS = mmap_sigma(out.mmap);
205 };
206 auto feasible = [&](const T& q) {
207 return dv(q) >= -feastol && dv(q) <= 1.0 + feastol;
208 };
209
210 // ---- the Poisson perturbation, which keeps the two-state structure ----
211 const bool degen1 = form == 1 && (dv(r1) < degentol || dv(r2) > 1.0 - degentol ||
212 std::fabs(dv(h2) - dv(h1) * dv(r2)) < degentol);
213 const bool degen2 =
214 form == 2 && (dv(r2) > 1.0 - degentol ||
215 std::fabs(dv(h1) - dv(h2) - dv(h1) * dv(r1) + dv(h1) * dv(r1) * dv(r2)) <
216 degentol);
217 if (degen1 || degen2) {
218 if (dv(r1) < degentol) r1 = num_traits<T>::from_double(degentol);
219 if (dv(r2) > 1.0 - degentol) r2 = num_traits<T>::from_double(1.0 - degentol);
220 if (form == 1 && std::fabs(dv(h2) - dv(h1) * dv(r2)) < degentol)
221 h2 = T(h1 * r2 + num_traits<T>::from_double(degentol));
222 if (form == 2 &&
223 std::fabs(dv(h1) - dv(h2) - dv(h1) * dv(r1) + dv(h1) * dv(r1) * dv(r2)) < degentol)
224 h1 = T((h2 + num_traits<T>::from_double(degentol)) / (one - r1 + r1 * r2));
225 mp.D0 = Matrix<T>(2, 2, zero);
226 mp.D1 = Matrix<T>(2, 2, zero);
227 mp.D0(0, 0) = T(-one / h1);
228 mp.D0(0, 1) = T(r1 / h1);
229 mp.D0(1, 1) = T(-one / h2);
230 if (form == 1) {
231 mp.D1(0, 0) = T((one - r1) / h1);
232 mp.D1(1, 0) = T(r2 / h2);
233 mp.D1(1, 1) = T((one - r2) / h2);
234 } else {
235 mp.D1(0, 1) = T((one - r1) / h1);
236 mp.D1(1, 0) = T(r2 / h2);
237 mp.D1(1, 1) = T((one - r2) / h2);
238 }
239 mp = map_normalize(mp);
240 out.mmap.D0 = mp.D0;
241 out.mmap.D1 = mp.D1;
242 }
243
244 // ---- the degenerate ladder, in the reference's order ------------------
245 if (form == 2 && dv(r2) < degentol && std::fabs(1.0 - dv(r1)) < degentol) {
246 finish(p[0], p[0], p[0]); // only the class probabilities are identifiable
247 return out;
248 }
249 if (form == 1 && dv(r2) < degentol) {
250 // A canonical APH(2): the problem IS the MAPH fit.
251 Map<T> aph = mp;
252 aph.D1(1, 1) = zero;
253 aph = map_normalize(aph);
254 const Maph2mFitResult<T> r = maph2m_fit_multiclass(aph, p, B, cw);
255 out.mmap = r.maph;
256 const std::vector<unsigned> ord(1, 1u);
257 const std::vector<std::vector<T>> bm = mmap_backward_moment(out.mmap, ord, true);
258 out.fB.assign(2, zero);
259 for (std::size_t c = 0; c < 2; ++c) out.fB[c] = bm[c][0];
260 out.fS = mmap_sigma(out.mmap);
261 return out;
262 }
263 if (std::fabs(1.0 - dv(r1)) < degentol) {
264 // Non-canonical: refit the timing as an APH(2), then mark it.
265 const Map<T> aph = aph2_fit_map(mp).aph;
266 const Maph2mFitResult<T> r = maph2m_fit_multiclass(aph, p, B, cw);
267 out.mmap = r.maph;
268 const std::vector<unsigned> ord(1, 1u);
269 const std::vector<std::vector<T>> bm = mmap_backward_moment(out.mmap, ord, true);
270 out.fB.assign(2, zero);
271 for (std::size_t c = 0; c < 2; ++c) out.fB[c] = bm[c][0];
272 out.fS = mmap_sigma(out.mmap);
273 return out;
274 }
275 if (form == 2 && dv(r2) < degentol) {
276 // The gamma < 0 degeneracy: fit B or sigma, whichever is weighted higher.
277 auto degen_backward = [&](const T& vB1, T* q1, T* q2, T* q3) {
278 *q1 = T((p[0] * (r1 - two) * (h2 - vB1 + h1 * r1)) /
279 ((r1 - one) * (h2 - h1 + h1 * r1)));
280 *q2 = T(-(p[0] * (vB1 - h1) * (r1 - two)) / (h2 - h1 + h1 * r1));
281 *q3 = p[0]; // meaningless when the form is truly degenerate
282 };
283 T q1 = zero, q2 = zero, q3 = zero;
284 if (dv(bw[0]) > dv(bw[1])) {
285 degen_backward(B[0], &q1, &q2, &q3);
286 if (!(feasible(q1) && feasible(q2) && feasible(q3))) {
287 // One variable, four inequalities: the box the reference solves
288 // a quadratic program over reduces to an interval, and the
289 // minimizer of (x/B - 1)^2 on it is the projection of B onto it.
290 const T q1B = T(-p[0] * (r1 - two) / ((r1 - one) * (h2 - h1 + h1 * r1)));
291 const T q1_0 = T(p[0] * (r1 - two) * (h2 + h1 * r1) /
292 ((r1 - one) * (h2 - h1 + h1 * r1)));
293 const T q2B = T(-p[0] * (r1 - two) / (h2 - h1 + h1 * r1));
294 const T q2_0 = T(p[0] * (r1 - two) * h1 / (h2 - h1 + h1 * r1));
295 double lo = 1e-6, hi = 1e6;
296 const double coefs[2] = {dv(q1B), dv(q2B)};
297 const double offs[2] = {dv(q1_0), dv(q2_0)};
298 for (int i = 0; i < 2; ++i) {
299 if (std::fabs(coefs[i]) < denumtol) continue;
300 // 0 <= coef x + off <= 1
301 const double a = -offs[i] / coefs[i], b = (1.0 - offs[i]) / coefs[i];
302 lo = std::max(lo, std::min(a, b));
303 hi = std::min(hi, std::max(a, b));
304 }
305 if (!(lo <= hi))
306 throw NumericError(
307 "mamap22_fit_bs_multiclass: the degenerate backward fit has an empty "
308 "feasible interval for this (p, B)");
309 double x = dv(B[0]);
310 if (x < lo) x = lo;
311 if (x > hi) x = hi;
312 degen_backward(num_traits<T>::from_double(x), &q1, &q2, &q3);
313 }
314 } else {
315 // sqrt(p1^2 - S11) is COMPLEX above p1^2, where the reference's own
316 // feasibility test then fails on the real part and sends it to the
317 // clamp. Report that as "not feasible" instead of raising, so the
318 // clamp below is reachable from the same inputs.
319 auto degen_transition = [&](const T& vS11, T* a, T* b, T* c) {
320 const double root = dv(T(p[0] * p[0] - vS11));
321 const T s = num_traits<T>::from_double(std::sqrt(std::max(root, 0.0)));
322 *a = T(p[0] + s / (r1 - one));
323 *b = T(p[0] + s);
324 *c = p[0];
325 return root >= 0.0;
326 };
327 const bool real = degen_transition(S(0, 0), &q1, &q2, &q3);
328 if (!real || !(feasible(q1) && feasible(q2) && feasible(q3))) {
329 // The reference clamps S11 into the interval the form admits.
330 const double safety = 1e-10;
331 const double p1 = dv(p[0]), rr1 = dv(r1);
332 const double lb = p1 * p1 * (1.0 - (1.0 - rr1) * (1.0 - rr1));
333 const double ub = p1 * p1 - (1.0 - p1) * (1.0 - p1);
334 double s11 = dv(S(0, 0));
335 if (s11 <= lb) s11 = lb + safety;
336 else if (s11 >= ub) s11 = ub - safety;
337 degen_transition(num_traits<T>::from_double(s11), &q1, &q2, &q3);
338 }
339 }
340 finish(q1, q2, q3);
341 return out;
342 }
343
344 // ---- the full form: the closed-form inverse -------------------------
345 const Mamap2mCoefficients<T> c = form == 1
346 ? mamap2m_can1_coefficients(h1, h2, r1, r2)
347 : mamap2m_can2_coefficients(h1, h2, r1, r2);
348 T q1 = zero, q2 = zero, q3 = zero;
349 if (form == 1)
350 bsdetail::fit_can1(c, p[0], B[0], S(0, 0), denumtol, &q1, &q2, &q3);
351 else
352 bsdetail::fit_can2(c, p[0], B[0], S(0, 0), denumtol, &q1, &q2, &q3);
353
354 if (feasible(q1) && feasible(q2) && feasible(q3)) {
355 out.exact = true;
356 finish(q1, q2, q3);
357 return out;
358 }
359 if (!adjust) {
360 finish(q1, q2, q3);
361 return out;
362 }
363 throw UnsupportedError(
364 "mamap22_fit_bs_multiclass: the closed-form backward-plus-sigma inverse is infeasible for "
365 "these targets, and the reference's repair solves a NONCONVEX bilinear program with "
366 "YALMIP's bmibnb, a spatial branch-and-bound returning a GLOBAL optimum. That solver is "
367 "not ported; a local method would report a different fit under the same name. Pass "
368 "adjust = false to take the clamped closed form, weight the forward moment above sigma so "
369 "mamap2m_fit_fb_multiclass applies, or relax the targets");
370}
371
372/**
373 * `mamap22_fit_gamma_bs`: fit over every AMAP(2) form and keep the closest.
374 *
375 * Port of matlab/lib/m3a/m3a/mamap22/mamap22_fit_gamma_bs.m: the class
376 * probabilities are fitted exactly, the BACKWARD moments and the one-step
377 * class transition probabilities approximately. When the moment set admits
378 * only a one-state process, the reference perturbs the second and third
379 * moments slightly above the exponential to recover a two-state form, and
380 * falls back to a marked Poisson only if that also fails; both steps are
381 * here, as in the `mamap22_fit_gamma_fs` twin.
382 */
383template <class T>
384Mmap<T> mamap22_fit_gamma_bs(const T& M1, const T& M2, const T& M3, const T& GAMMA,
385 const std::vector<T>& p, const std::vector<T>& B,
386 const Matrix<T>& S) {
387 const T one = num_traits<T>::from_int(1);
388 Amap2FitGammaResult<T> a = amap2_fit_gamma(M1, M2, M3, GAMMA);
389 if (a.amaps.size() == 1 && a.amaps[0].order() == 1) {
390 // perturb just above the exponential to recover a second-order form
391 const T M2a = T(M2 * (one + num_traits<T>::from_double(1e-4)));
392 const T ratio = T(M2a / M2);
393 const T M3a = T(M3 * num_traits<T>::from_double(
394 std::pow(num_traits<T>::to_double(ratio), 1.5)));
395 const std::vector<Map<T>> alt = amap2_fitall_gamma(M1, M2a, M3a, GAMMA);
396 if (!alt.empty()) {
397 a.amaps.clear();
398 for (std::size_t j = 0; j < alt.size(); ++j) a.amaps.push_back(map_normalize(alt[j]));
399 } else {
400 return mamapdetail::marked_poisson(M1, p);
401 }
402 }
403
404 Mmap<T> best;
405 double bestErr = 0.0;
406 bool have = false;
407 for (std::size_t j = 0; j < a.amaps.size(); ++j) {
409 try {
410 r = mamap22_fit_bs_multiclass(a.amaps[j], p, B, S);
411 } catch (const Error&) {
412 continue;
413 }
414 // the reference scores on the FIRST class alone: fB(1) and fS(1,1)
415 const double db = num_traits<T>::to_double(T(r.fB[0] / B[0])) - 1.0;
416 const double ds = num_traits<T>::to_double(T(r.fS(0, 0) / S(0, 0))) - 1.0;
417 const double err = db * db + ds * ds;
418 if (!have || err < bestErr) {
419 bestErr = err;
420 best = r.mmap;
421 have = true;
422 }
423 }
424 if (!have)
425 throw NumericError(
426 "mamap22_fit_gamma_bs: no AMAP(2) form admits a feasible backward-plus-sigma "
427 "marking for these targets");
428 return best;
429}
430
431/** `mamap22_fit_gamma_bs` driven from an MMAP[2] of arbitrary order. */
432template <class T>
434 const Map<T> mp = mm.map();
435 const std::vector<T> p = mmap_pc(mm);
436 const std::vector<std::vector<T>> bm =
437 mmap_backward_moment(mm, std::vector<unsigned>(1, 1u), true);
438 std::vector<T> B(p.size());
439 for (std::size_t c = 0; c < p.size(); ++c) B[c] = bm[c][0];
440 return mamap22_fit_gamma_bs(map_moment(mp, 1u), map_moment(mp, 2u), map_moment(mp, 3u),
441 map_gamma(mp), p, B, mmap_sigma(mm));
442}
443
444/** `mamap22_fit_gamma_bs` driven from a marked trace. */
445template <class T>
446Mmap<T> mamap22_fit_gamma_bs_trace(const std::vector<T>& Tv, const std::vector<int>& A) {
447 if (Tv.empty() || Tv.size() != A.size())
448 throw InputError(
449 "mamap22_fit_gamma_bs_trace: the trace and its labels must agree in length");
450 const T zero = num_traits<T>::from_int(0);
451 T m1 = zero, m2 = zero, m3 = zero;
452 for (std::size_t i = 0; i < Tv.size(); ++i) {
453 const T x = Tv[i];
454 m1 += x;
455 m2 += x * x;
456 m3 += x * x * x;
457 }
458 const T n = num_traits<T>::from_int(static_cast<long>(Tv.size()));
459 const std::vector<T> p = trace::mtrace_pc<T>(A);
460 const Matrix<T> bm =
461 trace::mtrace_backward_moment(Tv, A, std::vector<unsigned>(1, 1u));
462 std::vector<T> B(p.size(), zero);
463 for (std::size_t c = 0; c < p.size(); ++c) B[c] = bm(c, 0);
465 return mamap22_fit_gamma_bs(T(m1 / n), T(m2 / n), T(m3 / n),
466 line::trace::trace_gamma(Tv).gamma, p, B, S);
467}
468
469} // namespace mam
470} // namespace line
471
472#endif // LINE_API_MAM_MAMAP22_FIT_BS_H
AMAP(2) fit of three moments and the autocorrelation decay rate (matlab/lib/m3a/m3a/amap2/amap2_fit_g...
Base error for the multiprecision C++ port.
Definition error.h:31
InputError(const std::string &what)
Definition error.h:39
std::size_t cols() const
Definition matrix.h:90
std::size_t rows() const
Definition matrix.h:89
NumericError(const std::string &what)
Definition error.h:45
UnsupportedError(const std::string &what)
Definition error.h:51
The exception types the port throws.
The m3a fitters driven from a process or from a trace rather than from moments.
The marking coefficients of a canonical AMAP(2), for the sigma fitters.
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...
MAP constructors and structural transformations.
Fit a MAPH(2,m): a second-order acyclic phase-type marked with m classes.
Dense matrix and non-owning view.
Compression of a marked MAP into a smaller representation, and the two M3A primitives it is built fro...
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...
Class probabilities of a marked trace, p_c = count_c / N.
One-step class transition frequencies of a marked trace,.
Mamap2mCoefficients< T > mamap2m_can1_coefficients(const T &h1, const T &h2, const T &r1, const T &r2)
First canonical form, a positive autocorrelation decay.
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 > mamap22_fit_gamma_bs_trace(const std::vector< T > &Tv, const std::vector< int > &A)
mamap22_fit_gamma_bs driven from a marked trace.
Mamap2mCoefficients< T > mamap2m_can2_coefficients(const T &h1, const T &h2, const T &r1, const T &r2)
Second canonical form, a negative autocorrelation decay (E, V, Z).
Mmap< T > mamap22_fit_gamma_bs_mmap(const Mmap< T > &mm)
mamap22_fit_gamma_bs driven from an MMAP[2] of arbitrary order.
Aph2FitResult< T > aph2_fit_map(const Map< T > &m)
Fit an APH(2) to the first three moments of a MAP.
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).
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).
Definition mmap_stats.h:140
Mmap< T > mamap22_fit_gamma_bs(const T &M1, const T &M2, const T &M3, const T &GAMMA, const std::vector< T > &p, const std::vector< T > &B, const Matrix< T > &S)
mamap22_fit_gamma_bs: fit over every AMAP(2) form and keep the closest.
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...
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).
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
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.
Definition maph2m_fit.h:89
T map_gamma(const Map< T > &m, long limit=1000)
Autocorrelation decay rate of a MAP (map_gamma.m).
Definition map_gamma.h:192
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,...
Definition trace_gamma.h:73
std::vector< T > mtrace_pc(const std::vector< int > &A)
Class probabilities of a marked trace, p_c = count_c / N.
Definition mtrace_pc.h:42
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,...
T num_abs(const T &v)
Definition number.h:172
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.
std::vector< T > fB
achieved per-class backward moments
Matrix< T > fS
achieved class transition probabilities
The three coefficient tables of one canonical form.
std::vector< T > G
15 entries for form 1, 14 for form 2 (there called E)
std::vector< T > Y
3 determinants (Z for form 2)
std::vector< T > U
12 entries (V for form 2)
A MAP as the pair of matrices (D0, D1).
Definition map_moment.h:53
Matrix< T > D1
Definition map_moment.h:55
Matrix< T > D0
Definition map_moment.h:54
The fitted MAPH and the backward moments it actually achieved.
Definition maph2m_fit.h:75
An MMAP: the underlying MAP plus the per-class arrival matrices.
Definition mmap_lambda.h:45
Map< T > map() const
Definition mmap_lambda.h:52
Autocorrelation decay rate of a trace: the gamma of the geometric model rho(k) = rho0 * gamma^k,...