/// <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);
        }
        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);
        }
        /// <summary>Computations that depend on the observed value of numberOfIterationsDecreased and WetGrass</summary>
        /// <param name="numberOfIterations">The number of times to iterate each loop</param>
        public void Changed_numberOfIterationsDecreased_WetGrass(int numberOfIterations)
        {
            if (this.Changed_numberOfIterationsDecreased_WetGrass_iterationsDone == numberOfIterations)
            {
                return;
            }
            // The constant 'vBernoulli32'
            Bernoulli vBernoulli32 = Bernoulli.FromLogOdds(4.5951198501345889);

            this.WetGrass_marginal = ArrayHelper.MakeUniform <Bernoulli>(vBernoulli32);
            this.WetGrass_marginal = Distribution.SetPoint <Bernoulli, bool>(this.WetGrass_marginal, this.wetGrass);
            Bernoulli Rain_F = ArrayHelper.MakeUniform <Bernoulli>(this.vBernoulli30);
            // The constant 'vBernoulli27'
            Bernoulli vBernoulli27 = Bernoulli.FromLogOdds(0);

            this.Cloudy_marginal_F = ArrayHelper.MakeUniform <Bernoulli>(vBernoulli27);
            DistributionStructArray <Bernoulli, bool> Rain_cond_Cloudy_F = default(DistributionStructArray <Bernoulli, bool>);

            // Create array for 'Rain_cond_Cloudy' Forwards messages.
            Rain_cond_Cloudy_F = new DistributionStructArray <Bernoulli, bool>(2);
            for (int _gateind = 0; _gateind < 2; _gateind++)
            {
                Rain_cond_Cloudy_F[_gateind] = ArrayHelper.MakeUniform <Bernoulli>(this.vBernoulli30);
            }
            // Message to 'Rain_cond_Cloudy' from Copy factor
            Rain_cond_Cloudy_F[0] = Factor.Copy <Bernoulli>(this.vBernoulli30);
            // The constant 'vBernoulli31'
            Bernoulli vBernoulli31 = Bernoulli.FromLogOdds(-1.3862943611198906);

            // Message to 'Rain_cond_Cloudy' from Copy factor
            Rain_cond_Cloudy_F[1] = Factor.Copy <Bernoulli>(vBernoulli31);
            DistributionStructArray <Bernoulli, bool> Cloudy_selector_cases_F = default(DistributionStructArray <Bernoulli, bool>);

            // Create array for 'Cloudy_selector_cases' Forwards messages.
            Cloudy_selector_cases_F = new DistributionStructArray <Bernoulli, bool>(2);
            for (int _iv0 = 0; _iv0 < 2; _iv0++)
            {
                Cloudy_selector_cases_F[_iv0] = ArrayHelper.MakeUniform <Bernoulli>(new Bernoulli());
            }
            // Message to 'Cloudy_selector_cases' from Cases factor
            Cloudy_selector_cases_F = CasesOp.CasesAverageConditional <DistributionStructArray <Bernoulli, bool> >(vBernoulli27, Cloudy_selector_cases_F);
            // The constant 'vBernoulli28'
            Bernoulli vBernoulli28 = Bernoulli.FromLogOdds(-2.1972245773362191);
            DistributionStructArray <Bernoulli, bool> Sprinkler_cond_Cloudy_F = default(DistributionStructArray <Bernoulli, bool>);

            // Create array for 'Sprinkler_cond_Cloudy' Forwards messages.
            Sprinkler_cond_Cloudy_F = new DistributionStructArray <Bernoulli, bool>(2);
            for (int _gateind = 0; _gateind < 2; _gateind++)
            {
                Sprinkler_cond_Cloudy_F[_gateind] = ArrayHelper.MakeUniform <Bernoulli>(vBernoulli28);
            }
            // Message to 'Sprinkler_cond_Cloudy' from Copy factor
            Sprinkler_cond_Cloudy_F[0] = Factor.Copy <Bernoulli>(vBernoulli28);
            // Message to 'Sprinkler_cond_Cloudy' from Copy factor
            Sprinkler_cond_Cloudy_F[1] = Factor.Copy <Bernoulli>(vBernoulli27);
            Bernoulli Rain_cond_Sprinkler_0_selector_cases_0_B = ArrayHelper.MakeUniform <Bernoulli>(new Bernoulli());

            // Message to 'Rain_cond_Sprinkler_0_selector_cases_0' from Random factor
            Rain_cond_Sprinkler_0_selector_cases_0_B = Bernoulli.FromLogOdds(UnaryOp <bool> .LogEvidenceRatio <Bernoulli>(this.wetGrass, vBernoulli32));
            DistributionStructArray <Bernoulli, bool> Rain_cond_Sprinkler_0_selector_cases_B = default(DistributionStructArray <Bernoulli, bool>);

            // Create array for 'Rain_cond_Sprinkler_0_selector_cases' Backwards messages.
            Rain_cond_Sprinkler_0_selector_cases_B = new DistributionStructArray <Bernoulli, bool>(2);
            for (int _ind0 = 0; _ind0 < 2; _ind0++)
            {
                Rain_cond_Sprinkler_0_selector_cases_B[_ind0] = ArrayHelper.MakeUniform <Bernoulli>(new Bernoulli());
            }
            // Message to 'Rain_cond_Sprinkler_0_selector_cases' from Copy factor
            Rain_cond_Sprinkler_0_selector_cases_B[0] = Factor.Copy <Bernoulli>(Rain_cond_Sprinkler_0_selector_cases_0_B);
            // The constant 'vBernoulli33'
            Bernoulli vBernoulli33 = Bernoulli.FromLogOdds(2.1972245773362196);
            Bernoulli Rain_cond_Sprinkler_0_selector_cases_1_B = ArrayHelper.MakeUniform <Bernoulli>(new Bernoulli());

            // Message to 'Rain_cond_Sprinkler_0_selector_cases_1' from Random factor
            Rain_cond_Sprinkler_0_selector_cases_1_B = Bernoulli.FromLogOdds(UnaryOp <bool> .LogEvidenceRatio <Bernoulli>(this.wetGrass, vBernoulli33));
            // Message to 'Rain_cond_Sprinkler_0_selector_cases' from Copy factor
            Rain_cond_Sprinkler_0_selector_cases_B[1] = Factor.Copy <Bernoulli>(Rain_cond_Sprinkler_0_selector_cases_1_B);
            Bernoulli[] Sprinkler_selector_cases_0_uses_B = default(Bernoulli[]);
            // Create array for 'Sprinkler_selector_cases_0_uses' Backwards messages.
            Sprinkler_selector_cases_0_uses_B = new Bernoulli[5];
            for (int _ind = 0; _ind < 5; _ind++)
            {
                Sprinkler_selector_cases_0_uses_B[_ind] = ArrayHelper.MakeUniform <Bernoulli>(new Bernoulli());
            }
            Bernoulli Sprinkler_selector_cases_0_B = ArrayHelper.MakeUniform <Bernoulli>(new Bernoulli());
            DistributionStructArray <Bernoulli, bool> Sprinkler_selector_cases_B = default(DistributionStructArray <Bernoulli, bool>);

            // Create array for 'Sprinkler_selector_cases' Backwards messages.
            Sprinkler_selector_cases_B = new DistributionStructArray <Bernoulli, bool>(2);
            for (int _ind0 = 0; _ind0 < 2; _ind0++)
            {
                Sprinkler_selector_cases_B[_ind0] = ArrayHelper.MakeUniform <Bernoulli>(new Bernoulli());
            }
            Bernoulli Rain_cond_Sprinkler_1_selector_cases_0_B = ArrayHelper.MakeUniform <Bernoulli>(new Bernoulli());

            // Message to 'Rain_cond_Sprinkler_1_selector_cases_0' from Random factor
            Rain_cond_Sprinkler_1_selector_cases_0_B = Bernoulli.FromLogOdds(UnaryOp <bool> .LogEvidenceRatio <Bernoulli>(this.wetGrass, vBernoulli33));
            DistributionStructArray <Bernoulli, bool> Rain_cond_Sprinkler_1_selector_cases_B = default(DistributionStructArray <Bernoulli, bool>);

            // Create array for 'Rain_cond_Sprinkler_1_selector_cases' Backwards messages.
            Rain_cond_Sprinkler_1_selector_cases_B = new DistributionStructArray <Bernoulli, bool>(2);
            for (int _ind0 = 0; _ind0 < 2; _ind0++)
            {
                Rain_cond_Sprinkler_1_selector_cases_B[_ind0] = ArrayHelper.MakeUniform <Bernoulli>(new Bernoulli());
            }
            // Message to 'Rain_cond_Sprinkler_1_selector_cases' from Copy factor
            Rain_cond_Sprinkler_1_selector_cases_B[0] = Factor.Copy <Bernoulli>(Rain_cond_Sprinkler_1_selector_cases_0_B);
            // The constant 'vBernoulli35'
            Bernoulli vBernoulli35 = Bernoulli.FromLogOdds(Double.NegativeInfinity);
            Bernoulli Rain_cond_Sprinkler_1_selector_cases_1_B = ArrayHelper.MakeUniform <Bernoulli>(new Bernoulli());

            // Message to 'Rain_cond_Sprinkler_1_selector_cases_1' from Random factor
            Rain_cond_Sprinkler_1_selector_cases_1_B = Bernoulli.FromLogOdds(UnaryOp <bool> .LogEvidenceRatio <Bernoulli>(this.wetGrass, vBernoulli35));
            // Message to 'Rain_cond_Sprinkler_1_selector_cases' from Copy factor
            Rain_cond_Sprinkler_1_selector_cases_B[1] = Factor.Copy <Bernoulli>(Rain_cond_Sprinkler_1_selector_cases_1_B);
            Bernoulli[] Sprinkler_selector_cases_1_uses_B = default(Bernoulli[]);
            // Create array for 'Sprinkler_selector_cases_1_uses' Backwards messages.
            Sprinkler_selector_cases_1_uses_B = new Bernoulli[5];
            for (int _ind = 0; _ind < 5; _ind++)
            {
                Sprinkler_selector_cases_1_uses_B[_ind] = ArrayHelper.MakeUniform <Bernoulli>(new Bernoulli());
            }
            Bernoulli Sprinkler_selector_cases_1_B = ArrayHelper.MakeUniform <Bernoulli>(new Bernoulli());

            Bernoulli[] Sprinkler_selector_uses_B = default(Bernoulli[]);
            // Create array for 'Sprinkler_selector_uses' Backwards messages.
            Sprinkler_selector_uses_B = new Bernoulli[2];
            for (int _ind = 0; _ind < 2; _ind++)
            {
                Sprinkler_selector_uses_B[_ind] = ArrayHelper.MakeUniform <Bernoulli>(vBernoulli28);
            }
            Bernoulli Sprinkler_selector_B = ArrayHelper.MakeUniform <Bernoulli>(vBernoulli28);
            // Buffer for Replicate2BufferOp.UsesAverageConditional<DistributionStructArray<Bernoulli,bool>>
            DistributionStructArray <Bernoulli, bool> Cloudy_selector_cases_uses_B_marginal = default(DistributionStructArray <Bernoulli, bool>);

            // Message to 'Cloudy_selector_cases_uses' from Replicate factor
            Cloudy_selector_cases_uses_B_marginal = Replicate2BufferOp.MarginalInit <DistributionStructArray <Bernoulli, bool> >(Cloudy_selector_cases_F);
            DistributionStructArray <Bernoulli, bool>[] Cloudy_selector_cases_uses_F = default(DistributionStructArray <Bernoulli, bool>[]);
            // Create array for 'Cloudy_selector_cases_uses' Forwards messages.
            Cloudy_selector_cases_uses_F = new DistributionStructArray <Bernoulli, bool> [4];
            for (int _ind = 0; _ind < 4; _ind++)
            {
                // Create array for 'Cloudy_selector_cases_uses' Forwards messages.
                Cloudy_selector_cases_uses_F[_ind] = new DistributionStructArray <Bernoulli, bool>(2);
                for (int _iv0 = 0; _iv0 < 2; _iv0++)
                {
                    Cloudy_selector_cases_uses_F[_ind][_iv0] = ArrayHelper.MakeUniform <Bernoulli>(new Bernoulli());
                }
            }
            Bernoulli Sprinkler_F = ArrayHelper.MakeUniform <Bernoulli>(vBernoulli28);
            // Buffer for Replicate2BufferOp.UsesAverageConditional<Bernoulli>
            Bernoulli Sprinkler_selector_uses_B_marginal = default(Bernoulli);

            // Message to 'Sprinkler_selector_uses' from Replicate factor
            Sprinkler_selector_uses_B_marginal = Replicate2BufferOp.MarginalInit <Bernoulli>(Sprinkler_F);
            Bernoulli[] Sprinkler_selector_uses_F = default(Bernoulli[]);
            // Create array for 'Sprinkler_selector_uses' Forwards messages.
            Sprinkler_selector_uses_F = new Bernoulli[2];
            for (int _ind = 0; _ind < 2; _ind++)
            {
                Sprinkler_selector_uses_F[_ind] = ArrayHelper.MakeUniform <Bernoulli>(vBernoulli28);
            }
            Bernoulli Rain_cond_Sprinkler_0_selector_B = ArrayHelper.MakeUniform <Bernoulli>(this.vBernoulli30);

            // Message to 'Rain_cond_Sprinkler_0_selector' from Cases factor
            Rain_cond_Sprinkler_0_selector_B = CasesOp.BAverageConditional(Rain_cond_Sprinkler_0_selector_cases_B);
            DistributionStructArray <Bernoulli, bool> Rain_cond_Sprinkler_B = default(DistributionStructArray <Bernoulli, bool>);

            // Create array for 'Rain_cond_Sprinkler' Backwards messages.
            Rain_cond_Sprinkler_B = new DistributionStructArray <Bernoulli, bool>(2);
            for (int _gateind = 0; _gateind < 2; _gateind++)
            {
                Rain_cond_Sprinkler_B[_gateind] = ArrayHelper.MakeUniform <Bernoulli>(this.vBernoulli30);
            }
            // Message to 'Rain_cond_Sprinkler' from Copy factor
            Rain_cond_Sprinkler_B[0] = Factor.Copy <Bernoulli>(Rain_cond_Sprinkler_0_selector_B);
            Bernoulli Rain_cond_Sprinkler_1_selector_B = ArrayHelper.MakeUniform <Bernoulli>(this.vBernoulli30);

            // Message to 'Rain_cond_Sprinkler_1_selector' from Cases factor
            Rain_cond_Sprinkler_1_selector_B = CasesOp.BAverageConditional(Rain_cond_Sprinkler_1_selector_cases_B);
            // Message to 'Rain_cond_Sprinkler' from Copy factor
            Rain_cond_Sprinkler_B[1] = Factor.Copy <Bernoulli>(Rain_cond_Sprinkler_1_selector_B);
            for (int iteration = this.Changed_numberOfIterationsDecreased_WetGrass_iterationsDone; iteration < numberOfIterations; iteration++)
            {
                // Message to 'Cloudy_selector_cases_uses' from Replicate factor
                Cloudy_selector_cases_uses_B_marginal = Replicate2BufferOp.Marginal <DistributionStructArray <Bernoulli, bool> >(this.Cloudy_selector_cases_uses_B, Cloudy_selector_cases_F, Cloudy_selector_cases_uses_B_marginal);
                // Message to 'Cloudy_selector_cases_uses' from Replicate factor
                Cloudy_selector_cases_uses_F[1] = Replicate2BufferOp.UsesAverageConditional <DistributionStructArray <Bernoulli, bool> >(this.Cloudy_selector_cases_uses_B, Cloudy_selector_cases_F, Cloudy_selector_cases_uses_B_marginal, 1, Cloudy_selector_cases_uses_F[1]);
                // Message to 'Rain' from Exit factor
                Rain_F = GateExitOp <bool> .ExitAverageConditional <Bernoulli>(this.Rain_use_B, Cloudy_selector_cases_uses_F[1], Rain_cond_Cloudy_F, Rain_F);

                // Message to 'Sprinkler_selector_cases_1_uses' from Cases factor
                Sprinkler_selector_cases_1_uses_B[4] = Bernoulli.FromLogOdds(CasesOp.LogEvidenceRatio(Rain_cond_Sprinkler_1_selector_cases_B, Rain_F));
                // Message to 'Sprinkler_selector_cases_1' from Replicate factor
                Sprinkler_selector_cases_1_B = ReplicateOp.DefAverageConditional <Bernoulli>(Sprinkler_selector_cases_1_uses_B, Sprinkler_selector_cases_1_B);
                // Message to 'Sprinkler_selector_cases' from Copy factor
                Sprinkler_selector_cases_B[1] = Factor.Copy <Bernoulli>(Sprinkler_selector_cases_1_B);
                // Message to 'Sprinkler_selector_cases_0_uses' from Cases factor
                Sprinkler_selector_cases_0_uses_B[4] = Bernoulli.FromLogOdds(CasesOp.LogEvidenceRatio(Rain_cond_Sprinkler_0_selector_cases_B, Rain_F));
                // Message to 'Sprinkler_selector_cases_0' from Replicate factor
                Sprinkler_selector_cases_0_B = ReplicateOp.DefAverageConditional <Bernoulli>(Sprinkler_selector_cases_0_uses_B, Sprinkler_selector_cases_0_B);
                // Message to 'Sprinkler_selector_cases' from Copy factor
                Sprinkler_selector_cases_B[0] = Factor.Copy <Bernoulli>(Sprinkler_selector_cases_0_B);
                // Message to 'Sprinkler_selector_uses' from Cases factor
                Sprinkler_selector_uses_B[0] = CasesOp.BAverageConditional(Sprinkler_selector_cases_B);
                // Message to 'Sprinkler_selector' from Replicate factor
                Sprinkler_selector_B = ReplicateOp.DefAverageConditional <Bernoulli>(Sprinkler_selector_uses_B, Sprinkler_selector_B);
                // Message to 'Cloudy_selector_cases_uses' from Exit factor
                this.Cloudy_selector_cases_uses_B[3] = GateExitOp <bool> .CasesAverageConditional <Bernoulli, DistributionStructArray <Bernoulli, bool> >(Sprinkler_selector_B, Sprinkler_cond_Cloudy_F, this.Cloudy_selector_cases_uses_B[3]);

                // Message to 'Cloudy_selector_cases_uses' from Replicate factor
                Cloudy_selector_cases_uses_B_marginal = Replicate2BufferOp.Marginal <DistributionStructArray <Bernoulli, bool> >(this.Cloudy_selector_cases_uses_B, Cloudy_selector_cases_F, Cloudy_selector_cases_uses_B_marginal);
                // Message to 'Cloudy_selector_cases_uses' from Replicate factor
                Cloudy_selector_cases_uses_F[3] = Replicate2BufferOp.UsesAverageConditional <DistributionStructArray <Bernoulli, bool> >(this.Cloudy_selector_cases_uses_B, Cloudy_selector_cases_F, Cloudy_selector_cases_uses_B_marginal, 3, Cloudy_selector_cases_uses_F[3]);
                // Message to 'Sprinkler' from Exit factor
                Sprinkler_F = GateExitOp <bool> .ExitAverageConditional <Bernoulli>(Sprinkler_selector_B, Cloudy_selector_cases_uses_F[3], Sprinkler_cond_Cloudy_F, Sprinkler_F);

                // Message to 'Sprinkler_selector_uses' from Replicate factor
                Sprinkler_selector_uses_B_marginal = Replicate2BufferOp.Marginal <Bernoulli>(Sprinkler_selector_uses_B, Sprinkler_F, Sprinkler_selector_uses_B_marginal);
                // Message to 'Sprinkler_selector_uses' from Replicate factor
                Sprinkler_selector_uses_F[1] = Replicate2BufferOp.UsesAverageConditional <Bernoulli>(Sprinkler_selector_uses_B, Sprinkler_F, Sprinkler_selector_uses_B_marginal, 1, Sprinkler_selector_uses_F[1]);
                // Message to 'Rain_use' from EnterPartial factor
                this.Rain_use_B = GateEnterPartialOp <bool> .ValueAverageConditional <Bernoulli>(Rain_cond_Sprinkler_B, Sprinkler_selector_uses_F[1], Rain_F, new int[2] {
                    0, 1
                }, this.Rain_use_B);

                // Message to 'Cloudy_selector_cases_uses' from Exit factor
                this.Cloudy_selector_cases_uses_B[1] = GateExitOp <bool> .CasesAverageConditional <Bernoulli, DistributionStructArray <Bernoulli, bool> >(this.Rain_use_B, Rain_cond_Cloudy_F, this.Cloudy_selector_cases_uses_B[1]);

                this.OnProgressChanged(new ProgressChangedEventArgs(iteration));
            }
            DistributionStructArray <Bernoulli, bool> Cloudy_selector_cases_B = default(DistributionStructArray <Bernoulli, bool>);

            // Create array for 'Cloudy_selector_cases' Backwards messages.
            Cloudy_selector_cases_B = new DistributionStructArray <Bernoulli, bool>(2);
            for (int _iv0 = 0; _iv0 < 2; _iv0++)
            {
                Cloudy_selector_cases_B[_iv0] = ArrayHelper.MakeUniform <Bernoulli>(new Bernoulli());
            }
            // Message to 'Cloudy_selector_cases' from Replicate factor
            Cloudy_selector_cases_B = ReplicateOp.DefAverageConditional <DistributionStructArray <Bernoulli, bool> >(this.Cloudy_selector_cases_uses_B, Cloudy_selector_cases_B);
            Bernoulli Cloudy_selector_B = ArrayHelper.MakeUniform <Bernoulli>(vBernoulli27);

            // Message to 'Cloudy_selector' from Cases factor
            Cloudy_selector_B = CasesOp.BAverageConditional(Cloudy_selector_cases_B);
            // Message to 'Cloudy_marginal' from Variable factor
            this.Cloudy_marginal_F = VariableOp.MarginalAverageConditional <Bernoulli>(Cloudy_selector_B, vBernoulli27, this.Cloudy_marginal_F);
            this.Rain_marginal_F   = ArrayHelper.MakeUniform <Bernoulli>(this.vBernoulli30);
            // Message to 'Rain_marginal' from DerivedVariable factor
            this.Rain_marginal_F      = DerivedVariableOp.MarginalAverageConditional <Bernoulli>(this.Rain_use_B, Rain_F, this.Rain_marginal_F);
            this.Sprinkler_marginal_F = ArrayHelper.MakeUniform <Bernoulli>(vBernoulli28);
            // Message to 'Sprinkler_marginal' from DerivedVariable factor
            this.Sprinkler_marginal_F = DerivedVariableOp.MarginalAverageConditional <Bernoulli>(Sprinkler_selector_B, Sprinkler_F, this.Sprinkler_marginal_F);
            this.Changed_numberOfIterationsDecreased_WetGrass_iterationsDone = numberOfIterations;
        }
