You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The complexity is O(n log n + n M). For `M` of order O(1) or O(poly-log n) this is nearly linear; as `M`
118
+
approaches `n` it tends to O(n[super 2]).
119
+
120
+
An example is given below:
121
+
122
+
std::vector<double> X{1,2,3,4,5};
123
+
std::vector<double> Y{1,2,3,4,5};
124
+
using boost::math::statistics::chatterjee_correlation_mnn;
125
+
std::size_t M = 2;
126
+
double coeff = chatterjee_correlation_mnn(X, Y, M);
127
+
128
+
/Nota bene:/ If the input is an integer type the output will be a double precision type.
129
+
130
+
[heading Choice of M]
131
+
132
+
The asymptotic null variance of the statistic is minimised when `M` is of order sqrt(n), which is a reasonable
133
+
default for users who want improved power without the quadratic cost of large `M`. Pushing `M` closer to `n`
134
+
increases the power of the independence test against smooth alternatives at the cost of additional computation.
135
+
The choice is left to the caller; `M` must satisfy 1 <= M <= n.
136
+
137
+
/Nota bene:/ Even at `M` = 1 this statistic is not identical to `chatterjee_correlation`: it uses
138
+
min(R_i, R_j) in place of |R_i - R_j| and a different normalisation, so the two agree only up to a term of
139
+
order 1/n. Use `chatterjee_correlation` when the original coefficient is required.
140
+
141
+
[heading Invariants]
142
+
143
+
The function expects at least two samples, a non-constant vector Y, the same number of X's as Y's, and
144
+
1 <= M <= n.
145
+
If Y is constant, the result is a quiet NaN.
146
+
The data set must be sorted by X values.
147
+
If there are ties in the values of X, then the statistic is random due to the random breaking of ties.
148
+
149
+
[heading References]
150
+
151
+
* Lin, Zhexiao, and Fang Han. "On boosting the power of Chatterjee's rank correlation." Biometrika 110.2 (2023): 283-299. [@https://arxiv.org/abs/2108.06828 arXiv:2108.06828].
ForwardIterator v_begin, ForwardIterator v_end, std::size_t M)
232
+
{
233
+
BOOST_MATH_ASSERT_MSG(std::is_sorted(std::forward<ExecutionPolicy>(exec), u_begin, u_end), "The x values must be sorted in order to use this functionality");
234
+
235
+
const std::size_t n = static_cast<std::size_t>(std::distance(v_begin, v_end));
236
+
237
+
BOOST_MATH_ASSERT_MSG(M >= 1, "The number of right nearest neighbours M must be at least 1");
238
+
BOOST_MATH_ASSERT_MSG(M <= n, "The number of right nearest neighbours M must not exceed the number of samples");
239
+
240
+
// If Y is constant the statistic is undefined (Y must be non-constant); return a quiet NaN.
241
+
// This is checked on the input directly: rank() collapses tied values, so a constant Y would
242
+
// otherwise reduce the effective sample size to one.
243
+
if (v_begin != v_end)
244
+
{
245
+
using value_type = typename std::iterator_traits<ForwardIterator>::value_type;
246
+
const value_type first_value = *v_begin;
247
+
if (std::all_of(std::next(v_begin), v_end,
248
+
[&first_value](const value_type& value) { return value == first_value; }))
0 commit comments