LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
mtrace_moment.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_MOMENT_H
6#define LINE_API_TRACE_MTRACE_MOMENT_H
7
8/**
9 * @file
10 * @ingroup api_trace
11 * Empirical class-dependent moments of a marked trace.
12 *
13 * Templated port of matlab/lib/m3a/m3a/mtrace/mtrace_moment.m, cross-checked
14 * against jar/src/main/java/jline/api/trace/Mtrace_moment.java.
15 *
16 * after = false (Horvath variables): M(c,j) = (1/N) sum_{i: A_i=c} T_i^k
17 * after = true (Buchholz variables): M(c,j) = (1/(N-1)) sum_{i<N: A_i=c} T_{i+1}^k
18 *
19 * and with norm = true each entry is multiplied by N/count_c, which turns the
20 * contribution into the class-conditional moment normalized so that
21 * M_k = sum_c M(c,k) * p_c with p_c = count_c/N the class probabilities of
22 * mtrace_pc.
23 *
24 * REFERENCE DEFECT (JAR): Mtrace_moment.java divides the class sum by
25 * count_c ALREADY in the unnormalized branch, so its norm = 0 output is
26 * MATLAB's norm = 1 output, and its norm = 1 output is that value multiplied
27 * by N/count_c a SECOND time -- a quantity that is neither of the two
28 * documented normalizations and that diverges as the class becomes rare.
29 * Consequently sum_c M_java(c,k) is not the class-independent moment for
30 * either flag value. MATLAB is the reference and is implemented here.
31 * Measured on T = 1,2,3,4,5 with A = 1,2,1,2,1 and order 1: MATLAB returns
32 * (9/5, 6/5) unnormalized and (3, 3) normalized, the JAR returns (3, 3) and
33 * (5, 15/2). Only the MATLAB pair sums to the trace mean 3.
34 *
35 * A second, smaller divergence: for after = true the JAR normalizes by
36 * (N-1)/count_c whereas MATLAB uses N/count_c (its `length(T-1)` is the
37 * length of the elementwise T-1, i.e. N). MATLAB's factor is the one
38 * consistent with p_c = count_c/N, so it is kept.
39 *
40 * ARITHMETIC: sums of integer powers and a division, exact in Rational.
41 */
42
43#include <cstddef>
44#include <vector>
45
47#include "line/num/number.h"
48#include "line/util/error.h"
49#include "line/util/matrix.h"
50
51namespace line {
52namespace trace {
53
54/**
55 * @brief Empirical class-dependent moments of a marked trace.
56 *
57 * @param Tv inter-arrival times
58 * @param A class labels
59 * @param orders moment orders
60 * @param after false for Horvath variables, true for Buchholz variables
61 * @param norm true to normalize by N/count_c
62 * @return (C x |orders|) matrix, row c for the c-th smallest label
63 */
64template <class T>
65Matrix<T> mtrace_moment(const std::vector<T>& Tv, const std::vector<int>& A,
66 const std::vector<unsigned>& orders, bool after = false,
67 bool norm = false) {
68 detail::require_marked(Tv, A, "mtrace_moment");
69 const std::vector<int> marks = detail::unique_labels(A);
70 const std::size_t C = marks.size();
71 const std::size_t N = Tv.size();
72 if (after && N < 2) throw InputError("mtrace_moment: the Buchholz form needs N >= 2");
73
74 Matrix<T> M(C, orders.size(), num_traits<T>::from_int(0));
75 for (std::size_t j = 0; j < orders.size(); ++j) {
76 const unsigned k = orders[j];
77 for (std::size_t c = 0; c < C; ++c) {
79 long count = 0;
80 const std::size_t last = after ? N - 1 : N;
81 for (std::size_t i = 0; i < last; ++i) {
82 if (A[i] != marks[c]) continue;
83 sum += num_pow_int(Tv[after ? i + 1 : i], k);
84 ++count;
85 }
86 // unnormalized-entry mean rationale: see _kb/03-api-layer.md (cpp port notes: trace)
87 T val = sum / num_traits<T>::from_int(static_cast<long>(last));
88 if (norm && count > 0)
89 val *= num_traits<T>::from_int(static_cast<long>(N)) /
91 M(c, j) = val;
92 }
93 }
94 return M;
95}
96
97} // namespace trace
98} // namespace line
99
100#endif // LINE_API_TRACE_MTRACE_MOMENT_H
InputError(const std::string &what)
Definition error.h:39
The exception types the port throws.
Dense matrix and non-owning view.
Matrix< T > mtrace_moment(const std::vector< T > &Tv, const std::vector< int > &A, const std::vector< unsigned > &orders, bool after=false, bool norm=false)
Empirical class-dependent moments of a marked trace.
T num_pow_int(const T &base, unsigned e)
Integer power, valid in any field (no transcendental requirement).
Definition number.h:192
Number-type abstraction for the templated API port.
Shared declarations for the empirical trace statistics domain.