LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
m3pp_superpos_fitc.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_M3PP_SUPERPOS_FITC_H
6#define LINE_API_MAM_M3PP_SUPERPOS_FITC_H
7
8/**
9 * @file
10 * @ingroup api_mam
11 * M3PP obtained by SUPERPOSING one second-order process per class
12 * (matlab/lib/m3a/m3a/m3pp/m3pp_superpos_fitc.m and its two entry points
13 * m3pp_superpos_fitc_theoretical.m and m3pp_superpos_fitc_trace.m).
14 *
15 * Each class gets its own MMPP(2) from mmpp2_fitc on that class's own rate,
16 * IDC at t, IDC at infinity and third central moment of counts; the class is
17 * then a single-class MMAP {D0, D1, D1}, and the k of them are superposed.
18 * The result therefore has order 2^k, not k + 1: the phase process of a
19 * superposition is the PRODUCT chain, and the reference's own comment "M3PP[m]
20 * of order k+1" describes the lumped interleaving of m3pp2m_interleave, not
21 * this. What the superposition buys instead is that every per-class second-order
22 * characteristic is matched exactly and independently, since the components do
23 * not interact.
24 *
25 * REFERENCE DEFECT (m3pp_superpos_fitc_theoretical.m): it calls
26 * mmap_count_moment, which is defined NOWHERE in the MATLAB tree -- neither in
27 * m3a nor in matlab/src/api. The entry point therefore raises "Unrecognized
28 * function" before any fitting happens and cannot execute. The function is
29 * defined in the JAR (jline.api.mam.Mmap_count_moment) as the counting moments
30 * of the per-class MARGINAL MAP, {D0 + sum_{j != k} D1_j, D1_k}, which is the
31 * standard definition and is what mmap_count_moment in map_count_moment.h
32 * implements; that is what this port calls. MATLAB was NOT edited.
33 * m3pp_superpos_fitc_trace.m is unaffected: it reads its moments off the trace.
34 *
35 * Gated on transcendental arithmetic, through mmpp2_fitc.
36 */
37
38#include <cstddef>
39#include <vector>
40
46#include "line/num/number.h"
47#include "line/util/error.h"
48#include "line/util/matrix.h"
49
50namespace line {
51namespace mam {
52
53/** Result of the superposition fits. */
54template <class T>
56 Mmap<T> mmap; ///< the superposed process
57 std::vector<Mmap<T>> parts; ///< the per-class components, before superposition
58};
59
60namespace fitdetail {
61
62/** Sample central third moment of counts from the first three raw moments. */
63template <class T>
64T m3_from_raw(const T& m1, const T& m2, const T& m3) {
65 const T three = num_traits<T>::from_int(3);
66 const T two = num_traits<T>::from_int(2);
67 return m3 - three * m2 * m1 + two * m1 * m1 * m1;
68}
69
70/** Sample mean of the first `n` entries of a column. */
71template <class T>
72T col_mean(const Matrix<long>& C, std::size_t col, unsigned power) {
73 T acc = num_traits<T>::from_int(0);
74 for (std::size_t i = 0; i < C.rows(); ++i) {
75 T v = num_traits<T>::from_int(static_cast<long>(C(i, col)));
77 for (unsigned k = 0; k < power; ++k) p *= v;
78 acc += p;
79 }
80 return acc / num_traits<T>::from_int(static_cast<long>(C.rows()));
81}
82
83/** Sample variance (MATLAB `var`, i.e. the n-1 denominator) of a column. */
84template <class T>
85T col_var(const Matrix<long>& C, std::size_t col) {
86 const std::size_t n = C.rows();
87 if (n < 2) throw InputError("m3pp_superpos_fitc: fewer than two counting windows");
88 const T mu = col_mean<T>(C, col, 1);
89 T acc = num_traits<T>::from_int(0);
90 for (std::size_t i = 0; i < n; ++i) {
91 const T d = num_traits<T>::from_int(static_cast<long>(C(i, col))) - mu;
92 acc += d * d;
93 }
94 return acc / num_traits<T>::from_int(static_cast<long>(n - 1));
95}
96
97} // namespace fitdetail
98
99/**
100 * Fit one second-order M3PP per class from its counting characteristics and
101 * superpose them.
102 *
103 * @param av per-class rates
104 * @param btv per-class IDC(t)
105 * @param binfv per-class IDC(inf)
106 * @param m3tv per-class third central moment of counts at t
107 * @param t finite time scale
108 * @param tinf near-infinite time scale
109 */
110template <class T>
111M3ppSuperposResult<T> m3pp_superpos_fitc(const std::vector<T>& av, const std::vector<T>& btv,
112 const std::vector<T>& binfv, const std::vector<T>& m3tv,
113 const T& t, const T& tinf) {
115 "m3pp_superpos_fitc requires transcendental arithmetic");
116 const std::size_t m = av.size();
117 if (m == 0) throw InputError("m3pp_superpos_fitc: no classes");
118 if (btv.size() != m || binfv.size() != m || m3tv.size() != m)
119 throw InputError("m3pp_superpos_fitc: av, btv, binfv and m3tv must have the same length");
120
122 for (std::size_t i = 0; i < m; ++i) {
123 const Mmpp2FitcResult<T> f = mmpp2_fitc(av[i], btv[i], btv[i], binfv[i], m3tv[i], t, tinf);
124 Mmap<T> comp;
125 comp.D0 = f.map.D0;
126 comp.D1 = f.map.D1;
127 comp.Dc.push_back(f.map.D1);
128 res.parts.push_back(comp);
129 }
130
131 res.mmap = res.parts[0];
132 for (std::size_t i = 1; i < m; ++i) res.mmap = mmap_super(res.mmap, res.parts[i]);
133 return res;
134}
135
136/**
137 * Superpose one M3PP per class to fit the counting characteristics of a given
138 * MMAP.
139 *
140 * @param mm the process to fit
141 * @param t finite time scale
142 * @param tinf near-infinite time scale
143 */
144template <class T>
145M3ppSuperposResult<T> m3pp_superpos_fitc_theoretical(const Mmap<T>& mm, const T& t, const T& tinf) {
146 const std::size_t m = mm.classes();
147 if (m == 0) throw InputError("m3pp_superpos_fitc_theoretical: the MMAP has no classes");
148
149 const std::vector<T> av = mmap_count_mean(mm, num_traits<T>::from_int(1));
150 const std::vector<T> btv = mmap_count_idc(mm, t);
151 const std::vector<T> binfv = mmap_count_idc(mm, tinf);
152
153 std::vector<unsigned> orders;
154 orders.push_back(1);
155 orders.push_back(2);
156 orders.push_back(3);
157 const Matrix<T> mtv = mmap_count_moment(mm, t, orders);
158
159 std::vector<T> m3tv(m, num_traits<T>::from_int(0));
160 for (std::size_t i = 0; i < m; ++i)
161 m3tv[i] = fitdetail::m3_from_raw(mtv(0, i), mtv(1, i), mtv(2, i));
162
163 return m3pp_superpos_fitc(av, btv, binfv, m3tv, t, tinf);
164}
165
166/**
167 * Superpose one M3PP per class to fit a multi-class trace.
168 *
169 * @param Tv inter-arrival times
170 * @param A class labels
171 * @param t finite time scale
172 * @param tinf near-infinite time scale
173 */
174template <class T>
175M3ppSuperposResult<T> m3pp_superpos_fitc_trace(const std::vector<T>& Tv, const std::vector<int>& A,
176 const T& t, const T& tinf) {
177 if (Tv.empty()) throw InputError("m3pp_superpos_fitc_trace: empty trace");
178 if (A.size() != Tv.size())
179 throw InputError("m3pp_superpos_fitc_trace: labels and inter-arrival times disagree");
180
181 T sumT = num_traits<T>::from_int(0);
182 for (std::size_t i = 0; i < Tv.size(); ++i) sumT += Tv[i];
183 const T a = num_traits<T>::from_int(static_cast<long>(Tv.size())) / sumT;
184
187 const std::size_t m = Nt.labels.size();
188
189 std::vector<T> av(m), btv(m), binfv(m), m3tv(m);
190 for (std::size_t i = 0; i < m; ++i) {
191 long cnt = 0;
192 for (std::size_t k = 0; k < A.size(); ++k)
193 if (A[k] == Nt.labels[i]) ++cnt;
194 av[i] = a * num_traits<T>::from_int(cnt) /
195 num_traits<T>::from_int(static_cast<long>(A.size()));
196 btv[i] = fitdetail::col_var<T>(Nt.counts, i) / (av[i] * t);
197 binfv[i] = fitdetail::col_var<T>(Ninf.counts, i) / (av[i] * tinf);
198 m3tv[i] = fitdetail::m3_from_raw(fitdetail::col_mean<T>(Nt.counts, i, 1),
199 fitdetail::col_mean<T>(Nt.counts, i, 2),
200 fitdetail::col_mean<T>(Nt.counts, i, 3));
201 }
202 return m3pp_superpos_fitc(av, btv, binfv, m3tv, t, tinf);
203}
204
205/** m3pp_superpos_fitc_trace with the reference's default time scales. */
206template <class T>
208 const std::vector<int>& A) {
209 if (Tv.empty()) throw InputError("m3pp_superpos_fitc_trace: empty trace");
210 T sumT = num_traits<T>::from_int(0);
211 for (std::size_t i = 0; i < Tv.size(); ++i) sumT += Tv[i];
212 const T mean = sumT / num_traits<T>::from_int(static_cast<long>(Tv.size()));
213 const T t = num_traits<T>::from_int(10) * mean;
214 const T span = (sumT - Tv[0]) / num_traits<T>::from_int(100);
215 const T ten_t = num_traits<T>::from_int(10) * t;
216 return m3pp_superpos_fitc_trace(Tv, A, t, ten_t > span ? ten_t : span);
217}
218
219} // namespace mam
220} // namespace line
221
222#endif // LINE_API_MAM_M3PP_SUPERPOS_FITC_H
InputError(const std::string &what)
Definition error.h:39
std::size_t rows() const
Definition matrix.h:89
The exception types the port throws.
Power moments of the counts of a MAP in a window of length t.
Dense matrix and non-owning view.
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....
Per-class counting processes of a marked trace: for each arrival, how many events of each class fall ...
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
M3ppSuperposResult< T > m3pp_superpos_fitc_trace(const std::vector< T > &Tv, const std::vector< int > &A, const T &t, const T &tinf)
Superpose one M3PP per class to fit a multi-class trace.
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.
Matrix< T > mmap_count_moment(const Mmap< T > &m, const T &t, const std::vector< unsigned > &orders)
Per-class counting moments of a marked MAP, mmap_count_moment.
std::vector< T > mmap_count_idc(const Mmap< T > &mm, const T &t)
Per-class index of dispersion of counts over a window of length t.
Definition mmap_stats.h:198
M3ppSuperposResult< T > m3pp_superpos_fitc_theoretical(const Mmap< T > &mm, const T &t, const T &tinf)
Superpose one M3PP per class to fit the counting characteristics of a given MMAP.
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.
Definition mmap_stats.h:182
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
MtraceCountsResult< T > mtrace_iat2counts(const std::vector< T > &Tv, const std::vector< int > &A, const T &scale)
Per-class counting processes of a marked trace: for each arrival, how many events of each class fall ...
Number-type abstraction for the templated API port.
Result of the superposition fits.
Mmap< T > mmap
the superposed process
std::vector< Mmap< T > > parts
the per-class components, before superposition
An MMAP: the underlying MAP plus the per-class arrival matrices.
Definition mmap_lambda.h:45
std::size_t classes() const
Definition mmap_lambda.h:51
Matrix< T > D0
Definition mmap_lambda.h:46
Matrix< T > D1
Definition mmap_lambda.h:47
std::vector< Matrix< T > > Dc
per-class matrices, sum_c Dc = D1
Definition mmap_lambda.h:48
Result of mmpp2_fitc.
Definition mmpp2_fitc.h:91
Return value of mtrace_iat2counts.
Matrix< long > counts
(rows x C), column c for labels[c]
std::vector< int > labels
the distinct labels, increasing