/// <summary> /// EP message to 'second' /// </summary> /// <param name="concat">Incoming message from 'concat'. Must be a proper distribution. If any element is uniform, the result will be uniform.</param> /// <param name="first">Constant value for 'first'.</param> /// <param name="result">Modified to contain the outgoing message</param> /// <returns><paramref name="result"/></returns> /// <remarks><para> /// The outgoing message is a distribution matching the moments of 'second' as the random arguments are varied. /// The formula is <c>proj[p(second) sum_(concat) p(concat) factor(concat,first,second)]/p(second)</c>. /// </para></remarks> /// <exception cref="ImproperMessageException"><paramref name="concat"/> is not a proper distribution</exception> public static VectorGaussian SecondAverageConditional([SkipIfUniform] VectorGaussian concat, Vector first, VectorGaussian result) { // prec = concat.Precision[dim2,dim2] // meanTimesPrec = concat.MeanTimesPrecision[dim2] - concat.Precision[dim2,dim1]*first int dim1 = first.Count; int dim2 = result.Dimension; if (concat.Dimension != dim1 + dim2) throw new ArgumentException("concat.Dimension ("+concat.Dimension+") != first.Dimension ("+dim1+") + second.Dimension ("+dim2+")"); result.Precision.SetToSubmatrix(concat.Precision, dim1, dim1); Matrix prec21 = new Matrix(dim2, dim1); prec21.SetToSubmatrix(concat.Precision, dim1, 0); Vector prec21first = Vector.Zero(dim2); prec21first.SetToProduct(prec21, first); result.MeanTimesPrecision.SetToSubvector(concat.MeanTimesPrecision, dim1); result.MeanTimesPrecision.SetToDifference(result.MeanTimesPrecision, prec21first); return result; }
/// <summary> /// EP message to 'first' /// </summary> /// <param name="concat">Incoming message from 'concat'. Must be a proper distribution. If any element is uniform, the result will be uniform.</param> /// <param name="second">Constant value for 'second'.</param> /// <param name="result">Modified to contain the outgoing message</param> /// <returns><paramref name="result"/></returns> /// <remarks><para> /// The outgoing message is a distribution matching the moments of 'first' as the random arguments are varied. /// The formula is <c>proj[p(first) sum_(concat) p(concat) factor(concat,first,second)]/p(first)</c>. /// </para></remarks> /// <exception cref="ImproperMessageException"><paramref name="concat"/> is not a proper distribution</exception> public static VectorGaussian FirstAverageConditional([SkipIfUniform] VectorGaussian concat, Vector second, VectorGaussian result) { // joint distribution is proportional to: exp(-0.5 [first-mean1; second-mean2]' [prec11 prec12; prec21 prec22] [first-mean1; second-mean2]) // posterior for first is proportional to: exp(-0.5 ((first-mean1)' prec11 (first-mean1) + 2 (first-mean1)' prec12 (second-mean2))) // = exp(-0.5 (first' prec11 first - 2 first' prec11 mean1 + 2 first' prec12 (second-mean2))) // first.precision = prec11 // first.meanTimesPrecision = prec11 mean1 - prec12 (second-mean2) = [prec11; prec12] mean - prec12 second int dim1 = result.Dimension; int dim2 = second.Count; if (concat.Dimension != dim1 + dim2) throw new ArgumentException("concat.Dimension ("+concat.Dimension+") != first.Dimension ("+dim1+") + second.Dimension ("+dim2+")"); result.Precision.SetToSubmatrix(concat.Precision, 0, 0); Matrix prec12 = new Matrix(dim1, dim2); prec12.SetToSubmatrix(concat.Precision, 0, dim1); Vector prec12second = Vector.Zero(dim1); prec12second.SetToProduct(prec12, second); result.MeanTimesPrecision.SetToSubvector(concat.MeanTimesPrecision, 0); result.MeanTimesPrecision.SetToDifference(result.MeanTimesPrecision, prec12second); return result; }