internal void StudentIsPositiveTest4() { double shape = 1; Gamma precPrior = Gamma.FromShapeAndRate(shape, shape); // mean=-1 causes improper messages double mean = -1; Gaussian meanPrior = Gaussian.PointMass(mean); double evExpected; Gaussian xExpected = StudentIsPositiveExact(mean, precPrior, out evExpected); GaussianOp.ForceProper = false; GaussianOp_Laplace.modified = true; GaussianOp_Laplace.modified2 = true; Gaussian xF = Gaussian.Uniform(); Gaussian xB = Gaussian.Uniform(); Gamma q = GaussianOp_Laplace.QInit(); double r0 = 0.38; r0 = 0.1; for (int iter = 0; iter < 20; iter++) { q = GaussianOp_Laplace.Q(xB, meanPrior, precPrior, q); //xF = GaussianOp_Laplace.SampleAverageConditional(xB, meanPrior, precPrior, q); xF = Gaussian.FromMeanAndPrecision(mean, r0); xB = IsPositiveOp.XAverageConditional(true, xF); Console.WriteLine("xF = {0} xB = {1}", xF, xB); } Console.WriteLine("x = {0} should be {1}", xF * xB, xExpected); double[] precs = EpTests.linspace(1e-3, 5, 100); double[] evTrue = new double[precs.Length]; double[] evApprox = new double[precs.Length]; double[] evApprox2 = new double[precs.Length]; //r0 = q.GetMean(); double sum = 0, sum2 = 0; for (int i = 0; i < precs.Length; i++) { double r = precs[i]; Gaussian xFt = Gaussian.FromMeanAndPrecision(mean, r); evTrue[i] = IsPositiveOp.LogAverageFactor(true, xFt) + precPrior.GetLogProb(r); evApprox[i] = IsPositiveOp.LogAverageFactor(true, xF) + precPrior.GetLogProb(r) + xB.GetLogAverageOf(xFt) - xB.GetLogAverageOf(xF); evApprox2[i] = IsPositiveOp.LogAverageFactor(true, xF) + precPrior.GetLogProb(r0) + q.GetLogProb(r) - q.GetLogProb(r0); sum += System.Math.Exp(evApprox[i]); sum2 += System.Math.Exp(evApprox2[i]); } Console.WriteLine("r0 = {0}: {1} {2} {3}", r0, sum, sum2, q.GetVariance() + System.Math.Pow(r0 - q.GetMean(), 2)); //TODO: change path for cross platform using using (var writer = new MatlabWriter(@"..\..\..\Tests\student.mat")) { writer.Write("z", evTrue); writer.Write("z2", evApprox); writer.Write("z3", evApprox2); writer.Write("precs", precs); } }
private static Gaussian GetConstrainedMessage1(Gaussian sample, Gaussian mean, Gamma precision, Gaussian to_sample) { Gaussian sampleMarginal = sample * to_sample; double m1, v1; to_sample.GetMeanAndVariance(out m1, out v1); double m, v; sampleMarginal.GetMeanAndVariance(out m, out v); double moment2 = m * m + v; // vq < moment2 implies 1/vq > 1/moment2 // implies 1/v2 > 1/moment2 - to_sample.Precision double v2max = 1 / (1 / moment2 - to_sample.Precision); double v2min = 1e-2; double[] v2s = EpTests.linspace(v2min, v2max, 100); double p2min = 1 / moment2 - to_sample.Precision; if (p2min < 0.0) { return(to_sample); } double p2max = sample.Precision * 10; double[] p2s = EpTests.linspace(p2min, p2max, 100); Gaussian bestResult = to_sample; double bestScore = double.PositiveInfinity; for (int i = 0; i < p2s.Length; i++) { double p2 = p2s[i]; double vq = 1 / (to_sample.Precision + p2); double m2 = (System.Math.Sqrt(moment2 - vq) / vq - to_sample.MeanTimesPrecision) / p2; // check double mq = vq * (to_sample.MeanTimesPrecision + m2 * p2); Assert.True(MMath.AbsDiff(mq * mq + vq, moment2) < 1e-10); Gaussian sample2 = Gaussian.FromMeanAndPrecision(m2, p2); Gaussian result = GaussianOp.SampleAverageConditional_slow(sample2, mean, precision); double score = System.Math.Abs(result.MeanTimesPrecision); if (score < bestScore) { bestScore = score; bestResult = result; } } return(bestResult); }
public void QuantileTest() { // draw many samples from N(m,v) Rand.Restart(0); int n = 10000; double m = 2; double stddev = 3; Gaussian prior = new Gaussian(m, stddev * stddev); List <double> x = new List <double>(); for (int i = 0; i < n; i++) { x.Add(prior.Sample()); } x.Sort(); var sortedData = new OuterQuantiles(x.ToArray()); // compute quantiles var quantiles = InnerQuantiles.FromDistribution(100, sortedData); // loop over x's and compare true quantile rank var testPoints = EpTests.linspace(MMath.Min(x) - stddev, MMath.Max(x) + stddev, 100); double maxError = 0; foreach (var testPoint in testPoints) { var trueRank = MMath.NormalCdf((testPoint - m) / stddev); var estRank = quantiles.GetProbLessThan(testPoint); var error = System.Math.Abs(trueRank - estRank); //Trace.WriteLine($"{testPoint} trueRank={trueRank} estRank={estRank} error={error}"); Assert.True(error < 0.02); maxError = System.Math.Max(maxError, error); double estQuantile = quantiles.GetQuantile(estRank); error = MMath.AbsDiff(estQuantile, testPoint, 1e-8); //Trace.WriteLine($"{testPoint} estRank={estRank} estQuantile={estQuantile} error={error}"); Assert.True(error < 1e-8); estRank = sortedData.GetProbLessThan(testPoint); error = System.Math.Abs(trueRank - estRank); //Trace.WriteLine($"{testPoint} trueRank={trueRank} estRank={estRank} error={error}"); Assert.True(error < 0.02); } //Trace.WriteLine($"max rank error = {maxError}"); }
private static double Integrate(Func <double, double> func) { double sum = 0; var ts = EpTests.linspace(0, 1, 100000); double inc = ts[1] - ts[0]; for (int i = 0; i < ts.Length; i++) { double t = ts[i]; double term = func(t); if (i == 0 || i == ts.Length - 1) { term /= 2; } sum += term * inc; } return(sum); }
private void CheckProbLessThan(CanGetProbLessThan canGetProbLessThan, List <double> x, double maximumError) { x.Sort(); var sortedData = new OuterQuantiles(x.ToArray()); // check that quantiles match within the desired accuracy var min = MMath.Min(x); var max = MMath.Max(x); var range = max - min; var margin = range * 0.01; var testPoints = EpTests.linspace(min - margin, max + margin, 100); double maxError = 0; foreach (var testPoint in testPoints) { var trueRank = sortedData.GetProbLessThan(testPoint); var estRank = canGetProbLessThan.GetProbLessThan(testPoint); var error = System.Math.Abs(trueRank - estRank); maxError = System.Math.Max(maxError, error); } Console.WriteLine($"max rank error = {maxError}"); Assert.True(maxError <= maximumError); }
internal void StudentIsPositiveTest2() { GaussianOp.ForceProper = false; double shape = 1; double mean = -1; Gamma precPrior = Gamma.FromShapeAndRate(shape, shape); Gaussian meanPrior = Gaussian.PointMass(mean); double evExpected; Gaussian xExpected = StudentIsPositiveExact(mean, precPrior, out evExpected); Gaussian xF2 = Gaussian.FromMeanAndVariance(-1, 1); // the energy has a stationary point here (min in both dimensions), even though xF0 is improper Gaussian xB0 = new Gaussian(2, 1); xF2 = Gaussian.FromMeanAndVariance(-4.552, 6.484); //xB0 = new Gaussian(1.832, 0.9502); //xB0 = new Gaussian(1.792, 1.558); //xB0 = new Gaussian(1.71, 1.558); //xB0 = new Gaussian(1.792, 1.5); Gaussian xF0 = GaussianOp_Slow.SampleAverageConditional(xB0, meanPrior, precPrior); //Console.WriteLine("xB0 = {0} xF0 = {1}", xB0, xF0); //Console.WriteLine(xF0*xB0); //Console.WriteLine(xF2*xB0); xF2 = new Gaussian(0.8651, 1.173); xB0 = new Gaussian(-4, 2); xB0 = new Gaussian(7, 7); if (false) { xF2 = new Gaussian(mean, 1); double[] xs = EpTests.linspace(0, 100, 1000); double[] logTrue = Util.ArrayInit(xs.Length, i => GaussianOp.LogAverageFactor(xs[i], mean, precPrior)); Normalize(logTrue); xF2 = FindxF4(xs, logTrue, xF2); xF2 = Gaussian.FromNatural(-0.85, 0); xB0 = IsPositiveOp.XAverageConditional(true, xF2); Console.WriteLine("xF = {0} xB = {1}", xF2, xB0); Console.WriteLine("x = {0} should be {1}", xF2 * xB0, xExpected); Console.WriteLine("proj[T*xB] = {0}", GaussianOp_Slow.SampleAverageConditional(xB0, meanPrior, precPrior) * xB0); double ev = System.Math.Exp(IsPositiveOp.LogAverageFactor(true, xF2) + GaussianOp_Slow.LogAverageFactor(xB0, meanPrior, precPrior) - xF2.GetLogAverageOf(xB0)); Console.WriteLine("evidence = {0} should be {1}", ev, evExpected); return; } if (false) { xF2 = new Gaussian(mean, 1); xF2 = FindxF3(xExpected, evExpected, meanPrior, precPrior, xF2); xB0 = IsPositiveOp.XAverageConditional(true, xF2); Console.WriteLine("xF = {0} xB = {1}", xF2, xB0); Console.WriteLine("x = {0} should be {1}", xF2 * xB0, xExpected); //double ev = Math.Exp(IsPositiveOp.LogAverageFactor(true, xF2) + GaussianOp.LogAverageFactor_slow(xB0, meanPrior, precPrior) - xF2.GetLogAverageOf(xB0)); //Console.WriteLine("evidence = {0} should be {1}", ev, evExpected); return; } if (false) { xF2 = new Gaussian(-2, 10); xF2 = FindxF2(meanPrior, precPrior, xF2); xB0 = IsPositiveOp.XAverageConditional(true, xF2); xF0 = GaussianOp_Slow.SampleAverageConditional(xB0, meanPrior, precPrior); Console.WriteLine("xB = {0}", xB0); Console.WriteLine("xF = {0} should be {1}", xF0, xF2); return; } if (false) { xF2 = new Gaussian(-3998, 4000); xF2 = new Gaussian(0.8651, 1.173); xB0 = new Gaussian(-4, 2); xB0 = new Gaussian(2000, 1e-5); xB0 = FindxB(xB0, meanPrior, precPrior, xF2); xF0 = GaussianOp_Slow.SampleAverageConditional(xB0, meanPrior, precPrior); Console.WriteLine("xB = {0}", xB0); Console.WriteLine("xF = {0} should be {1}", xF0, xF2); return; } if (false) { //xF2 = new Gaussian(-7, 10); //xF2 = new Gaussian(-50, 52); xB0 = new Gaussian(-1.966, 5.506e-08); //xF2 = new Gaussian(-3998, 4000); xF0 = FindxF(xB0, meanPrior, precPrior, xF2); Gaussian xB2 = IsPositiveOp.XAverageConditional(true, xF0); Console.WriteLine("xF = {0}", xF0); Console.WriteLine("xB = {0} should be {1}", xB2, xB0); return; } if (true) { xF0 = new Gaussian(-3.397e+08, 5.64e+08); xF0 = new Gaussian(-2.373e+04, 2.8e+04); xB0 = new Gaussian(2.359, 1.392); xF0 = Gaussian.FromNatural(-0.84, 0); //xF0 = Gaussian.FromNatural(-0.7, 0); for (int iter = 0; iter < 10; iter++) { xB0 = FindxB(xB0, meanPrior, precPrior, xF0); Gaussian xFt = GaussianOp_Slow.SampleAverageConditional(xB0, meanPrior, precPrior); Console.WriteLine("xB = {0}", xB0); Console.WriteLine("xF = {0} should be {1}", xFt, xF0); xF0 = FindxF0(xB0, meanPrior, precPrior, xF0); Gaussian xBt = IsPositiveOp.XAverageConditional(true, xF0); Console.WriteLine("xF = {0}", xF0); Console.WriteLine("xB = {0} should be {1}", xBt, xB0); } Console.WriteLine("x = {0} should be {1}", xF0 * xB0, xExpected); double ev = System.Math.Exp(IsPositiveOp.LogAverageFactor(true, xF0) + GaussianOp_Slow.LogAverageFactor(xB0, meanPrior, precPrior) - xF0.GetLogAverageOf(xB0)); Console.WriteLine("evidence = {0} should be {1}", ev, evExpected); return; } //var precs = EpTests.linspace(1e-6, 1e-5, 200); var precs = EpTests.linspace(xB0.Precision / 11, xB0.Precision, 100); //var precs = EpTests.linspace(xF0.Precision/20, xF0.Precision/3, 100); precs = EpTests.linspace(1e-9, 1e-5, 100); //precs = new double[] { xB0.Precision }; var ms = EpTests.linspace(xB0.GetMean() - 1, xB0.GetMean() + 1, 100); //var ms = EpTests.linspace(xF0.GetMean()-1, xF0.GetMean()+1, 100); //precs = EpTests.linspace(1.0/10, 1.0/8, 200); ms = EpTests.linspace(2000, 4000, 100); //ms = new double[] { xB0.GetMean() }; Matrix result = new Matrix(precs.Length, ms.Length); Matrix result2 = new Matrix(precs.Length, ms.Length); //ms = new double[] { 0.7 }; for (int j = 0; j < ms.Length; j++) { double maxZ = double.NegativeInfinity; double minZ = double.PositiveInfinity; Gaussian maxxF = Gaussian.Uniform(); Gaussian minxF = Gaussian.Uniform(); Gaussian maxxB = Gaussian.Uniform(); Gaussian minxB = Gaussian.Uniform(); Vector v = Vector.Zero(3); for (int i = 0; i < precs.Length; i++) { Gaussian xF = Gaussian.FromMeanAndPrecision(ms[j], precs[i]); xF = xF2; Gaussian xB = IsPositiveOp.XAverageConditional(true, xF); xB = Gaussian.FromMeanAndPrecision(ms[j], precs[i]); //xB = xB0; v[0] = IsPositiveOp.LogAverageFactor(true, xF); v[1] = GaussianOp.LogAverageFactor_slow(xB, meanPrior, precPrior); //v[1] = GaussianOp_Slow.LogAverageFactor(xB, meanPrior, precPrior); v[2] = -xF.GetLogAverageOf(xB); double logZ = v.Sum(); double Z = logZ; if (Z > maxZ) { maxZ = Z; maxxF = xF; maxxB = xB; } if (Z < minZ) { minZ = Z; minxF = xF; minxB = xB; } result[i, j] = Z; result2[i, j] = IsPositiveOp.LogAverageFactor(true, xF) + xF0.GetLogAverageOf(xB) - xF.GetLogAverageOf(xB); //Gaussian xF3 = GaussianOp.SampleAverageConditional_slower(xB, meanPrior, precPrior); //result[i, j] = Math.Pow(xF3.Precision - xF.Precision, 2); //result2[i, j] = Math.Pow((xF2*xB).Precision - (xF*xB).Precision, 2); //result2[i, j] = -xF.GetLogAverageOf(xB); //Gaussian xF2 = GaussianOp.SampleAverageConditional_slow(xB, Gaussian.PointMass(0), precPrior); Gaussian xMarginal = xF * xB; //Console.WriteLine("xF = {0} Z = {1} x = {2}", xF, Z.ToString("g4"), xMarginal); } double delta = v[1] - v[2]; //Console.WriteLine("xF = {0} xB = {1} maxZ = {2} x = {3}", maxxF, maxxB, maxZ.ToString("g4"), maxxF*maxxB); //Console.WriteLine("xF = {0} maxZ = {1} delta = {2}", maxxF, maxZ.ToString("g4"), delta.ToString("g4")); Console.WriteLine("xF = {0} xB = {1} minZ = {2} x = {3}", minxF, minxB, minZ.ToString("g4"), minxF * minxB); } //TODO: change path for cross platform using using (var writer = new MatlabWriter(@"..\..\..\Tests\student.mat")) { writer.Write("z", result); writer.Write("z2", result2); writer.Write("precs", precs); writer.Write("ms", ms); } }