LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Toggle main menu visibility
Loading...
Searching...
No Matches
trace_gamma.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_GAMMA_H
6
#define LINE_API_TRACE_TRACE_GAMMA_H
7
8
/**
9
* @file
10
* @ingroup api_trace
11
* Autocorrelation decay rate of a trace: the gamma of the geometric model
12
* rho(k) = rho0 * gamma^k, with rho0 = (1 - 1/scv)/2 fixed by the second
13
* moment and gamma fitted by least squares on the empirical acf.
14
*
15
* Templated port of `jar/src/main/java/jline/api/trace/Trace_var.java#trace_gamma`,
16
* cross-checked against matlab/lib/kpctoolbox/trace/trace_gamma.m.
17
*
18
* DIVERGENCE, MATLAB vs JAR: MATLAB fits gamma by nonlinear regression
19
* (nlinfit with a fair robust weight, falling back to lsqcurvefit), the JAR
20
* by an exhaustive search over the ten grid points 0.990, 0.991, ..., 0.999.
21
* The JAR can therefore never report a decay rate outside that window and its
22
* resolution is 1e-3, so the two agree only when the true rate happens to sit
23
* on the grid. The grid search is what is ported, because it is the only one
24
* of the two that is deterministic and free of an optimizer dependency; the
25
* grid is exposed as a parameter so a caller can refine it.
26
*
27
* REFERENCE DEFECT (JAR): trace_gamma builds the lags 1..min(limit, n-1) and
28
* then indexes the trace_acf result by those lags, but trace_acf silently
29
* DROPS every lag above n-2. For any trace with n <= limit+1 -- with the
30
* default limit of 1000, any trace of at most 1001 samples -- the returned
31
* array is one element shorter than the loop bound and the method throws
32
* ArrayIndexOutOfBoundsException. This port builds the lags as
33
* 1..min(limit, n-2) so that the residual is computed on the acf that
34
* actually exists.
35
*
36
* ARITHMETIC: rho0 and the residual sum of squares are rational in the
37
* samples, and the grid points are raised to INTEGER lag powers, so the whole
38
* fit is a field computation; instantiated for double, Rational and Real50.
39
*/
40
41
#include <cstddef>
42
#include <vector>
43
44
#include "
line/api/trace/trace_acf.h
"
45
#include "
line/api/trace/trace_mean.h
"
46
#include "
line/api/trace/trace_scv.h
"
47
#include "
line/api/trace/trace_types.h
"
48
#include "
line/num/number.h
"
49
#include "
line/util/error.h
"
50
51
namespace
line
{
52
namespace
trace
{
53
54
/** Return value of trace_gamma, mirroring [GAMMA, RHO0, RESIDUALS]. */
55
template
<
class
T>
56
struct
TraceGammaResult
{
57
T
gamma
;
///< best decay rate on the grid
58
T
rho0
;
///< (1 - 1/scv)/2, the GE-type lag-0 amplitude
59
T
residuals
;
///< sum of squared deviations from the fitted model
60
};
61
62
/**
63
* @brief Autocorrelation decay rate of a trace: the gamma of the geometric
64
* model rho(k) = rho0 * gamma^k, with rho0 = (1 - 1/scv)/2 fixed by
65
* the second moment and gamma fitted by least squares on the empirical
66
* acf.
67
*
68
* @param S the trace
69
* @param limit largest lag considered (the JAR default is 1000)
70
* @param grid candidate decay rates; the JAR grid 0.990..0.999 by default
71
*/
72
template
<
class
T>
73
TraceGammaResult<T>
trace_gamma
(
const
std::vector<T>& S,
long
limit = 1000,
74
const
std::vector<T>& grid = std::vector<T>()) {
75
detail::require_nonempty(S,
"trace_gamma"
);
76
const
long
n =
static_cast<
long
>
(S.size());
77
if
(n < 4)
throw
InputError
(
"trace_gamma: the fit needs at least four samples"
);
78
79
const
long
maxlag = std::min<long>(limit, n - 2);
80
std::vector<int> lags;
81
for
(
long
l = 1; l <= maxlag; ++l) lags.push_back(
static_cast<
int
>
(l));
82
const
std::vector<T> rho =
trace_acf
(S, lags);
83
84
// rho0 uses the POPULATION scv, as both references do (they form
85
// M2 - M1^2 explicitly rather than calling var).
86
const
T scv =
trace_scv
(S,
false
);
87
if
(scv ==
num_traits<T>::from_int
(0))
88
throw
NumericError
(
"trace_gamma: the trace has zero scv, rho0 is undefined"
);
89
TraceGammaResult<T>
out;
90
out.
rho0
=
num_traits<T>::from_rational
(1, 2) *
91
(
num_traits<T>::from_int
(1) -
num_traits<T>::from_int
(1) / scv);
92
93
std::vector<T> g = grid;
94
if
(g.empty())
95
for
(
long
k = 990; k <= 999; ++k) g.push_back(
num_traits<T>::from_rational
(k, 1000));
96
97
bool
first =
true
;
98
for
(std::size_t a = 0; a < g.size(); ++a) {
99
T res =
num_traits<T>::from_int
(0);
100
for
(std::size_t i = 0; i < rho.size(); ++i) {
101
const
T expected = out.
rho0
*
num_pow_int
(g[a],
static_cast<
unsigned
>
(lags[i]));
102
const
T d = rho[i] - expected;
103
res += d * d;
104
}
105
if
(first || res < out.
residuals
) {
106
out.
residuals
= res;
107
out.
gamma
= g[a];
108
first =
false
;
109
}
110
}
111
if
(first)
throw
InputError
(
"trace_gamma: the candidate grid is empty"
);
112
return
out;
113
}
114
115
}
// namespace trace
116
}
// namespace line
117
118
#endif
// LINE_API_TRACE_TRACE_GAMMA_H
line::InputError::InputError
InputError(const std::string &what)
Definition
error.h:39
line::NumericError::NumericError
NumericError(const std::string &what)
Definition
error.h:45
error.h
The exception types the port throws.
line::trace
Definition
autocov.h:38
line::trace::trace_gamma
TraceGammaResult< T > trace_gamma(const std::vector< T > &S, long limit=1000, const std::vector< T > &grid=std::vector< T >())
Autocorrelation decay rate of a trace: the gamma of the geometric model rho(k) = rho0 * gamma^k,...
Definition
trace_gamma.h:73
line::trace::trace_scv
T trace_scv(const std::vector< T > &S, bool unbiased=true)
Squared coefficient of variation of a trace, var/mean^2.
Definition
trace_scv.h:39
line::trace::trace_acf
std::vector< T > trace_acf(const std::vector< T > &S, const std::vector< int > &lags)
Autocorrelation coefficients of a trace at the requested lags.
Definition
trace_acf.h:57
line
Definition
aoi_dist2ph.h:52
line::num_pow_int
T num_pow_int(const T &base, unsigned e)
Integer power, valid in any field (no transcendental requirement).
Definition
number.h:192
number.h
Number-type abstraction for the templated API port.
line::num_traits
Definition
number.h:111
line::trace::TraceGammaResult
Return value of trace_gamma, mirroring [GAMMA, RHO0, RESIDUALS].
Definition
trace_gamma.h:56
line::trace::TraceGammaResult::rho0
T rho0
(1 - 1/scv)/2, the GE-type lag-0 amplitude
Definition
trace_gamma.h:58
line::trace::TraceGammaResult::gamma
T gamma
best decay rate on the grid
Definition
trace_gamma.h:57
line::trace::TraceGammaResult::residuals
T residuals
sum of squared deviations from the fitted model
Definition
trace_gamma.h:59
trace_acf.h
Autocorrelation coefficients of a trace at the requested lags.
trace_mean.h
Sample mean of a trace.
trace_scv.h
Squared coefficient of variation of a trace, var/mean^2.
trace_types.h
Shared declarations for the empirical trace statistics domain.
include
line
api
trace
trace_gamma.h
Generated by
1.18.0