ShiftBounds

ShiftBounds(x,y,misrate)=[z(kleft),z(kright)]\operatorname{ShiftBounds}(\mathbf{x}, \mathbf{y}, \mathrm{misrate}) = [z_{(k_{\text{left}})}, z_{(k_{\text{right}})}]

where z=xiyj\mathbf{z} = { x_i - y_j } (sorted), kleft=PairwiseMargin/2+1k_{\text{left}} = \lfloor \operatorname{PairwiseMargin} / 2 \rfloor + 1, kright=nmPairwiseMargin/2k_{\text{right}} = n m - \lfloor \operatorname{PairwiseMargin} / 2 \rfloor

Robust bounds on Shift(x,y)\operatorname{Shift}(\mathbf{x}, \mathbf{y}) with specified coverage.

Input

  • x=(x1,x2,,xn)\mathbf{x} = (x_1, x_2, \ldots, x_n) — first sample of measurements
  • y=(y1,y2,,ym)\mathbf{y} = (y_1, y_2, \ldots, y_m) — second sample of measurements
  • misrate2/(n+mn)\mathrm{misrate} \geq 2 / \binom{n+m}{n} — probability that true shift falls outside bounds in the long run

Output

  • Value — interval [L,U][L, U] bounding Shift(x,y)\operatorname{Shift}(\mathbf{x}, \mathbf{y})
  • Unit — same unit as x\mathbf{x}, y\mathbf{y}

Notes

  • Also known as — distribution-free confidence interval for Hodges–Lehmann
  • Note — assumes weak shape and weak continuity (ties from measurement resolution are tolerated but may yield conservative bounds)

Properties

  • Shift invariance ShiftBounds(x+k,y+k,misrate)=ShiftBounds(x,y,misrate)\operatorname{ShiftBounds}(\mathbf{x} + k, \mathbf{y} + k, \mathrm{misrate}) = \operatorname{ShiftBounds}(\mathbf{x}, \mathbf{y}, \mathrm{misrate})
  • Scale equivariance ShiftBounds(kx,ky,misrate)=kShiftBounds(x,y,misrate)\operatorname{ShiftBounds}(k \cdot \mathbf{x}, k \cdot \mathbf{y}, \mathrm{misrate}) = k \cdot \operatorname{ShiftBounds}(\mathbf{x}, \mathbf{y}, \mathrm{misrate})

Example

  • ShiftBounds([1..30], [21..50], 1e-4) = [-30, -10] where Shift = -20
  • Bounds fail to cover true shift with probability misrate\approx \mathrm{misrate}

ShiftBounds\operatorname{ShiftBounds} provides not just the estimated shift but also the uncertainty of that estimate. The function returns an interval of plausible shift values given the data. Set misrate\mathrm{misrate} to control how often the bounds might fail to contain the true shift: use 10310^{-3} for everyday analysis or 10610^{-6} for critical decisions where errors are costly. These bounds require weak shape but no specific distributional form: coverage is exact for any continuous distributions that differ only by a shift. When the shapes differ, the actual coverage may deviate from 1misrate1 - \mathrm{misrate}. If the bounds exclude zero, that suggests a reliable difference between the two groups.

See also: Compare2\operatorname{Compare2} for comparing Shift against practical thresholds with automatic verdict generation.

Algorithm

The ShiftBounds\operatorname{ShiftBounds} estimator constructs distribution-free bounds on Shift(x,y)\operatorname{Shift}(\mathbf{x}, \mathbf{y}) by selecting specific order statistics from the pairwise differences.

Given samples x=(x1,,xn)\mathbf{x} = (x_1, \ldots, x_n) and y=(y1,,ym)\mathbf{y} = (y_1, \ldots, y_m), the algorithm proceeds as follows:

  • Compute the margin — Call PairwiseMargin(n,m,misrate)\operatorname{PairwiseMargin}(n, m, \mathrm{misrate}) (see PairwiseMargin) to determine how many extreme pairwise differences to exclude from each tail.

  • Determine quantile ranks — From the margin MM, compute kleft=M/2+1k_{\text{left}} = \lfloor M / 2 \rfloor + 1 and kright=nmM/2k_{\text{right}} = n m - \lfloor M / 2 \rfloor. These are the ranks of the order statistics that form the bounds.

  • Compute quantiles via Shift — Use the Shift algorithm to compute the kleftk_{\text{left}}-th and krightk_{\text{right}}-th order statistics of all nmn m pairwise differences xiyjx_i - y_j. The Shift algorithm’s value-space binary search finds these quantiles in O((n+m)logL)O((n + m) \log L) time without materializing all differences.

  • Return bounds — Return [z(kleft),z(kright)][z_{(k_{\text{left}})}, z_{(k_{\text{right}})}].

