Chapter 2: Location Tests

HDElliptical keeps low-dimensional reference tests, robust sign/rank tests, and high-dimensional mean tests behind a common htest-compatible interface. Rows are observations and columns are variables. Every method also returns the raw formula components and numerical diagnostics needed to audit its calibration.

A reproducible sample

The following correlated Gaussian samples are deliberately small enough for the classical Hotelling tests. The same interfaces continue to work for the high-dimensional procedures when the number of variables exceeds the sample size, subject to each method’s assumptions.

library(HDElliptical)

set.seed(20260814)
p <- 8
shape <- toeplitz(0.45^(0:(p - 1)))
x <- relliptical(40, rep(0.10, p), shape)
y <- relliptical(44, c(rep(0.10, 3), rep(0, p - 3)), shape)
colnames(x) <- colnames(y) <- paste0("V", seq_len(p))

Fixed-dimensional reference procedures

The one- and two-sample Hotelling statistics use exact (F) calibration and therefore require nonsingular covariance estimates and the corresponding positive residual degrees of freedom. The sign and rank tests use asymptotic chi-squared calibration. They fail explicitly when the empirical directional moment matrix is singular; no pseudoinverse is substituted.

classical <- list(
  Hotelling.one = hotelling_one_sample_test(x),
  Hotelling.two = hotelling_two_sample_test(x, y),
  Sign.one = spatial_sign_test(x),
  Signed.rank.one = spatial_signed_rank_test(x),
  Spatial.rank.two = spatial_rank_test(x, y)
)

data.frame(
  method = names(classical),
  statistic = vapply(classical, function(z) unname(z$statistic), numeric(1)),
  p.value = vapply(classical, function(z) z$p.value, numeric(1)),
  row.names = NULL
)
#>             method statistic    p.value
#> 1    Hotelling.one  1.484114 0.20185828
#> 2    Hotelling.two  1.795962 0.09113087
#> 3         Sign.one 11.197828 0.19073999
#> 4  Signed.rank.one  6.285802 0.61525154
#> 5 Spatial.rank.two 12.911278 0.11493894

The signed-rank implementation includes the Hoeffding-projection factor (1/4) required by the score definition used in the book. The pooled two-sample spatial-rank covariance uses the sample-covariance divisor (N-1).

High-dimensional quadratic and diagonal procedures

The first high-dimensional block contains one-sample diagonal tests and two-sample Euclidean or diagonal tests. Their normal calibrations are all right-tailed because large nonnegative quadratic signal is evidence against the vector null, even though the scientific alternative is conventionally described as two-sided.

high_dimensional <- list(
  Srivastava.Du = srivastava_du_one_sample_test(x),
  Park.Ayyala = park_ayyala_one_sample_test(x),
  Bai.Saranadasa = bai_saranadasa_two_sample_test(x, y),
  Chen.Qin = chen_qin_two_sample_test(x, y),
  Srivastava.Katayama.Kano =
    srivastava_katayama_kano_two_sample_test(x, y)
)

data.frame(
  method = names(high_dimensional),
  Z = vapply(high_dimensional, function(z) unname(z$statistic), numeric(1)),
  p.value = vapply(high_dimensional, function(z) z$p.value, numeric(1)),
  row.names = NULL
)
#>                     method        Z     p.value
#> 1            Srivastava.Du 1.940097 0.026183965
#> 2              Park.Ayyala 2.212111 0.013479504
#> 3           Bai.Saranadasa 3.079545 0.001036586
#> 4                 Chen.Qin 3.072297 0.001062092
#> 5 Srivastava.Katayama.Kano 2.904926 0.001836698

The original common-covariance Bai–Saranadasa statistic and the unequal-covariance Chen–Qin U-statistic are separate functions. This matters in finite samples: the expression labelled as Bai–Saranadasa in the current book draft is algebraically the Chen–Qin numerator. Park–Ayyala and Chen–Qin expose their leave-out sums in components, while internally scaled copies protect the standardized statistic from overflow or underflow.

