// Commented out since this test is very slow and does not have any assertions //[Fact] internal void GaussianFromMeanAndVarianceVaryTruePrec() { double mean = 2.0; var Nvar = Variable.Observed <int>(50); var n = new Range(Nvar); var noisePrecision = 10; var variancePriors = new double[] { 1, 5, 10 }.Select(i => Gamma.FromShapeAndRate(i, i)).ToArray(); var varPriorVar = Variable.Observed(new Gamma()); var variance_EP = Variable <double> .Random(varPriorVar); var x_ep = GaussianFromMeanAndVarianceSampleSizeModel(variance_EP, n, true, noisePrecision); var ie_EP = new InferenceEngine(); ie_EP.ShowWarnings = false; ie_EP.ShowProgress = false; var ev = Variable.Bernoulli(.5); var modelBlock = Variable.If(ev); var variance_MC = Variable <double> .Random(varPriorVar); var x_mc = GaussianFromMeanAndVarianceSampleSizeModel(variance_MC, n, true, noisePrecision); modelBlock.CloseBlock(); var ie_MC = new InferenceEngine(); ie_MC.ShowWarnings = false; ie_MC.ShowProgress = false; var precision_VMP = Variable.GammaFromShapeAndRate(1, 1); var x_vmp = GaussianFromMeanAndVarianceSampleSizeModel(precision_VMP, n, false, noisePrecision); var ie_VMP = new InferenceEngine(new VariationalMessagePassing()); ie_VMP.ShowWarnings = false; ie_VMP.ShowProgress = false; var ie_EP_prec = new InferenceEngine(); ie_EP_prec.ShowWarnings = false; ie_EP_prec.ShowProgress = false; Console.WriteLine("var " + variancePriors.Select(i => "EP" + i.Shape).Aggregate((i, j) => i + " " + j) + " " + variancePriors.Select(i => "MC" + i.Shape).Aggregate((i, j) => i + " " + j) + " EPp VMP EMP"); for (int j = 0; j < 10; j++) { Rand.Restart(2); //int N = (int)Math.Pow(10, j + 1); double variance = System.Math.Exp(-5 + j); var data = Enumerable.Range(0, Nvar.ObservedValue).Select(i => Gaussian.Sample(mean, 1.0 / variance) + Gaussian.Sample(0, noisePrecision)).ToArray(); x_ep.ObservedValue = data; x_mc.ObservedValue = data; x_vmp.ObservedValue = data; var epMeans = variancePriors.Select(i => { double res = double.NaN; varPriorVar.ObservedValue = i; try { res = ie_EP.Infer <Gamma>(variance_EP).GetMean(); } catch { } ; return(res); }).ToArray(); var mcMeans = variancePriors.Select(p => { double varianceSample = 2; var ge = new GammaEstimator(); varPriorVar.ObservedValue = p; Converter <double, double> f = vari => { variance_MC.ObservedValue = vari; return(ie_MC.Infer <Bernoulli>(ev).LogOdds); }; int burnin = 1000, thin = 5, numSamples = 1000; var samples = new double[numSamples]; for (int i = 0; i < burnin; i++) { varianceSample = NonconjugateVMP2Tests.SliceSampleUnivariate(varianceSample, f, lower_bound: 0); } for (int i = 0; i < numSamples; i++) { for (int k = 0; k < thin; k++) { varianceSample = NonconjugateVMP2Tests.SliceSampleUnivariate(varianceSample, f, lower_bound: 0); } samples[i] = varianceSample; ge.Add(varianceSample); } return(samples.Sum() / numSamples); }).ToArray(); double epMean2 = double.NaN; try { epMean2 = ie_EP_prec.Infer <Gamma>(precision_VMP).GetMeanInverse(); } catch { } ; double vmpMean = ie_VMP.Infer <Gamma>(precision_VMP).GetMeanInverse(); var empiricalMean = data.Sum() / data.Length; var empVar = data.Sum(o => o * o) / data.Length - empiricalMean * empiricalMean; Console.Write("{0:G3} ", variance); foreach (var i in epMeans) { Console.Write("{0:G3} ", i); } foreach (var i in mcMeans) { Console.Write("{0:G3} ", i); } Console.WriteLine("{0:G3} {1:G3} {2:G3}", epMean2, vmpMean, empVar); } }
// Commented out since this test is very slow and does not have any assertions //[Fact] internal void GaussianFromMeanAndVarianceVaryNoise() { double mean = 2.0, variance = 2.0; var Nvar = Variable.Observed <int>(1); var n = new Range(Nvar); var noisePrecision = Variable.Array <double>(n); var variance_EP = Variable.GammaFromShapeAndRate(1, 1); var x_ep = GaussianPlusNoiseModel(variance_EP, n, true, noisePrecision); var ie_EP = new InferenceEngine(); ie_EP.ShowWarnings = false; ie_EP.ShowProgress = false; var ev = Variable.Bernoulli(.5); var modelBlock = Variable.If(ev); var variance_MC = Variable.GammaFromShapeAndRate(1, 1); var x_mc = GaussianPlusNoiseModel(variance_MC, n, true, noisePrecision); modelBlock.CloseBlock(); var ie_MC = new InferenceEngine(); ie_MC.ShowWarnings = false; ie_MC.ShowProgress = false; var precision_VMP = Variable.GammaFromShapeAndRate(1, 1); var x_vmp = GaussianPlusNoiseModel(precision_VMP, n, false, noisePrecision); var ie_VMP = new InferenceEngine(new VariationalMessagePassing()); ie_VMP.ShowWarnings = false; ie_VMP.ShowProgress = false; Console.WriteLine("N EP MC VMP EMP"); for (int j = 0; j < 10; j++) { Rand.Restart(2); //int N = (int)Math.Pow(10, j + 1); int N = 10 * (j + 1); var noiseP = Enumerable.Range(0, N).Select(i => { if (i % 3 == 0) { return(.1); } if (i % 3 == 1) { return(1); } else { return(10); } }).ToArray(); var data = noiseP.Select(i => Gaussian.Sample(mean, 1.0 / variance) + Gaussian.Sample(0, i)).ToArray(); Nvar.ObservedValue = N; noisePrecision.ObservedValue = noiseP; x_ep.ObservedValue = data; x_mc.ObservedValue = data; x_vmp.ObservedValue = data; double epMean = double.NaN; try { epMean = ie_EP.Infer <Gamma>(variance_EP).GetMean(); } catch { } ; double vmpMean = ie_VMP.Infer <Gamma>(precision_VMP).GetMeanInverse(); double varianceSample = 2; var ge = new GammaEstimator(); Converter <double, double> f = vari => { variance_MC.ObservedValue = vari; return(ie_MC.Infer <Bernoulli>(ev).LogOdds); }; int burnin = 1000, thin = 5, numSamples = 1000; var samples = new double[numSamples]; for (int i = 0; i < burnin; i++) { varianceSample = NonconjugateVMP2Tests.SliceSampleUnivariate(varianceSample, f, lower_bound: 0); } for (int i = 0; i < numSamples; i++) { for (int k = 0; k < thin; k++) { varianceSample = NonconjugateVMP2Tests.SliceSampleUnivariate(varianceSample, f, lower_bound: 0); } samples[i] = varianceSample; ge.Add(varianceSample); } double mcMean = samples.Sum() / numSamples; var empiricalMean = data.Sum() / data.Length; var empVar = data.Sum(o => o * o) / data.Length - empiricalMean * empiricalMean; Console.WriteLine(N + " " + epMean + " " + mcMean + " " + vmpMean + " " + empVar); } }
public static Gamma RateAverageConditional([SkipIfUniform] Gamma y, double shape, Gamma rate) { if (y.IsPointMass) return RateAverageConditional(y.Point, shape); // q(y) = y^(a1-1) exp(-b1 y) // q(b) = b^(a2-1) exp(-b2 b) // f(y,b) = y^(a-1) b^a exp(-by) // q(y) q(b) f(y,b) = y^(a+a1-2) b^(a+a2-1) exp(-b2 b - b1 y - b y) // int over y = b^(a+a2-1) exp(-b2 b) / (b + b1)^(a+a1-1) // this is dist of ratio Ga(a+1,1)/Ga(a1-2,1) times Ga(a2,b2) pdf double max = shape/y.GetMean()*10; int n = 1000; double inc = max/n; GammaEstimator est = new GammaEstimator(); for (int i = 0; i < n; i++) { double b = (i+1)*inc; double logp = (shape + rate.Shape - 1)*Math.Log(b) - b*rate.Rate - (shape + y.Shape - 1)*Math.Log(b + y.Rate); est.Add(b, Math.Exp(logp)); } Gamma post = est.GetDistribution(new Gamma()); //Console.WriteLine("y = {0}, shape = {1}, rate = {2}, post = {3}", y, shape, rate, post); return post / rate; //throw new NotSupportedException(NotSupportedMessage); }
private void GaussianFromMeanAndVarianceTest(double mm, double vm, double mx, double vx, double a, double b) { Variable <bool> evidence = Variable.Bernoulli(0.5).Named("evidence"); IfBlock block = Variable.If(evidence); Variable <double> mean = Variable.GaussianFromMeanAndVariance(mm, vm).Named("mean"); Variable <double> variance = Variable.GammaFromShapeAndRate(a, b).Named("variance"); Variable <double> x = Variable.GaussianFromMeanAndVariance(mean, variance).Named("x"); Variable.ConstrainEqualRandom(x, new Gaussian(mx, vx)); block.CloseBlock(); InferenceEngine engine = new InferenceEngine(); engine.Compiler.RecommendedQuality = QualityBand.Experimental; double evExpected; Gaussian xExpected; Gamma vExpected; if (a == 1 || a == 2) { double c = System.Math.Sqrt(2 * b); double m = c * (mx - mm); double v = c * c * (vx + vm); double Z, mu, m2u; VarianceGammaTimesGaussianMoments(a, m, v, out Z, out mu, out m2u); evExpected = System.Math.Log(Z * c); double vu = m2u - mu * mu; double r = Double.IsPositiveInfinity(vx) ? 1.0 : vx / (vx + vm); double mp = r * (mu / c + mm) + (1 - r) * mx; double vp = r * r * vu / (c * c) + r * vm; xExpected = new Gaussian(mp, vp); double Zplus1, Zplus2; VarianceGammaTimesGaussianMoments(a + 1, m, v, out Zplus1, out mu, out m2u); VarianceGammaTimesGaussianMoments(a + 2, m, v, out Zplus2, out mu, out m2u); double vmp = a / b * Zplus1 / Z; double vm2p = a * (a + 1) / (b * b) * Zplus2 / Z; double vvp = vm2p - vmp * vmp; vExpected = Gamma.FromMeanAndVariance(vmp, vvp); } else { int n = 1000000; GaussianEstimator est = new GaussianEstimator(); GammaEstimator vEst = new GammaEstimator(); Gaussian xLike = new Gaussian(mx, vx); for (int i = 0; i < n; i++) { double m = Gaussian.Sample(mm, 1 / vm); double v = Rand.Gamma(a) / b; double xSample = Gaussian.Sample(m, 1 / v); double weight = System.Math.Exp(xLike.GetLogProb(xSample)); est.Add(xSample, weight); vEst.Add(v, weight); } evExpected = System.Math.Log(est.mva.Count / n); xExpected = est.GetDistribution(new Gaussian()); vExpected = vEst.GetDistribution(new Gamma()); } double evActual = engine.Infer <Bernoulli>(evidence).LogOdds; Console.WriteLine("evidence = {0} should be {1}", evActual, evExpected); Gaussian xActual = engine.Infer <Gaussian>(x); Console.WriteLine("x = {0} should be {1}", xActual, xExpected); Gamma vActual = engine.Infer <Gamma>(variance); Console.WriteLine("variance = {0} should be {1}", vActual, vExpected); Assert.True(MMath.AbsDiff(evExpected, evActual, 1e-10) < 1e-4); Assert.True(xExpected.MaxDiff(xActual) < 1e-4); Assert.True(vExpected.MaxDiff(vActual) < 1e-4); }
public static Gamma YAverageConditional(Gamma y, double shape, [SkipIfUniform] Gamma rate) { if (rate.IsPointMass) return YAverageConditional(shape, rate.Point); // q(b) = b^(a2-1) exp(-b2 b) // f(y,b) = y^(a-1) b^a exp(-by) // q(b) f(y,b) = y^(a-1) b^(a+a2-1) exp(-b (y+b2)) // int over b = y^(a-1) / (y + b2)^(a+a2) = ratio of Ga(a,1)/Ga(a2,1/b2) double max = shape/rate.GetMean()*10; int n = 1000; double inc = max/n; GammaEstimator est = new GammaEstimator(); for (int i = 0; i < n; i++) { double x = (i+1)*inc; double logp = (shape + y.Shape - 2)*Math.Log(x) - x*y.Rate - (shape + rate.Shape)*Math.Log(x + rate.Rate); est.Add(x, Math.Exp(logp)); } Gamma post = est.GetDistribution(new Gamma()); return post / rate; //throw new NotSupportedException(NotSupportedMessage); }