The PairwiseMargin\operatorname{PairwiseMargin} function encodes the statistical theory: it determines which order statistics provide bounds with coverage 1misrate1 - \mathrm{misrate}. The Shift\operatorname{Shift} algorithm provides the computational machinery: it extracts those specific order statistics efficiently from the implicit matrix of pairwise differences.

Notes

Width Convergence

The table below shows how Width=UL\text{Width} = U - L narrows as NN grows, for x=y=(1,1+1/(N1),,2)\mathbf{x} = \mathbf{y} = (1, 1 + 1/(N-1), \ldots, 2) (NN evenly spaced points on [1,2][1, 2]) and misrate=103\mathrm{misrate} = 10^{-3}. Dashes indicate NN too small to achieve the target misrate.

NWidth
2
3
4
5
101.3333
200.7368
300.5517
400.5128
500.4490
1000.2828
2000.2010
3000.1605
4000.1404
5000.1242
10000.0861
100000.0270

Tests

ShiftBounds(x,y,misrate)=[z(kleft),z(kright)]\operatorname{ShiftBounds}(\mathbf{x}, \mathbf{y}, \mathrm{misrate}) = [z_{(k_{\text{left}})}, z_{(k_{\text{right}})}]

where

z=xiyj1in,1jm(sorted)\mathbf{z} = { x_i - y_j }_{1 \leq i \leq n, 1 \leq j \leq m} \quad (\text{sorted}) kleft=PairwiseMargin(n,m,misrate)2+1k_{\text{left}} = \lfloor \frac{\operatorname{PairwiseMargin}(n, m, \mathrm{misrate})}{2} \rfloor + 1 kright=nmPairwiseMargin(n,m,misrate)2k_{\text{right}} = n m - \lfloor \frac{\operatorname{PairwiseMargin}(n, m, \mathrm{misrate})}{2} \rfloor

The ShiftBounds\operatorname{ShiftBounds} test suite contains 63 test cases (3 demo + 9 natural + 6 property + 10 edge + 9 additive + 4 uniform + 5 misrate + 15 unsorted + 2 error). Since ShiftBounds\operatorname{ShiftBounds} returns bounds rather than a point estimate, tests validate that the bounds contain Shift(x,y)\operatorname{Shift}(\mathbf{x}, \mathbf{y}) and satisfy equivariance properties. Each test case output is a JSON object with lower and upper fields representing the interval bounds. The domain constraint misrate2/(n+mn)\mathrm{misrate} \geq 2 / \binom{n+m}{n} is enforced; inputs violating this return a domain error.

Demo examples (n=m=5n = m = 5) — from manual introduction, validating basic bounds:

  • demo-1: x=(1,2,3,4,5)\mathbf{x} = (1, 2, 3, 4, 5), y=(3,4,5,6,7)\mathbf{y} = (3, 4, 5, 6, 7), expected output: [4,0][-4, 0]
  • demo-2: x=(1,2,3,4,5)\mathbf{x} = (1, 2, 3, 4, 5), y=(3,4,5,6,7)\mathbf{y} = (3, 4, 5, 6, 7), stricter fixture misrate, expected output: [5,1][-5, 1]
  • demo-3: x=(3,4,5,6,7)\mathbf{x} = (3, 4, 5, 6, 7), y=(3,4,5,6,7)\mathbf{y} = (3, 4, 5, 6, 7), expected output: bounds containing 00 (identity case)

These cases illustrate how tighter misrates produce wider bounds and validate the identity property where identical samples yield bounds containing zero.

