예제 #1
0
        // 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);
            }
        }
예제 #2
0
        // 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);
            }
        }
예제 #3
0
		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);
		}
예제 #4
0
        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);
        }
예제 #5
0
		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);
		}