LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Toggle main menu visibility
Loading...
Searching...
No Matches
sim_vonneumann.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_SIM_SIM_VONNEUMANN_H
6
#define LINE_API_SIM_SIM_VONNEUMANN_H
7
8
/**
9
* @file
10
* @ingroup api_sim
11
* Von Neumann ratio test for randomness of a sequence.
12
*
13
* Port of matlab/src/api/sim/sim_vonneumann.m. The statistic is the ratio of the
14
* mean square successive difference to the variance,
15
* ratio = sum_{i=1}^{b-1} (x_{i+1}-x_i)^2 / sum_{i=1}^{b} (x_i - xbar)^2,
16
* with b the number of observations. Under the null hypothesis that x is i.i.d.
17
* normal the ratio has mean 2 and variance 4(b-2)/((b-1)(b+1)), and (ratio-2)/sd
18
* is asymptotically standard normal, so the two-sided p-value is 2(1-Phi(|z|)).
19
* Serial correlation of either sign moves the ratio away from 2: positive
20
* correlation shrinks the successive differences and pushes the ratio below 2,
21
* negative correlation pushes it above.
22
*
23
* The null mean and variance above were confirmed by Monte Carlo over
24
* b = 10, 16, 24, 32, 50 to within 0.3% in the reference.
25
*
26
* The test is TWO-SIDED and its rejection is used as a stopping rule by the
27
* QUEST procedures, so alpha here is a stage significance (0.30 by default in
28
* sim_fquest, decaying during warmup) and not the interval's coverage level.
29
*
30
* Reference: J. von Neumann, "Distribution of the Ratio of the Mean Square
31
* Successive Difference to the Variance", Ann. Math. Statist. 12(4), 1941;
32
* L. C. Young, "Randomness in Ordered Sequences", Ann. Math. Statist. 12, 1941.
33
*/
34
35
#include <cmath>
36
#include <cstddef>
37
#include <vector>
38
39
#include "
line/api/sim/sim_dist.h
"
40
#include "
line/api/sim/sim_types.h
"
41
#include "
line/num/number.h
"
42
#include "
line/util/error.h
"
43
44
namespace
line
{
45
namespace
sim
{
46
47
/**
48
* Outcome of the von Neumann randomness test.
49
*
50
* The statistic stays in the working type T; the standardized value and the
51
* p-value are doubles because they come out of a normal approximation, see the
52
* arithmetic note in sim_types.h.
53
*/
54
template
<
class
T>
55
struct
VonNeumannResult
{
56
T
ratio
;
///< The von Neumann ratio
57
double
zscore
= 0.0;
///< Standardized statistic (ratio-2)/sd
58
double
pvalue
= 1.0;
///< Two-sided p-value
59
bool
reject
=
false
;
///< True when pvalue < alpha, i.e. randomness is rejected
60
std::size_t
nobs
= 0;
///< Number of observations b
61
};
62
63
/**
64
* @brief Von Neumann ratio test for randomness of a sequence.
65
*
66
* @param x the sequence, at least 3 finite observations
67
* @param alpha significance level in (0,1), 0.05 by default
68
*/
69
template
<
class
T>
70
VonNeumannResult<T>
sim_vonneumann
(
const
std::vector<T>& x,
double
alpha = 0.05) {
71
static_assert
(
num_traits<T>::has_transcendental
,
72
"sim_vonneumann: the p-value is a normal tail, so exact arithmetic is refused"
);
73
if
(!(alpha > 0.0) || !(alpha < 1.0))
74
throw
InputError
(
"sim_vonneumann: alpha must be a real scalar in (0,1)"
);
75
76
const
std::size_t b = x.size();
77
if
(b < 3)
78
throw
InputError
(
"sim_vonneumann: at least 3 observations are required"
);
79
for
(std::size_t i = 0; i < b; ++i)
80
if
(!detail::num_isfinite(x[i]))
81
throw
InputError
(
"sim_vonneumann: the sequence must be finite"
);
82
83
T
sum
=
num_traits<T>::from_int
(0);
84
for
(std::size_t i = 0; i < b; ++i)
sum
+= x[i];
85
const
T mean =
sum
/
num_traits<T>::from_int
(
static_cast<
long
>
(b));
86
87
T den =
num_traits<T>::from_int
(0);
88
for
(std::size_t i = 0; i < b; ++i) {
89
const
T d = T(x[i] - mean);
90
den += T(d * d);
91
}
92
if
(!(den >
num_traits<T>::from_int
(0)))
93
throw
InputError
(
"sim_vonneumann: the sequence is constant, the ratio is undefined"
);
94
95
T num =
num_traits<T>::from_int
(0);
96
for
(std::size_t i = 1; i < b; ++i) {
97
const
T d = T(x[i] - x[i - 1]);
98
num += T(d * d);
99
}
100
101
VonNeumannResult<T>
r;
102
r.
nobs
= b;
103
r.
ratio
= T(num / den);
104
const
double
bd =
static_cast<
double
>
(b);
105
const
double
sd = std::sqrt(4.0 * (bd - 2.0) / ((bd - 1.0) * (bd + 1.0)));
106
r.
zscore
= (
num_traits<T>::to_double
(r.
ratio
) - 2.0) / sd;
107
r.
pvalue
= 2.0 * (1.0 -
sim_normcdf
(std::fabs(r.
zscore
)));
108
r.
reject
= r.
pvalue
< alpha;
109
return
r;
110
}
111
112
}
// namespace sim
113
}
// namespace line
114
115
#endif
// LINE_API_SIM_SIM_VONNEUMANN_H
line::InputError::InputError
InputError(const std::string &what)
Definition
error.h:39
error.h
The exception types the port throws.
line::sim
Definition
sim_dist.h:44
line::sim::sim_vonneumann
VonNeumannResult< T > sim_vonneumann(const std::vector< T > &x, double alpha=0.05)
Von Neumann ratio test for randomness of a sequence.
Definition
sim_vonneumann.h:70
line::sim::sim_normcdf
double sim_normcdf(double z)
Standard normal cumulative distribution function.
Definition
sim_dist.h:52
line::sum
Definition
sum_closed.h:61
line
Definition
aoi_dist2ph.h:52
number.h
Number-type abstraction for the templated API port.
sim_dist.h
Normal and Student t quantiles used by the output-analysis routines.
sim_types.h
Shared arithmetic helpers for the templated simulation output-analysis port.
line::num_traits
Definition
number.h:111
line::sim::VonNeumannResult
Outcome of the von Neumann randomness test.
Definition
sim_vonneumann.h:55
line::sim::VonNeumannResult::nobs
std::size_t nobs
Number of observations b.
Definition
sim_vonneumann.h:60
line::sim::VonNeumannResult::zscore
double zscore
Standardized statistic (ratio-2)/sd.
Definition
sim_vonneumann.h:57
line::sim::VonNeumannResult::ratio
T ratio
The von Neumann ratio.
Definition
sim_vonneumann.h:56
line::sim::VonNeumannResult::reject
bool reject
True when pvalue < alpha, i.e. randomness is rejected.
Definition
sim_vonneumann.h:59
line::sim::VonNeumannResult::pvalue
double pvalue
Two-sided p-value.
Definition
sim_vonneumann.h:58
include
line
api
sim
sim_vonneumann.h
Generated by
1.18.0