5#ifndef LINE_API_MAM_M3PP2M_INTERLEAVE_H
6#define LINE_API_MAM_M3PP2M_INTERLEAVE_H
73 const std::size_t L = parts.size();
74 if (L == 0)
throw InputError(
"m3pp2m_interleave: no components");
77 std::vector<bool> deg(L,
false);
79 for (std::size_t i = 0; i < L; ++i) {
80 if (parts[i].order() != 1 && parts[i].order() != 2)
81 throw InputError(
"m3pp2m_interleave: every component must have order 1 or 2");
82 deg[i] = parts[i].order() == 1;
83 all_deg = all_deg && deg[i];
88 for (std::size_t i = 0; i < L; ++i)
89 for (std::size_t c = 0; c < parts[i].classes(); ++c) {
90 p.
Dc.push_back(parts[i].Dc[c]);
91 p.
D1(0, 0) += parts[i].Dc[c](0, 0);
94 p.
D0(0, 0) = zero - p.
D1(0, 0);
100 std::vector<T> r0(L, zero), r1(L, zero);
101 for (std::size_t k = L; k-- > 0;) {
102 if (deg[k])
continue;
104 for (std::size_t j = k + 1; j < L; ++j) acc += r0[j];
105 r0[k] = parts[k].D0(0, 1) - acc;
107 for (std::size_t i = 0; i < L; ++i) {
108 if (deg[i])
continue;
110 for (std::size_t j = 0; j < i; ++j) acc += r1[j];
111 r1[i] = parts[i].D0(1, 0) - acc;
115 for (std::size_t i = 0; i < L; ++i) M += parts[i].classes();
116 const std::size_t n = 2 + (L - 1);
120 for (std::size_t i = 0; i < n; ++i)
121 for (std::size_t j = 0; j < n; ++j) {
123 s.
D0(i, j) = r0[j - 1];
128 for (std::size_t i = 0; i < L; ++i) {
129 for (std::size_t c = 0; c < parts[i].classes(); ++c) {
131 for (std::size_t h = 0; h < n; ++h)
132 Dc(h, h) = (h <= i || deg[i]) ? parts[i].Dc[c](0, 0) : parts[i].Dc[c](1, 1);
138 for (std::size_t c = 0; c < M; ++c)
139 for (std::size_t i = 0; i < n; ++i)
140 for (std::size_t j = 0; j < n; ++j) s.
D1(i, j) += s.
Dc[c](i, j);
142 for (std::size_t h = 0; h < n; ++h) {
144 for (std::size_t j = 0; j < n; ++j) acc += s.
D0(h, j) + s.
D1(h, j);
162 "m3pp2m_fitc_theoretical requires transcendental arithmetic");
163 const std::size_t m = mm.
classes();
164 if (m == 0)
throw InputError(
"m3pp2m_fitc_theoretical: the MMAP has no classes");
165 if (method ==
"approx_cov" && m > 2)
166 throw InputError(
ErrorKind{
"Argument"},
"m3pp2m_fitc_theoretical: approximate covariance fitting only supports "
169 const T t1 = t, t2 = t, t3 = t;
180 const T a = mu[0] / t1;
181 const T bt1 = vr[0] / (a * t1);
182 const T bt2 = vr[1] / (a * t2);
183 const T binf = vr[2] / (a * tinf);
185 std::vector<unsigned> orders;
190 const T m3t2 = fitdetail::m3_from_raw(mt2[0], mt2[1], mt2[2]);
194 if (method ==
"exact_delta" || method ==
"approx_delta") {
195 std::vector<T> dvt3(m);
196 for (std::size_t i = 0; i < m; ++i) {
200 two.
Dc.push_back(mm.
Dc[i]);
202 for (std::size_t r = 0; r < rest.
rows(); ++r)
203 for (std::size_t c = 0; c < rest.
cols(); ++c) rest(r, c) -= mm.
Dc[i](r, c);
204 two.
Dc.push_back(rest);
206 dvt3[i] = V[0] - V[1];
208 if (method ==
"exact_delta")
209 return m3pp2m_fitc(a, bt1, bt2, binf, m3t2, t1, t2, ai, dvt3, t3).mmap;
212 if (method ==
"approx_cov") {
215 for (std::size_t i = 0; i < vi.size(); ++i)
sum += vi[i];
219 if (method ==
"approx_ag") {
220 std::vector<T> gt3(m);
221 for (std::size_t i = 0; i < m; ++i) {
225 two.
Dc.push_back(mm.
Dc[i]);
227 for (std::size_t r = 0; r < rest.
rows(); ++r)
228 for (std::size_t c = 0; c < rest.
cols(); ++c) rest(r, c) -= mm.
Dc[i](r, c);
229 two.
Dc.push_back(rest);
232 gt3[i] = V[0] + S(0, 1);
236 throw InputError(
"m3pp2m_fitc_theoretical: unknown method '" + method +
"'");
265 const std::vector<T>& binfv,
266 const std::vector<T>& stv,
const T& t) {
268 "m3pp22_interleave_fitc requires transcendental arithmetic");
269 using fitdetail::lambertw0;
270 using fitdetail::num_exp;
271 using fitdetail::num_sqrt;
277 const std::size_t L = av.
rows();
278 if (L == 0)
throw InputError(
"m3pp22_interleave_fitc: no pairs");
279 if (av.
cols() != 2)
throw InputError(
"m3pp22_interleave_fitc: av must have two columns");
280 if (btv.size() != L || binfv.size() != L || stv.size() != L)
281 throw InputError(
"m3pp22_interleave_fitc: btv, binfv and stv must have one entry per pair");
284 std::vector<T> uv(L, zero), dv(L, zero);
285 for (std::size_t i = 0; i < L; ++i) {
286 const T a = av(i, 0) + av(i, 1);
287 if (!(binfv[i] > btv[i] && btv[i] > one))
288 throw InputError(
"m3pp22_interleave_fitc: infeasible IDC pair, IDC(inf) must exceed "
289 "IDC(t) and IDC(t) must exceed one");
290 const T c = (binfv[i] - one) / (binfv[i] - btv[i]);
291 const T w = lambertw0(T(-c * num_exp(T(-c))), 200u);
292 const T d = (w + c) / t;
293 const T z = (binfv[i] - one) * pw(d, 3) * a;
294 uv[i] = d * z / (two * a * a * d * d + z);
301 for (std::size_t j = 0; j < 2 * L; ++j) {
307 for (std::size_t i = 0; i < L; ++i) {
309 for (std::size_t j = i; j < L; ++j) model.
row_add(j, one);
312 for (std::size_t j = i; j < L; ++j) model.
row_add(j, T(-one));
313 model.
emit_le(T(-uv[i] - eps));
315 for (std::size_t i = 0; i < L; ++i) {
317 for (std::size_t j = i; j < L; ++j) model.
row_add(j, one);
318 for (std::size_t j = 0; j <= i; ++j) model.
row_add(L + j, one);
323 throw NumericError(
ErrorKind{
"Infeasible"},
"m3pp22_interleave_fitc: no feasible set of off-diagonal rates (" +
327 for (std::size_t i = 0; i < L; ++i) {
328 T r1 = zero, r2 = zero;
329 for (std::size_t j = i; j < L; ++j) r1 += sol.
x[j];
330 for (std::size_t j = 0; j <= i; ++j) r2 += sol.
x[L + j];
331 const T a = av(i, 0) + av(i, 1);
333 const T z = (binfv[i] - one) * pw(d, 3) * a;
334 const T delta = num_sqrt(T(z / (two * r1 * r2)));
335 const T l2 = a - r2 / d * delta;
336 const T l1 = l2 + delta;
345 for (std::size_t h = 0; h < 2; ++h)
346 base.
D0(h, h) = -(base.
D0(h, 0) + base.
D0(h, 1) + base.
D1(h, 0) + base.
D1(h, 1));
349 ai.push_back(av(i, 0));
350 ai.push_back(av(i, 1));
352 out.parts.push_back(f.
mmap);
353 out.sigma.push_back(f.
sigma);
NumericError(const std::string &what)
Sparse LP in the natural form, with per-variable bounds.
void emit_eq(const T &rhs)
void set_maximize(bool m)
true to maximize c'x (the default), false to minimize.
void emit_le(const T &rhs)
void set_free_upper(std::size_t j)
void set_cost(std::size_t j, const T &v)
void set_lower(std::size_t j, const T &v)
void row_clear()
Discard whatever the row accumulator holds.
void row_add(std::size_t j, const T &v)
row(j) += v, the accumulation the MATLAB reference performs.
The exception types the port throws.
M3PP(2, 2) fitted to the count COVARIANCE between its two classes (matlab/lib/m3a/m3a/m3pp/m3pp22_fit...
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 obtained by SUPERPOSING one second-order process per class (matlab/lib/m3a/m3a/m3pp/m3pp_superpo...
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.
Dense matrix and non-owning view.
Per-class variance of the counting process of a marked MAP.
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,...
MMPP(2) matching counting-process characteristics (matlab/lib/kpctoolbox/mmpp/mmpp2_fitc....
const char * lp_status_name(LpStatus s)
LpSolution< T > simplex_solve(const LpModel< T > &model, std::size_t max_iterations=0)
Solve the model.
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 > >3, 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...
M3pp22InterleaveResult< T > m3pp22_interleave_fitc(const Matrix< T > &av, const std::vector< T > &btv, const std::vector< T > &binfv, const std::vector< T > &stv, const T &t)
Fit L PAIRS of classes into one MMAP by lumped interleaving of L M3PP(2, 2).
Mmap< T > m3pp2m_interleave(const std::vector< Mmap< T > > &parts)
Interleave L M3PP(2, m_i) into one M3PP of order L + 1 whose class list is the concatenation of their...
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).
Matrix< T > mmap_count_mcov(const Mmap< T > &mm, const T &t)
Covariance matrix of the per-class counts over a window of length t.
std::vector< T > map_count_var(const Map< T > &m, const std::vector< T > &t)
Variance of the counting process of a MAP at resolution t.
std::vector< T > map_count_mean(const Map< T > &m, const std::vector< T > &t)
Mean of the counting process of a MAP at resolution t.
std::vector< T > mmap_count_mean(const Mmap< T > &mm, const T &t)
Per-class mean of the counting process over a window of length t.
M3pp22FitcCovResult< T > m3pp22_fitc_approx_cov(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 T &st3, const T &t3, const AugLagOptions< T > &opt)
Fit the underlying MMPP(2) by optimization, then apply the covariance split.
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...
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.
std::vector< T > mmap_count_var(const Mmap< T > &mm, const T &t)
Per-class variance of the counting process of a marked MAP.
M3pp22FitcCovResult< T > m3pp22_fitc_approx_cov_multiclass(const Map< T > &mmpp, const std::vector< T > &ai, const T &st3, const T &t3)
Split a GIVEN MMPP(2) into two classes, matching the per-class rates exactly and the count covariance...
Mmap< T > m3pp2m_fitc_theoretical(const Mmap< T > &mm, const std::string &method, const T &t, const T &tinf)
Fit the counting characteristics of a GIVEN MMAP with an M3PP(2, m).
Conservation laws of a layered queueing network, enumerated from its structure.
Number-type abstraction for the templated API port.
Templated primal simplex with Bland's rule.
The <kind> part of a LINE:<category>:<kind> identifier (see _kb/17-error-vocabulary....
std::vector< T > x
primal solution in the ORIGINAL variable space
Result of the covariance-matching M3PP(2, 2) fits.
Mmap< T > mmap
the fitted M3PP(2, 2)
T sigma
the covariance actually realised, after clamping
Result of m3pp22_interleave_fitc.
Mmap< T > mmap
the lumped process, of order L + 1
std::vector< Mmap< T > > parts
the L M3PP(2, 2) components
std::vector< T > sigma
the covariance realised for each pair
A MAP as the pair of matrices (D0, D1).
An MMAP: the underlying MAP plus the per-class arrival matrices.
std::size_t classes() const
std::vector< Matrix< T > > Dc
per-class matrices, sum_c Dc = D1