public void TwoCoinsEnum()
        {
            var             firstCoin         = Variable.EnumUniform <Coin>();
            var             secondCoin        = Variable.EnumUniform <Coin>();
            Variable <bool> bothHeads         = ((firstCoin == Coin.Heads) & (secondCoin == Coin.Heads)).Named("bothHeads");
            InferenceEngine ie                = new InferenceEngine();
            Bernoulli       bothHeadsActual   = ie.Infer <Bernoulli>(bothHeads);
            Bernoulli       bothHeadsExpected = new Bernoulli(0.25);

            Console.WriteLine("Probability both coins are heads: {0} (should be {1})", bothHeadsActual, bothHeadsExpected);
            bothHeads.ObservedValue = false;
            DiscreteEnum <Coin> firstCoinActual   = ie.Infer <DiscreteEnum <Coin> >(firstCoin);
            DiscreteEnum <Coin> firstCoinExpected = DiscreteEnum <Coin> .FromProbs(2.0 / 3.0, 1.0 / 3.0);

            Console.WriteLine("Probability distribution over firstCoin: " + firstCoinActual);
            Console.WriteLine("should be: " + firstCoinExpected);
            Assert.True(bothHeadsExpected.MaxDiff(bothHeadsActual) < 1e-10);
            Assert.True(firstCoinExpected.MaxDiff(firstCoinActual) < 1e-10);
        }
        public void ClinicalTrialEnum()
        {
            // Data from clinical trial
            VariableArray <Outcome> controlGroup =
                Variable.Observed(new Outcome[] { Outcome.Bad, Outcome.Bad, Outcome.Good, Outcome.Good, Outcome.Bad, Outcome.Bad }).Named("controlGroup");
            VariableArray <Outcome> treatedGroup =
                Variable.Observed(new Outcome[] { Outcome.Good, Outcome.Bad, Outcome.Good, Outcome.Good, Outcome.Good, Outcome.Good }).Named("treatedGroup");
            Range i = controlGroup.Range.Named("i");
            Range j = treatedGroup.Range.Named("j");

            // Prior on being effective treatment
            Variable <bool>   isEffective = Variable.Bernoulli(0.5).Named("isEffective");
            Variable <Vector> probIfTreated, probIfControl;

            using (Variable.If(isEffective))
            {
                // Model if treatment is effective
                probIfControl   = Variable.Dirichlet(new double[] { 1.0, 1.0 }).Named("probIfControl");
                controlGroup[i] = Variable.EnumDiscrete <Outcome>(probIfControl).ForEach(i);
                probIfTreated   = Variable.Dirichlet(new double[] { 1.0, 1.0 }).Named("probIfTreated");
                treatedGroup[j] = Variable.EnumDiscrete <Outcome>(probIfTreated).ForEach(j);
            }
            using (Variable.IfNot(isEffective))
            {
                // Model if treatment is not effective
                Variable <Vector> probAll = Variable.Dirichlet(new double[] { 1.0, 1.0 }).Named("probAll");
                controlGroup[i] = Variable.EnumDiscrete <Outcome>(probAll).ForEach(i);
                treatedGroup[j] = Variable.EnumDiscrete <Outcome>(probAll).ForEach(j);
            }
            InferenceEngine ie = new InferenceEngine();

            Console.WriteLine("Probability treatment has an effect = " + ie.Infer(isEffective));
            Console.WriteLine("Distribution over outcomes if given treatment = "
                              + DiscreteEnum <Outcome> .FromVector(ie.Infer <Dirichlet>(probIfTreated).GetMean()));
            Console.WriteLine("Distribution over outcomes if control = "
                              + DiscreteEnum <Outcome> .FromVector(ie.Infer <Dirichlet>(probIfControl).GetMean()));
        }
