/// <summary>
        /// VMP message to 'a'
        /// </summary>
        /// <param name="Product">Incoming message from 'product'. Must be a proper distribution.  If uniform, the result will be uniform.</param>
        /// <param name="B">Incoming message from 'b'. Must be a proper distribution.  If uniform, the result will be uniform.</param>
        /// <returns>The outgoing VMP message to the 'a' argument</returns>
        /// <remarks><para>
        /// The outgoing message is the exponential of the average log-factor value, where the average is over all arguments except 'a'.
        /// Because the factor is deterministic, 'product' is integrated out before taking the logarithm.
        /// The formula is <c>exp(sum_(b) p(b) log(sum_product p(product) factor(product,a,b)))</c>.
        /// </para></remarks>
        /// <exception cref="ImproperMessageException"><paramref name="Product"/> is not a proper distribution</exception>
        /// <exception cref="ImproperMessageException"><paramref name="B"/> is not a proper distribution</exception>
        public static Gaussian AAverageLogarithm([SkipIfUniform] Gaussian Product, [Proper] Gamma B)
        {
            if (B.IsPointMass)
            {
                return(GaussianProductVmpOp.AAverageLogarithm(Product, B.Point));
            }
            if (Product.IsPointMass)
            {
                return(AAverageLogarithm(Product.Point, B));
            }
            if (!B.IsProper())
            {
                throw new ImproperMessageException(B);
            }
            double mb, vb;

            B.GetMeanAndVariance(out mb, out vb);
            // catch uniform case to avoid 0*Inf
            if (Product.IsUniform())
            {
                return(Product);
            }
            Gaussian result = new Gaussian();

            result.Precision          = Product.Precision * (vb + mb * mb);
            result.MeanTimesPrecision = Product.MeanTimesPrecision * mb;
            return(result);
        }
