Generate perfectly correlated data, and observe that the xi correlation is nearly 1.0.
>>> import numpy as np
>>> from scipy import stats
>>> rng = np.random.default_rng()
>>> x = rng.uniform(0, 10, size=100)
>>> y = np.sin(x)
>>> res = stats.chatterjeexi(x, y)
>>> res.statistic
np.float64(0.9012901290129013)
The probability of observing such a high value of the statistic under the null hypothesis of independence is very low.
>>> res.pvalue
np.float64(2.2206974648177804e-46)
As noise is introduced, the correlation coefficient decreases.
>>> noise = rng.normal(scale=[[0.1], [0.5], [1]], size=(3, 100))
>>> res = stats.chatterjeexi(x, y + noise, axis=-1)
>>> res.statistic
array([0.79507951, 0.41824182, 0.16651665])
Because the distribution of y is continuous, it is valid to pass
y_continuous=True. The statistic is identical, and the p-value
(not shown) is only slightly different.
>>> stats.chatterjeexi(x, y + noise, y_continuous=True, axis=-1).statistic
array([0.79507951, 0.41824182, 0.16651665])
Consider a case in which there are ties in x.
>>> x = rng.integers(10, size=1000)
>>> y = rng.integers(10, size=1000)
[1] recommends breaking the ties uniformly at random.
>>> d = rng.uniform(1e-5, size=x.size)
>>> res = stats.chatterjeexi(x + d, y)
>>> res.statistic
-0.029919991638798438
Since this gives a randomized estimate of the statistic, [1] also suggests considering the average over all possibilities of breaking ties. This is computationally infeasible when there are many ties, but a randomized estimate of this quantity can be obtained by considering many random possibilities of breaking ties.
>>> d = rng.uniform(1e-5, size=(9999, x.size))
>>> res = stats.chatterjeexi(x + d, y, axis=1)
>>> np.mean(res.statistic)
0.001186895213756626