Exemple #3
0
 /// <summary>EP message to <c>a</c>.</summary>
 /// <param name="areEqual">Incoming message from <c>areEqual</c>. Must be a proper distribution. If uniform, the result will be uniform.</param>
 /// <param name="B">Incoming message from <c>b</c>.</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 <c>a</c> as the random arguments are varied. The formula is <c>proj[p(a) sum_(areEqual,b) p(areEqual,b) factor(areEqual,a,b)]/p(a)</c>.</para>
 /// </remarks>
 /// <exception cref="ImproperMessageException">
 ///   <paramref name="areEqual" /> is not a proper distribution.</exception>
 public static DiscreteEnum <TEnum> AAverageConditional([SkipIfUniform] Bernoulli areEqual, TEnum B, DiscreteEnum <TEnum> result)
 {
     return(DiscreteEnum <TEnum> .FromDiscrete(DiscreteAreEqualOp.AAverageConditional(areEqual, ToInt(B), result.GetInternalDiscrete())));
 }
Exemple #4
0
 /// <summary>VMP message to <c>Enum</c>.</summary>
 /// <param name="Int">Constant value for <c>Int</c>.</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 <c>Enum</c> conditioned on the given values.</para>
 /// </remarks>
 public static DiscreteEnum <TEnum> EnumAverageLogarithm(int Int, DiscreteEnum <TEnum> result)
 {
     return(EnumAverageConditional(Int, result));
 }
 /// <summary>
 /// EP message to 'Enum'
 /// </summary>
 /// <param name="Int">Constant value for 'Int'.</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 'Enum' conditioned on the given values.
 /// </para></remarks>
 public static DiscreteEnum <TEnum> EnumAverageConditional(int Int, DiscreteEnum <TEnum> result)
 {
     result.Point = Int;
     return(result);
 }
Exemple #6
0
 /// <summary>Evidence message for EP.</summary>
 /// <param name="areEqual">Constant value for <c>areEqual</c>.</param>
 /// <param name="A">Incoming message from <c>a</c>.</param>
 /// <param name="B">Incoming message from <c>b</c>.</param>
 /// <param name="to_B">Outgoing message to <c>B</c>.</param>
 /// <returns>Logarithm of the factor's contribution the EP model evidence.</returns>
 /// <remarks>
 ///   <para>The formula for the result is <c>log(sum_(a,b) p(a,b) factor(areEqual,a,b))</c>. Adding up these values across all factors and variables gives the log-evidence estimate for EP.</para>
 /// </remarks>
 public static double LogEvidenceRatio(bool areEqual, TEnum A, DiscreteEnum <TEnum> B, [Fresh] DiscreteEnum <TEnum> to_B)
 {
     return(DiscreteAreEqualOp.LogEvidenceRatio(areEqual, ToInt(A), B.GetInternalDiscrete(), to_B.GetInternalDiscrete()));
 }
Exemple #7
0
 /// <summary>Evidence message for EP.</summary>
 /// <param name="areEqual">Constant value for <c>areEqual</c>.</param>
 /// <param name="A">Incoming message from <c>a</c>.</param>
 /// <param name="B">Incoming message from <c>b</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_(a,b) p(a,b) factor(areEqual,a,b))</c>.</para>
 /// </remarks>
 public static double LogAverageFactor(bool areEqual, TEnum A, DiscreteEnum <TEnum> B)
 {
     return(DiscreteAreEqualOp.LogAverageFactor(areEqual, ToInt(A), B.GetInternalDiscrete()));
 }
Exemple #8
0
 /// <summary>VMP message to <c>areEqual</c>.</summary>
 /// <param name="A">Incoming message from <c>a</c>.</param>
 /// <param name="B">Incoming message from <c>b</c>.</param>
 /// <returns>The outgoing VMP message to the <c>areEqual</c> argument.</returns>
 /// <remarks>
 ///   <para>The outgoing message is a distribution matching the moments of <c>areEqual</c> as the random arguments are varied. The formula is <c>proj[sum_(a,b) p(a,b) factor(areEqual,a,b)]</c>.</para>
 /// </remarks>
 public static Bernoulli AreEqualAverageLogarithm(TEnum A, DiscreteEnum <TEnum> B)
 {
     return(DiscreteAreEqualOp.AreEqualAverageLogarithm(ToInt(A), B.GetInternalDiscrete()));
 }
