public void ConstrainEqualGateExitTest3() { double bPrior = 0.1; var b = Variable.Bernoulli(bPrior).Named("b"); var x = Variable.New <bool>().Named("x"); using (Variable.If(b)) { x.SetTo(Variable.Bernoulli(0.2)); Variable.ConstrainEqual(x, true); } using (Variable.IfNot(b)) { x.SetTo(Variable.Bernoulli(0.3)); Variable.ConstrainEqual(x, false); } Variable.ConstrainEqual(b, true); bPrior = 1; InferenceEngine engine = new InferenceEngine(); Bernoulli xActual = engine.Infer <Bernoulli>(x); double evExpected = bPrior * 0.2 + (1 - bPrior); Bernoulli xExpected = new Bernoulli((bPrior * 0.2 + (1 - bPrior) * 0.3) / evExpected); Console.WriteLine("x = {0} should be {1}", xActual, xExpected); Assert.True(xExpected.MaxDiff(xActual) < 1e-10); }
public void ConstrainEqualGateExitTest() { double bPrior = 0.1; var b = Variable.Bernoulli(bPrior).Named("b"); var x = Variable.New <bool>().Named("x"); using (Variable.If(b)) { if (true) { x.SetTo(Variable.Bernoulli(0.2)); Variable.ConstrainEqual(x, true); } else { // this is what the above code should transform into var y = Variable.Bernoulli(0.2); Variable.ConstrainEqual(y, true); x.SetTo(Variable.Copy(Variable.Constant(true))); } } using (Variable.IfNot(b)) { x.SetTo(Variable.Bernoulli(0.3)); } InferenceEngine engine = new InferenceEngine(); Bernoulli xActual = engine.Infer <Bernoulli>(x); double evExpected = bPrior * 0.2 + (1 - bPrior); Bernoulli xExpected = new Bernoulli((bPrior * 0.2 + (1 - bPrior) * 0.3) / evExpected); Console.WriteLine("x = {0} should be {1}", xActual, xExpected); Assert.True(xExpected.MaxDiff(xActual) < 1e-10); }
public void EulerProject205() { // Peter has nine four-sided (pyramidal) dice, each with faces numbered 1, 2, 3, 4. // Colin has six six-sided (cubic) dice, each with faces numbered 1, 2, 3, 4, 5, 6. // // Peter and Colin roll their dice and compare totals: the highest total wins. // The result is a draw if the totals are equal. // // What is the probability that Pyramidal Pete beats Cubic Colin? // http://projecteuler.net/index.php?section=problems&id=205 // We encode this problem by using variables sum[0] for Peter and sum[1] for Colin. // Ideally, we want to add up dice variables that range from 1-4 and 1-6. // However, integers in Infer.NET must start from 0. // One approach is to use dice that range from 0-4 and 0-6, with zero probability on the value 0. // Another approach is to use dice that range 0-3 and 0-5, and add an offset at the end. // We use the second approach here. int[] numSides = new int[2] { 4, 6 }; Vector[] probs = new Vector[2]; for (int i = 0; i < 2; i++) { probs[i] = Vector.Constant(numSides[i], 1.0 / numSides[i]); } int[] numDice = new int[] { 9, 6 }; Variable <int>[] sum = new Variable <int> [2]; for (int i = 0; i < 2; i++) { sum[i] = Variable.Discrete(probs[i]).Named("die" + i + "0"); for (int j = 1; j < numDice[i]; j++) { sum[i] += Variable.Discrete(probs[i]).Named("die" + i + j); } } for (int i = 0; i < 2; i++) { // add an offset due to zero-based integers sum[i] += numDice[i]; } sum[0].Name = "sum0"; sum[1].Name = "sum1"; Variable <bool> win = sum[0] > sum[1]; win.Name = "win"; InferenceEngine engine = new InferenceEngine(); engine.NumberOfIterations = 1; // Only one iteration needed Bernoulli winMarginal = engine.Infer <Bernoulli>(win); Console.WriteLine("{0:0.0000000}", winMarginal.GetProbTrue()); Bernoulli winExpected = new Bernoulli(0.5731441); Assert.True(winExpected.MaxDiff(winMarginal) < 1e-7); }
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 TestBossPredictor() { InferenceEngine engine = new InferenceEngine(new ExpectationPropagation()); //compiler.BrowserMode = ModelCompiler.BrowserModeOptions.ALWAYS; engine.Compiler.DeclarationProvider = Microsoft.ML.Probabilistic.Compiler.RoslynDeclarationProvider.Instance; var ca = engine.Compiler.Compile(BossPredictorModel, true); ca.Execute(10); Console.WriteLine("Probability of approving trip (raining)=" + ca.Marginal("approvesTrip")); Bernoulli expected = new Bernoulli(0.71); Bernoulli actual = ca.Marginal <Bernoulli>("approvesTrip"); Assert.True(expected.MaxDiff(actual) < 1e-10); ca.SetObservedValue("isRaining", false); ca.Execute(10); Console.WriteLine("Probability of approving trip (not raining)=" + ca.Marginal("approvesTrip")); expected = new Bernoulli(0.85); actual = ca.Marginal <Bernoulli>("approvesTrip"); Assert.True(expected.MaxDiff(actual) < 1e-10); }
public void ConstrainEqualManyToOneTest() { double bPrior = 0.1; double cPrior = 0.2; var c = Variable.Bernoulli(cPrior).Named("c"); Range i = new Range(2).Named("i"); var bools = Variable.Array <bool>(i).Named("bools"); using (Variable.ForEach(i)) { bools[i] = Variable.Bernoulli(bPrior); Variable.ConstrainEqual(bools[i], c); } bools.ObservedValue = new bool[] { true, true }; InferenceEngine engine = new InferenceEngine(); Bernoulli cActual = engine.Infer <Bernoulli>(c); Bernoulli cExpected = new Bernoulli(1); Console.WriteLine("c = {0} should be {1}", cActual, cExpected); Assert.True(cExpected.MaxDiff(cActual) < 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); } } } }