/// <summary>
		/// Evidence message for EP
		/// </summary>
		/// <param name="concat">Constant value for 'concat'.</param>
		/// <param name="first">Incoming message from 'first'.</param>
		/// <param name="second">Incoming message from 'second'.</param>
		/// <returns>Logarithm of the factor's average value across the given argument distributions</returns>
		/// <remarks><para>
		/// The formula for the result is <c>log(sum_(first,second) p(first,second) factor(concat,first,second))</c>.
		/// </para></remarks>
		public static double LogAverageFactor(Vector concat, VectorGaussian first, VectorGaussian second)
		{
			Vector concat1 = Vector.Subvector(concat, 0, first.Dimension);
			Vector concat2 = Vector.Subvector(concat, first.Dimension, second.Dimension);
			return first.GetLogProb(concat1) + second.GetLogProb(concat2);
		}
		/// <summary>
		/// Evidence message for EP
		/// </summary>
		/// <param name="concat">Constant value for 'concat'.</param>
		/// <param name="first">Constant value for 'first'.</param>
		/// <param name="second">Incoming message from 'second'.</param>
		/// <returns>Logarithm of the factor's average value across the given argument distributions</returns>
		/// <remarks><para>
		/// The formula for the result is <c>log(sum_(second) p(second) factor(concat,first,second))</c>.
		/// </para></remarks>
		public static double LogAverageFactor(Vector concat, Vector first, VectorGaussian second)
		{
			for (int i = 0; i < first.Count; i++) {
				if (concat[i] != first[i]) return Double.NegativeInfinity;
			}
			Vector concat2 = Vector.Subvector(concat, first.Count, second.Dimension);
			return second.GetLogProb(concat2);
		}
		/// <summary>
		/// Evidence message for EP
		/// </summary>
		/// <param name="concat">Incoming message from 'concat'.</param>
		/// <param name="first">Constant value for 'first'.</param>
		/// <param name="second">Constant value for 'second'.</param>
		/// <returns>Logarithm of the factor's average value across the given argument distributions</returns>
		/// <remarks><para>
		/// The formula for the result is <c>log(sum_(concat) p(concat) factor(concat,first,second))</c>.
		/// </para></remarks>
		public static double LogAverageFactor(VectorGaussian concat, Vector first, Vector second)
		{
			return concat.GetLogProb(Vector.Concat(first, second));
		}
		/// <summary>
		/// Evidence message for EP
		/// </summary>
		/// <param name="concat">Constant value for 'concat'.</param>
		/// <param name="first">Incoming message from 'first'.</param>
		/// <param name="second">Constant value for 'second'.</param>
		/// <returns>Logarithm of the factor's average value across the given argument distributions</returns>
		/// <remarks><para>
		/// The formula for the result is <c>log(sum_(first) p(first) factor(concat,first,second))</c>.
		/// </para></remarks>
		public static double LogAverageFactor(Vector concat, VectorGaussian first, Vector second)
		{
			int dim1 = first.Dimension;
			for (int i = 0; i < second.Count; i++) {
				if (concat[i + dim1] != second[i]) return Double.NegativeInfinity;
			}
			Vector concat1 = Vector.Subvector(concat, 0, first.Dimension);
			return first.GetLogProb(concat1);
		}
Пример #5
0
        /// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="MatrixVectorProductOp"]/message_doc[@name="LogAverageFactor(Vector, Matrix, VectorGaussian, Vector, PositiveDefiniteMatrix)"]/*'/>
        public static double LogAverageFactor(Vector product, Matrix A, VectorGaussian B, Vector BMean, PositiveDefiniteMatrix BVariance)
        {
            VectorGaussian toProduct = ProductAverageConditional(A, BMean, BVariance, new VectorGaussian(A.Rows));

            return(toProduct.GetLogProb(product));
        }