Natural sequences ([n,m]in5,8,10×5,8,10[n, m] in {5, 8, 10} \times {5, 8, 10}, achievable fixture misrates) — 9 combinations:

  • natural-5-5: x=(1,,5)\mathbf{x} = (1, \ldots, 5), y=(1,,5)\mathbf{y} = (1, \ldots, 5), expected bounds containing 00
  • natural-5-8: x=(1,,5)\mathbf{x} = (1, \ldots, 5), y=(1,,8)\mathbf{y} = (1, \ldots, 8)
  • natural-5-10: x=(1,,5)\mathbf{x} = (1, \ldots, 5), y=(1,,10)\mathbf{y} = (1, \ldots, 10)
  • natural-8-5: x=(1,,8)\mathbf{x} = (1, \ldots, 8), y=(1,,5)\mathbf{y} = (1, \ldots, 5)
  • natural-8-8: x=(1,,8)\mathbf{x} = (1, \ldots, 8), y=(1,,8)\mathbf{y} = (1, \ldots, 8), expected bounds containing 00
  • natural-8-10: x=(1,,8)\mathbf{x} = (1, \ldots, 8), y=(1,,10)\mathbf{y} = (1, \ldots, 10)
  • natural-10-5: x=(1,,10)\mathbf{x} = (1, \ldots, 10), y=(1,,5)\mathbf{y} = (1, \ldots, 5)
  • natural-10-8: x=(1,,10)\mathbf{x} = (1, \ldots, 10), y=(1,,8)\mathbf{y} = (1, \ldots, 8)
  • natural-10-10: x=(1,,10)\mathbf{x} = (1, \ldots, 10), y=(1,,10)\mathbf{y} = (1, \ldots, 10), expected bounds containing 00

These sizes are chosen to satisfy misrate2/(n+mn)\mathrm{misrate} \geq 2 / \binom{n+m}{n} for all combinations.

Property validation (n=m=10n = m = 10, misrate=103\mathrm{misrate} = 10^{-3}) — 6 tests:

  • property-identity: x=(0,2,4,,18)\mathbf{x} = (0, 2, 4, \ldots, 18), y=(0,2,4,,18)\mathbf{y} = (0, 2, 4, \ldots, 18), bounds must contain 00
  • property-location-shift: x=(7,9,11,,25)\mathbf{x} = (7, 9, 11, \ldots, 25), y=(13,15,17,,31)\mathbf{y} = (13, 15, 17, \ldots, 31)
  • Must produce same bounds as base case (location invariance)
  • property-scale-2x: x=(2,4,6,,20)\mathbf{x} = (2, 4, 6, \ldots, 20), y=(6,8,10,,24)\mathbf{y} = (6, 8, 10, \ldots, 24)
  • Bounds must be 2× the base case bounds (scale equivariance)
  • property-antisymmetry: x=(3,4,,12)\mathbf{x} = (3, 4, \ldots, 12), y=(1,2,,10)\mathbf{y} = (1, 2, \ldots, 10)
  • Bounds must be negated: if original is [a,b][a, b], this yields [b,a][-b, -a]
  • property-negative: x=(10,9,,1)\mathbf{x} = (-10, -9, \ldots, -1), y=(12,11,,3)\mathbf{y} = (-12, -11, \ldots, -3)
  • Validates sign handling with all negative values
  • property-mixed-signs: x=(4,3,,5)\mathbf{x} = (-4, -3, \ldots, 5), y=(3,2,,6)\mathbf{y} = (-3, -2, \ldots, 6)
  • Validates bounds crossing zero with mixed-sign samples

