/// <summary>VMP message to <c>A</c>.</summary> /// <param name="sum">Incoming message from <c>Sum</c>. Must be a proper distribution. If uniform, the result will be uniform.</param> /// <param name="A">Incoming message from <c>A</c>. Must be a proper distribution. If any element is uniform, the result will be uniform.</param> /// <param name="B">Incoming message from <c>B</c>. Must be a proper distribution. If any element is uniform, the result will be uniform.</param> /// <param name="MeanOfB">Buffer <c>MeanOfB</c>.</param> /// <param name="CovarianceOfB">Buffer <c>CovarianceOfB</c>.</param> /// <param name="result">Modified to contain the outgoing message.</param> /// <returns> /// <paramref name="result" /> /// </returns> /// <remarks> /// <para>The outgoing message is the exponential of the average log-factor value, where the average is over all arguments except <c>A</c>. Because the factor is deterministic, <c>Sum</c> is integrated out before taking the logarithm. The formula is <c>exp(sum_(B) p(B) log(sum_Sum p(Sum) factor(Sum,A,B)))</c>.</para> /// </remarks> /// <exception cref="ImproperMessageException"> /// <paramref name="sum" /> is not a proper distribution.</exception> /// <exception cref="ImproperMessageException"> /// <paramref name="A" /> is not a proper distribution.</exception> /// <exception cref="ImproperMessageException"> /// <paramref name="B" /> is not a proper distribution.</exception> public static DistributionStructArray <Bernoulli, bool> AAverageLogarithm( [SkipIfUniform] Gaussian sum, [Proper] DistributionStructArray <Bernoulli, bool> A, [Proper] VectorGaussian B, Vector MeanOfB, PositiveDefiniteMatrix CovarianceOfB, DistributionStructArray <Bernoulli, bool> result) { double mu = sum.GetMean(); var Ebbt = new PositiveDefiniteMatrix(A.Count, A.Count); Ebbt.SetToSumWithOuter(CovarianceOfB, 1, MeanOfB, MeanOfB); var ma = A.Select(x => x.GetMean()).ToArray(); for (int i = 0; i < A.Count; i++) { double term1 = 0.0; for (int j = 0; j < A.Count; j++) { if (j != i) { term1 += ma[i] * Ebbt[i, j]; } } var ri = result[i]; ri.LogOdds = -.5 * sum.Precision * (2.0 * term1 + Ebbt[i, i] - 2.0 * mu * MeanOfB[i]); result[i] = ri; } return(result); }
/// <summary> /// VMP message to 'B' /// </summary> /// <param name="sum">Incoming message from 'Sum'. Must be a proper distribution. If uniform, the result will be uniform.</param> /// <param name="A">Incoming message from 'A'.</param> /// <param name="result">Modified to contain the outgoing message</param> /// <returns><paramref name="result"/></returns> /// <remarks><para> /// The outgoing message is the exponential of the average log-factor value, where the average is over all arguments except 'B'. /// Because the factor is deterministic, 'Sum' is integrated out before taking the logarithm. /// The formula is <c>exp(sum_(A) p(A) log(sum_Sum p(Sum) factor(Sum,A,B)))</c>. /// </para></remarks> /// <exception cref="ImproperMessageException"><paramref name="sum"/> is not a proper distribution</exception> public static VectorGaussian BAverageLogarithm([SkipIfUniform] Gaussian sum, DistributionStructArray <Bernoulli, bool> A, VectorGaussian result) { if (result == default(VectorGaussian)) { result = new VectorGaussian(A.Count); } // E[log N(x; ab, 0)] = -0.5 E[(x-ab)^2]/0 = -0.5 (E[x^2] - 2 E[x] a' E[b] + trace(aa' E[bb']))/0 // message to a = N(a; E[x]*inv(var(b)+E[b]E[b]')*E[b], var(x)*inv(var(b)+E[b]E[b]')) // result.Precision = (var(b)+E[b]*E[b]')/var(x) // result.MeanTimesPrecision = E[x]/var(x)*E[b] = E[b]*X.MeanTimesPrecision Vector ma = Vector.FromArray(A.Select(x => x.GetMean()).ToArray()); Vector va = Vector.FromArray(A.Select(x => x.GetVariance()).ToArray()); result.Precision.SetToDiagonal(va); result.Precision.SetToSumWithOuter(result.Precision, 1, ma, ma); result.Precision.SetToProduct(result.Precision, sum.Precision); result.MeanTimesPrecision.SetToProduct(ma, sum.MeanTimesPrecision); return(result); }
/// <summary> /// VMP message to 'A' /// </summary> /// <param name="sum">Incoming message from 'Sum'. Must be a proper distribution. If uniform, the result will be uniform.</param> /// <param name="A">Incoming message from 'A'. Must be a proper distribution. If all elements are uniform, the result will be uniform.</param> /// <param name="B">Constant value for 'B'.</param> /// <param name="result">Modified to contain the outgoing message</param> /// <returns><paramref name="result"/></returns> /// <remarks><para> /// The outgoing message is the factor viewed as a function of 'A' with 'Sum' integrated out. /// The formula is <c>sum_Sum p(Sum) factor(Sum,A,B)</c>. /// </para></remarks> /// <exception cref="ImproperMessageException"><paramref name="sum"/> is not a proper distribution</exception> /// <exception cref="ImproperMessageException"><paramref name="A"/> is not a proper distribution</exception> public static DistributionStructArray <Bernoulli, bool> AAverageLogarithm([SkipIfUniform] Gaussian sum, [SkipIfAllUniform] DistributionStructArray <Bernoulli, bool> A, Vector B, DistributionStructArray <Bernoulli, bool> result) { double mu = sum.GetMean(); var ma = A.Select(x => x.GetMean()).ToArray(); for (int i = 0; i < A.Count; i++) { double term1 = 0.0; for (int j = 0; j < A.Count; j++) { if (j != i) { term1 += ma[i] * B[i] * B[j]; } } var ri = result[i]; ri.LogOdds = -.5 * sum.Precision * (2.0 * term1 + B[i] * B[i] - 2.0 * mu * B[i]); result[i] = ri; } return(result); }
/// <summary> /// VMP message to 'B' /// </summary> /// <param name="sum">Incoming message from 'Sum'. Must be a proper distribution. If uniform, the result will be uniform.</param> /// <param name="A">Incoming message from 'A'.</param> /// <param name="result">Modified to contain the outgoing message</param> /// <returns><paramref name="result"/></returns> /// <remarks><para> /// The outgoing message is the exponential of the average log-factor value, where the average is over all arguments except 'B'. /// Because the factor is deterministic, 'Sum' is integrated out before taking the logarithm. /// The formula is <c>exp(sum_(A) p(A) log(sum_Sum p(Sum) factor(Sum,A,B)))</c>. /// </para></remarks> /// <exception cref="ImproperMessageException"><paramref name="sum"/> is not a proper distribution</exception> public static VectorGaussian BAverageLogarithm([SkipIfUniform] Gaussian sum, DistributionStructArray<Bernoulli, bool> A, VectorGaussian result) { if (result == default(VectorGaussian)) result = new VectorGaussian(A.Count); // E[log N(x; ab, 0)] = -0.5 E[(x-ab)^2]/0 = -0.5 (E[x^2] - 2 E[x] a' E[b] + trace(aa' E[bb']))/0 // message to a = N(a; E[x]*inv(var(b)+E[b]E[b]')*E[b], var(x)*inv(var(b)+E[b]E[b]')) // result.Precision = (var(b)+E[b]*E[b]')/var(x) // result.MeanTimesPrecision = E[x]/var(x)*E[b] = E[b]*X.MeanTimesPrecision Vector ma = Vector.FromArray(A.Select(x => x.GetMean()).ToArray()); Vector va = Vector.FromArray(A.Select(x => x.GetVariance()).ToArray()); result.Precision.SetToDiagonal(va); result.Precision.SetToSumWithOuter(result.Precision, 1, ma, ma); result.Precision.SetToProduct(result.Precision, sum.Precision); result.MeanTimesPrecision.SetToProduct(ma, sum.MeanTimesPrecision); return result; }