The scale-invariant unequal-covariance Behrens–Fisher method uses leave-four-out within-group and two-plus-two leaveout cross traces. A compact example keeps vignette build time modest:

set.seed(2411)
x.bf <- matrix(rnorm(8 * 7), 8, 7)
y.bf <- matrix(rnorm(9 * 7, 0.15), 9, 7)
bf <- feng_zou_wang_zhu_two_sample_test(x.bf, y.bf)
c(Z = unname(bf$statistic), p.value = bf$p.value)
#>          Z    p.value 
#> -1.1893122  0.8828416

Precision-adjusted maximum testing

The Cai–Liu–Xia interface requires the precision source to be stated explicitly. An oracle population precision uses its diagonal in the denominator. A supplied feasible estimate instead uses empirical within-group variances after transforming both samples. The adaptive path estimates the precision by entrywise adaptive thresholding and then follows the feasible path.

clx_adaptive <- cai_liu_xia_two_sample_test(x, y)
clx_oracle <- cai_liu_xia_two_sample_test(
  x, y, precision = solve(shape), precision_source = "oracle"
)

c(
  adaptive.G = unname(clx_adaptive$statistic),
  adaptive.p = clx_adaptive$p.value,
  oracle.G = unname(clx_oracle$statistic),
  oracle.p = clx_oracle$p.value
)
#> adaptive.G adaptive.p   oracle.G   oracle.p 
#>  0.8699354  0.3059365  0.3251553  0.3809276

clx_adaptive$diagnostics$denominator.source
#> [1] "transformed empirical within-group variances with divisors n1 and n2"
clx_adaptive$components$maximum.coordinate
#> $index
#> [1] 5
#> 
#> $name
#> [1] "V5"

The reported CLX statistic is

\[ G=M-2\log(p)+\log\{\log(p)\}, \]

with the type-I extreme-value calibration. Any eigenvalue adjustment made by the adaptive precision backend is recorded in diagnostics$adaptive.thresholding; setting eigen_floor = 0 prohibits that adjustment and turns a non-positive thresholded eigenvalue into an error.

High-dimensional sign tests

The Wang–Peng–Li function uses raw spatial signs and the paper’s literal leave-two-out variance estimator. The two-sample tINST function combines inverse-norm signs with observation-specific leave-one-out diagonal and location fits. The Feng–Sun function uses pair-specific leave-two-out joint location/diagonal fits for scalar-invariant one-sample inference. All return the published variance components and explicit degeneracy diagnostics.

wpl <- wang_peng_li_one_sample_test(x)

set.seed(2608)
x.fs <- matrix(rt(8 * 6, df = 5), 8, 6)
fs <- feng_sun_one_sample_test(x.fs, tol = 1e-6)

set.seed(25101)
x.sign <- matrix(rnorm(8 * 3), 8, 3)
y.sign <- matrix(rnorm(11 * 3, 0.2), 11, 3)
tinst <- tinst_two_sample_test(
  x.sign, y.sign, tol = 1e-7, max_iter = 2000
)

c(WPL.p = wpl$p.value, FengSun.p = fs$p.value, tINST.p = tinst$p.value)
#>     WPL.p FengSun.p   tINST.p 
#> 0.1153015 0.2027384 0.9819162
tinst$diagnostics[c("iteration.stable", "score.residual")]
#> $iteration.stable
#> [1] TRUE
#> 
#> $score.residual
#> [1] Inf

For tINST, iteration.stable follows the relative-update stopping convention used to operationalize the paper’s iteration. score.residual is retained as a separate diagnostic and is not represented as an equation-root certificate.

Failure policy

The package does not silently repair a singular covariance, a non-positive leave-out variance, or an unconverged precision estimate. Such inputs produce an informative error. This is intentional: adding a ridge, taking an absolute value, or using a generalized inverse changes the named statistical method and its reference law.