/// <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); }
/// <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) { } }