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;

        }