public void QuantileEstimatorInflationTest() { double maximumError = 0.05; int n = 1000; // g1 has weight 2/3, g2 has weight 1/3 Gaussian g1 = new Gaussian(2, 3); Gaussian g2 = new Gaussian(5, 1); var est = new QuantileEstimator(maximumError); List <double> x = new List <double>(); for (int i = 0; i < n; i++) { double sample = g1.Sample(); x.Add(sample); x.Add(sample); est.Add(sample); } est.Inflate(); for (int i = 0; i < n; i++) { double sample = g2.Sample(); x.Add(sample); est.Add(sample); } CheckProbLessThan(est, x, maximumError); }
public override double GetValue(Sample a, Sample b, Probability probability) { Assertion.NotNull(nameof(a), a); Assertion.NotNull(nameof(b), b); try { double aMad = MedianAbsoluteDeviation.CalcMad(a); double bMad = MedianAbsoluteDeviation.CalcMad(b); if (aMad < Eps && bMad < Eps) { double aMedian = QuantileEstimator.GetMedian(a); double bMedian = QuantileEstimator.GetMedian(b); if (Math.Abs(aMedian - bMedian) < Eps) { return(0); } return(aMedian < bMedian ? double.PositiveInfinity : double.NegativeInfinity); } double aQuantile = QuantileEstimator.GetQuantile(a, probability); double bQuantile = QuantileEstimator.GetQuantile(b, probability); double pooledMad = PooledMad(a.Count, b.Count, aMad, bMad); return((bQuantile - aQuantile) / pooledMad); } catch (Exception) { return(double.NaN); } }
public void QuantileEstimator_DoubleDuplicationTest2() { var data = new double[] { 0.16659357378138889, // 0 0.70210023978217528, // 0.25 0.70210023978217528, // 0.5 0.70319732172768734, // 0.75 0.70319732172768734 // 1 }; var est = new QuantileEstimator(0.01); est.AddRange(data); Assert.Equal(data[4], est.GetQuantile(0.76)); Assert.Equal(data[2], est.GetQuantile(0.3)); CheckGetQuantile(est, est); var outer = new OuterQuantiles(data); Assert.Equal(data[4], outer.GetQuantile(0.76)); Assert.Equal(data[2], outer.GetQuantile(0.3)); CheckGetQuantile(outer, outer); var inner = InnerQuantiles.FromDistribution(7, outer); CheckGetQuantile(inner, inner, (int)Math.Ceiling(100.0 / 8), (int)Math.Floor(100.0 * 7 / 8)); }
public void QuantileEstimator_DoubleDuplicationTest() { double first = 1; double second = 2; double between = (first + second) / 2; double next = MMath.NextDouble(second); double[] x = { first, first, second, second }; // quantiles are 0, 1/3, 2/3, 1 var outer = new OuterQuantiles(x); Assert.Equal(0.0, outer.GetProbLessThan(first)); Assert.Equal(first, outer.GetQuantile(0.0)); Assert.Equal(0.5, outer.GetProbLessThan(between)); Assert.Equal(between, outer.GetQuantile(0.5)); Assert.Equal(2.0 / 3, outer.GetProbLessThan(second)); Assert.Equal(second, outer.GetQuantile(2.0 / 3)); Assert.Equal(1.0, outer.GetProbLessThan(next)); Assert.Equal(next, outer.GetQuantile(1.0)); CheckGetQuantile(outer, outer); var inner = InnerQuantiles.FromDistribution(5, outer); CheckGetQuantile(inner, inner, (int)Math.Ceiling(100.0 / 6), (int)Math.Floor(100.0 * 5 / 6)); var est = new QuantileEstimator(0.01); est.Add(first, 2); est.Add(second, 2); Assert.Equal(0.0, est.GetProbLessThan(first)); Assert.Equal(first, est.GetQuantile(0.0)); Assert.Equal(0.5, est.GetProbLessThan(between)); Assert.Equal(second, est.GetQuantile(2.0 / 3)); Assert.Equal(1.0, est.GetProbLessThan(next)); Assert.Equal(next, est.GetQuantile(1.0)); CheckGetQuantile(est, est); }
public void QuantileEstimator_AllEqualTest() { double middle = 3.4; double next = MMath.NextDouble(middle); double[] x = { middle, middle, middle }; var outer = new OuterQuantiles(x); Assert.Equal(0.0, outer.GetProbLessThan(middle)); Assert.Equal(middle, outer.GetQuantile(0.0)); Assert.Equal(middle, outer.GetQuantile(0.75)); Assert.Equal(1.0, outer.GetProbLessThan(next)); Assert.Equal(next, outer.GetQuantile(1.0)); foreach (int weight in new[] { 1, 2, 3 }) { var est = new QuantileEstimator(0.01); foreach (var item in x) { est.Add(item, weight); } Assert.Equal(0.0, est.GetProbLessThan(middle)); Assert.Equal(middle, est.GetQuantile(0.0)); Assert.Equal(1.0, est.GetProbLessThan(next)); Assert.Equal(next, est.GetQuantile(1.0)); } }
/// <summary> /// Test that QuantileEstimator can handle billions of items. /// </summary> //[TestMethod, TestCategory("Performance")] internal void QuantileEstimatorBillionsTest() { long n = 100000; double maximumError = 1e-2; QuantileEstimator est = new QuantileEstimator(maximumError); for (int i = 0; i < n; i++) { if (i % 100 == 0) { Console.WriteLine(i); } for (int j = 0; j < n; j++) { est.Add(i + j); } } long expectedCount = n * n; ulong actualCount = est.GetCount(); Console.WriteLine($"count = {actualCount} should be {expectedCount}"); Assert.Equal(expectedCount, actualCount, maximumError * expectedCount); double expectedMedian = n - 2; double actualMedian = est.GetQuantile(0.5); Console.WriteLine($"median = {actualMedian} should be {expectedMedian}"); Assert.Equal(expectedMedian, actualMedian, maximumError * expectedMedian); }
public void QuantileEstimator_InfinityTest() { var est = new QuantileEstimator(0.1); est.Add(double.PositiveInfinity); Assert.Equal(double.PositiveInfinity, est.GetQuantile(0.1)); }
public void QuantileEstimator_DuplicationTest() { double middle = 3.4; double[] x = { 1.2, middle, middle, middle, 5.6 }; var outer = new OuterQuantiles(x); Assert.Equal(0.25, outer.GetProbLessThan(middle)); Assert.Equal(outer.GetQuantile(0.3), middle); Assert.Equal(outer.GetQuantile(0.5), middle); Assert.Equal(outer.GetQuantile(0.7), middle); CheckGetQuantile(outer, outer); var inner = new InnerQuantiles(7, outer); Assert.Equal(0.25, inner.GetProbLessThan(middle)); Assert.Equal(outer.GetQuantile(0.3), middle); Assert.Equal(outer.GetQuantile(0.5), middle); Assert.Equal(outer.GetQuantile(0.7), middle); CheckGetQuantile(inner, inner, 100 / 8, 100 * 7 / 8); var est = new QuantileEstimator(0.01); est.AddRange(x); Assert.Equal(0.25, est.GetProbLessThan(middle)); Assert.Equal(est.GetQuantile(0.3), middle); Assert.Equal(est.GetQuantile(0.5), middle); Assert.Equal(est.GetQuantile(0.7), middle); CheckGetQuantile(est, est); }
public void QuantileEstimator_DuplicationTest() { double middle = 3.4; double[] x = { 1.2, middle, middle, middle, 5.6 }; var outer = new OuterQuantiles(x); Assert.Equal(0.25, outer.GetProbLessThan(middle)); Assert.Equal(outer.GetQuantile(0.3), middle); Assert.Equal(outer.GetQuantile(0.5), middle); Assert.Equal(outer.GetQuantile(0.7), middle); CheckGetQuantile(outer, outer); var inner = InnerQuantiles.FromDistribution(7, outer); Assert.Equal(0.25, inner.GetProbLessThan(middle)); Assert.Equal(outer.GetQuantile(0.3), middle); Assert.Equal(outer.GetQuantile(0.5), middle); Assert.Equal(outer.GetQuantile(0.7), middle); CheckGetQuantile(inner, inner, (int)Math.Ceiling(100.0 / 8), (int)Math.Floor(100.0 * 7 / 8)); var est = new QuantileEstimator(0.01); est.AddRange(x); Assert.Equal(est.GetQuantile(0.3), middle); Assert.Equal(est.GetQuantile(0.5), middle); // InterpolationType==1 returns NextDouble(middle) Assert.Equal(est.GetQuantile(0.7), middle, 1e-15); CheckGetQuantile(est, est); }
public void QuantileEstimatorMergingTest() { double maximumError = 0.05; // draw many samples from N(m,v) Rand.Restart(0); double m = 2; double stddev = 3; Gaussian prior = new Gaussian(m, stddev * stddev); var est = new QuantileEstimator(maximumError); List <double> x = new List <double>(); int batchCount = 10; for (int batch = 0; batch < batchCount; batch++) { var est2 = new QuantileEstimator(maximumError); int n = ((1 << 5) - 1) * 46 + 1; for (int i = 0; i < n; i++) { double sample = prior.Sample(); x.Add(sample); est2.Add(sample); } est.Add(est2); } CheckProbLessThan(est, x, maximumError); }
public void InnerQuantiles_InfinityTest() { Assert.Throws <ArgumentOutOfRangeException>(() => { var inner = new InnerQuantiles(new double[] { double.PositiveInfinity }); }); Assert.Throws <ArgumentOutOfRangeException>(() => { var est = new QuantileEstimator(0.1); est.Add(double.PositiveInfinity); //est.Add(double.NegativeInfinity); var inner = InnerQuantiles.FromDistribution(10, est); }); }
public void QuantileEstimator_SinglePointIsMedian() { QuantileEstimator est = new QuantileEstimator(0.1); double point = 2; est.Add(point); Assert.Equal(point, est.GetQuantile(0.5)); OuterQuantiles outer = new OuterQuantiles(new[] { point }); Assert.Equal(point, outer.GetQuantile(0.5)); InnerQuantiles inner = new InnerQuantiles(new[] { point }); Assert.Equal(point, inner.GetQuantile(0.5)); }
public void QuantileEstimator_MedianTest() { double middle = 3.4; double[] x = { 1.2, middle, 5.6 }; var outer = new OuterQuantiles(x); Assert.Equal(outer.GetQuantile(0.5), middle); var inner = new InnerQuantiles(3, outer); Assert.Equal(inner.GetQuantile(0.5), middle); var est = new QuantileEstimator(0.01); est.AddRange(x); Assert.Equal(est.GetQuantile(0.5), middle); }
private void QuantileEstimatorTester(double maximumError, int n) { // draw many samples from N(m,v) Rand.Restart(0); double m = 2; double stddev = 3; Gaussian prior = new Gaussian(m, stddev * stddev); var est = new QuantileEstimator(maximumError); List <double> x = new List <double>(); for (int i = 0; i < n; i++) { double sample = prior.Sample(); x.Add(sample); est.Add(sample); } CheckProbLessThan(est, x, maximumError); }
public override double[] GetValues(Sample a, Sample b, IReadOnlyList <Probability> probabilities) { Assertion.NotNull(nameof(a), a); Assertion.NotNull(nameof(b), b); Assertion.NotNullOrEmpty(nameof(probabilities), probabilities); int k = probabilities.Count; try { double aMad = MedianAbsoluteDeviation.CalcMad(a); double bMad = MedianAbsoluteDeviation.CalcMad(b); if (aMad < Eps && bMad < Eps) { double aMedian = QuantileEstimator.GetMedian(a); double bMedian = QuantileEstimator.GetMedian(b); if (Math.Abs(aMedian - bMedian) < Eps) { return(ConstantSequence.Zero.GenerateArray(k)); } return(aMedian < bMedian ? ConstantSequence.PositiveInfinity.GenerateArray(k) : ConstantSequence.NegativeInfinity.GenerateArray(k)); } double[] aQuantile = QuantileEstimator.GetQuantiles(a, probabilities); double[] bQuantile = QuantileEstimator.GetQuantiles(b, probabilities); double pooledMad = PooledMad(a.Count, b.Count, aMad, bMad); double[] values = new double[k]; for (int i = 0; i < k; i++) { values[i] = (bQuantile[i] - aQuantile[i]) / pooledMad; } return(values); } catch (Exception) { return(ConstantSequence.NaN.GenerateArray(k)); } }
public void QuantileEstimator_MedianTest() { double left = 1.2; double middle = 3.4; double right = 5.6; double[] x = { left, middle, right }; var outer = new OuterQuantiles(x); Assert.Equal(middle, outer.GetQuantile(0.5)); var inner = InnerQuantiles.FromDistribution(3, outer); Assert.Equal(middle, inner.GetQuantile(0.5)); inner = new InnerQuantiles(x); CheckGetQuantile(inner, inner, 25, 75); var est = new QuantileEstimator(0.01); est.AddRange(x); Assert.Equal(est.GetQuantile(0.5), middle); }
public void QuantileDeserializationTest() { var seed = Rand.Int(); var initialEstimator = new QuantileEstimator(Rand.Double()); initialEstimator.SetRandomSeed(Rand.Int()); var serialized = JsonConvert.SerializeObject(initialEstimator); var deserialized = JsonConvert.DeserializeObject <QuantileEstimator>(serialized); double[] GetRandomQuantiles(QuantileEstimator estimator) { var rand = new Random(seed); var numbers = Enumerable.Range(0, rand.Next(100)) .Select(x => rand.Next()) .ToArray(); foreach (var item in numbers) { estimator.Add(item, 1 + rand.Next(20)); } var quantiles = numbers .Select(x => estimator.GetProbLessThan(x)) .ToArray(); return(quantiles); } // Run the same estimation run twice with the same serialized // object to use to test that the results are the same. var firstRun = GetRandomQuantiles(initialEstimator); var secondRun = GetRandomQuantiles(deserialized); Assert.Equal(firstRun, secondRun); }
public void QuantileSeedTest() { var seed = Rand.Int(); double[] GetRandomQuantiles() { var rand = new Random(seed); var estimator = new QuantileEstimator(rand.NextDouble()); estimator.SetRandomSeed(rand.Next()); var numbers = Enumerable.Range(0, rand.Next(100)) .Select(x => rand.Next()) .ToArray(); foreach (var item in numbers) { estimator.Add(item, 1 + rand.Next(20)); } var quantiles = numbers .Select(x => estimator.GetProbLessThan(x)) .ToArray(); return(quantiles); } // Run the same estimation run twice with the same seed to test // that the results are the same. var firstRun = GetRandomQuantiles(); var secondRun = GetRandomQuantiles(); Assert.Equal(firstRun, secondRun); }
public void Initialize(bool skipStringDistributions = false) { // DO NOT make this a constructor, because it makes the test not notice complete lack of serialization as an empty object is set up exactly as the thing // you are trying to deserialize. this.pareto = new Pareto(1.2, 3.5); this.poisson = new Poisson(2.3); this.wishart = new Wishart(20, new PositiveDefiniteMatrix(new double[, ] { { 22, 21 }, { 21, 23 } })); this.vectorGaussian = new VectorGaussian(Vector.FromArray(13, 14), new PositiveDefiniteMatrix(new double[, ] { { 16, 15 }, { 15, 17 } })); this.unnormalizedDiscrete = UnnormalizedDiscrete.FromLogProbs(DenseVector.FromArray(5.1, 5.2, 5.3)); this.pointMass = PointMass <double> .Create(1.1); this.gaussian = new Gaussian(11.0, 12.0); this.nonconjugateGaussian = new NonconjugateGaussian(1.2, 2.3, 3.4, 4.5); this.gamma = new Gamma(9.0, 10.0); this.gammaPower = new GammaPower(5.6, 2.8, 3.4); this.discrete = new Discrete(6.0, 7.0, 8.0); this.conjugateDirichlet = new ConjugateDirichlet(1.2, 2.3, 3.4, 4.5); this.dirichlet = new Dirichlet(3.0, 4.0, 5.0); this.beta = new Beta(2.0, 1.0); this.binomial = new Binomial(5, 0.8); this.bernoulli = new Bernoulli(0.6); this.sparseBernoulliList = SparseBernoulliList.Constant(4, new Bernoulli(0.1)); this.sparseBernoulliList[1] = new Bernoulli(0.9); this.sparseBernoulliList[3] = new Bernoulli(0.7); this.sparseBetaList = SparseBetaList.Constant(5, new Beta(2.0, 2.0)); this.sparseBetaList[0] = new Beta(3.0, 4.0); this.sparseBetaList[1] = new Beta(5.0, 6.0); this.sparseGaussianList = SparseGaussianList.Constant(6, Gaussian.FromMeanAndPrecision(0.1, 0.2)); this.sparseGaussianList[4] = Gaussian.FromMeanAndPrecision(0.3, 0.4); this.sparseGaussianList[5] = Gaussian.FromMeanAndPrecision(0.5, 0.6); this.sparseGammaList = SparseGammaList.Constant(1, Gamma.FromShapeAndRate(1.0, 2.0)); this.truncatedGamma = new TruncatedGamma(1.2, 2.3, 3.4, 4.5); this.truncatedGaussian = new TruncatedGaussian(1.2, 3.4, 5.6, 7.8); this.wrappedGaussian = new WrappedGaussian(1.2, 2.3, 3.4); ga = Distribution <double> .Array(new[] { this.gaussian, this.gaussian }); vga = Distribution <Vector> .Array(new[] { this.vectorGaussian, this.vectorGaussian }); ga2D = Distribution <double> .Array(new[, ] { { this.gaussian, this.gaussian }, { this.gaussian, this.gaussian } }); vga2D = Distribution <Vector> .Array(new[, ] { { this.vectorGaussian, this.vectorGaussian }, { this.vectorGaussian, this.vectorGaussian } }); gaJ = Distribution <double> .Array(new[] { new[] { this.gaussian, this.gaussian }, new[] { this.gaussian, this.gaussian } }); vgaJ = Distribution <Vector> .Array(new[] { new[] { this.vectorGaussian, this.vectorGaussian }, new[] { this.vectorGaussian, this.vectorGaussian } }); var gp = new GaussianProcess(new ConstantFunction(0), new SquaredExponential(0)); var basis = Util.ArrayInit(2, i => Vector.FromArray(1.0 * i)); this.sparseGp = new SparseGP(new SparseGPFixed(gp, basis)); this.quantileEstimator = new QuantileEstimator(0.01); this.quantileEstimator.Add(5); this.outerQuantiles = OuterQuantiles.FromDistribution(3, this.quantileEstimator); this.innerQuantiles = InnerQuantiles.FromDistribution(3, this.outerQuantiles); if (!skipStringDistributions) { // String distributions can not be serialized by some formatters (namely BinaryFormatter) // That is fine because this combination is never used in practice this.stringDistribution1 = StringDistribution.String("aa") .Append(StringDistribution.OneOf("b", "ccc")).Append("dddd"); this.stringDistribution2 = new StringDistribution(); this.stringDistribution2.SetToProduct(StringDistribution.OneOf("a", "b"), StringDistribution.OneOf("b", "c")); } }
public void Initialize() { // DO NOT make this a constructor, because it makes the test not notice complete lack of serialization as an empty object is set up exactly as the thing // you are trying to deserialize. this.pareto = new Pareto(1.2, 3.5); this.poisson = new Poisson(2.3); this.wishart = new Wishart(20, new PositiveDefiniteMatrix(new double[, ] { { 22, 21 }, { 21, 23 } })); this.vectorGaussian = new VectorGaussian(Vector.FromArray(13, 14), new PositiveDefiniteMatrix(new double[, ] { { 16, 15 }, { 15, 17 } })); this.unnormalizedDiscrete = UnnormalizedDiscrete.FromLogProbs(DenseVector.FromArray(5.1, 5.2, 5.3)); this.pointMass = PointMass <double> .Create(1.1); this.gaussian = new Gaussian(11.0, 12.0); this.nonconjugateGaussian = new NonconjugateGaussian(1.2, 2.3, 3.4, 4.5); this.gamma = new Gamma(9.0, 10.0); this.gammaPower = new GammaPower(5.6, 2.8, 3.4); this.discrete = new Discrete(6.0, 7.0, 8.0); this.conjugateDirichlet = new ConjugateDirichlet(1.2, 2.3, 3.4, 4.5); this.dirichlet = new Dirichlet(3.0, 4.0, 5.0); this.beta = new Beta(2.0, 1.0); this.binomial = new Binomial(5, 0.8); this.bernoulli = new Bernoulli(0.6); this.sparseBernoulliList = SparseBernoulliList.Constant(4, new Bernoulli(0.1)); this.sparseBernoulliList[1] = new Bernoulli(0.9); this.sparseBernoulliList[3] = new Bernoulli(0.7); this.sparseBetaList = SparseBetaList.Constant(5, new Beta(2.0, 2.0)); this.sparseBetaList[0] = new Beta(3.0, 4.0); this.sparseBetaList[1] = new Beta(5.0, 6.0); this.sparseGaussianList = SparseGaussianList.Constant(6, Gaussian.FromMeanAndPrecision(0.1, 0.2)); this.sparseGaussianList[4] = Gaussian.FromMeanAndPrecision(0.3, 0.4); this.sparseGaussianList[5] = Gaussian.FromMeanAndPrecision(0.5, 0.6); this.sparseGammaList = SparseGammaList.Constant(1, Gamma.FromShapeAndRate(1.0, 2.0)); this.truncatedGamma = new TruncatedGamma(1.2, 2.3, 3.4, 4.5); this.truncatedGaussian = new TruncatedGaussian(1.2, 3.4, 5.6, 7.8); this.wrappedGaussian = new WrappedGaussian(1.2, 2.3, 3.4); ga = Distribution <double> .Array(new[] { this.gaussian, this.gaussian }); vga = Distribution <Vector> .Array(new[] { this.vectorGaussian, this.vectorGaussian }); ga2D = Distribution <double> .Array(new[, ] { { this.gaussian, this.gaussian }, { this.gaussian, this.gaussian } }); vga2D = Distribution <Vector> .Array(new[, ] { { this.vectorGaussian, this.vectorGaussian }, { this.vectorGaussian, this.vectorGaussian } }); gaJ = Distribution <double> .Array(new[] { new[] { this.gaussian, this.gaussian }, new[] { this.gaussian, this.gaussian } }); vgaJ = Distribution <Vector> .Array(new[] { new[] { this.vectorGaussian, this.vectorGaussian }, new[] { this.vectorGaussian, this.vectorGaussian } }); var gp = new GaussianProcess(new ConstantFunction(0), new SquaredExponential(0)); var basis = Util.ArrayInit(2, i => Vector.FromArray(1.0 * i)); this.sparseGp = new SparseGP(new SparseGPFixed(gp, basis)); this.quantileEstimator = new QuantileEstimator(0.01); this.quantileEstimator.Add(5); }