Пример #6
0
        /// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="MatrixVectorProductOp"]/message_doc[@name="AAverageConditional(VectorGaussian, DistributionArray2D{Gaussian, double}, Vector, PositiveDefiniteMatrix, DistributionStructArray2D{Gaussian, double})"]/*'/>
        public static DistributionStructArray2D <Gaussian, double> AAverageConditional([SkipIfUniform] VectorGaussian product, DistributionArray2D <Gaussian, double> A, Vector BMean, PositiveDefiniteMatrix BVariance, DistributionStructArray2D <Gaussian, double> result)
        {
            if (product.IsUniform())
            {
                result.SetToUniform();
                return(result);
            }
            if (!A.IsPointMass)
            {
                throw new ArgumentException("A is not a point mass");
            }
            // logZ = log N(mProduct; A*BMean, vProduct + A*BVariance*A')
            //      = -0.5 (mProduct - A*BMean)' inv(vProduct + A*BVariance*A') (mProduct - A*BMean) - 0.5 logdet(vProduct + A*BVariance*A')
            //      = -0.5 (mProduct - A*BMean)' pProduct inv(pProduct + pProduct*A*BVariance*A'*pProduct) pProduct (mProduct - A*BMean)
            //        - 0.5 logdet(pProduct + pProduct*A*BVariance*A'*pProduct) + logdet(pProduct)
            // dlogZ   = 0.5 (dA*BMean)' pProduct inv(pProduct + pProduct*A*BVariance*A'*pProduct) pProduct (mProduct - A*BMean)
            //         +0.5 (mProduct - A*BMean)' pProduct inv(pProduct + pProduct*A*BVariance*A'*pProduct) pProduct (dA*BMean)
            //         +0.5 (mProduct - A*BMean)' pProduct inv(pProduct + pProduct*A*BVariance*A'*pProduct) (pProduct*dA*BVariance*A'*pProduct + pProduct*A*BVariance*dA'*pProduct) inv(pProduct + pProduct*A*BVariance*A'*pProduct) pProduct (mProduct - A*BMean)
            //         - 0.5 tr(inv(pProduct + pProduct*A*BVariance*A'*pProduct) (pProduct*dA*BVariance*A'*pProduct + pProduct*A*BVariance*dA'*pProduct))
            // dlogZ/dA = pProduct inv(pProduct + pProduct*A*BVariance*A'*pProduct) pProduct (mProduct - A*BMean) BMean'
            //          + pProduct inv(pProduct + pProduct*A*BVariance*A'*pProduct) pProduct (mProduct - A*BMean) (mProduct - A*BMean)' pProduct inv(pProduct + pProduct*A*BVariance*A'*pProduct) pProduct*A*BVariance
            //          - pProduct inv(pProduct + pProduct*A*BVariance*A'*pProduct) pProduct A*BVariance
            var Amatrix                 = new Matrix(A.Point);
            var pProductA               = product.Precision * Amatrix;
            var pProductABV             = pProductA * BVariance;
            PositiveDefiniteMatrix prec = new PositiveDefiniteMatrix(product.Dimension, product.Dimension);

            prec.SetToSum(product.Precision, pProductABV * pProductA.Transpose());
            // pProductA is now free
            for (int i = 0; i < prec.Rows; i++)
            {
                if (prec[i, i] == 0)
                {
                    prec[i, i] = 1;
                }
            }
            var v           = prec.Inverse();
            var ABM         = Amatrix * BMean;
            var pProductABM = product.Precision * ABM;
            var diff        = pProductABM;

            diff.SetToDifference(product.MeanTimesPrecision, pProductABM);
            // ABM is now free
            var pProductV     = product.Precision * v;
            var pProductVdiff = ABM;

            pProductVdiff.SetToProduct(pProductV, diff);
            var Vdiff = v * diff;

            pProductV.Scale(-1);
            pProductV.SetToSumWithOuter(pProductV, 1, pProductVdiff, Vdiff);
            Matrix dlogZ = pProductA;

            dlogZ.SetToProduct(pProductV, pProductABV);
            dlogZ.SetToSumWithOuter(dlogZ, 1, pProductVdiff, BMean);
            int rows = A.GetLength(0);
            int cols = A.GetLength(1);

            for (int i = 0; i < rows; i++)
            {
                for (int j = 0; j < cols; j++)
                {
                    double dlogp = dlogZ[i, j];
                    // for now, we don't compute the second derivative.
                    double ddlogp = -1;
                    result[i, j] = Gaussian.FromDerivatives(A[i, j].Point, dlogp, ddlogp, false);

                    bool check = false;
                    if (check)
                    {
                        double logZ(Matrix m)
                        {
                            var vgm = ProductAverageConditional(m, BMean, BVariance, new VectorGaussianMoments(m.Rows));

                            return(VectorGaussian.GetLogProb(product.GetMean(), vgm.Mean, product.GetVariance() + vgm.Variance));
                        }

                        var    Amatrix2 = (Matrix)Amatrix.Clone();
                        double delta    = 1e-4;
                        Amatrix2[i, j] += delta;
                        double dlogp2 = (logZ(Amatrix2) - logZ(Amatrix)) / delta;
                        if (MMath.AbsDiff(dlogp, dlogp2, 1e-10) > 1e-5)
                        {
                            throw new Exception();
                        }
                    }
                }
            }
            return(result);
        }
Пример #7
0
 /// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="ConcatOp"]/message_doc[@name="LogAverageFactor(VectorGaussian, Vector, Vector)"]/*'/>
 public static double LogAverageFactor(VectorGaussian concat, Vector first, Vector second)
 {
     return(concat.GetLogProb(Vector.Concat(first, second)));
 }