Пример #2
0
        /// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="ProductGaussianBetaVmpOp"]/message_doc[@name="AAverageLogarithm(Gaussian, Beta)"]/*'/>
        public static Gaussian AAverageLogarithm([SkipIfUniform] Gaussian Product, [Proper] Beta B)
        {
            if (B.IsPointMass)
            {
                return(GaussianProductVmpOp.AAverageLogarithm(Product, B.Point));
            }
            if (Product.IsPointMass)
            {
                return(AAverageLogarithm(Product.Point, B));
            }
            double mb, vb;

            B.GetMeanAndVariance(out mb, out vb);
            Gaussian result = new Gaussian();

            result.Precision          = Product.Precision * (vb + mb * mb);
            result.MeanTimesPrecision = Product.MeanTimesPrecision * mb;
            return(result);
        }
        public void ProductOpTest()
        {
            Assert.True(GaussianProductVmpOp.ProductAverageLogarithm(
                            2.0,
                            Gaussian.FromMeanAndVariance(3.0, 5.0)).MaxDiff(Gaussian.FromMeanAndVariance(2 * 3, 4 * 5)) < 1e-8);
            Assert.True(GaussianProductOp.ProductAverageConditional(
                            2.0,
                            Gaussian.FromMeanAndVariance(3.0, 5.0)).MaxDiff(Gaussian.FromMeanAndVariance(2 * 3, 4 * 5)) < 1e-8);
            Assert.True(GaussianProductOp.ProductAverageConditional(new Gaussian(0, 1),
                                                                    Gaussian.PointMass(2.0),
                                                                    Gaussian.FromMeanAndVariance(3.0, 5.0)).MaxDiff(Gaussian.FromMeanAndVariance(2 * 3, 4 * 5)) < 1e-8);
            Assert.True(GaussianProductVmpOp.ProductAverageLogarithm(
                            0.0,
                            Gaussian.FromMeanAndVariance(3.0, 5.0)).MaxDiff(Gaussian.PointMass(0.0)) < 1e-8);
            Assert.True(GaussianProductOp.ProductAverageConditional(
                            0.0,
                            Gaussian.FromMeanAndVariance(3.0, 5.0)).MaxDiff(Gaussian.PointMass(0.0)) < 1e-8);
            Assert.True(GaussianProductOp.ProductAverageConditional(new Gaussian(0, 1),
                                                                    Gaussian.PointMass(0.0),
                                                                    Gaussian.FromMeanAndVariance(3.0, 5.0)).MaxDiff(Gaussian.PointMass(0.0)) < 1e-8);

            Assert.True(GaussianProductVmpOp.ProductAverageLogarithm(
                            Gaussian.FromMeanAndVariance(2, 4),
                            Gaussian.FromMeanAndVariance(3, 5)).MaxDiff(Gaussian.FromMeanAndVariance(2 * 3, 4 * 5 + 3 * 3 * 4 + 2 * 2 * 5)) < 1e-8);
            Assert.True(GaussianProductOp.ProductAverageConditional(Gaussian.Uniform(),
                                                                    Gaussian.FromMeanAndVariance(2, 4),
                                                                    Gaussian.FromMeanAndVariance(3, 5)).MaxDiff(Gaussian.FromMeanAndVariance(2 * 3, 4 * 5 + 3 * 3 * 4 + 2 * 2 * 5)) <
                        1e-8);
            Assert.True(GaussianProductOp.ProductAverageConditional(Gaussian.FromMeanAndVariance(0, 1e16),
                                                                    Gaussian.FromMeanAndVariance(2, 4),
                                                                    Gaussian.FromMeanAndVariance(3, 5)).MaxDiff(Gaussian.FromMeanAndVariance(2 * 3, 4 * 5 + 3 * 3 * 4 + 2 * 2 * 5)) <
                        1e-4);

            Assert.True(GaussianProductOp.AAverageConditional(6.0, 2.0)
                        .MaxDiff(Gaussian.PointMass(6.0 / 2.0)) < 1e-8);
            Assert.True(GaussianProductOp.AAverageConditional(6.0, new Gaussian(1, 3), Gaussian.PointMass(2.0))
                        .MaxDiff(Gaussian.PointMass(6.0 / 2.0)) < 1e-8);
            Assert.True(GaussianProductOp.AAverageConditional(0.0, 0.0).IsUniform());
            Assert.True(GaussianProductOp.AAverageConditional(Gaussian.Uniform(), 2.0).IsUniform());
            Assert.True(GaussianProductOp.AAverageConditional(Gaussian.Uniform(), new Gaussian(1, 3), Gaussian.PointMass(2.0)).IsUniform());
            Assert.True(GaussianProductOp.AAverageConditional(Gaussian.Uniform(), new Gaussian(1, 3), new Gaussian(2, 4)).IsUniform());

            Gaussian aPrior = Gaussian.FromMeanAndVariance(0.0, 1000.0);

            Assert.True((GaussianProductOp.AAverageConditional(
                             Gaussian.FromMeanAndVariance(10.0, 1.0),
                             aPrior,
                             Gaussian.FromMeanAndVariance(5.0, 1.0)) * aPrior).MaxDiff(
                            Gaussian.FromMeanAndVariance(2.208041421368822, 0.424566765678152)) < 1e-4);

            Gaussian g = new Gaussian(0, 1);

            Assert.True(GaussianProductOp.AAverageConditional(g, 0.0).IsUniform());
            Assert.True(GaussianProductOp.AAverageConditional(0.0, 0.0).IsUniform());
            Assert.True(GaussianProductVmpOp.AAverageLogarithm(g, 0.0).IsUniform());
            Assert.True(Gaussian.PointMass(3.0).MaxDiff(GaussianProductVmpOp.AAverageLogarithm(6.0, 2.0)) < 1e-10);
            Assert.True(GaussianProductVmpOp.AAverageLogarithm(0.0, 0.0).IsUniform());
            try
            {
                Assert.True(GaussianProductVmpOp.AAverageLogarithm(6.0, g).IsUniform());
                Assert.True(false, "Did not throw NotSupportedException");
            }
            catch (NotSupportedException)
            {
            }
            try
            {
                g = GaussianProductOp.AAverageConditional(12.0, 0.0);
                Assert.True(false, "Did not throw AllZeroException");
            }
            catch (AllZeroException)
            {
            }
            try
            {
                g = GaussianProductVmpOp.AAverageLogarithm(12.0, 0.0);
                Assert.True(false, "Did not throw AllZeroException");
            }
            catch (AllZeroException)
            {
            }
        }