コード例 #1
0
ファイル: EnumTests.cs プロジェクト: ScriptBox21/dotnet-infer
        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);
        }
コード例 #2
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);
                    }
                }
            }
        }