Exemple #9
0
 /// <summary>VMP message to <c>b</c>.</summary>
 /// <param name="areEqual">Constant value for <c>areEqual</c>.</param>
 /// <param name="A">Incoming message from <c>a</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>b</c>. The formula is <c>exp(sum_(a) p(a) log(factor(areEqual,a,b)))</c>.</para>
 /// </remarks>
 public static DiscreteEnum <TEnum> BAverageLogarithm(bool areEqual, TEnum A, DiscreteEnum <TEnum> result)
 {
     return(DiscreteEnum <TEnum> .FromDiscrete(DiscreteAreEqualOp.BAverageLogarithm(areEqual, ToInt(A), result.GetInternalDiscrete())));
 }
Exemple #10
0
 /// <summary>Evidence message for EP.</summary>
 /// <param name="Int">Constant value for <c>Int</c>.</param>
 /// <param name="Enum">Incoming message from <c>Enum</c>.</param>
 /// <returns>Logarithm of the factor's contribution the EP model evidence.</returns>
 /// <remarks>
 ///   <para>The formula for the result is <c>log(sum_(Enum) p(Enum) factor(Int,Enum))</c>. Adding up these values across all factors and variables gives the log-evidence estimate for EP.</para>
 /// </remarks>
 public static double LogEvidenceRatio(int Int, DiscreteEnum <TEnum> Enum)
 {
     return(LogAverageFactor(Int, Enum));
 }
Exemple #11
0
 /// <summary>Evidence message for EP.</summary>
 /// <param name="Int">Constant value for <c>Int</c>.</param>
 /// <param name="Enum">Incoming message from <c>Enum</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_(Enum) p(Enum) factor(Int,Enum))</c>.</para>
 /// </remarks>
 public static double LogAverageFactor(int Int, DiscreteEnum <TEnum> Enum)
 {
     return(Enum.GetLogProb((TEnum)(object)Int));
 }
