/// <summary>EP message to <c>isPositive</c>.</summary> /// <param name="x">Incoming message from <c>x</c>. Must be a proper distribution. If uniform, the result will be uniform.</param> /// <returns>The outgoing EP message to the <c>isPositive</c> argument.</returns> /// <remarks> /// <para>The outgoing message is a distribution matching the moments of <c>isPositive</c> as the random arguments are varied. The formula is <c>proj[p(isPositive) sum_(x) p(x) factor(isPositive,x)]/p(isPositive)</c>.</para> /// </remarks> /// <exception cref="ImproperMessageException"> /// <paramref name="x" /> is not a proper distribution.</exception> public static Bernoulli IsPositiveAverageConditional([SkipIfUniform, Proper] Gaussian x) { Bernoulli result = new Bernoulli(); if (x.IsPointMass) { result.Point = Factor.IsPositive(x.Point); } else if (x.IsUniform()) { result.LogOdds = 0.0; } else if (!x.IsProper()) { throw new ImproperMessageException(x); } else { // m/sqrt(v) = (m/v)/sqrt(1/v) double z = x.MeanTimesPrecision / Math.Sqrt(x.Precision); // p(true) = NormalCdf(z) // log(p(true)/p(false)) = NormalCdfLogit(z) result.LogOdds = MMath.NormalCdfLogit(z); } return(result); }
/// <summary> /// Evidence message for EP /// </summary> /// <param name="isPositive">Incoming message from 'isPositive'.</param> /// <param name="x">Incoming message from 'x'.</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_(isPositive,x) p(isPositive,x) factor(isPositive,x))</c>. /// </para></remarks> public static double LogAverageFactor(Bernoulli isPositive, Gaussian x) { Bernoulli to_isPositive = IsPositiveAverageConditional(x); return(isPositive.GetLogAverageOf(to_isPositive)); #if false // Z = p(b=T) p(x > 0) + p(b=F) p(x <= 0) // = p(b=F) + (p(b=T) - p(b=F)) p(x > 0) if (x.IsPointMass) { return(Factor.IsPositive(x.Point) ? isPositive.GetLogProbTrue() : isPositive.GetLogProbFalse()); } else if (x.IsUniform()) { return(Bernoulli.LogProbEqual(isPositive.LogOdds, 0.0)); } else { // m/sqrt(v) = (m/v)/sqrt(1/v) double z = x.MeanTimesPrecision / Math.Sqrt(x.Precision); if (isPositive.IsPointMass) { return(isPositive.Point ? MMath.NormalCdfLn(z) : MMath.NormalCdfLn(-z)); } else { return(MMath.LogSumExp(isPositive.GetLogProbTrue() + MMath.NormalCdfLn(z), isPositive.GetLogProbFalse() + MMath.NormalCdfLn(-z))); } } #endif }
/// <summary>Evidence message for EP.</summary> /// <param name="isPositive">Constant value for <c>isPositive</c>.</param> /// <param name="x">Constant value for <c>x</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(factor(isPositive,x))</c>.</para> /// </remarks> public static double LogAverageFactor(bool isPositive, double x) { return((isPositive == Factor.IsPositive(x)) ? 0.0 : Double.NegativeInfinity); }