LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
trace_pmf.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_TRACE_PMF_H
6#define LINE_API_TRACE_TRACE_PMF_H
7
8/**
9 * @file
10 * @ingroup api_trace
11 * Empirical probability mass function of a discrete trace (counts, batch
12 * sizes, queue-length samples).
13 *
14 * Templated port of `jar/src/main/java/jline/api/trace/Trace_var.java#trace_pmf`,
15 * cross-checked against matlab/lib/kpctoolbox/trace/trace_pmf.m.
16 *
17 * DIVERGENCE, MATLAB vs JAR: MATLAB computes `hist(X, max(X))' ./ numel(X)`,
18 * i.e. it spreads max(X) equally spaced BINS over the range of the data and
19 * returns their relative frequencies, while separately returning unique(X) as
20 * the support. The two outputs then have different lengths and are not
21 * aligned whenever the observed values are not exactly 1..max(X) -- the
22 * MATLAB pmf is a histogram, not a pmf on the returned support. The JAR
23 * counts the distinct observed values, which is the documented intent and is
24 * what this port implements. The pmf sums to 1 by construction, so its
25 * cumulative sum is a proper empirical CDF.
26 *
27 * ARITHMETIC: counts divided by the sample size, exact in Rational.
28 */
29
30#include <cstddef>
31#include <vector>
32
34#include "line/num/number.h"
35#include "line/util/error.h"
36
37namespace line {
38namespace trace {
39
40/** Return value of trace_pmf, mirroring [pmf, px]. */
41template <class T>
43 std::vector<T> pmf; ///< relative frequency of each distinct value
44 std::vector<int> values; ///< the distinct values, in increasing order
45};
46
47/**
48 * @brief Empirical probability mass function of a discrete trace (counts,
49 * batch sizes, queue-length samples).
50 *
51 * @param X the discrete trace.
52 */
53template <class T>
54TracePmfResult<T> trace_pmf(const std::vector<int>& X) {
55 if (X.empty()) throw InputError("trace_pmf: the trace is empty");
57 out.values = detail::unique_labels(X);
58 out.pmf.reserve(out.values.size());
59 const T n = num_traits<T>::from_int(static_cast<long>(X.size()));
60 for (std::size_t i = 0; i < out.values.size(); ++i) {
61 long count = 0;
62 for (std::size_t k = 0; k < X.size(); ++k)
63 if (X[k] == out.values[i]) ++count;
64 out.pmf.push_back(num_traits<T>::from_int(count) / n);
65 }
66 return out;
67}
68
69} // namespace trace
70} // namespace line
71
72#endif // LINE_API_TRACE_TRACE_PMF_H
InputError(const std::string &what)
Definition error.h:39
The exception types the port throws.
TracePmfResult< T > trace_pmf(const std::vector< int > &X)
Empirical probability mass function of a discrete trace (counts, batch sizes, queue-length samples).
Definition trace_pmf.h:54
Number-type abstraction for the templated API port.
Return value of trace_pmf, mirroring [pmf, px].
Definition trace_pmf.h:42
std::vector< T > pmf
relative frequency of each distinct value
Definition trace_pmf.h:43
std::vector< int > values
the distinct values, in increasing order
Definition trace_pmf.h:44
Shared declarations for the empirical trace statistics domain.