Exemple #12
0
        public void GatedOutcomeAreEqualTest()
        {
            foreach (var algorithm in new Models.Attributes.IAlgorithm[] { new ExpectationPropagation(), new VariationalMessagePassing() })
            {
                Variable <bool>    evidence = Variable.Bernoulli(0.5).Named("evidence");
                IfBlock            block    = Variable.If(evidence);
                Vector             priorA   = Vector.FromArray(0.1, 0.9);
                Vector             priorB   = Vector.FromArray(0.2, 0.8);
                Variable <Outcome> a        = Variable.EnumDiscrete <Outcome>(priorA).Named("a");
                Variable <Outcome> b        = Variable.EnumDiscrete <Outcome>(priorB).Named("b");
                Variable <bool>    c        = (a == b).Named("c");
                double             priorC   = 0.3;
                Variable.ConstrainEqualRandom(c, new Bernoulli(priorC));
                block.CloseBlock();

                InferenceEngine engine = new InferenceEngine(algorithm);

                double probEqual = priorA.Inner(priorB);
                double evPrior   = 0;
                for (int atrial = 0; atrial < 2; atrial++)
                {
                    if (atrial == 1)
                    {
                        a.ObservedValue = Outcome.Bad;
                        probEqual       = priorB[1];
                        c.ClearObservedValue();
                        evPrior   = System.Math.Log(priorA[1]);
                        priorA[0] = 0.0;
                        priorA[1] = 1.0;
                    }
                    double evExpected = System.Math.Log(probEqual * priorC + (1 - probEqual) * (1 - priorC)) + evPrior;
                    double evActual   = engine.Infer <Bernoulli>(evidence).LogOdds;
                    Console.WriteLine("evidence = {0} should be {1}", evActual, evExpected);
                    if (algorithm is ExpectationPropagation || atrial == 1)
                    {
                        Assert.True(MMath.AbsDiff(evExpected, evActual, 1e-5) < 1e-5);
                    }

                    Bernoulli cExpected = new Bernoulli(probEqual * priorC / (probEqual * priorC + (1 - probEqual) * (1 - priorC)));
                    Bernoulli cActual   = engine.Infer <Bernoulli>(c);
                    Console.WriteLine("c = {0} should be {1}", cActual, cExpected);
                    if (algorithm is ExpectationPropagation || atrial == 1)
                    {
                        Assert.True(cExpected.MaxDiff(cActual) < 1e-10);
                    }

                    Vector postB = Vector.Zero(2);
                    postB[0] = priorB[0] * (priorA[0] * priorC + priorA[1] * (1 - priorC));
                    postB[1] = priorB[1] * (priorA[1] * priorC + priorA[0] * (1 - priorC));
                    postB.Scale(1.0 / postB.Sum());
                    DiscreteEnum <Outcome> bExpected = new DiscreteEnum <Outcome>(postB);
                    DiscreteEnum <Outcome> bActual   = engine.Infer <DiscreteEnum <Outcome> >(b);
                    Console.WriteLine("b = {0} should be {1}", bActual, bExpected);
                    if (algorithm is ExpectationPropagation || atrial == 1)
                    {
                        Assert.True(bExpected.MaxDiff(bActual) < 1e-10);
                    }

                    if (atrial == 0 && algorithm is VariationalMessagePassing)
                    {
                        continue;
                    }

                    for (int trial = 0; trial < 2; trial++)
                    {
                        if (trial == 0)
                        {
                            c.ObservedValue = true;
                            evExpected      = System.Math.Log(probEqual * priorC) + evPrior;
                        }
                        else
                        {
                            c.ObservedValue = false;
                            evExpected      = System.Math.Log((1 - probEqual) * (1 - priorC)) + evPrior;
                        }
                        evActual = engine.Infer <Bernoulli>(evidence).LogOdds;
                        Console.WriteLine("evidence = {0} should be {1}", evActual, evExpected);
                        Assert.True(MMath.AbsDiff(evExpected, evActual, 1e-5) < 1e-5);

                        if (a.IsObserved)
                        {
                            Outcome flip(Outcome x) => (x == Outcome.Good ? Outcome.Bad : Outcome.Good);

                            bExpected = DiscreteEnum <Outcome> .PointMass(c.ObservedValue?a.ObservedValue : flip(a.ObservedValue));
                        }
                        else
                        {
                            postB[0] = priorB[0] * (c.ObservedValue ? priorA[0] : priorA[1]);
                            postB[1] = priorB[1] * (c.ObservedValue ? priorA[1] : priorA[0]);
                            postB.Scale(1.0 / postB.Sum());
                            bExpected = new DiscreteEnum <Outcome>(postB);
                        }
                        bActual = engine.Infer <DiscreteEnum <Outcome> >(b);
                        Console.WriteLine("b = {0} should be {1}", bActual, bExpected);
                        Assert.True(bExpected.MaxDiff(bActual) < 1e-10);
                    }
                }
            }
        }
Exemple #13
0
 public DiscreteDomain(DiscreteEnum flag, T value)
 {
     Flag  = flag;
     Value = value;
 }
Exemple #14
0
 /// <summary>EP message to <c>a</c>.</summary>
 /// <param name="areEqual">Constant value for <c>areEqual</c>.</param>
 /// <param name="B">Incoming message from <c>b</c>.</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 <c>a</c> as the random arguments are varied. The formula is <c>proj[p(a) sum_(b) p(b) factor(areEqual,a,b)]/p(a)</c>.</para>
 /// </remarks>
 public static DiscreteEnum <TEnum> AAverageConditional(bool areEqual, TEnum B, DiscreteEnum <TEnum> result)
 {
     return(DiscreteEnum <TEnum> .FromDiscrete(DiscreteAreEqualOp.AAverageConditional(areEqual, ToInt(B), result.GetInternalDiscrete())));
 }
