Beispiel #1
0
        /// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="InnerProductOpBase"]/message_doc[@name="AAverageConditional(Gaussian, Vector, DenseVector, PositiveDefiniteMatrix, VectorGaussian)"]/*'/>
        public static VectorGaussian AAverageConditional([SkipIfUniform] Gaussian innerProduct, Vector A, DenseVector BMean, PositiveDefiniteMatrix BVariance, VectorGaussian result)
        {
            if (innerProduct.IsUniform())
            {
                return(VectorGaussian.Uniform(A.Count));
            }
            // logZ = log N(mProduct; A'*BMean, vProduct + A'*BVariance*A)
            //      = -0.5 (mProduct - A'*BMean)^2 / (vProduct + A'*BVariance*A) -0.5 log(vProduct + A'*BVariance*A)
            // v*innerProduct.Precision
            double v    = 1 + BVariance.QuadraticForm(A, A) * innerProduct.Precision;
            double diff = innerProduct.MeanTimesPrecision - A.Inner(BMean) * innerProduct.Precision;
            // dlogZ/dA = BMean * (mProduct - A'*BMean)/v + (BVariance*A) (diff)^2 / v^2 - (BVariance*A)/v
            double diff2   = diff * diff;
            double v2      = v * v;
            var    avb     = BVariance * A;
            var    avbPrec = avb * innerProduct.Precision;
            var    dlogZ   = (BMean * diff - avbPrec) / v + avb * diff2 / v2;
            // -ddlogZ/dA^2 = (BMean.Outer(BMean) + BVariance) / v + avb.Outer(avb) * (4 * diff2 / (v2 * v))
            //               -(avb.Outer(avb - BMean * (2 * diff)) * 2 + BVariance * diff2) / v2;
            PositiveDefiniteMatrix negativeHessian = BVariance * (innerProduct.Precision / v - diff2 / v2);

            negativeHessian.SetToSumWithOuter(negativeHessian, innerProduct.Precision / v, BMean, BMean);
            negativeHessian.SetToSumWithOuter(negativeHessian, 4 * diff2 / (v2 * v) - 2 * innerProduct.Precision / v2, avb, avbPrec);
            negativeHessian.SetToSumWithOuter(negativeHessian, 2 * diff / v2, avbPrec, BMean);
            negativeHessian.SetToSumWithOuter(negativeHessian, 2 * diff / v2, BMean, avbPrec);
            negativeHessian.Symmetrize();
            return(VectorGaussian.FromDerivatives(A, dlogZ, negativeHessian, GaussianProductOp.ForceProper));
        }
Beispiel #2
0
 private static void GetProductMoments(Matrix A, Vector BMean, PositiveDefiniteMatrix BVariance, Vector mean, PositiveDefiniteMatrix variance)
 {
     // P.mean = A*B.mean
     // P.var = A*B.var*A'
     mean.SetToProduct(A, BMean);
     if (UseAccurateMethod)
     {
         int dim = BVariance.Rows;
         LowerTriangularMatrix cholesky = new LowerTriangularMatrix(dim, dim);
         cholesky.SetToCholesky(BVariance);
         Matrix AL = A * cholesky;
         variance.SetToOuter(AL);
     }
     else
     {
         variance.SetToProduct(A, (A * BVariance).Transpose());
         variance.Symmetrize();
     }
 }