/// <summary>EP message to <c>mean</c>.</summary> /// <param name="sample">Incoming message from <c>sample</c>. Must be a proper distribution. If uniform, the result will be uniform.</param> /// <param name="mean">Incoming message from <c>mean</c>. Must be a proper distribution. If uniform, the result will be uniform.</param> /// <returns>The outgoing EP message to the <c>mean</c> argument.</returns> /// <remarks> /// <para>The outgoing message is a distribution matching the moments of <c>mean</c> as the random arguments are varied. The formula is <c>proj[p(mean) sum_(sample) p(sample) factor(sample,mean)]/p(mean)</c>.</para> /// </remarks> /// <exception cref="ImproperMessageException"> /// <paramref name="sample" /> is not a proper distribution.</exception> /// <exception cref="ImproperMessageException"> /// <paramref name="mean" /> is not a proper distribution.</exception> public static Gamma MeanAverageConditional([SkipIfUniform] Poisson sample, [Proper] Gamma mean) { if (sample.IsUniform()) { return(Gamma.Uniform()); } if (sample.IsPointMass) { return(MeanAverageConditional(sample.Point)); } if (sample.Precision != 0) { throw new NotImplementedException("sample.Precision != 0 is not implemented"); } // Z = int_m sum_x r^x m^x exp(-m)/x! q(m) // = int_m exp(rm -m) q(m) // = (1 + (1-r)/b)^(-a) // logZ = -a log(1 + (1-r)/b) // alpha = -b dlogZ/db // = -a(1-r)/(b + (1-r)) // beta = -b dalpha/db // = -ba(1-r)/(b + (1-r))^2 double omr = 1 - sample.Rate; double denom = 1 / (mean.Rate + omr); double alpha = -mean.Shape * omr * denom; double beta = mean.Rate * alpha * denom; return(GaussianOp.GammaFromAlphaBeta(mean, alpha, beta, ForceProper)); }
/// <summary> /// EP message to 'mean' /// </summary> /// <param name="sample">Incoming message from 'sample'. Must be a proper distribution. If uniform, the result will be uniform.</param> /// <returns>The outgoing EP message to the 'mean' argument</returns> /// <remarks><para> /// The outgoing message is a distribution matching the moments of 'mean' as the random arguments are varied. /// The formula is <c>proj[p(mean) sum_(sample) p(sample) factor(sample,mean)]/p(mean)</c>. /// </para></remarks> /// <exception cref="ImproperMessageException"><paramref name="sample"/> is not a proper distribution</exception> public static Gamma MeanAverageConditional([SkipIfUniform] Poisson sample) { // Z = sum_sample sum_mean (mean*rate)^sample exp(-mean)/Gamma(sample+1)^(nu+1)/Z(rate,nu) if (sample.IsUniform()) { return(Gamma.Uniform()); } throw new NotSupportedException(NotSupportedMessage); }
/// <summary>Evidence message for EP.</summary> /// <param name="sample">Incoming message from <c>sample</c>.</param> /// <param name="mean">Incoming message from <c>mean</c>.</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_(sample,mean) p(sample,mean) factor(sample,mean))</c>.</para> /// </remarks> public static double LogAverageFactor(Poisson sample, Gamma mean) { if (sample.IsUniform()) { return(0); } if (sample.IsPointMass) { return(LogAverageFactor(sample.Point, mean, MeanAverageConditional(sample.Point))); } if (sample.Precision != 0) { throw new NotImplementedException("sample.Precision != 0 is not implemented"); } return(-mean.Shape * Math.Log(1 + (1 - sample.Rate) / mean.Rate) - sample.GetLogNormalizer()); }