Edge cases — boundary conditions and extreme scenarios (10 tests):

  • edge-min-samples: x=(1,2,3,4,5)\mathbf{x} = (1, 2, 3, 4, 5), y=(6,7,8,9,10)\mathbf{y} = (6, 7, 8, 9, 10)
  • edge-permissive-misrate: x=(1,2,3,4,5)\mathbf{x} = (1, 2, 3, 4, 5), y=(3,4,5,6,7)\mathbf{y} = (3, 4, 5, 6, 7), very loose fixture misrate (very wide bounds)
  • edge-strict-misrate: n=m=20n = m = 20, misrate=106\mathrm{misrate} = 10^{-6} (very narrow bounds)
  • edge-zero-shift: n=m=10n = m = 10, all values =5= 5, misrate=103\mathrm{misrate} = 10^{-3} (bounds around 0)
  • edge-asymmetric-3-100: n=3n = 3, m=100m = 100 (extreme size difference)
  • edge-asymmetric-5-50: n=5n = 5, m=50m = 50, misrate=103\mathrm{misrate} = 10^{-3} (highly unbalanced)
  • edge-duplicates: x=(3,3,3,3,3)\mathbf{x} = (3, 3, 3, 3, 3), y=(5,5,5,5,5)\mathbf{y} = (5, 5, 5, 5, 5) (all duplicates, bounds around −2)
  • edge-wide-range: n=m=10n = m = 10, values spanning 10310^{-3} to 10810^8, misrate=103\mathrm{misrate} = 10^{-3} (extreme value range)
  • edge-tiny-values: n=m=10n = m = 10, values 108\approx 10^{-8}, misrate=103\mathrm{misrate} = 10^{-3} (numerical precision)
  • edge-large-values: n=m=10n = m = 10, values 108\approx 10^8, misrate=103\mathrm{misrate} = 10^{-3} (large magnitude)

These edge cases stress-test boundary conditions, numerical stability, and the margin calculation with extreme parameters.

Additive distribution ([n,m]in10,30,50×10,30,50[n, m] in {10, 30, 50} \times {10, 30, 50}, misrate=103\mathrm{misrate} = 10^{-3}) — 9 combinations with Additive(10,1)\underline{\operatorname{Additive}}(10, 1):

  • additive-10-10, additive-10-30, additive-10-50
  • additive-30-10, additive-30-30, additive-30-50
  • additive-50-10, additive-50-30, additive-50-50
  • Random generation: x\mathbf{x} uses seed 0, y\mathbf{y} uses seed 1

These fuzzy tests validate that bounds properly encompass the shift estimate for realistic normally-distributed data at various sample sizes.

Uniform distribution ([n,m]in10,100×10,100[n, m] in {10, 100} \times {10, 100}, misrate=104\mathrm{misrate} = 10^{-4}) — 4 combinations with Uniform(0,1)\underline{\operatorname{Uniform}}(0, 1):

  • uniform-10-10, uniform-10-100, uniform-100-10, uniform-100-100
  • Random generation: x\mathbf{x} uses seed 2, y\mathbf{y} uses seed 3

The asymmetric size combinations are particularly important for testing margin calculation with unbalanced samples.

Misrate variation (n=m=20n = m = 20, x=(0,2,4,,38)\mathbf{x} = (0, 2, 4, \ldots, 38), y=(10,12,14,,48)\mathbf{y} = (10, 12, 14, \ldots, 48)) — 5 tests from a loose achievable fixture misrate down to 10610^{-6}:

These tests use identical samples with varying misrates to validate the monotonicity property: smaller misrates (higher confidence) produce wider bounds. The sequence demonstrates how bound width increases as misrate decreases, helping implementations verify correct margin calculation.