Exemple #15
0
 /// <summary>Evidence message for EP.</summary>
 /// <param name="Int">Incoming message from <c>Int</c>.</param>
 /// <param name="Enum">Incoming message from <c>Enum</c>.</param>
 /// <param name="to_Int">Outgoing message to <c>Int</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_(Int,Enum) p(Int,Enum) factor(Int,Enum))</c>.</para>
 /// </remarks>
 public static double LogAverageFactor(Discrete Int, DiscreteEnum <TEnum> Enum, [Fresh] Discrete to_Int)
 {
     return(to_Int.GetLogAverageOf(Int));
 }
Exemple #16
0
 /// <summary>VMP message to <c>b</c>.</summary>
 /// <param name="areEqual">Incoming message from <c>areEqual</c>. Must be a proper distribution. If uniform, the result will be uniform.</param>
 /// <param name="A">Incoming message from <c>a</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>b</c>. Because the factor is deterministic, <c>areEqual</c> is integrated out before taking the logarithm. The formula is <c>exp(sum_(a) p(a) log(sum_areEqual p(areEqual) factor(areEqual,a,b)))</c>.</para>
 /// </remarks>
 /// <exception cref="ImproperMessageException">
 ///   <paramref name="areEqual" /> is not a proper distribution.</exception>
 public static DiscreteEnum <TEnum> BAverageLogarithm([SkipIfUniform] Bernoulli areEqual, TEnum A, DiscreteEnum <TEnum> result)
 {
     return(DiscreteEnum <TEnum> .FromDiscrete(DiscreteAreEqualOp.BAverageLogarithm(areEqual, ToInt(A), result.GetInternalDiscrete())));
 }
Exemple #17
0
 public static Discrete IntAverageConditionalInit([IgnoreDependency] DiscreteEnum <TEnum> Enum)
 {
     return(Discrete.Uniform(Enum.Dimension));
 }
Exemple #18
0
 /// <summary>EP message to <c>areEqual</c>.</summary>
 /// <param name="A">Incoming message from <c>a</c>.</param>
 /// <param name="B">Incoming message from <c>b</c>.</param>
 /// <returns>The outgoing EP message to the <c>areEqual</c> argument.</returns>
 /// <remarks>
 ///   <para>The outgoing message is a distribution matching the moments of <c>areEqual</c> as the random arguments are varied. The formula is <c>proj[p(areEqual) sum_(a,b) p(a,b) factor(areEqual,a,b)]/p(areEqual)</c>.</para>
 /// </remarks>
 public static Bernoulli AreEqualAverageConditional(DiscreteEnum <TEnum> A, TEnum B)
 {
     return(DiscreteAreEqualOp.AreEqualAverageConditional(A.GetInternalDiscrete(), ToInt(B)));
 }
Exemple #19
0
 /// <summary>EP message to <c>Enum</c>.</summary>
 /// <param name="Int">Incoming message from <c>Int</c>. Must be a proper distribution. If uniform, the result will be uniform.</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 <c>Enum</c> as the random arguments are varied. The formula is <c>proj[p(Enum) sum_(Int) p(Int) factor(Int,Enum)]/p(Enum)</c>.</para>
 /// </remarks>
 /// <exception cref="ImproperMessageException">
 ///   <paramref name="Int" /> is not a proper distribution.</exception>
 public static DiscreteEnum <TEnum> EnumAverageConditional([SkipIfUniform] Discrete Int, DiscreteEnum <TEnum> result)
 {
     result.SetProbs(Int.GetWorkspace());
     return(result);
 }
Exemple #20
0
 /// <summary>VMP message to <c>areEqual</c>.</summary>
 /// <param name="A">Incoming message from <c>a</c>.</param>
 /// <param name="B">Incoming message from <c>b</c>.</param>
 /// <returns>The outgoing VMP message to the <c>areEqual</c> argument.</returns>
 /// <remarks>
 ///   <para>The outgoing message is a distribution matching the moments of <c>areEqual</c> as the random arguments are varied. The formula is <c>proj[sum_(a,b) p(a,b) factor(areEqual,a,b)]</c>.</para>
 /// </remarks>
 public static Bernoulli AreEqualAverageLogarithm(DiscreteEnum <TEnum> A, TEnum B)
 {
     return(DiscreteAreEqualOp.AreEqualAverageLogarithm(A.GetInternalDiscrete(), ToInt(B)));
 }
