LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
mtrace_iat2counts.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_TRACE_MTRACE_IAT2COUNTS_H
6#define LINE_API_TRACE_MTRACE_IAT2COUNTS_H
7
8/**
9 * @file
10 * @ingroup api_trace
11 * Per-class counting processes of a marked trace: for each arrival, how many
12 * events of each class fall in the window of length `scale` that starts at
13 * that arrival.
14 *
15 * Templated port of the pure-MATLAB branch of
16 * matlab/lib/m3a/m3a/mtrace/mtrace_iat2counts.m (the function prefers a MEX
17 * implementation, mtrace_iat2counts_native, when it is compiled; the MATLAB
18 * fallback is the specification and is what is ported), cross-checked against
19 * jar/src/main/java/jline/api/trace/Mtrace_iat2counts.java.
20 *
21 * DIVERGENCE, MATLAB vs JAR: the JAR compares CT[cur+1] against CT[i+1] where
22 * MATLAB compares CT(cur+1) against CT(i), so its window ends one arrival
23 * early; it also seeds the search with max(i, previousCur) instead of
24 * MATLAB's (i-1)+C(i-1). The seeds are only a speed-up (the scan is monotone,
25 * so any lower start converges to the same window), but the endpoint is not,
26 * and the JAR counts are systematically one arrival short. MATLAB is the
27 * reference.
28 *
29 * Note also that MATLAB's own speed-up seed `cur = (i-1) + C(i-1)` uses
30 * LINEAR indexing into the count matrix, so it reads the class-1 count rather
31 * than the total; it is an underestimate of the previous window end and
32 * therefore harmless, but it makes the loop slower, not faster, on
33 * multi-class traces.
34 *
35 * The series is truncated at the first window that reaches the end of the
36 * trace, because from there on the counts are censored.
37 *
38 * ARITHMETIC: additions and comparisons, exact in Rational.
39 */
40
41#include <cstddef>
42#include <vector>
43
45#include "line/num/number.h"
46#include "line/util/error.h"
47#include "line/util/matrix.h"
48
49namespace line {
50namespace trace {
51
52/** Return value of mtrace_iat2counts. */
53template <class T>
55 std::vector<int> labels; ///< the distinct labels, increasing
56 Matrix<long> counts; ///< (rows x C), column c for labels[c]
57};
58
59/**
60 * @brief Per-class counting processes of a marked trace: for each arrival,
61 * how many events of each class fall in the window of length `scale`
62 * that starts at that arrival.
63 *
64 * @param Tv inter-arrival times
65 * @param A class labels
66 * @param scale window length
67 */
68template <class T>
69MtraceCountsResult<T> mtrace_iat2counts(const std::vector<T>& Tv, const std::vector<int>& A,
70 const T& scale) {
71 detail::require_marked(Tv, A, "mtrace_iat2counts");
72 if (scale <= num_traits<T>::from_int(0))
73 throw InputError("mtrace_iat2counts: the time scale must be positive");
74 const long n = static_cast<long>(Tv.size());
75 if (n < 2) throw InputError("mtrace_iat2counts: at least two events are required");
77 out.labels = detail::unique_labels(A);
78 const std::size_t K = out.labels.size();
79 const std::vector<T> cs = detail::cumsum0(Tv); // cs[k] = MATLAB CT(k)
80
81 std::vector<std::vector<long>> rows;
82 for (long i = 1; i <= n - 1; ++i) {
83 long cur = i;
84 bool censored = false;
85 while (cs[static_cast<std::size_t>(cur + 1)] - cs[static_cast<std::size_t>(i)] <= scale) {
86 ++cur;
87 if (cur == n) {
88 censored = true;
89 break;
90 }
91 }
92 std::vector<long> row(K, 0);
93 for (long t = i + 1; t <= cur; ++t)
94 for (std::size_t j = 0; j < K; ++j)
95 if (A[static_cast<std::size_t>(t - 1)] == out.labels[j]) ++row[j];
96 rows.push_back(row);
97 if (censored) break;
98 }
99 out.counts = Matrix<long>(rows.size(), K, 0);
100 for (std::size_t r = 0; r < rows.size(); ++r)
101 for (std::size_t j = 0; j < K; ++j) out.counts(r, j) = rows[r][j];
102 return out;
103}
104
105} // namespace trace
106} // namespace line
107
108#endif // LINE_API_TRACE_MTRACE_IAT2COUNTS_H
InputError(const std::string &what)
Definition error.h:39
The exception types the port throws.
Dense matrix and non-owning view.
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.
Return value of mtrace_iat2counts.
Matrix< long > counts
(rows x C), column c for labels[c]
std::vector< int > labels
the distinct labels, increasing
Shared declarations for the empirical trace statistics domain.