Beispiel #4
0
        /// <summary>Computations that depend on the observed value of Sprinkler and WetGrass</summary>
        public void Changed_Sprinkler_WetGrass()
        {
            if (this.Changed_Sprinkler_WetGrass_iterationsDone == 1)
            {
                return;
            }
            // The constant 'vBernoulli1'
            Bernoulli vBernoulli1 = Bernoulli.FromLogOdds(-2.1972245773362191);

            this.Sprinkler_marginal = ArrayHelper.MakeUniform <Bernoulli>(vBernoulli1);
            this.Sprinkler_marginal = Distribution.SetPoint <Bernoulli, bool>(this.Sprinkler_marginal, this.sprinkler);
            // The constant 'vBernoulli5'
            Bernoulli vBernoulli5 = Bernoulli.FromLogOdds(4.5951198501345889);

            this.WetGrass_marginal = ArrayHelper.MakeUniform <Bernoulli>(vBernoulli5);
            this.WetGrass_marginal = Distribution.SetPoint <Bernoulli, bool>(this.WetGrass_marginal, this.wetGrass);
            // The constant 'vBernoulli3'
            Bernoulli vBernoulli3 = Bernoulli.FromLogOdds(1.3862943611198908);
            Bernoulli Rain_F      = ArrayHelper.MakeUniform <Bernoulli>(vBernoulli3);
            // The constant 'vBernoulli0'
            Bernoulli vBernoulli0 = Bernoulli.FromLogOdds(0);

            this.Cloudy_marginal_F = ArrayHelper.MakeUniform <Bernoulli>(vBernoulli0);
            Bernoulli[] Cloudy_selector_cases_0_uses_B = default(Bernoulli[]);
            // Create array for 'Cloudy_selector_cases_0_uses' Backwards messages.
            Cloudy_selector_cases_0_uses_B = new Bernoulli[7];
            for (int _ind = 0; _ind < 7; _ind++)
            {
                Cloudy_selector_cases_0_uses_B[_ind] = ArrayHelper.MakeUniform <Bernoulli>(new Bernoulli());
            }
            // Message to 'Cloudy_selector_cases_0_uses' from Random factor
            Cloudy_selector_cases_0_uses_B[6] = Bernoulli.FromLogOdds(UnaryOp <bool> .LogEvidenceRatio <Bernoulli>(this.sprinkler, vBernoulli1));
            Bernoulli Cloudy_selector_cases_0_B = ArrayHelper.MakeUniform <Bernoulli>(new Bernoulli());

            // Message to 'Cloudy_selector_cases_0' from Replicate factor
            Cloudy_selector_cases_0_B = ReplicateOp.DefAverageConditional <Bernoulli>(Cloudy_selector_cases_0_uses_B, Cloudy_selector_cases_0_B);
            DistributionStructArray <Bernoulli, bool>[] Cloudy_selector_cases_uses_B = default(DistributionStructArray <Bernoulli, bool>[]);
            // Create array for 'Cloudy_selector_cases_uses' Backwards messages.
            Cloudy_selector_cases_uses_B = new DistributionStructArray <Bernoulli, bool> [3];
            for (int _ind = 0; _ind < 3; _ind++)
            {
                // Create array for 'Cloudy_selector_cases_uses' Backwards messages.
                Cloudy_selector_cases_uses_B[_ind] = new DistributionStructArray <Bernoulli, bool>(2);
                for (int _iv0 = 0; _iv0 < 2; _iv0++)
                {
                    Cloudy_selector_cases_uses_B[_ind][_iv0] = ArrayHelper.MakeUniform <Bernoulli>(new Bernoulli());
                }
            }
            // Message to 'Cloudy_selector_cases_uses' from Copy factor
            Cloudy_selector_cases_uses_B[0][0] = Factor.Copy <Bernoulli>(Cloudy_selector_cases_0_B);
            DistributionStructArray <Bernoulli, bool> Rain_cond_Cloudy_F = default(DistributionStructArray <Bernoulli, bool>);

            // Create array for 'Rain_cond_Cloudy' Forwards messages.
            Rain_cond_Cloudy_F = new DistributionStructArray <Bernoulli, bool>(2);
            for (int _gateind = 0; _gateind < 2; _gateind++)
            {
                Rain_cond_Cloudy_F[_gateind] = ArrayHelper.MakeUniform <Bernoulli>(vBernoulli3);
            }
            // Message to 'Rain_cond_Cloudy' from Copy factor
            Rain_cond_Cloudy_F[0] = Factor.Copy <Bernoulli>(vBernoulli3);
            // The constant 'vBernoulli4'
            Bernoulli vBernoulli4 = Bernoulli.FromLogOdds(-1.3862943611198906);

            // Message to 'Rain_cond_Cloudy' from Copy factor
            Rain_cond_Cloudy_F[1] = Factor.Copy <Bernoulli>(vBernoulli4);
            if (this.sprinkler)
            {
                this.Rain_cond_Sprinkler_0_selector_cases_0_B = ArrayHelper.MakeUniform <Bernoulli>(new Bernoulli());
                // Message to 'Rain_cond_Sprinkler_0_selector_cases_0' from Random factor
                this.Rain_cond_Sprinkler_0_selector_cases_0_B = Bernoulli.FromLogOdds(UnaryOp <bool> .LogEvidenceRatio <Bernoulli>(this.wetGrass, vBernoulli5));
                // Create array for 'Rain_cond_Sprinkler_0_selector_cases' Backwards messages.
                this.Rain_cond_Sprinkler_0_selector_cases_B = new DistributionStructArray <Bernoulli, bool>(2);
                for (int _ind0 = 0; _ind0 < 2; _ind0++)
                {
                    this.Rain_cond_Sprinkler_0_selector_cases_B[_ind0] = ArrayHelper.MakeUniform <Bernoulli>(new Bernoulli());
                }
                // Message to 'Rain_cond_Sprinkler_0_selector_cases' from Copy factor
                this.Rain_cond_Sprinkler_0_selector_cases_B[0] = Factor.Copy <Bernoulli>(this.Rain_cond_Sprinkler_0_selector_cases_0_B);
            }
            // The constant 'vBernoulli6'
            Bernoulli vBernoulli6 = Bernoulli.FromLogOdds(2.1972245773362196);

            if (this.sprinkler)
            {
                this.Rain_cond_Sprinkler_0_selector_cases_1_B = ArrayHelper.MakeUniform <Bernoulli>(new Bernoulli());
                // Message to 'Rain_cond_Sprinkler_0_selector_cases_1' from Random factor
                this.Rain_cond_Sprinkler_0_selector_cases_1_B = Bernoulli.FromLogOdds(UnaryOp <bool> .LogEvidenceRatio <Bernoulli>(this.wetGrass, vBernoulli6));
                // Message to 'Rain_cond_Sprinkler_0_selector_cases' from Copy factor
                this.Rain_cond_Sprinkler_0_selector_cases_B[1] = Factor.Copy <Bernoulli>(this.Rain_cond_Sprinkler_0_selector_cases_1_B);
                this.Rain_cond_Sprinkler_0_selector_B          = ArrayHelper.MakeUniform <Bernoulli>(vBernoulli3);
                // Message to 'Rain_cond_Sprinkler_0_selector' from Cases factor
                this.Rain_cond_Sprinkler_0_selector_B = CasesOp.BAverageConditional(this.Rain_cond_Sprinkler_0_selector_cases_B);
            }
            // Message from use of 'Rain'
            Bernoulli Rain_use_B = ArrayHelper.MakeUniform <Bernoulli>(vBernoulli3);

            if (this.sprinkler)
            {
                // Message to 'Rain_use' from Copy factor
                Rain_use_B = Factor.Copy <Bernoulli>(this.Rain_cond_Sprinkler_0_selector_B);
            }
            if (!this.sprinkler)
            {
                this.Rain_cond_Sprinkler_1_selector_cases_0_B = ArrayHelper.MakeUniform <Bernoulli>(new Bernoulli());
                // Message to 'Rain_cond_Sprinkler_1_selector_cases_0' from Random factor
                this.Rain_cond_Sprinkler_1_selector_cases_0_B = Bernoulli.FromLogOdds(UnaryOp <bool> .LogEvidenceRatio <Bernoulli>(this.wetGrass, vBernoulli6));
                // Create array for 'Rain_cond_Sprinkler_1_selector_cases' Backwards messages.
                this.Rain_cond_Sprinkler_1_selector_cases_B = new DistributionStructArray <Bernoulli, bool>(2);
                for (int _ind0 = 0; _ind0 < 2; _ind0++)
                {
                    this.Rain_cond_Sprinkler_1_selector_cases_B[_ind0] = ArrayHelper.MakeUniform <Bernoulli>(new Bernoulli());
                }
                // Message to 'Rain_cond_Sprinkler_1_selector_cases' from Copy factor
                this.Rain_cond_Sprinkler_1_selector_cases_B[0] = Factor.Copy <Bernoulli>(this.Rain_cond_Sprinkler_1_selector_cases_0_B);
            }
            // The constant 'vBernoulli8'
            Bernoulli vBernoulli8 = Bernoulli.FromLogOdds(Double.NegativeInfinity);

            if (!this.sprinkler)
            {
                this.Rain_cond_Sprinkler_1_selector_cases_1_B = ArrayHelper.MakeUniform <Bernoulli>(new Bernoulli());
                // Message to 'Rain_cond_Sprinkler_1_selector_cases_1' from Random factor
                this.Rain_cond_Sprinkler_1_selector_cases_1_B = Bernoulli.FromLogOdds(UnaryOp <bool> .LogEvidenceRatio <Bernoulli>(this.wetGrass, vBernoulli8));
                // Message to 'Rain_cond_Sprinkler_1_selector_cases' from Copy factor
                this.Rain_cond_Sprinkler_1_selector_cases_B[1] = Factor.Copy <Bernoulli>(this.Rain_cond_Sprinkler_1_selector_cases_1_B);
                this.Rain_cond_Sprinkler_1_selector_B          = ArrayHelper.MakeUniform <Bernoulli>(vBernoulli3);
                // Message to 'Rain_cond_Sprinkler_1_selector' from Cases factor
                this.Rain_cond_Sprinkler_1_selector_B = CasesOp.BAverageConditional(this.Rain_cond_Sprinkler_1_selector_cases_B);
                // Message to 'Rain_use' from Copy factor
                Rain_use_B = Factor.Copy <Bernoulli>(this.Rain_cond_Sprinkler_1_selector_B);
            }
            // Rain_use_B is now updated in all contexts
            // Message to 'Cloudy_selector_cases_uses' from Exit factor
            Cloudy_selector_cases_uses_B[1] = GateExitOp <bool> .CasesAverageConditional <Bernoulli, DistributionStructArray <Bernoulli, bool> >(Rain_use_B, Rain_cond_Cloudy_F, Cloudy_selector_cases_uses_B[1]);

            Bernoulli[] Cloudy_selector_cases_1_uses_B = default(Bernoulli[]);
            // Create array for 'Cloudy_selector_cases_1_uses' Backwards messages.
            Cloudy_selector_cases_1_uses_B = new Bernoulli[7];
            for (int _ind = 0; _ind < 7; _ind++)
            {
                Cloudy_selector_cases_1_uses_B[_ind] = ArrayHelper.MakeUniform <Bernoulli>(new Bernoulli());
            }
            // Message to 'Cloudy_selector_cases_1_uses' from Random factor
            Cloudy_selector_cases_1_uses_B[6] = Bernoulli.FromLogOdds(UnaryOp <bool> .LogEvidenceRatio <Bernoulli>(this.sprinkler, vBernoulli0));
            Bernoulli Cloudy_selector_cases_1_B = ArrayHelper.MakeUniform <Bernoulli>(new Bernoulli());

            // Message to 'Cloudy_selector_cases_1' from Replicate factor
            Cloudy_selector_cases_1_B = ReplicateOp.DefAverageConditional <Bernoulli>(Cloudy_selector_cases_1_uses_B, Cloudy_selector_cases_1_B);
            // Message to 'Cloudy_selector_cases_uses' from Copy factor
            Cloudy_selector_cases_uses_B[2][1] = Factor.Copy <Bernoulli>(Cloudy_selector_cases_1_B);
            DistributionStructArray <Bernoulli, bool> Cloudy_selector_cases_B = default(DistributionStructArray <Bernoulli, bool>);

            // Create array for 'Cloudy_selector_cases' Backwards messages.
            Cloudy_selector_cases_B = new DistributionStructArray <Bernoulli, bool>(2);
            for (int _iv0 = 0; _iv0 < 2; _iv0++)
            {
                Cloudy_selector_cases_B[_iv0] = ArrayHelper.MakeUniform <Bernoulli>(new Bernoulli());
            }
            // Message to 'Cloudy_selector_cases' from Replicate factor
            Cloudy_selector_cases_B = ReplicateOp.DefAverageConditional <DistributionStructArray <Bernoulli, bool> >(Cloudy_selector_cases_uses_B, Cloudy_selector_cases_B);
            Bernoulli Cloudy_selector_B = ArrayHelper.MakeUniform <Bernoulli>(vBernoulli0);

            // Message to 'Cloudy_selector' from Cases factor
            Cloudy_selector_B = CasesOp.BAverageConditional(Cloudy_selector_cases_B);
            // Message to 'Cloudy_marginal' from Variable factor
            this.Cloudy_marginal_F = VariableOp.MarginalAverageConditional <Bernoulli>(Cloudy_selector_B, vBernoulli0, this.Cloudy_marginal_F);
            DistributionStructArray <Bernoulli, bool> Cloudy_selector_cases_F = default(DistributionStructArray <Bernoulli, bool>);

            // Create array for 'Cloudy_selector_cases' Forwards messages.
            Cloudy_selector_cases_F = new DistributionStructArray <Bernoulli, bool>(2);
            for (int _iv0 = 0; _iv0 < 2; _iv0++)
            {
                Cloudy_selector_cases_F[_iv0] = ArrayHelper.MakeUniform <Bernoulli>(new Bernoulli());
            }
            DistributionStructArray <Bernoulli, bool>[] Cloudy_selector_cases_uses_F = default(DistributionStructArray <Bernoulli, bool>[]);
            // Create array for 'Cloudy_selector_cases_uses' Forwards messages.
            Cloudy_selector_cases_uses_F = new DistributionStructArray <Bernoulli, bool> [3];
            for (int _ind = 0; _ind < 3; _ind++)
            {
                // Create array for 'Cloudy_selector_cases_uses' Forwards messages.
                Cloudy_selector_cases_uses_F[_ind] = new DistributionStructArray <Bernoulli, bool>(2);
                for (int _iv0 = 0; _iv0 < 2; _iv0++)
                {
                    Cloudy_selector_cases_uses_F[_ind][_iv0] = ArrayHelper.MakeUniform <Bernoulli>(new Bernoulli());
                }
            }
            // Message to 'Cloudy_selector_cases' from Cases factor
            Cloudy_selector_cases_F = CasesOp.CasesAverageConditional <DistributionStructArray <Bernoulli, bool> >(vBernoulli0, Cloudy_selector_cases_F);
            // Buffer for Replicate2BufferOp.UsesAverageConditional<DistributionStructArray<Bernoulli,bool>>
            DistributionStructArray <Bernoulli, bool> Cloudy_selector_cases_uses_B_marginal = default(DistributionStructArray <Bernoulli, bool>);

            // Message to 'Cloudy_selector_cases_uses' from Replicate factor
            Cloudy_selector_cases_uses_B_marginal = Replicate2BufferOp.MarginalInit <DistributionStructArray <Bernoulli, bool> >(Cloudy_selector_cases_F);
            // Message to 'Cloudy_selector_cases_uses' from Replicate factor
            Cloudy_selector_cases_uses_B_marginal = Replicate2BufferOp.Marginal <DistributionStructArray <Bernoulli, bool> >(Cloudy_selector_cases_uses_B, Cloudy_selector_cases_F, Cloudy_selector_cases_uses_B_marginal);
            // Message to 'Cloudy_selector_cases_uses' from Replicate factor
            Cloudy_selector_cases_uses_F[1] = Replicate2BufferOp.UsesAverageConditional <DistributionStructArray <Bernoulli, bool> >(Cloudy_selector_cases_uses_B, Cloudy_selector_cases_F, Cloudy_selector_cases_uses_B_marginal, 1, Cloudy_selector_cases_uses_F[1]);
            this.Rain_marginal_F            = ArrayHelper.MakeUniform <Bernoulli>(vBernoulli3);
            // Message to 'Rain' from Exit factor
            Rain_F = GateExitOp <bool> .ExitAverageConditional <Bernoulli>(Rain_use_B, Cloudy_selector_cases_uses_F[1], Rain_cond_Cloudy_F, Rain_F);

            // Message to 'Rain_marginal' from DerivedVariable factor
            this.Rain_marginal_F = DerivedVariableOp.MarginalAverageConditional <Bernoulli>(Rain_use_B, Rain_F, this.Rain_marginal_F);
            this.Changed_Sprinkler_WetGrass_iterationsDone = 1;
        }