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 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); } } } }