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