/// <summary>
 /// EP message to 'array'.
 /// </summary>
 /// <param name="allTrue">Incoming message from 'allTrue'. Must be a proper distribution.  If uniform, the result will be uniform.</param>
 /// <param name="array">Incoming message from 'array'.</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 'array' as the random arguments are varied.
 /// The formula is <c>proj[p(array) sum_(allTrue) p(allTrue) factor(allTrue,array)]/p(array)</c>.
 /// </para></remarks>
 /// <exception cref="ImproperMessageException"><paramref name="allTrue"/> is not a proper distribution</exception>
 public static BernoulliList ArrayAverageConditional <BernoulliList>([SkipIfUniform] Bernoulli allTrue, IList <Bernoulli> array, BernoulliList result)
     where BernoulliList : IList <Bernoulli>
 {
     if (result.Count == 0)
     {
     }
     else if (result.Count == 1)
     {
         result[0] = allTrue;
     }
     else if (result.Count == 2)
     {
         result[0] = BooleanAndOp.AAverageConditional(allTrue, array[1]);
         result[1] = BooleanAndOp.BAverageConditional(allTrue, array[0]);
     }
     else                 // result.Count >= 3
     {
         double   notallTruePrevious = Double.NegativeInfinity;
         double[] notallTrueNext     = new double[result.Count];
         notallTrueNext[notallTrueNext.Length - 1] = Double.NegativeInfinity;
         for (int i = notallTrueNext.Length - 2; i >= 0; i--)
         {
             notallTrueNext[i] = Bernoulli.Or(-array[i + 1].LogOdds, notallTrueNext[i + 1]);
         }
         for (int i = 0; i < result.Count; i++)
         {
             double notallTrueExcept = Bernoulli.Or(notallTruePrevious, notallTrueNext[i]);
             result[i]          = Bernoulli.FromLogOdds(-Bernoulli.Gate(-allTrue.LogOdds, notallTrueExcept));
             notallTruePrevious = Bernoulli.Or(notallTruePrevious, -array[i].LogOdds);
         }
     }
     return(result);
 }
예제 #2
0
 /// <summary>
 /// EP message to 'a'.
 /// </summary>
 /// <param name="and">Incoming message from 'and'. Must be a proper distribution.  If uniform, the result will be uniform.</param>
 /// <param name="B">Incoming message from 'b'.</param>
 /// <returns>The outgoing EP message to the 'a' argument.</returns>
 /// <remarks><para>
 /// The outgoing message is the integral of the factor times incoming messages, over all arguments except 'a'.
 /// The formula is <c>int f(a,x) q(x) dx</c> where <c>x = (and,b)</c>.
 /// </para></remarks>
 /// <exception cref="ImproperMessageException"><paramref name="and"/> is not a proper distribution</exception>
 public static Bernoulli AAverageConditional([SkipIfUniform] Bernoulli and, Bernoulli B)
 {
     if (B.IsPointMass)
     {
         return(AAverageConditional(and, B.Point));
     }
     return(Bernoulli.FromLogOdds(-Bernoulli.Gate(-and.LogOdds, -B.LogOdds)));
 }