Tutorial for spatial ordinal pattern tests

Libraries

using StatsOrdinalPatterns, Random, Statistics, DataFrames, CairoMakie

Hypothesis Testing with Spatial Ordinal Patterns

A spatial ordinal pattern (SOP) test asks whether the frequencies of rank permutations in a 2D image are consistent with a spatially i.i.d. process. For an \(M \times N\) image, overlapping \(2 \times 2\) windows at delays \((d_1, d_2)\) are each mapped to the permutation that describes the relative order of the four values. The resulting frequency distribution is summarised by a scalar test statistic. Under \(H_0\) (spatial white noise) that distribution is uniform across all \(4! = 24\) patterns.

StatsOrdinalPatterns.jl provides:

  • Computing the statistic
    • stat_sop() — computes the chosen test statistic from the observed pattern frequencies.
  • Asymptotic inference
    • test_sop() — compares the statistic to an analytical critical value. Supports all image sizes.
  • Bootstrap inference

Key functions

Available chart statistics

Seven chart statistics are available. They differ in what they measure and the direction of the rejection region.

Statistic Constructor Under \(H_0\) Reject \(H_0\) when Distribution
\(\hat{\tau}\) (TauTilde) TauTilde() \(\hat{\tau} = 0\) \(\lvert\hat{\tau}\rvert > c\) Normal
\(\hat{\tau}_1\) (TauHat) TauHat() \(\hat{\tau}_1 = 0\) \(\lvert\hat{\tau}_1\rvert > c\) Normal
\(\hat{\kappa}\) (KappaTilde) KappaTilde() \(\hat{\kappa} = 0\) \(\lvert\hat{\kappa}\rvert > c\) Normal
\(\hat{\kappa}_1\) (KappaHat) KappaHat() \(\hat{\kappa}_1 = 0\) \(\lvert\hat{\kappa}_1\rvert > c\) Normal
DistanceToWhiteNoise (\(\hat{\Delta}\)) DistanceToWhiteNoise() \(\hat{\Delta} = 0\) \(\hat{\Delta} > c\) Generalized \(\chi^2\)
Shannon entropy (\(\hat{H}\)) Shannon(base=exp(1)) \(\hat{H} = \log(3)\) \(\hat{H} > c\) Generalized \(\chi^2\)
Shannon extropy (\(\hat{H}_\text{ex}\)) ShannonExtropy(base=exp(1)) \(\hat{H}_\text{ex} = \cdots\) \(\hat{H}_\text{ex} > c\) Generalized \(\chi^2\)
  • The four Tau/Kappa statistics use a two-sided test (signed deviation from zero).
  • The three entropy statistics undergo an internal standardisation that converts them to upper-tail tests — both test_sop and test_sop_bootstrap apply this standardisation consistently, so their critical values sit on the same scale and can be compared directly.
  • The asymptotic critical values and limiting distributions are derived in Weiß (2022).
  • Shannon and ShannonExtropy use base 2 by default, while the papers use the natural logarithm. The rescaled statistic, the p-value and the test decision do not depend on the base. See Logarithm base for details.

Setup

Random.seed!(42)
M, N = 20, 20   # image dimensions
d1, d2 = 1, 1     # row and column delays
(1, 1)

Example data

data_iid = randn(M, N)   # spatial white noise — H₀ is true

φ = 0.4
data_sar = zeros(M, N)
data_sar[1, :] .= randn(N);
data_sar[:, 1] .= randn(M);
for i in 2:M, j in 2:N
    data_sar[i, j] = φ * (data_sar[i-1, j] + data_sar[i, j-1]) / 2 + randn()
end   # SAR-type process — H₀ is false

Asymptotic testing: test_sop()

Two-sided — TauTilde

test_sop(data_iid, d1, d2; chart_choice=TauTilde())
SOPTestResult
  Chart:            TauTilde()
  Statistic:        -0.0148
  ─────────────────────────────
  Asymptotic test
    Critical value: 0.053
    p-value:        0.5851
    Reject H₀:      false
test_sop(data_sar, d1, d2; chart_choice=TauTilde())
SOPTestResult
  Chart:            TauTilde()
  Statistic:        -0.1034
  ─────────────────────────────
  Asymptotic test
    Critical value: 0.053
    p-value:        0.0001
    Reject H₀:      true

Upper-tail — DistanceToWhiteNoise

test_sop(data_iid, d1, d2; chart_choice=DistanceToWhiteNoise())
SOPTestResult
  Chart:            DistanceToWhiteNoise()
  Statistic:        0.0059
  ─────────────────────────────
  Asymptotic test
    Critical value: 0.0063
    p-value:        0.0607
    Reject H₀:      false
