Exemplo n.º 1
0
        /// <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);
        }