void VerifyPercsWithAbsoluteEpsilon(double[] a, QuantileStream s) { Array.Sort(a); foreach (var target in _targets) { var n = (double) a.Length; var k = (int)(target.Quantile * n); var lower = (int) ((target.Quantile - target.Epsilon)*n); if (lower < 1) lower = 1; var upper = (int) Math.Ceiling((target.Quantile + target.Epsilon) *n); if (upper > a.Length) upper = a.Length; var w = a[k - 1]; var min = a[lower - 1]; var max = a[upper - 1]; var g = s.Query(target.Quantile); Assert.That(g, Is.GreaterThanOrEqualTo(min), $"q={target.Quantile}: want {w} [{min}, {max}], got {g}"); Assert.That(g, Is.LessThanOrEqualTo(max), $"q={target.Quantile}: want {w} [{min}, {max}], got {g}"); } }
void VerifyHighPercsWithRelativeEpsilon(double[] a, QuantileStream s) { Array.Sort(a); foreach (var qu in _highQuantiles) { var n = (double) a.Length; var k = (int) (qu*n); var lowerRank = (int) ((1 - (1 + RelativeEpsilon)*(1 - qu))*n); var upperRank = (int) (Math.Ceiling((1 - (1 - RelativeEpsilon)*(1 - qu))*n)); var w = a[k - 1]; var min = a[lowerRank - 1]; var max = a[upperRank - 1]; var g = s.Query(qu); Assert.That(g, Is.GreaterThanOrEqualTo(min), $"q={qu}: want {w} [{min}, {max}], got {g}"); Assert.That(g, Is.LessThanOrEqualTo(max), $"q={qu}: want {w} [{min}, {max}], got {g}"); } }
static double[] PopulateStream(QuantileStream stream, Random random) { var a = new double[100100]; for (int i = 0; i < a.Length; i++) { var v = random.NormDouble(); // Add 5% asymmetric outliers. if (i%20 == 0) v = v*v + 1; stream.Insert(v); a[i] = v; } return a; }