Joint distance distribution

CausalityTools.JointDistanceDistribution.jddMethod
jdd(source, target; distance_metric = SqEuclidean(), 
    B::Int = 10, D::Int = 2, τ::Int = 1) → Vector{Float64}

Compute the joint distance distribution [1] from source to target using the provided distance_metric, with B controlling the number of subintervals, D the embedding dimension and τ the embedding lag.

Example

using CausalityTools
x, y = rand(1000), rand(1000)

jdd(x, y)

Keyword arguments

  • distance_metric::Metric: An instance of a valid distance metric from Distances.jl. Defaults to SqEuclidean().
  • B: The number of equidistant subintervals to divide the interval [0, 1] into when comparing the normalised distances.
  • D: Embedding dimension.
  • τ: Embedding delay.

References

[1] Amigó, José M., and Yoshito Hirata. "Detecting directional couplings from multivariate flows by the joint distance distribution." Chaos: An Interdisciplinary Journal of Nonlinear Science 28.7 (2018): 075302.

source

For the joint distance distribution to indicate a causal influence, it must be significantly skewed towards positive values.

Providing the OneSampleTTest type as the first argument to jdd yields a one sample t-test on the joint distance distribution. From this test, you can extract p-values and obtain confidence intervals like in HypothesisTests.jl as usual.

CausalityTools.JointDistanceDistribution.jddMethod
jdd(test::OneSampleTTest, source, target;
    distance_metric = SqEuclidean(), B::Int = 10, D::Int = 2, τ::Int = 1, 
    μ0 = 0.0) → OneSampleTTest

Perform a one sample t-test to check that the joint distance distribution[Amigo] computed from source to target is biased towards positive values, using the null hypothesis that the mean of the distribution is μ0.

The interpretation of the t-test is that if we can reject the null, then the joint distance distribution is biased towards positive values, and then there exists an underlying coupling from source to target.

Example

using CausalityTools, HypothesisTests
x, y = rand(1000), rand(1000)

jdd(OneSampleTTest, x, y)

which gives

One sample t-test
-----------------
Population details:
    parameter of interest:   Mean
    value under h_0:         0.0
    point estimate:          0.06361857324022721
    95% confidence interval: (0.0185, 0.1087)

Test summary:
    outcome with 95% confidence: reject h_0
    two-sided p-value:           0.0082

Details:
    number of observations:   20
    t-statistic:              2.9517208721082873
    degrees of freedom:       19
    empirical standard error: 0.0215530451545668

The lower bound of the confidence interval for the mean of the joint distance distribution is 0.0185 at confidence level α = 0.05. The meaning that the test falsely detected causality from x to y between these two random time series.

To get the confidence intervals at confidence level α, run

confinf(jdd(OneSampleTTest, x, y), α).

If you just want the p-value at 95% confidence, run

pvalue(jdd(OneSampleTTest, x, y), tail = :right)

Keyword arguments

  • distance_metric::Metric: An instance of a valid distance metric from Distances.jl. Defaults to SqEuclidean().
  • B: The number of equidistant subintervals to divide the interval [0, 1] into when comparing the normalised distances.
  • D: Embedding dimension.
  • τ: Embedding delay.
  • μ0: The hypothetical mean value of the joint distance distribution if there is no coupling between x and y (default is μ0 = 0.0).

References

source

Example: two coupled Lorenz attractors

The joint distance distribution was introduced in Amigo et al. (2018)[Amigo2018]. Here, we'll attempt to reproduce figures 1a and 1b from their paper, but first we'll do a couple of simple examples.

Let's start by generating some time series. We'll use the lorenz_lorenz_bidir example system that ships with CausalityTools, which implements their bidirectionally coupled Lorenz systems.

using CausalityTools, Plots, DynamicalSystems

# Time series of length 10000, sampled every 0.1 time steps.
ΔT, npts, Ttr = 0.1, 1000, 100
T = npts * ΔT

# Let there be unidirectional coupling from x to y
cxy, cyx = 1.5, 0.0
sys = lorenz_lorenz_bidir(c_xy = cxy, c_yx = cyx)
orbit = trajectory(sys, T, ΔT = ΔT, Ttr = 500)
x1, x2, x3, y1, y2, y3 = columns(orbit)
plot(xlabel = "Time step", ylabel = "Value", size = (800, 220))
plot!(x1, label = "x1")
plot!(y1, label = "y1")
"/home/runner/work/CausalityTools.jl/CausalityTools.jl/docs/build/lorenz_lorenz_timeseries.svg"

Let's compute the joint distance distribution from x to y. For this example, we'll use an embedding dimension of 10 and embedding lag of 10. In real applications, these parameters should be optimized.

jxy = jdd(x1, y1, D = 10, τ = 10)
10-element Vector{Float64}:
 0.013505615114505563
 0.010873272968460367
 0.008227909742350485
 0.0076780053382948426
 0.011674024417140603
 0.016992922403498825
 0.015624120671938468
 0.017083164623847312
 0.02884562801195594
 0.029900979779609652