Exemple #21
0
 /// <summary>EP message to <c>Enum</c>.</summary>
 /// <param name="Int">Constant value for <c>Int</c>.</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 <c>Enum</c> conditioned on the given values.</para>
 /// </remarks>
 public static DiscreteEnum <TEnum> EnumAverageConditional(int Int, DiscreteEnum <TEnum> result)
 {
     result.Point = (TEnum)Enum.GetValues(typeof(TEnum)).GetValue(Int);
     return(result);
 }
Exemple #22
0
 /// <summary>Evidence message for EP.</summary>
 /// <param name="areEqual">Constant value for <c>areEqual</c>.</param>
 /// <param name="A">Incoming message from <c>a</c>.</param>
 /// <param name="B">Incoming message from <c>b</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_(a,b) p(a,b) factor(areEqual,a,b))</c>.</para>
 /// </remarks>
 public static double LogAverageFactor(bool areEqual, DiscreteEnum <TEnum> A, TEnum B)
 {
     return(DiscreteAreEqualOp.LogAverageFactor(areEqual, A.GetInternalDiscrete(), ToInt(B)));
 }
Exemple #23
0
 /// <summary>VMP message to <c>Enum</c>.</summary>
 /// <param name="Int">Incoming message from <c>Int</c>. Must be a proper distribution. If uniform, the result will be uniform.</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 <c>Enum</c> with <c>Int</c> integrated out. The formula is <c>sum_Int p(Int) factor(Int,Enum)</c>.</para>
 /// </remarks>
 /// <exception cref="ImproperMessageException">
 ///   <paramref name="Int" /> is not a proper distribution.</exception>
 public static DiscreteEnum <TEnum> EnumAverageLogarithm([SkipIfUniform] Discrete Int, DiscreteEnum <TEnum> result)
 {
     return(EnumAverageConditional(Int, result));
 }
Exemple #24
0
 /// <summary>Evidence message for EP.</summary>
 /// <param name="areEqual">Constant value for <c>areEqual</c>.</param>
 /// <param name="A">Incoming message from <c>a</c>.</param>
 /// <param name="B">Incoming message from <c>b</c>.</param>
 /// <param name="to_A">Outgoing message to <c>A</c>.</param>
 /// <returns>Logarithm of the factor's contribution the EP model evidence.</returns>
 /// <remarks>
 ///   <para>The formula for the result is <c>log(sum_(a,b) p(a,b) factor(areEqual,a,b))</c>. Adding up these values across all factors and variables gives the log-evidence estimate for EP.</para>
 /// </remarks>
 public static double LogEvidenceRatio(bool areEqual, DiscreteEnum <TEnum> A, TEnum B, [Fresh] DiscreteEnum <TEnum> to_A)
 {
     return(DiscreteAreEqualOp.LogEvidenceRatio(areEqual, A.GetInternalDiscrete(), ToInt(B), to_A.GetInternalDiscrete()));
 }
 /// <summary>
 /// EP message to 'Enum'
 /// </summary>
 /// <param name="Int">Incoming message from 'Int'. Must be a proper distribution.  If uniform, the result will be uniform.</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 'Enum' as the random arguments are varied.
 /// The formula is <c>proj[p(Enum) sum_(Int) p(Int) factor(Int,Enum)]/p(Enum)</c>.
 /// </para></remarks>
 /// <exception cref="ImproperMessageException"><paramref name="Int"/> is not a proper distribution</exception>
 public static DiscreteEnum <TEnum> EnumAverageConditional([SkipIfUniform] Discrete Int, DiscreteEnum <TEnum> result)
 {
     result.SetTo(Int);
     return(result);
 }