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");
75 for (std::size_t i = 0; i < L; ++i)
76 if (parts[i].order() != 2)
77 throw InputError(
"m3pp2m_interleave: every component must have order 2");
81 std::vector<T> r0(L, zero), r1(L, zero);
82 r0[L - 1] = parts[L - 1].D0(0, 1);
83 for (std::size_t k = L - 1; k-- > 0;) {
85 for (std::size_t j = k + 1; j < L; ++j) acc += r0[j];
86 r0[k] = parts[k].D0(0, 1) - acc;
88 r1[0] = parts[0].D0(1, 0);
89 for (std::size_t i = 1; i < L; ++i) {
91 for (std::size_t j = 0; j < i; ++j) acc += r1[j];
92 r1[i] = parts[i].D0(1, 0) - acc;
96 for (std::size_t i = 0; i < L; ++i) M += parts[i].classes();
97 const std::size_t n = 2 + (L - 1);
101 for (std::size_t i = 0; i < n; ++i)
102 for (std::size_t j = 0; j < n; ++j) {
104 s.
D0(i, j) = r0[j - 1];
109 for (std::size_t i = 0; i < L; ++i) {
110 for (std::size_t c = 0; c < parts[i].classes(); ++c) {
112 for (std::size_t h = 0; h < n; ++h)
113 Dc(h, h) = h <= i ? parts[i].Dc[c](0, 0) : parts[i].Dc[c](1, 1);
119 for (std::size_t c = 0; c < M; ++c)
120 for (std::size_t i = 0; i < n; ++i)
121 for (std::size_t j = 0; j < n; ++j) s.
D1(i, j) += s.
Dc[c](i, j);
123 for (std::size_t h = 0; h < n; ++h) {
125 for (std::size_t j = 0; j < n; ++j) acc += s.
D0(h, j) + s.
D1(h, j);
143 "m3pp2m_fitc_theoretical requires transcendental arithmetic");
144 const std::size_t m = mm.
classes();
145 if (m == 0)
throw InputError(
"m3pp2m_fitc_theoretical: the MMAP has no classes");
146 if (method ==
"approx_cov" && m > 2)
147 throw InputError(
"m3pp2m_fitc_theoretical: approximate covariance fitting only supports "
150 const T t1 = t, t2 = t, t3 = t;
161 const T a = mu[0] / t1;
162 const T bt1 = vr[0] / (a * t1);
163 const T bt2 = vr[1] / (a * t2);
164 const T binf = vr[2] / (a * tinf);
166 std::vector<unsigned> orders;
171 const T m3t2 = fitdetail::m3_from_raw(mt2[0], mt2[1], mt2[2]);
175 if (method ==
"exact_delta" || method ==
"approx_delta") {
176 std::vector<T> dvt3(m);
177 for (std::size_t i = 0; i < m; ++i) {
181 two.
Dc.push_back(mm.
Dc[i]);
183 for (std::size_t r = 0; r < rest.
rows(); ++r)
184 for (std::size_t c = 0; c < rest.
cols(); ++c) rest(r, c) -= mm.
Dc[i](r, c);
185 two.
Dc.push_back(rest);
187 dvt3[i] = V[0] - V[1];
189 if (method ==
"exact_delta")
190 return m3pp2m_fitc(a, bt1, bt2, binf, m3t2, t1, t2, ai, dvt3, t3).mmap;
193 if (method ==
"approx_cov") {
196 for (std::size_t i = 0; i < vi.size(); ++i)
sum += vi[i];
200 if (method ==
"approx_ag") {
201 std::vector<T> gt3(m);
202 for (std::size_t i = 0; i < m; ++i) {
206 two.
Dc.push_back(mm.
Dc[i]);
208 for (std::size_t r = 0; r < rest.
rows(); ++r)
209 for (std::size_t c = 0; c < rest.
cols(); ++c) rest(r, c) -= mm.
Dc[i](r, c);
210 two.
Dc.push_back(rest);
213 gt3[i] = V[0] + S(0, 1);
217 throw InputError(
"m3pp2m_fitc_theoretical: unknown method '" + method +
"'");
246 const std::vector<T>& binfv,
247 const std::vector<T>& stv,
const T& t) {
249 "m3pp22_interleave_fitc requires transcendental arithmetic");
250 using fitdetail::lambertw0;
251 using fitdetail::num_exp;
252 using fitdetail::num_sqrt;
258 const std::size_t L = av.
rows();
259 if (L == 0)
throw InputError(
"m3pp22_interleave_fitc: no pairs");
260 if (av.
cols() != 2)
throw InputError(
"m3pp22_interleave_fitc: av must have two columns");
261 if (btv.size() != L || binfv.size() != L || stv.size() != L)
262 throw InputError(
"m3pp22_interleave_fitc: btv, binfv and stv must have one entry per pair");
265 std::vector<T> uv(L, zero), dv(L, zero);
266 for (std::size_t i = 0; i < L; ++i) {
267 const T a = av(i, 0) + av(i, 1);
268 if (!(binfv[i] > btv[i] && btv[i] > one))
269 throw InputError(
"m3pp22_interleave_fitc: infeasible IDC pair, IDC(inf) must exceed "
270 "IDC(t) and IDC(t) must exceed one");
271 const T c = (binfv[i] - one) / (binfv[i] - btv[i]);
272 const T w = lambertw0(T(-c * num_exp(T(-c))), 200u);
273 const T d = (w + c) / t;
274 const T z = (binfv[i] - one) * pw(d, 3) * a;
275 uv[i] = d * z / (two * a * a * d * d + z);
282 for (std::size_t j = 0; j < 2 * L; ++j) {
288 for (std::size_t i = 0; i < L; ++i) {
290 for (std::size_t j = i; j < L; ++j) model.
row_add(j, one);
293 for (std::size_t j = i; j < L; ++j) model.
row_add(j, T(-one));
294 model.
emit_le(T(-uv[i] - eps));
296 for (std::size_t i = 0; i < L; ++i) {
298 for (std::size_t j = i; j < L; ++j) model.
row_add(j, one);
299 for (std::size_t j = 0; j <= i; ++j) model.
row_add(L + j, one);
304 throw NumericError(
"m3pp22_interleave_fitc: no feasible set of off-diagonal rates (" +
308 for (std::size_t i = 0; i < L; ++i) {
309 T r1 = zero, r2 = zero;
310 for (std::size_t j = i; j < L; ++j) r1 += sol.
x[j];
311 for (std::size_t j = 0; j <= i; ++j) r2 += sol.
x[L + j];
312 const T a = av(i, 0) + av(i, 1);
314 const T z = (binfv[i] - one) * pw(d, 3) * a;
315 const T delta = num_sqrt(T(z / (two * r1 * r2)));
316 const T l2 = a - r2 / d * delta;
317 const T l1 = l2 + delta;
326 for (std::size_t h = 0; h < 2; ++h)
327 base.
D0(h, h) = -(base.
D0(h, 0) + base.
D0(h, 1) + base.
D1(h, 0) + base.
D1(h, 1));
330 ai.push_back(av(i, 0));
331 ai.push_back(av(i, 1));
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).
Number-type abstraction for the templated API port.
Templated primal simplex with Bland's rule.
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