AvgSpread
Weighted average of dispersions (pooled scale).
- Also known as — robust pooled standard deviation
- Domain — any real numbers
- Assumptions — sparity(x), sparity(y)
- Unit — same as measurements
- Caveat — (pooled scale, not concatenated spread)
Properties
- Self-average
- Symmetry
- Scale equivariance
- Mixed scaling
Example
AvgSpread(x, y) = 5whereSpread(x) = 6,Spread(y) = 4,n = mAvgSpread(x, y) = AvgSpread(y, x)
provides a single number representing the typical variability across two groups. It combines the spread of both samples, giving more weight to larger samples since they provide more reliable estimates. This pooled spread serves as a common reference scale, essential for expressing a difference in relative terms. uses internally to normalize the shift into a scale-free effect size.
Algorithm
The function computes the weighted average of per-sample spreads:
The algorithm delegates to the Spread algorithm independently for each sample, then forms the weighted linear combination with weights and .
using Pragmastat.Algorithms;
using Pragmastat.Exceptions;
using Pragmastat.Internal;
using Pragmastat.Metrology;
namespace Pragmastat.Estimators;
internal class AvgSpreadEstimator : ITwoSampleEstimator
{
public static readonly AvgSpreadEstimator Instance = new();
public Measurement Estimate(Sample x, Sample y)
{
Assertion.MatchedUnit(x, y);
// Check validity for x (priority 0, subject x)
Assertion.Validity(x, Subject.X);
// Check validity for y (priority 0, subject y)
Assertion.Validity(y, Subject.Y);
// Check sparity for x (priority 2, subject x)
Assertion.Sparity(x, Subject.X);
// Check sparity for y (priority 2, subject y)
Assertion.Sparity(y, Subject.Y);
// Calculate spreads (using internal implementation since we already validated)
var spreadX = FastSpread.Estimate(x.SortedValues, isSorted: true);
var spreadY = FastSpread.Estimate(y.SortedValues, isSorted: true);
return ((x.Size * spreadX + y.Size * spreadY) / (x.Size + y.Size)).WithUnitOf(x);
}
}
Tests
The test suite contains 36 test cases (5 demo + 4 natural + 1 negative + 9 additive + 4 uniform + 1 composite + 12 unsorted). Since is a weighted average of two estimates, tests validate both the individual spread calculations and the weighting formula.
Demo examples () from manual introduction, validating properties:
demo-1: , , expected output: (base case)demo-2: , , expected output: (equal samples)demo-3: , , expected output: (scale equivariance, demo-1)demo-4: , , expected output: (swap symmetry with demo-1)demo-5: , , expected output: (scale, demo-1)
Natural sequences () 4 combinations:
natural-2-2,natural-2-3,natural-3-2,natural-3-3- Minimum size required for meaningful dispersion
Negative values () sign handling validation:
negative-2-2: , , expected output:
Additive distribution () 9 combinations with :
additive-5-5,additive-5-10,additive-5-30additive-10-5,additive-10-10,additive-10-30additive-30-5,additive-30-10,additive-30-30- Random generation: uses seed 0, uses seed 1
Uniform distribution () 4 combinations with :
uniform-5-5,uniform-5-100,uniform-100-5,uniform-100-100- Random generation: uses seed 0, uses seed 1
Composite estimator stress test 1 test:
composite-asymmetric-weights: , (, , highly asymmetric weights , )
Unsorted tests verify sorting independence (12 tests):
unsorted-x-natural-{n}-{m}for : X unsorted (reversed), Y sorted (2 tests)unsorted-y-natural-{n}-{m}for : X sorted, Y unsorted (reversed) (2 tests)unsorted-both-natural-{n}-{m}for : both unsorted (reversed) (2 tests)unsorted-demo-unsorted-x: demo-1 with X unsortedunsorted-demo-unsorted-y: demo-1 with Y unsortedunsorted-demo-both-unsorted: demo-1 with both unsortedunsorted-identity-unsorted: equal samples, both unsortedunsorted-negative-unsorted: negative values, both unsortedunsorted-asymmetric-weights-unsorted: asymmetric weights, both unsorted
As a composite estimator, tests both individual computations and the weighted combination. Unsorted variants verify end-to-end correctness including the weighting formula.