test_sop(data_sar, d1, d2; chart_choice=DistanceToWhiteNoise())
SOPTestResult
  Chart:            DistanceToWhiteNoise()
  Statistic:        0.016
  ─────────────────────────────
  Asymptotic test
    Critical value: 0.0063
    p-value:        0.0005
    Reject H₀:      true

Upper-tail — Shannon entropy

test_sop(data_iid, d1, d2; chart_choice=Shannon(base=exp(1)))
SOPTestResult
  Chart:            Shannon(base = 2.718281828459045)
  Statistic:        0.0058
  ─────────────────────────────
  Asymptotic test
    Critical value: 0.0063
    p-value:        0.0636
    Reject H₀:      false
test_sop(data_sar, d1, d2; chart_choice=Shannon(base=exp(1)))
SOPTestResult
  Chart:            Shannon(base = 2.718281828459045)
  Statistic:        0.0171
  ─────────────────────────────
  Asymptotic test
    Critical value: 0.0063
    p-value:        0.0003
    Reject H₀:      true

The white-noise image is not rejected; the SAR image is. The critical value depends on the image dimensions M, N, the delays d1, d2, and alpha — not on the data.

Bootstrap testing: test_sop_bootstrap()

test_sop_bootstrap() generates the empirical null distribution via 2D resampling of the observed image and computes the bootstrap critical value and p-value in the correct direction.

Random.seed!(42)
res_boot = test_sop_bootstrap(data_sar, 2_000, d1, d2; chart_choice=TauTilde())
SOPTestResultBoot
  Chart:            TauTilde()
  Statistic:        -0.1034
  ─────────────────────────────
  Bootstrap  (n_boot = 2000)
    Critical value: 0.0536
    p-value:        0.0
    Reject H₀:      true

The bootstrap critical value agrees closely with the asymptotic one shown above.

With CairoMakie loaded, plot shows the resampled statistics stored in res_boot.boot_dist as a histogram, together with the two sided rejection region, the critical values and the observed statistic. See the plotting tutorial for the options.

plot(res_boot)

Full comparison: asymptotic vs. bootstrap

Random.seed!(42)
chart_list = [
    ("TauTilde (τ̃)", TauTilde(), "two-sided"),
    ("TauHat (τ̂)", TauHat(), "two-sided"),
    ("KappaTilde (κ̃)", KappaTilde(), "two-sided"),
    ("KappaHat (κ̂)", KappaHat(), "two-sided"),
    ("DistanceToWhiteNoise (Δ)", DistanceToWhiteNoise(), "upper-tail"),
    ("Shannon entropy (H)", Shannon(base=exp(1)), "upper-tail"),
    ("Shannon extropy (Hex)", ShannonExtropy(base=exp(1)), "upper-tail"),
]
asymp_res = [test_sop(data_sar, d1, d2; chart_choice=c) for (_, c, _) in chart_list]
boot_res = [test_sop_bootstrap(data_sar, 2_000, d1, d2; chart_choice=c) for (_, c, _) in chart_list]
DataFrame(
    Statistic=[t[1] for t in chart_list],
    Direction=[t[3] for t in chart_list],
    asymp_crit=round.([r.asymp_crit for r in asymp_res], digits=3),
    asymp_pval=round.([r.asymp_pval for r in asymp_res], digits=3),
    boot_crit=round.([r.boot_crit for r in boot_res], digits=3),
    boot_pval=round.([r.boot_pval for r in boot_res], digits=3),
    reject=[r.asymp_reject for r in asymp_res],
)
7×7 DataFrame
Row Statistic Direction asymp_crit asymp_pval boot_crit boot_pval reject
String String Float64 Float64 Float64 Float64 Bool
1 TauTilde (τ̃) two-sided 0.053 0.0 0.054 0.0 true
2 TauHat (τ̂) two-sided 0.051 0.046 0.052 0.055 true
3 KappaTilde (κ̃) two-sided 0.087 1.0 0.086 1.0 false
4 KappaHat (κ̂) two-sided 0.091 0.001 0.089 0.001 true
5 DistanceToWhiteNoise (Δ) upper-tail 0.006 0.0 0.006 0.0 true
6 Shannon entropy (H) upper-tail 0.006 0.0 0.007 0.001 true
7 Shannon extropy (Hex) upper-tail 0.006 0.001 0.006 0.0 true

The asymptotic and bootstrap critical values are in close agreement across all statistics, and the bootstrap p-values are consistent with the reject column.

References

Weiß, Christian H. 2022. “Non-Parametric Tests for Serial Dependence in Time Series Based on Asymptotic Implementations of Ordinal-Pattern Statistics.” Chaos: An Interdisciplinary Journal of Nonlinear Science 32 (9). https://pubs.aip.org/aip/cha/article-abstract/32/9/093107/2835852/Non-parametric-tests-for-serial-dependence-in-time?redirectedFrom=fulltext.