Unsorted tests — verify independent sorting of x\mathbf{x} and y\mathbf{y} (15 tests):

  • unsorted-x-natural-5-5: x=(5,3,1,4,2)\mathbf{x} = (5, 3, 1, 4, 2), y=(1,2,3,4,5)\mathbf{y} = (1, 2, 3, 4, 5) (X reversed, Y sorted)
  • unsorted-y-natural-5-5: x=(1,2,3,4,5)\mathbf{x} = (1, 2, 3, 4, 5), y=(5,3,1,4,2)\mathbf{y} = (5, 3, 1, 4, 2) (X sorted, Y reversed)
  • unsorted-both-natural-5-5: x=(5,3,1,4,2)\mathbf{x} = (5, 3, 1, 4, 2), y=(5,3,1,4,2)\mathbf{y} = (5, 3, 1, 4, 2) (both reversed)
  • unsorted-x-shuffle-5-5: x=(3,1,5,4,2)\mathbf{x} = (3, 1, 5, 4, 2), y=(1,2,3,4,5)\mathbf{y} = (1, 2, 3, 4, 5) (X shuffled)
  • unsorted-y-shuffle-5-5: x=(1,2,3,4,5)\mathbf{x} = (1, 2, 3, 4, 5), y=(4,2,5,1,3)\mathbf{y} = (4, 2, 5, 1, 3) (Y shuffled)
  • unsorted-both-shuffle-5-5: x=(3,1,5,4,2)\mathbf{x} = (3, 1, 5, 4, 2), y=(2,4,1,5,3)\mathbf{y} = (2, 4, 1, 5, 3) (both shuffled)
  • unsorted-demo-unsorted-x: x=(5,1,4,2,3)\mathbf{x} = (5, 1, 4, 2, 3), y=(3,4,5,6,7)\mathbf{y} = (3, 4, 5, 6, 7) (demo-1 X unsorted)
  • unsorted-demo-unsorted-y: x=(1,2,3,4,5)\mathbf{x} = (1, 2, 3, 4, 5), y=(7,3,6,4,5)\mathbf{y} = (7, 3, 6, 4, 5) (demo-1 Y unsorted)
  • unsorted-demo-both-unsorted: x=(4,1,5,2,3)\mathbf{x} = (4, 1, 5, 2, 3), y=(6,3,7,4,5)\mathbf{y} = (6, 3, 7, 4, 5) (demo-1 both unsorted)
  • unsorted-identity-unsorted: x=(4,1,5,2,3)\mathbf{x} = (4, 1, 5, 2, 3), y=(5,1,4,3,2)\mathbf{y} = (5, 1, 4, 3, 2) (identity property, both unsorted)
  • unsorted-negative-unsorted: x=(1,5,3,2,4)\mathbf{x} = (-1, -5, -3, -2, -4), y=(2,4,3,5,1)\mathbf{y} = (-2, -4, -3, -5, -1) (negative values unsorted)
  • unsorted-asymmetric-5-10: x=(2,5,1,3,4)\mathbf{x} = (2, 5, 1, 3, 4), y=(10,5,2,8,4,1,9,3,7,6)\mathbf{y} = (10, 5, 2, 8, 4, 1, 9, 3, 7, 6) (asymmetric sizes, both unsorted)
  • unsorted-duplicates: x=(3,3,3,3,3)\mathbf{x} = (3, 3, 3, 3, 3), y=(5,5,5,5,5)\mathbf{y} = (5, 5, 5, 5, 5) (all duplicates, any order)
  • unsorted-mixed-duplicates-x: x=(2,1,3,2,1)\mathbf{x} = (2, 1, 3, 2, 1), y=(1,1,2,2,3)\mathbf{y} = (1, 1, 2, 2, 3) (X has unsorted duplicates)
  • unsorted-mixed-duplicates-y: x=(1,1,2,2,3)\mathbf{x} = (1, 1, 2, 2, 3), y=(3,2,1,3,2)\mathbf{y} = (3, 2, 1, 3, 2) (Y has unsorted duplicates)

These unsorted tests are critical because ShiftBounds\operatorname{ShiftBounds} computes bounds from pairwise differences, requiring both samples to be sorted independently. The variety ensures implementations don’t incorrectly assume pre-sorted input or sort samples together. Each test must produce identical output to its sorted counterpart, validating that the implementation correctly handles the sorting step.

Error cases — input validation (2 tests):

  • error-empty-x: x=()\mathbf{x} = (), y=(1,2,3,4,5)\mathbf{y} = (1, 2, 3, 4, 5) — empty X array violates validity
  • error-empty-y: x=(1,2,3,4,5)\mathbf{x} = (1, 2, 3, 4, 5), y=()\mathbf{y} = () — empty Y array violates validity

No performance testShiftBounds\operatorname{ShiftBounds} uses the ShiftImpl\text{ShiftImpl} algorithm internally, which is already validated by the Shift\operatorname{Shift} performance test. Since bounds computation involves only two quantile calculations from the pairwise differences (at positions determined by PairwiseMargin\operatorname{PairwiseMargin}), the performance characteristics are equivalent to computing two Shift\operatorname{Shift} estimates, which completes efficiently for large samples.