If jxy is biased towards positive values, then in the framework of the joint distance distribution, the variables are coupled and there exists a continuous functional dependence $x = \phi(y)$. In the context of causal inference, this is is the same as saying that x drives y. Likewise, if jxy is not biased towards positive values, then there exists no such relationship, and the variables are not coupled.

To formally test whether the distribution jxy is skewed torwards positive values, we can use a one-sample t-test to test the null hypothesis mean(jxy) == 0, and compute the right-sided p-value for the test. If p < 0.05 for the test, we take that as rejection of the null hypothesis, and accept the alternative hypothesis that mean(jxy) is skewed towards positive values.

pvalue(jdd(OneSampleTTest, x1, y1, D = 10, τ = 10), tail = :right)
0.01612628565313734

Similarly, we can also see if the joint distance distribution test provides evidence of a coupling from y to x:

pvalue(jdd(OneSampleTTest, y1, x1, D = 10, τ = 10), tail = :right)
0.15938852302498777

If the test works perfectly, then we expect p < 0.05 when computing the joint distance distribution from x to y and p >= 0.05 when computing the distribution from y to x. However, for a single finite time series realization, this might not necessarily always be the case.

Reproducing Amigo et al. (2018)

Here, we attempt reproduce figures 1a and 1b from Amigo et al., which computes p-values for a range of coupling strengths in both directions. We'll use a coarser coupling resolution and shorter time series to limit computation time.

using CausalityTools, Plots, DynamicalSystems

cxys = 0.0:0.25:2.0
cyxs = 0.0:0.25:2.0
# We'll use time series 2000 points long, to limit computation time
ΔT, npts, Ttr = 0.1, 200, 100
T = npts * ΔT

pvals_xy = zeros(length(cyxs), length(cxys))
pvals_yx = zeros(length(cyxs), length(cxys))

for (i, cxy) in enumerate(cxys)
    for (j, cyx) in enumerate(cyxs)
        sys = lorenz_lorenz_bidir(c_xy = cxy, c_yx = cyx)
        orbit = trajectory(sys, T, ΔT = ΔT, Ttr = Ttr)
        x1, x2, x3, y1, y2, y3 = columns(orbit)

        # The original paper uses an embedding dimension of 10 and embedding lag of 10
        pvals_xy[j, i] = pvalue(jdd(OneSampleTTest, x1, y1, D = 10, τ = 10), tail = :right)
        pvals_yx[j, i] = pvalue(jdd(OneSampleTTest, y1, x1, D = 10, τ = 10), tail = :right)
    end
end
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181
┌ Warning: Direct propagation of keyword arguments to DifferentialEquations.jl is deprecated.
│ From now on pass any DiffEq-related keywords as a `NamedTuple` using the
│ explicit keyword `diffeq` instead.
└ @ DynamicalSystemsBase ~/.julia/packages/DynamicalSystemsBase/t40uG/src/core/continuous.jl:181

Plotting the p-values for the tests in the direction x to y, and in the direction y to x, as a function of coupling strengths in both directions, we get the following:

z = [0, 0.0001, 0.001, 0.01, 0.05, 1.0]
c = cgrad(:magma, categorical = true)

p_xy = plot(xlabel = "Coupling from x to y", ylabel = "Coupling from y to x")
yticks!((1:length(cyxs), string.(cyxs)))
xticks!((1:length(cxys), string.(cxys)))
heatmap!(pvals_xy, c = c, logscale = true)

p_yx = plot(xlabel = "Coupling from x to y", ylabel = "")
yticks!((1:length(cyxs), string.(cyxs)))
xticks!((1:length(cxys), string.(cxys)))
heatmap!(pvals_yx, c = c, logscale = true)

plot(p_xy, p_yx, layout = grid(1, 2), size = (900, 300))
"/home/runner/work/CausalityTools.jl/CausalityTools.jl/docs/build/jdd_heatmap.svg"

Values on the x-axis are the coupling strengths from x to y, and those on the y-axis are the coupling strengths from y to x. The colorbar indicates the p-value.

For sufficiently high coupling strengths, the test successfully identifies the couplings both from x to y and vice versa. For lower coupling strengths, we cannot reject the null hypothesis.

Note that using longer time series and more carefully tuned embeddings would likely lead to better performance.

  • AmigoAmigó, José M., and Yoshito Hirata. "Detecting directional couplings from multivariate flows by the joint distance distribution." Chaos: An Interdisciplinary Journal of Nonlinear Science 28.7 (2018): 075302.
  • Amigo2018Amigó, José M., and Yoshito Hirata. "Detecting directional couplings from multivariate flows by the joint distance distribution." Chaos: An Interdisciplinary Journal of Nonlinear Science 28.7 (2018): 075302.