/// <summary> /// Tests EP and BP gate exit ops for Bernoulli random variable for correctness given message parameters and a shift. /// </summary> /// <param name="gate1ProbTrue">Probability of being true for the variable when the selector is true.</param> /// <param name="gate2ProbTrue">Probability of being true for the variable when the selector is false.</param> /// <param name="selectorProbTrue">Probability of being true for the selector variable.</param> /// <param name="shift">The value of the shift.</param> private void DoBernoulliExitTest(double gate1ProbTrue, double gate2ProbTrue, double selectorProbTrue, double shift) { const double ExitTwoProbTrue = 0.3; // ExitTwo op depends on the incoming message from outside the gate var cases = new[] { Bernoulli.FromLogOdds(Math.Log(selectorProbTrue) - shift), Bernoulli.FromLogOdds(Math.Log(1 - selectorProbTrue) - shift) }; var values = new[] { new Bernoulli(gate1ProbTrue), new Bernoulli(gate2ProbTrue) }; var exitTwo = new Bernoulli(ExitTwoProbTrue); Bernoulli value1, value2; double expectedProbTrueFromExit = (selectorProbTrue * gate1ProbTrue) + ((1 - selectorProbTrue) * gate2ProbTrue); value1 = GateExitOp <bool> .ExitAverageConditional(new Bernoulli(), cases, values, new Bernoulli()); value2 = BeliefPropagationGateExitOp.ExitAverageConditional(cases, values, new Bernoulli()); Assert.Equal(expectedProbTrueFromExit, value1.GetProbTrue(), 1e-4); Assert.Equal(expectedProbTrueFromExit, value2.GetProbTrue(), 1e-4); double gate1Scale = (ExitTwoProbTrue * gate1ProbTrue) + ((1 - ExitTwoProbTrue) * (1 - gate1ProbTrue)); double gate2Scale = (ExitTwoProbTrue * gate2ProbTrue) + ((1 - ExitTwoProbTrue) * (1 - gate2ProbTrue)); double expectedProbTrueFromExitTwo = (selectorProbTrue * gate1ProbTrue / gate1Scale) + ((1 - selectorProbTrue) * gate2ProbTrue / gate2Scale); double expectedProbFalseFromExitTwo = (selectorProbTrue * (1 - gate1ProbTrue) / gate1Scale) + ((1 - selectorProbTrue) * (1 - gate2ProbTrue) / gate2Scale); expectedProbTrueFromExitTwo /= expectedProbTrueFromExitTwo + expectedProbFalseFromExitTwo; value1 = GateExitTwoOp.ExitTwoAverageConditional <Bernoulli>(exitTwo, cases[0], cases[1], values, new Bernoulli()); value2 = BeliefPropagationGateExitTwoOp.ExitTwoAverageConditional(exitTwo, cases[0], cases[1], values, new Bernoulli()); Assert.Equal(expectedProbTrueFromExitTwo, value1.GetProbTrue(), 1e-4); Assert.Equal(expectedProbTrueFromExitTwo, value2.GetProbTrue(), 1e-4); }
/// <summary>Computations that depend on the observed value of vbool2</summary> public void Changed_vbool2() { if (this.Changed_vbool2_iterationsDone == 1) { return; } this.vbool2_marginal = ArrayHelper.MakeUniform <Bernoulli>(new Bernoulli()); this.vbool2_marginal = Distribution.SetPoint <Bernoulli, bool>(this.vbool2_marginal, this.Vbool2); // The constant 'vBernoulli0' Bernoulli vBernoulli0 = Bernoulli.FromLogOdds(0); this.vbool0_marginal_F = ArrayHelper.MakeUniform <Bernoulli>(vBernoulli0); // Message from use of 'vbool0' Bernoulli vbool0_use_B = ArrayHelper.MakeUniform <Bernoulli>(vBernoulli0); // Message to 'vbool0_use' from And factor vbool0_use_B = BooleanAndOp.AAverageConditional(this.Vbool2, vBernoulli0); // Message to 'vbool0_marginal' from Variable factor this.vbool0_marginal_F = VariableOp.MarginalAverageConditional <Bernoulli>(vbool0_use_B, vBernoulli0, this.vbool0_marginal_F); this.vbool1_marginal_F = ArrayHelper.MakeUniform <Bernoulli>(vBernoulli0); // Message from use of 'vbool1' Bernoulli vbool1_use_B = ArrayHelper.MakeUniform <Bernoulli>(vBernoulli0); // Message to 'vbool1_use' from And factor vbool1_use_B = BooleanAndOp.BAverageConditional(this.Vbool2, vBernoulli0); // Message to 'vbool1_marginal' from Variable factor this.vbool1_marginal_F = VariableOp.MarginalAverageConditional <Bernoulli>(vbool1_use_B, vBernoulli0, this.vbool1_marginal_F); this.Changed_vbool2_iterationsDone = 1; }
/// <summary>Computations that do not depend on observed values</summary> public void Constant() { if (this.Constant_iterationsDone == 1) { return; } // The constant 'vBernoulli0' Bernoulli vBernoulli0 = Bernoulli.FromLogOdds(0); this.vbool0_marginal_F = ArrayHelper.MakeUniform <Bernoulli>(vBernoulli0); // Message from use of 'vbool0' Bernoulli vbool0_use_B = ArrayHelper.MakeUniform <Bernoulli>(vBernoulli0); // Message to 'vbool0_marginal' from Variable factor this.vbool0_marginal_F = VariableOp.MarginalAverageConditional <Bernoulli>(vbool0_use_B, vBernoulli0, this.vbool0_marginal_F); this.vbool1_marginal_F = ArrayHelper.MakeUniform <Bernoulli>(vBernoulli0); // Message from use of 'vbool1' Bernoulli vbool1_use_B = ArrayHelper.MakeUniform <Bernoulli>(vBernoulli0); // Message to 'vbool1_marginal' from Variable factor this.vbool1_marginal_F = VariableOp.MarginalAverageConditional <Bernoulli>(vbool1_use_B, vBernoulli0, this.vbool1_marginal_F); Bernoulli vbool2_F = ArrayHelper.MakeUniform <Bernoulli>(new Bernoulli()); this.vbool2_marginal_F = ArrayHelper.MakeUniform <Bernoulli>(new Bernoulli()); // Message from use of 'vbool2' Bernoulli vbool2_use_B = ArrayHelper.MakeUniform <Bernoulli>(new Bernoulli()); // Message to 'vbool2' from And factor vbool2_F = BooleanAndOp.AndAverageConditional(vBernoulli0, vBernoulli0); // Message to 'vbool2_marginal' from DerivedVariable factor this.vbool2_marginal_F = DerivedVariableOp.MarginalAverageConditional <Bernoulli>(vbool2_use_B, vbool2_F, this.vbool2_marginal_F); this.Constant_iterationsDone = 1; }
/// <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); }
/// <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">Constant value for '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, bool B) { if (and.IsPointMass) { return(AAverageConditional(and.Point, B)); } return(Bernoulli.FromLogOdds(B ? and.LogOdds : 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))); }
/// <summary>EP message to <c>a</c>.</summary> /// <param name="or">Incoming message from <c>or</c>. Must be a proper distribution. If uniform, the result will be uniform.</param> /// <param name="B">Constant value for <c>b</c>.</param> /// <returns>The outgoing EP message to the <c>a</c> argument.</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_(or) p(or) factor(or,a,b)]/p(a)</c>.</para> /// </remarks> /// <exception cref="ImproperMessageException"> /// <paramref name="or" /> is not a proper distribution.</exception> public static Bernoulli AAverageConditional([SkipIfUniform] Bernoulli or, bool B) { if (or.IsPointMass) { return(AAverageConditional(or.Point, B)); } return(Bernoulli.FromLogOdds(B ? 0 : or.LogOdds)); }
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="BooleanAreEqualOp"]/message_doc[@name="AAverageLogarithm(Bernoulli, Bernoulli)"]/*'/> public static Bernoulli AAverageLogarithm([SkipIfUniform] Bernoulli areEqual, [SkipIfUniform] Bernoulli B) { if (areEqual.IsPointMass) { return(AAverageLogarithm(areEqual.Point, B)); } // when AreEqual is marginalized, the factor is proportional to exp((A==B)*areEqual.LogOdds) return(Bernoulli.FromLogOdds(areEqual.LogOdds * (2 * B.GetProbTrue() - 1))); }
/// <summary> /// EP message to 'allTrue'. /// </summary> /// <param name="array">Incoming message from 'array'.</param> /// <returns>The outgoing EP message to the 'allTrue' argument.</returns> /// <remarks><para> /// The outgoing message is a distribution matching the moments of 'allTrue' as the random arguments are varied. /// The formula is <c>proj[p(allTrue) sum_(array) p(array) factor(allTrue,array)]/p(allTrue)</c>. /// </para></remarks> public static Bernoulli AllTrueAverageConditional(IList <Bernoulli> array) { double logOdds = Double.NegativeInfinity; for (int i = 0; i < array.Count; i++) { logOdds = Bernoulli.Or(logOdds, -array[i].LogOdds); } return(Bernoulli.FromLogOdds(-logOdds)); }
// result.LogOdds = [log p(b=true), log p(b=false)] /// <summary> /// EP message to 'cases'. /// </summary> /// <param name="b">Incoming message from 'b'.</param> /// <param name="result">Modified to contain the outgoing message.</param> /// <returns><paramref name="result"/></returns> /// <remarks><para> /// The outgoing message is the integral of the factor times incoming messages, over all arguments except 'cases'. /// The formula is <c>int f(cases,x) q(x) dx</c> where <c>x = (b)</c>. /// </para></remarks> public static BernoulliList CasesAverageConditional <BernoulliList>(Bernoulli b, BernoulliList result) where BernoulliList : IList <Bernoulli> { if (result.Count != 2) { throw new ArgumentException("result.Count != 2"); } result[0] = Bernoulli.FromLogOdds(b.GetLogProbTrue()); result[1] = Bernoulli.FromLogOdds(b.GetLogProbFalse()); return(result); }
/// <summary>Gets or sets an element.</summary> public Bernoulli this[int index] { get { return(Bernoulli.FromLogOdds(LogOddsVector[index])); } set { LogOddsVector[index] = value.LogOdds; } }
/// <summary> /// EP message to 'casesInt'. /// </summary> /// <param name="i">Incoming message from 'i'.</param> /// <param name="result">Modified to contain the outgoing message.</param> /// <returns><paramref name="result"/></returns> /// <remarks><para> /// The outgoing message is the integral of the factor times incoming messages, over all arguments except 'casesInt'. /// The formula is <c>int f(casesInt,x) q(x) dx</c> where <c>x = (i)</c>. /// </para></remarks> public static BernoulliList CasesAverageConditional <BernoulliList>(Discrete i, BernoulliList result) where BernoulliList : IList <Bernoulli> { if (result.Count != i.Dimension) { throw new ArgumentException("result.Count (" + result.Count + ") != i.Dimension (" + i.Dimension + ")"); } for (int j = 0; j < result.Count; j++) { result[j] = Bernoulli.FromLogOdds(i.GetLogProb(j)); } return(result); }
/// <summary>Computations that depend on the observed value of FeatureIndexes and FeatureValues and InstanceCount and InstanceFeatureCounts and Labels and numberOfIterations and WeightConstraints and WeightPriors</summary> /// <param name="numberOfIterations">The number of times to iterate each loop</param> private void Changed_FeatureIndexes_FeatureValues_InstanceCount_InstanceFeatureCounts_Labels_numberOfIterations_W7(int numberOfIterations) { if (this.Changed_FeatureIndexes_FeatureValues_InstanceCount_InstanceFeatureCounts_Labels_numberOfIterations_W7_isDone) { return; } for (int iteration = this.numberOfIterationsDone; iteration < numberOfIterations; iteration++) { for (int InstanceRange = 0; InstanceRange < this.instanceCount; InstanceRange++) { this.Weights_FeatureIndexes_F[InstanceRange] = JaggedSubarrayWithMarginalOp <double> .ItemsAverageConditional <DistributionStructArray <Gaussian, double>, Gaussian, DistributionStructArray <Gaussian, double> >(this.IndexedWeights_B[InstanceRange], this.Weights_uses_F[1], this.Weights_marginal_F, this.featureIndexes, InstanceRange, this.Weights_FeatureIndexes_F[InstanceRange]); for (int InstanceFeatureRanges = 0; InstanceFeatureRanges < this.instanceFeatureCounts[InstanceRange]; InstanceFeatureRanges++) { this.FeatureScores_F[InstanceRange][InstanceFeatureRanges] = GaussianProductOpBase.ProductAverageConditional(this.featureValues[InstanceRange][InstanceFeatureRanges], this.Weights_FeatureIndexes_F[InstanceRange][InstanceFeatureRanges]); } this.Score_F[InstanceRange] = FastSumOp.SumAverageConditional(this.FeatureScores_F[InstanceRange]); this.NoisyScore_F[InstanceRange] = GaussianFromMeanAndVarianceOp.SampleAverageConditional(this.Score_F[InstanceRange], 1.0); this.NoisyScore_use_B[InstanceRange] = IsPositiveOp_Proper.XAverageConditional(Bernoulli.PointMass(this.labels[InstanceRange]), this.NoisyScore_F[InstanceRange]); this.Score_B[InstanceRange] = GaussianFromMeanAndVarianceOp.MeanAverageConditional(this.NoisyScore_use_B[InstanceRange], 1.0); this.FeatureScores_B[InstanceRange] = FastSumOp.ArrayAverageConditional <DistributionStructArray <Gaussian, double> >(this.Score_B[InstanceRange], this.Score_F[InstanceRange], this.FeatureScores_F[InstanceRange], this.FeatureScores_B[InstanceRange]); for (int InstanceFeatureRanges = 0; InstanceFeatureRanges < this.instanceFeatureCounts[InstanceRange]; InstanceFeatureRanges++) { this.IndexedWeights_B[InstanceRange][InstanceFeatureRanges] = GaussianProductOpBase.BAverageConditional(this.FeatureScores_B[InstanceRange][InstanceFeatureRanges], this.featureValues[InstanceRange][InstanceFeatureRanges]); } this.Weights_marginal_F = JaggedSubarrayWithMarginalOp <double> .MarginalIncrementItems <DistributionStructArray <Gaussian, double>, Gaussian, DistributionStructArray <Gaussian, double> >(this.IndexedWeights_B[InstanceRange], this.Weights_FeatureIndexes_F[InstanceRange], this.featureIndexes, InstanceRange, this.Weights_marginal_F); } this.OnProgressChanged(new ProgressChangedEventArgs(iteration)); } for (int InstanceRange = 0; InstanceRange < this.instanceCount; InstanceRange++) { this.Weights_FeatureIndexes_B[InstanceRange] = ArrayHelper.SetTo <DistributionStructArray <Gaussian, double> >(this.Weights_FeatureIndexes_B[InstanceRange], this.IndexedWeights_B[InstanceRange]); } this.Weights_uses_B[1] = JaggedSubarrayWithMarginalOp <double> .ArrayAverageConditional <DistributionStructArray <Gaussian, double> >(this.Weights_uses_F[1], this.Weights_marginal_F, this.Weights_uses_B[1]); this.Weights_uses_F[0] = ReplicateOp_NoDivide.UsesAverageConditional <DistributionStructArray <Gaussian, double> >(this.Weights_uses_B, this.weightPriors, 0, this.Weights_uses_F[0]); this.ModelSelector_selector_cases_0_uses_B[3] = Bernoulli.FromLogOdds(ReplicateOp.LogEvidenceRatio <DistributionStructArray <Gaussian, double> >(this.Weights_uses_B, this.weightPriors, this.Weights_uses_F)); this.ModelSelector_selector_cases_0_uses_B[4] = Bernoulli.FromLogOdds(ConstrainEqualRandomOp <double[]> .LogEvidenceRatio <DistributionStructArray <Gaussian, double> >(this.Weights_uses_F[0], this.weightConstraints)); this.ModelSelector_selector_cases_0_uses_B[8] = Bernoulli.FromLogOdds(JaggedSubarrayWithMarginalOp <double> .LogEvidenceRatio <Gaussian, DistributionRefArray <DistributionStructArray <Gaussian, double>, double[]>, DistributionStructArray <Gaussian, double> >(this.Weights_FeatureIndexes_B, this.Weights_uses_F[1], this.featureIndexes, this.Weights_FeatureIndexes_F)); for (int InstanceRange = 0; InstanceRange < this.instanceCount; InstanceRange++) { this.ModelSelector_selector_cases_0_rep9_B[InstanceRange] = Bernoulli.FromLogOdds(IsPositiveOp.LogEvidenceRatio(this.labels[InstanceRange], this.NoisyScore_F[InstanceRange])); } this.ModelSelector_selector_cases_0_uses_B[16] = ReplicateOp_NoDivide.DefAverageConditional <Bernoulli>(this.ModelSelector_selector_cases_0_rep9_B, this.ModelSelector_selector_cases_0_uses_B[16]); this.ModelSelector_selector_cases_0_B = ReplicateOp_NoDivide.DefAverageConditional <Bernoulli>(this.ModelSelector_selector_cases_0_uses_B, this.ModelSelector_selector_cases_0_B); this.ModelSelector_selector_cases_B[0] = ArrayHelper.SetTo <Bernoulli>(this.ModelSelector_selector_cases_B[0], this.ModelSelector_selector_cases_0_B); this.ModelSelector_selector_B = CasesOp.BAverageConditional(this.ModelSelector_selector_cases_B); this.ModelSelector_marginal_F = VariableOp.MarginalAverageConditional <Bernoulli>(this.ModelSelector_selector_B, this.vBernoulli1, this.ModelSelector_marginal_F); this.Weights_B = ReplicateOp_NoDivide.DefAverageConditional <DistributionStructArray <Gaussian, double> >(this.Weights_uses_B, this.Weights_B); this.Changed_FeatureIndexes_FeatureValues_InstanceCount_InstanceFeatureCounts_Labels_numberOfIterations_W7_isDone = true; }
public void GaussianExitTest() { double pb = 2.0 / 3; var cases = new[] { Bernoulli.FromLogOdds(Math.Log(pb)), Bernoulli.FromLogOdds(Math.Log(1 - pb)) }; var g1 = new Gaussian(1, 2); var g2 = new Gaussian(3, 4); var values = new[] { g1, g2 }; double meanDiff = g1.GetMean() - g2.GetMean(); var expected = new Gaussian( (pb * g1.GetMean()) + ((1 - pb) * g2.GetMean()), (pb * g1.GetVariance()) + ((1 - pb) * g2.GetVariance()) + (pb * (1 - pb) * meanDiff * meanDiff)); var actual = GateExitOp <double> .ExitAverageConditional(new Gaussian(), cases, values, new Gaussian()); Assert.True(actual.MaxDiff(expected) < 1e-4); }
// result = p(b=true) / (p(b=true) + p(b=false)) // = 1 / (1 + p(b=false)/p(b=true)) // = 1 / (1 + exp(-(log p(b=true) - log p(b=false))) // where cases[0].LogOdds = log p(b=true) // cases[1].LogOdds = log p(b=false) /// <summary> /// EP message to 'b'. /// </summary> /// <param name="cases">Incoming message from 'cases'. Must be a proper distribution. If all elements are uniform, the result will be uniform.</param> /// <returns>The outgoing EP message to the 'b' argument.</returns> /// <remarks><para> /// The outgoing message is the integral of the factor times incoming messages, over all arguments except 'b'. /// The formula is <c>int f(b,x) q(x) dx</c> where <c>x = (cases)</c>. /// </para></remarks> /// <exception cref="ImproperMessageException"><paramref name="cases"/> is not a proper distribution</exception> public static Bernoulli BAverageConditional([SkipIfAnyUniform] IList <Bernoulli> cases) { // avoid (-Infinity) - (-Infinity) if (cases[0].LogOdds == cases[1].LogOdds) { if (Double.IsNegativeInfinity(cases[0].LogOdds) && Double.IsNegativeInfinity(cases[1].LogOdds)) { throw new AllZeroException(); } return(new Bernoulli()); } else { return(Bernoulli.FromLogOdds(cases[0].LogOdds - cases[1].LogOdds)); } }
/// <summary>Computations that do not depend on observed values</summary> private void Constant() { if (this.Constant_isDone) { return; } Bernoulli vBernoulli0 = Bernoulli.FromLogOdds(0.40546510810816422); this.vbool0_marginal_F = Bernoulli.Uniform(); Bernoulli vbool0_selector_uses_B_toDef; // Message to 'vbool0_selector_uses' from Replicate factor vbool0_selector_uses_B_toDef = ReplicateOp_Divide.ToDefInit <Bernoulli>(vBernoulli0); // Message to 'vbool0_marginal' from Variable factor this.vbool0_marginal_F = VariableOp.MarginalAverageConditional <Bernoulli>(vbool0_selector_uses_B_toDef, vBernoulli0, this.vbool0_marginal_F); this.Constant_isDone = true; }
/// <summary>EP message to <c>sample</c>.</summary> /// <param name="probTrue">Incoming message from <c>probTrue</c>. Must be a proper distribution. If uniform, the result will be uniform.</param> /// <returns>The outgoing EP message to the <c>sample</c> argument.</returns> /// <remarks> /// <para>The outgoing message is a distribution matching the moments of <c>sample</c> as the random arguments are varied. The formula is <c>proj[p(sample) sum_(probTrue) p(probTrue) factor(sample,probTrue)]/p(sample)</c>.</para> /// </remarks> /// <exception cref="ImproperMessageException"> /// <paramref name="probTrue" /> is not a proper distribution.</exception> public static Bernoulli SampleAverageConditional([SkipIfUniform] Beta probTrue) { if (probTrue.IsPointMass) { return(new Bernoulli(probTrue.Point)); } else if (!probTrue.IsProper()) { throw new ImproperMessageException(probTrue); } else { // p(x=true) = trueCount/total // p(x=false) = falseCount/total // log(p(x=true)/p(x=false)) = log(trueCount/falseCount) return(Bernoulli.FromLogOdds(Math.Log(probTrue.TrueCount / probTrue.FalseCount))); } }
/// <summary>Computations that do not depend on observed values</summary> public void Constant() { if (this.Constant_iterationsDone == 1) { return; } this.vBernoulli30 = Bernoulli.FromLogOdds(1.3862943611198908); // Create array for 'Cloudy_selector_cases_uses' Backwards messages. this.Cloudy_selector_cases_uses_B = new DistributionStructArray <Bernoulli, bool> [4]; for (int _ind = 0; _ind < 4; _ind++) { // Create array for 'Cloudy_selector_cases_uses' Backwards messages. this.Cloudy_selector_cases_uses_B[_ind] = new DistributionStructArray <Bernoulli, bool>(2); } this.Constant_iterationsDone = 1; this.Changed_numberOfIterationsDecreased_WetGrass_iterationsDone = 0; this.Init_numberOfIterationsDecreased_WetGrass_iterationsDone = 0; }
/// <summary>VMP message to <c>sample</c>.</summary> /// <param name="probTrue">Incoming message from <c>probTrue</c>. Must be a proper distribution. If uniform, the result will be uniform.</param> /// <returns>The outgoing VMP message to the <c>sample</c> argument.</returns> /// <remarks> /// <para>The outgoing message is the exponential of the average log-factor value, where the average is over all arguments except <c>sample</c>. The formula is <c>exp(sum_(probTrue) p(probTrue) log(factor(sample,probTrue)))</c>.</para> /// </remarks> /// <exception cref="ImproperMessageException"> /// <paramref name="probTrue" /> is not a proper distribution.</exception> public static Bernoulli SampleAverageLogarithm([SkipIfUniform] Beta probTrue) { if (probTrue.IsPointMass) { return(new Bernoulli(probTrue.Point)); } else if (!probTrue.IsProper()) { throw new ImproperMessageException(probTrue); } else { // E[x*log(p) + (1-x)*log(1-p)] = x*E[log(p)] + (1-x)*E[log(1-p)] // p(x=true) = exp(E[log(p)])/(exp(E[log(p)]) + exp(E[log(1-p)])) // log(p(x=true)/p(x=false)) = E[log(p)] - E[log(1-p)] = digamma(trueCount) - digamma(falseCount) return(Bernoulli.FromLogOdds(MMath.Digamma(probTrue.TrueCount) - MMath.Digamma(probTrue.FalseCount))); } }
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="CasesOp"]/message_doc[@name="BAverageConditional(IList{Bernoulli})"]/*'/> public static Bernoulli BAverageConditional([SkipIfUniform] IList <Bernoulli> cases) { // result = p(b=true) / (p(b=true) + p(b=false)) // = 1 / (1 + p(b=false)/p(b=true)) // = 1 / (1 + exp(-(log p(b=true) - log p(b=false))) // where cases[0].LogOdds = log p(b=true) // cases[1].LogOdds = log p(b=false) if (cases[0].LogOdds == cases[1].LogOdds) // avoid (-Infinity) - (-Infinity) { if (Double.IsNegativeInfinity(cases[0].LogOdds) && Double.IsNegativeInfinity(cases[1].LogOdds)) { throw new AllZeroException(); } return(new Bernoulli()); } else { return(Bernoulli.FromLogOdds(cases[0].LogOdds - cases[1].LogOdds)); } }
/// <summary> /// VMP 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 the factor viewed as a function of 'array' with 'allTrue' integrated out. /// The formula is <c>sum_allTrue p(allTrue) factor(allTrue,array)</c>. /// </para></remarks> /// <exception cref="ImproperMessageException"><paramref name="allTrue"/> is not a proper distribution</exception> public static BernoulliList ArrayAverageLogarithm <BernoulliList>([SkipIfUniform] Bernoulli allTrue, IList <Bernoulli> array, BernoulliList result) where BernoulliList : IList <Bernoulli> { // when 'allTrue' is marginalized, the factor is proportional to exp(allTrue.LogOdds*prod_i a[i]) // therefore we maintain the value of prod_i E(a[i]) as we update each a[i]'s distribution double prodProbTrue = 1.0; for (int i = 0; i < array.Count; i++) { prodProbTrue *= array[i].GetProbTrue(); } for (int i = 0; i < result.Count; i++) { prodProbTrue /= array[i].GetProbTrue(); Bernoulli ratio = array[i] / result[i]; result[i] = Bernoulli.FromLogOdds(allTrue.LogOdds * prodProbTrue); Bernoulli newMarginal = ratio * result[i]; prodProbTrue *= newMarginal.GetProbTrue(); } return(result); }
/// <summary> /// Tests EP and BP gate enter ops for Bernoulli random variable for correctness given message parameters. /// </summary> /// <param name="valueProbTrue">Probability of being true for the variable entering the gate.</param> /// <param name="enterOneProbTrue">Probability of being true for the variable approximation inside the gate when the selector is true.</param> /// <param name="selectorProbTrue">Probability of being true for the selector variable.</param> private void DoBernoulliEnterTest(double valueProbTrue, double enterOneProbTrue, double selectorProbTrue) { var value = new Bernoulli(valueProbTrue); var enterOne = new Bernoulli(enterOneProbTrue); var selector = new Bernoulli(selectorProbTrue); var selectorInverse = new Bernoulli(selector.GetProbFalse()); var discreteSelector = new Discrete(selector.GetProbTrue(), selector.GetProbFalse()); var discreteSelectorInverse = new Discrete(selector.GetProbFalse(), selector.GetProbTrue()); var cases = new[] { Bernoulli.FromLogOdds(selector.GetLogProbTrue()), Bernoulli.FromLogOdds(selector.GetLogProbFalse()) }; // Compute expected message double logShift = enterOne.GetLogNormalizer() + value.GetLogNormalizer() - (value * enterOne).GetLogNormalizer(); double expectedProbTrue = selector.GetProbFalse() + (selector.GetProbTrue() * enterOne.GetProbTrue() * Math.Exp(logShift)); double expectedProbFalse = selector.GetProbFalse() + (selector.GetProbTrue() * enterOne.GetProbFalse() * Math.Exp(logShift)); double expectedNormalizer = expectedProbTrue + expectedProbFalse; expectedProbTrue /= expectedNormalizer; Bernoulli value1, value2; // Enter partial (bernoulli selector, first case) value1 = GateEnterPartialOp <bool> .ValueAverageConditional( new[] { enterOne }, selector, value, new[] { 0 }, new Bernoulli()); value2 = BeliefPropagationGateEnterPartialOp.ValueAverageConditional( new[] { enterOne }, selector, value, new[] { 0 }, new Bernoulli()); Assert.Equal(expectedProbTrue, value1.GetProbTrue(), 1e-4); Assert.Equal(expectedProbTrue, value2.GetProbTrue(), 1e-4); // Enter partial (bernoulli selector, second case) value1 = GateEnterPartialOp <bool> .ValueAverageConditional( new[] { enterOne }, selectorInverse, value, new[] { 1 }, new Bernoulli()); value2 = BeliefPropagationGateEnterPartialOp.ValueAverageConditional( new[] { enterOne }, selectorInverse, value, new[] { 1 }, new Bernoulli()); Assert.Equal(expectedProbTrue, value1.GetProbTrue(), 1e-4); Assert.Equal(expectedProbTrue, value2.GetProbTrue(), 1e-4); // Enter partial (bernoulli selector, both cases) value1 = GateEnterPartialOp <bool> .ValueAverageConditional( new[] { enterOne, Bernoulli.Uniform() }, selector, value, new[] { 0, 1 }, new Bernoulli()); value2 = BeliefPropagationGateEnterPartialOp.ValueAverageConditional( new[] { enterOne, Bernoulli.Uniform() }, selector, value, new[] { 0, 1 }, new Bernoulli()); Assert.Equal(expectedProbTrue, value1.GetProbTrue(), 1e-4); Assert.Equal(expectedProbTrue, value2.GetProbTrue(), 1e-4); // Enter partial (discrete selector, first case) value1 = GateEnterPartialOp <bool> .ValueAverageConditional( new[] { enterOne }, discreteSelector, value, new[] { 0 }, new Bernoulli()); value2 = BeliefPropagationGateEnterPartialOp.ValueAverageConditional( new[] { enterOne }, discreteSelector, value, new[] { 0 }, new Bernoulli()); Assert.Equal(expectedProbTrue, value1.GetProbTrue(), 1e-4); Assert.Equal(expectedProbTrue, value2.GetProbTrue(), 1e-4); // Enter partial (discrete selector, second case) value1 = GateEnterPartialOp <bool> .ValueAverageConditional( new[] { enterOne }, discreteSelectorInverse, value, new[] { 1 }, new Bernoulli()); value2 = BeliefPropagationGateEnterPartialOp.ValueAverageConditional( new[] { enterOne }, discreteSelectorInverse, value, new[] { 1 }, new Bernoulli()); Assert.Equal(expectedProbTrue, value1.GetProbTrue(), 1e-4); Assert.Equal(expectedProbTrue, value2.GetProbTrue(), 1e-4); // Enter partial (discrete selector, both cases) value1 = GateEnterPartialOp <bool> .ValueAverageConditional( new[] { enterOne, Bernoulli.Uniform() }, discreteSelector, value, new[] { 0, 1 }, new Bernoulli()); value2 = BeliefPropagationGateEnterPartialOp.ValueAverageConditional( new[] { enterOne, Bernoulli.Uniform() }, discreteSelector, value, new[] { 0, 1 }, new Bernoulli()); Assert.Equal(expectedProbTrue, value1.GetProbTrue(), 1e-4); Assert.Equal(expectedProbTrue, value2.GetProbTrue(), 1e-4); // Enter one (discrete selector, first case) value1 = GateEnterOneOp <bool> .ValueAverageConditional( enterOne, discreteSelector, value, 0, new Bernoulli()); value2 = BeliefPropagationGateEnterOneOp.ValueAverageConditional( enterOne, discreteSelector, value, 0, new Bernoulli()); Assert.Equal(expectedProbTrue, value1.GetProbTrue(), 1e-4); Assert.Equal(expectedProbTrue, value2.GetProbTrue(), 1e-4); // Enter one (discrete selector, second case) value1 = GateEnterOneOp <bool> .ValueAverageConditional( enterOne, discreteSelectorInverse, value, 1, new Bernoulli()); value2 = BeliefPropagationGateEnterOneOp.ValueAverageConditional( enterOne, discreteSelectorInverse, value, 1, new Bernoulli()); Assert.Equal(expectedProbTrue, value1.GetProbTrue(), 1e-4); Assert.Equal(expectedProbTrue, value2.GetProbTrue(), 1e-4); // Enter partial two (first case) value1 = GateEnterPartialTwoOp.ValueAverageConditional( new[] { enterOne }, cases[0], cases[1], value, new[] { 0 }, new Bernoulli()); value2 = BeliefPropagationGateEnterPartialTwoOp.ValueAverageConditional( new[] { enterOne }, cases[0], cases[1], value, new[] { 0 }, new Bernoulli()); Assert.Equal(expectedProbTrue, value1.GetProbTrue(), 1e-4); Assert.Equal(expectedProbTrue, value2.GetProbTrue(), 1e-4); // Enter partial two (second case) value1 = GateEnterPartialTwoOp.ValueAverageConditional( new[] { enterOne }, cases[1], cases[0], value, new[] { 1 }, new Bernoulli()); value2 = BeliefPropagationGateEnterPartialTwoOp.ValueAverageConditional( new[] { enterOne }, cases[1], cases[0], value, new[] { 1 }, new Bernoulli()); Assert.Equal(expectedProbTrue, value1.GetProbTrue(), 1e-4); Assert.Equal(expectedProbTrue, value2.GetProbTrue(), 1e-4); // Enter partial two (both cases) value1 = GateEnterPartialTwoOp.ValueAverageConditional( new[] { enterOne, Bernoulli.Uniform() }, cases[0], cases[1], value, new[] { 0, 1 }, new Bernoulli()); value2 = BeliefPropagationGateEnterPartialTwoOp.ValueAverageConditional( new[] { enterOne, Bernoulli.Uniform() }, cases[0], cases[1], value, new[] { 0, 1 }, new Bernoulli()); Assert.Equal(expectedProbTrue, value1.GetProbTrue(), 1e-4); Assert.Equal(expectedProbTrue, value2.GetProbTrue(), 1e-4); // Enter (discrete selector) value1 = GateEnterOp <bool> .ValueAverageConditional( new[] { enterOne, Bernoulli.Uniform() }, discreteSelector, value, new Bernoulli()); value2 = BeliefPropagationGateEnterOp.ValueAverageConditional( new[] { enterOne, Bernoulli.Uniform() }, discreteSelector, value, new Bernoulli()); Assert.Equal(expectedProbTrue, value1.GetProbTrue(), 1e-4); Assert.Equal(expectedProbTrue, value2.GetProbTrue(), 1e-4); }
/// <summary>Computations that depend on the observed value of FeatureCount and FeatureValues and InstanceCount and Labels and numberOfIterations and WeightConstraints and WeightPriors</summary> /// <param name="numberOfIterations">The number of times to iterate each loop</param> private void Changed_FeatureCount_FeatureValues_InstanceCount_Labels_numberOfIterations_WeightConstraints_WeightP8(int numberOfIterations) { if (this.Changed_FeatureCount_FeatureValues_InstanceCount_Labels_numberOfIterations_WeightConstraints_WeightP8_isDone) { return; } for (int iteration = this.numberOfIterationsDone; iteration < numberOfIterations; iteration++) { for (int FeatureRange = 0; FeatureRange < this.featureCount; FeatureRange++) { this.Weights_depth1_rep_F_marginal[FeatureRange] = ReplicateOp_Divide.Marginal <Gaussian>(this.Weights_depth1_rep_B_toDef[FeatureRange], this.Weights_uses_F[1][FeatureRange], this.Weights_depth1_rep_F_marginal[FeatureRange]); } for (int InstanceRange = 0; InstanceRange < this.instanceCount; InstanceRange++) { for (int FeatureRange = 0; FeatureRange < this.featureCount; FeatureRange++) { this.Weights_depth1_rep_F[FeatureRange][InstanceRange] = ReplicateOp_Divide.UsesAverageConditional <Gaussian>(this.Weights_depth1_rep_B[FeatureRange][InstanceRange], this.Weights_depth1_rep_F_marginal[FeatureRange], InstanceRange, this.Weights_depth1_rep_F[FeatureRange][InstanceRange]); this.FeatureScores_F[InstanceRange][FeatureRange] = GaussianProductOpBase.ProductAverageConditional(this.featureValues[InstanceRange][FeatureRange], this.Weights_depth1_rep_F[FeatureRange][InstanceRange]); } this.Score_F[InstanceRange] = FastSumOp.SumAverageConditional(this.FeatureScores_F[InstanceRange]); this.NoisyScore_F[InstanceRange] = GaussianFromMeanAndVarianceOp.SampleAverageConditional(this.Score_F[InstanceRange], 1.0); this.NoisyScore_use_B[InstanceRange] = IsPositiveOp_Proper.XAverageConditional(Bernoulli.PointMass(this.labels[InstanceRange]), this.NoisyScore_F[InstanceRange]); this.Score_B[InstanceRange] = GaussianFromMeanAndVarianceOp.MeanAverageConditional(this.NoisyScore_use_B[InstanceRange], 1.0); this.FeatureScores_B[InstanceRange] = FastSumOp.ArrayAverageConditional <DistributionStructArray <Gaussian, double> >(this.Score_B[InstanceRange], this.Score_F[InstanceRange], this.FeatureScores_F[InstanceRange], this.FeatureScores_B[InstanceRange]); for (int FeatureRange = 0; FeatureRange < this.featureCount; FeatureRange++) { this.Weights_depth1_rep_B[FeatureRange][InstanceRange] = GaussianProductOpBase.BAverageConditional(this.FeatureScores_B[InstanceRange][FeatureRange], this.featureValues[InstanceRange][FeatureRange]); this.Weights_depth1_rep_F_marginal[FeatureRange] = ReplicateOp_Divide.MarginalIncrement <Gaussian>(this.Weights_depth1_rep_F_marginal[FeatureRange], this.Weights_depth1_rep_F[FeatureRange][InstanceRange], this.Weights_depth1_rep_B[FeatureRange][InstanceRange]); } } for (int FeatureRange = 0; FeatureRange < this.featureCount; FeatureRange++) { this.Weights_depth1_rep_B_toDef[FeatureRange] = ReplicateOp_Divide.ToDef <Gaussian>(this.Weights_depth1_rep_B[FeatureRange], this.Weights_depth1_rep_B_toDef[FeatureRange]); } this.OnProgressChanged(new ProgressChangedEventArgs(iteration)); } for (int _iv = 0; _iv < this.featureCount; _iv++) { this.Weights_uses_B[1][_iv] = ArrayHelper.SetTo <Gaussian>(this.Weights_uses_B[1][_iv], this.Weights_depth1_rep_B_toDef[_iv]); } this.Weights_uses_F[0] = ReplicateOp_NoDivide.UsesAverageConditional <DistributionStructArray <Gaussian, double> >(this.Weights_uses_B, this.weightPriors, 0, this.Weights_uses_F[0]); this.ModelSelector_selector_cases_0_uses_B[6] = Bernoulli.FromLogOdds(ReplicateOp.LogEvidenceRatio <DistributionStructArray <Gaussian, double> >(this.Weights_uses_B, this.weightPriors, this.Weights_uses_F)); this.ModelSelector_selector_cases_0_uses_B[7] = Bernoulli.FromLogOdds(ConstrainEqualRandomOp <double[]> .LogEvidenceRatio <DistributionStructArray <Gaussian, double> >(this.Weights_uses_F[0], this.weightConstraints)); for (int FeatureRange = 0; FeatureRange < this.featureCount; FeatureRange++) { this.ModelSelector_selector_cases_0_rep3_uses_B[FeatureRange][1] = Bernoulli.FromLogOdds(ReplicateOp.LogEvidenceRatio <Gaussian>(this.Weights_depth1_rep_B[FeatureRange], this.Weights_uses_F[1][FeatureRange], this.Weights_depth1_rep_F[FeatureRange])); this.ModelSelector_selector_cases_0_rep3_B[FeatureRange] = ReplicateOp_NoDivide.DefAverageConditional <Bernoulli>(this.ModelSelector_selector_cases_0_rep3_uses_B[FeatureRange], this.ModelSelector_selector_cases_0_rep3_B[FeatureRange]); } this.ModelSelector_selector_cases_0_uses_B[12] = ReplicateOp_NoDivide.DefAverageConditional <Bernoulli>(this.ModelSelector_selector_cases_0_rep3_B, this.ModelSelector_selector_cases_0_uses_B[12]); for (int InstanceRange = 0; InstanceRange < this.instanceCount; InstanceRange++) { this.ModelSelector_selector_cases_0_rep8_B[InstanceRange] = Bernoulli.FromLogOdds(IsPositiveOp.LogEvidenceRatio(this.labels[InstanceRange], this.NoisyScore_F[InstanceRange])); } this.ModelSelector_selector_cases_0_uses_B[17] = ReplicateOp_NoDivide.DefAverageConditional <Bernoulli>(this.ModelSelector_selector_cases_0_rep8_B, this.ModelSelector_selector_cases_0_uses_B[17]); this.ModelSelector_selector_cases_0_B = ReplicateOp_NoDivide.DefAverageConditional <Bernoulli>(this.ModelSelector_selector_cases_0_uses_B, this.ModelSelector_selector_cases_0_B); this.ModelSelector_selector_cases_B[0] = ArrayHelper.SetTo <Bernoulli>(this.ModelSelector_selector_cases_B[0], this.ModelSelector_selector_cases_0_B); this.ModelSelector_selector_B = CasesOp.BAverageConditional(this.ModelSelector_selector_cases_B); this.ModelSelector_marginal_F = VariableOp.MarginalAverageConditional <Bernoulli>(this.ModelSelector_selector_B, this.vBernoulli0, this.ModelSelector_marginal_F); this.Weights_use_B = ReplicateOp_NoDivide.DefAverageConditional <DistributionStructArray <Gaussian, double> >(this.Weights_uses_B, this.Weights_use_B); this.Weights_marginal_F = VariableOp.MarginalAverageConditional <DistributionStructArray <Gaussian, double> >(this.Weights_use_B, this.weightPriors, this.Weights_marginal_F); this.Changed_FeatureCount_FeatureValues_InstanceCount_Labels_numberOfIterations_WeightConstraints_WeightP8_isDone = true; }
/// <summary> /// EP message to 'and'. /// </summary> /// <param name="A">Incoming message from 'a'.</param> /// <param name="B">Incoming message from 'b'.</param> /// <returns>The outgoing EP message to the 'and' argument.</returns> /// <remarks><para> /// The outgoing message is the integral of the factor times incoming messages, over all arguments except 'and'. /// The formula is <c>int f(and,x) q(x) dx</c> where <c>x = (a,b)</c>. /// </para></remarks> public static Bernoulli AndAverageConditional(Bernoulli A, Bernoulli B) { return(Bernoulli.FromLogOdds(-Bernoulli.Or(-A.LogOdds, -B.LogOdds))); }
/// <summary> /// VMP 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">Constant value for 'b'.</param> /// <returns>The outgoing VMP message to the 'a' argument.</returns> /// <remarks><para> /// The outgoing message is the exponential of the integral of the log-factor times incoming messages, over all arguments except 'a'. /// The formula is <c>int log(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 AAverageLogarithm([SkipIfUniform] Bernoulli and, bool B) { return(Bernoulli.FromLogOdds(B ? and.LogOdds : 0.0)); }
/// <summary> /// VMP 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 VMP message to the 'a' argument.</returns> /// <remarks><para> /// The outgoing message is the exponential of the integral of the log-factor times incoming messages, over all arguments except 'a'. /// The formula is <c>int log(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 AAverageLogarithm([SkipIfUniform] Bernoulli and, Bernoulli B) { // when 'and' is marginalized, the factor is proportional to exp(A*B*and.LogOdds) return(Bernoulli.FromLogOdds(and.LogOdds * B.GetProbTrue())); }
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GateExitOp{T}"]/message_doc[@name="CasesAverageConditional{TDist}(TDist, IList{T}, int)"]/*'/> /// <typeparam name="TDist">The type of the distribution over the variable exiting the gate.</typeparam> public static Bernoulli CasesAverageConditional <TDist>(TDist exit, IList <T> values, int resultIndex) where TDist : CanGetLogProb <T> { return(Bernoulli.FromLogOdds(exit.GetLogProb(values[resultIndex]))); }
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GateExitTwoOp"]/message_doc[@name="Case1AverageLogarithm{TExit}(TExit, IList{TExit})"]/*'/> /// <typeparam name="TExit">The type of the distribution over the variable exiting the gate.</typeparam> public static Bernoulli Case1AverageLogarithm <TExit>(TExit exitTwo, [SkipIfAllUniform, Proper] IList <TExit> values) where TExit : CanGetAverageLog <TExit> { return(Bernoulli.FromLogOdds(values[1].GetAverageLog(exitTwo))); }
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GateExitTwoOp"]/message_doc[@name="Case1AverageConditional{TExit, TExitDomain}(TExit, IList{TExitDomain})"]/*'/> /// <typeparam name="TExit">The type of the distribution over the variable exiting the gate.</typeparam> /// <typeparam name="TExitDomain">The domain of the variable exiting the gate.</typeparam> public static Bernoulli Case1AverageConditional <TExit, TExitDomain>(TExit exitTwo, IList <TExitDomain> values) where TExit : CanGetLogProb <TExitDomain> { return(Bernoulli.FromLogOdds(exitTwo.GetLogProb(values[1]))); }
[NoTriggers] // see VmpTests.GateExitTriggerTest public static Bernoulli CasesAverageLogarithm <TDist>( [SkipIfUniform] TDist exit, [SkipIfAllUniform, Proper, Trigger] IList <TDist> values, int resultIndex) where TDist : CanGetAverageLog <TDist> { return(Bernoulli.FromLogOdds(values[resultIndex].GetAverageLog(exit))); }