Esempio n. 1
0
        /**
         * Reset this instances persistent variables to be used between called to
         * particleFiltering().
         *
         * @param N
         *            the number of samples to be maintained
         * @param dbn
         *            a DBN with prior <b>P</b>(<b>X</b><sub>0</sub>), transition
         *            model <b>P</b>(<b>X</b><sub>1</sub> | <b>X</b><sub>0</sub>),
         *            sensor model <b>P</b>(<b>E</b><sub>1</sub> |
         *            <b>X</b><sub>1</sub>)
         */
        public void initPersistent(int N, IDynamicBayesianNetwork dbn)
        {
            this.N   = N;
            this.dbn = dbn;
            // persistent: S, a vector of samples of size N, initially generated
            // from <b>P</b>(<b>X</b><sub>0</sub>)
            S     = new AssignmentProposition[N][];
            S_tp1 = new AssignmentProposition[N][];
            int[] indexes = new int[N];
            for (int i = 0; i < N; ++i)
            {
                S[i]       = new AssignmentProposition[this.dbn.GetX_0().Size()];
                S_tp1[i]   = new AssignmentProposition[this.dbn.GetX_0().Size()];
                indexes[i] = i;
                IMap <IRandomVariable, object> sample = priorSampler.priorSample(this.dbn.GetPriorNetwork());
                int idx = 0;
                foreach (var sa in sample)
                {
                    S[i][idx]     = new AssignmentProposition(this.dbn.GetX_0_to_X_1().Get(sa.GetKey()), sa.GetValue());
                    S_tp1[i][idx] = new AssignmentProposition(this.dbn.GetX_0_to_X_1().Get(sa.GetKey()), sa.GetValue());
                    idx++;
                }
            }

            sensorModel   = new FiniteBayesModel(dbn, new EliminationAsk());
            sampleIndexes = new RandVar("SAMPLE_INDEXES", new FiniteIntegerDomain(indexes));
        }
Esempio n. 2
0
        protected void test_ToothacheCavityCatchWeatherModel_Distributions(
            IFiniteProbabilityModel model)
        {
            AssignmentProposition asunny = new AssignmentProposition(
                ExampleRV.WEATHER_RV, "sunny");
            AssignmentProposition acavity = new AssignmentProposition(
                ExampleRV.CAVITY_RV, true);

            // Should be able to run all the same queries for this independent
            // sub model.
            test_ToothacheCavityCatchModel_Distributions(model);

            // AIMA3e pg. 487
            // P(sunny, Cavity)
            // Would be a two-element vector giving the probabilities of a sunny day
            // with a cavity and a sunny day with no cavity.
            assertArrayEquals(new double[] { 0.12, 0.48 }, model
                              .priorDistribution(asunny, ExampleRV.CAVITY_RV).getValues(),
                              DELTA_THRESHOLD);

            // AIMA3e pg. 488 (i.e. one element Vector returned)
            // P(sunny, cavity)
            assertArrayEquals(new double[] { 0.12 }, model
                              .priorDistribution(asunny, acavity).getValues(),
                              DELTA_THRESHOLD);
            // P(sunny AND cavity)
            assertArrayEquals(new double[] { 0.12 }, model
                              .priorDistribution(new ConjunctiveProposition(asunny, acavity))
                              .getValues(), DELTA_THRESHOLD);
            // P(sunny) = <0.6>
            assertArrayEquals(new double[] { 0.6 },
                              model.priorDistribution(asunny).getValues(), DELTA_THRESHOLD);
        }
Esempio n. 3
0
 /**
  * Instantiate an instance of the Forward Backward algorithm.
  *
  * @param transitionModel
  *            the transition model.
  * @param tToTm1StateVarMap
  *            a map from the X<sub>t<sub> random variables in the transition
  *            model the to X<sub>t-1</sub> random variables.
  * @param sensorModel
  *            the sensor model.
  */
 public ForwardBackward(IFiniteProbabilityModel transitionModel,
                        IMap <IRandomVariable, IRandomVariable> tToTm1StateVarMap,
                        IFiniteProbabilityModel sensorModel)
 {
     this.transitionModel = transitionModel;
     this.tToTm1StateVarMap.AddAll(tToTm1StateVarMap);
     this.sensorModel = sensorModel;
 }
Esempio n. 4
0
 public CategoricalDistributionIteratorImpl(IFiniteProbabilityModel transitionModel, IMap <IRandomVariable, AssignmentProposition> xtVarAssignMap, ICategoricalDistribution s1, IProposition xtp1, AssignmentProposition[] xt)
 {
     this.transitionModel = transitionModel;
     this.xtVarAssignMap  = xtVarAssignMap;
     this.s1   = s1;
     this.xtp1 = xtp1;
     this.xt   = xt;
 }
Esempio n. 5
0
 public CategoricalDistributionIteratorImpl2(IMap <IRandomVariable, AssignmentProposition> x_kp1VarAssignMap, IFiniteProbabilityModel sensorModel, IFiniteProbabilityModel transitionModel, ICategoricalDistribution b_kp1t, IProposition pe_kp1, IProposition xk, IProposition x_kp1)
 {
     this.x_kp1VarAssignMap = x_kp1VarAssignMap;
     this.sensorModel       = sensorModel;
     this.transitionModel   = transitionModel;
     this.b_kp1t            = b_kp1t;
     this.pe_kp1            = pe_kp1;
     this.xk    = xk;
     this.x_kp1 = x_kp1;
 }
Esempio n. 6
0
        protected static void demoBurglaryAlarmModel(IFiniteProbabilityModel model)
        {
            System.Console.WriteLine("--------------------");
            System.Console.WriteLine("Burglary Alarm Model");
            System.Console.WriteLine("--------------------");

            AssignmentProposition aburglary = new AssignmentProposition(
                ExampleRV.BURGLARY_RV, true);
            AssignmentProposition anotburglary = new AssignmentProposition(
                ExampleRV.BURGLARY_RV, false);
            AssignmentProposition anotearthquake = new AssignmentProposition(
                ExampleRV.EARTHQUAKE_RV, false);
            AssignmentProposition aalarm = new AssignmentProposition(
                ExampleRV.ALARM_RV, true);
            AssignmentProposition anotalarm = new AssignmentProposition(
                ExampleRV.ALARM_RV, false);
            AssignmentProposition ajohnCalls = new AssignmentProposition(
                ExampleRV.JOHN_CALLS_RV, true);
            AssignmentProposition amaryCalls = new AssignmentProposition(
                ExampleRV.MARY_CALLS_RV, true);

            // AIMA3e pg. 514
            System.Console.WriteLine("P(j,m,a,~b,~e) = "
                                     + model.prior(ajohnCalls, amaryCalls, aalarm, anotburglary,
                                                   anotearthquake));
            System.Console.WriteLine("P(j,m,~a,~b,~e) = "
                                     + model.prior(ajohnCalls, amaryCalls, anotalarm, anotburglary,
                                                   anotearthquake));

            // AIMA3e. pg. 514
            // P<>(Alarm | JohnCalls = true, MaryCalls = true, Burglary = false,
            // Earthquake = false)
            // = <0.558, 0.442>
            System.Console
            .WriteLine("P<>(Alarm | JohnCalls = true, MaryCalls = true, Burglary = false, Earthquake = false) = "
                       + model.posteriorDistribution(ExampleRV.ALARM_RV,
                                                     ajohnCalls, amaryCalls, anotburglary,
                                                     anotearthquake));

            // AIMA3e pg. 523
            // P<>(Burglary | JohnCalls = true, MaryCalls = true) = <0.284, 0.716>
            System.Console
            .WriteLine("P<>(Burglary | JohnCalls = true, MaryCalls = true) = "
                       + model.posteriorDistribution(ExampleRV.BURGLARY_RV,
                                                     ajohnCalls, amaryCalls));

            // AIMA3e pg. 528
            // P<>(JohnCalls | Burglary = true)
            System.Console.WriteLine("P<>(JohnCalls | Burglary = true) = "
                                     + model.posteriorDistribution(ExampleRV.JOHN_CALLS_RV,
                                                                   aburglary));
        }
Esempio n. 7
0
        // AIMA3e pg. 496
        protected void test_MeningitisStiffNeckModel_Distributions(
            IFiniteProbabilityModel model)
        {
            AssignmentProposition astiffNeck = new AssignmentProposition(
                ExampleRV.STIFF_NECK_RV, true);

            // AIMA3e pg. 497
            // P<>(Mengingitis | stiffneck) = &alpha;<P(s | m)P(m), P(s | ~m)P(~m)>
            ICategoricalDistribution dMeningitisGivenStiffNeck = model
                                                                 .posteriorDistribution(ExampleRV.MENINGITIS_RV, astiffNeck);

            Assert.AreEqual(2, dMeningitisGivenStiffNeck.getValues().Length);
            Assert.AreEqual(0.0014, dMeningitisGivenStiffNeck.getValues()[0],
                            DELTA_THRESHOLD);
            Assert.AreEqual(0.9986, dMeningitisGivenStiffNeck.getValues()[1],
                            DELTA_THRESHOLD);
        }
Esempio n. 8
0
        protected static void demoToothacheCavityCatchModel(IFiniteProbabilityModel model)
        {
            System.Console.WriteLine("Toothache, Cavity, and Catch Model");
            System.Console.WriteLine("----------------------------------");
            AssignmentProposition atoothache = new AssignmentProposition(
                ExampleRV.TOOTHACHE_RV, true);
            AssignmentProposition acavity = new AssignmentProposition(
                ExampleRV.CAVITY_RV, true);
            AssignmentProposition anotcavity = new AssignmentProposition(
                ExampleRV.CAVITY_RV, false);
            AssignmentProposition acatch = new AssignmentProposition(
                ExampleRV.CATCH_RV, true);

            // AIMA3e pg. 485
            System.Console.WriteLine("P(cavity) = " + model.prior(acavity));
            System.Console.WriteLine("P(cavity | toothache) = "
                                     + model.posterior(acavity, atoothache));

            // AIMA3e pg. 492
            DisjunctiveProposition cavityOrToothache = new DisjunctiveProposition(
                acavity, atoothache);

            System.Console.WriteLine("P(cavity OR toothache) = "
                                     + model.prior(cavityOrToothache));

            // AIMA3e pg. 493
            System.Console.WriteLine("P(~cavity | toothache) = "
                                     + model.posterior(anotcavity, atoothache));

            // AIMA3e pg. 493
            // P<>(Cavity | toothache) = <0.6, 0.4>
            System.Console.WriteLine("P<>(Cavity | toothache) = "
                                     + model.posteriorDistribution(ExampleRV.CAVITY_RV, atoothache));

            // AIMA3e pg. 497
            // P<>(Cavity | toothache AND catch) = <0.871, 0.129>
            System.Console.WriteLine("P<>(Cavity | toothache AND catch) = "
                                     + model.posteriorDistribution(ExampleRV.CAVITY_RV, atoothache,
                                                                   acatch));
        }
Esempio n. 9
0
        protected void test_BurglaryAlarmModel_Distributions(
            IFiniteProbabilityModel model)
        {
            AssignmentProposition aburglary = new AssignmentProposition(
                ExampleRV.BURGLARY_RV, true);
            AssignmentProposition anotburglary = new AssignmentProposition(
                ExampleRV.BURGLARY_RV, false);
            AssignmentProposition anotearthquake = new AssignmentProposition(
                ExampleRV.EARTHQUAKE_RV, false);
            AssignmentProposition ajohnCalls = new AssignmentProposition(
                ExampleRV.JOHN_CALLS_RV, true);
            AssignmentProposition amaryCalls = new AssignmentProposition(
                ExampleRV.MARY_CALLS_RV, true);

            // AIMA3e. pg. 514
            // P<>(Alarm | JohnCalls = true, MaryCalls = true, Burglary = false,
            // Earthquake = false)
            // = <0.558, 0.442>
            assertArrayEquals(
                new double[] { 0.5577689243027888, 0.44223107569721115 },
                model.posteriorDistribution(ExampleRV.ALARM_RV, ajohnCalls,
                                            amaryCalls, anotburglary, anotearthquake).getValues(),
                DELTA_THRESHOLD);

            // AIMA3e pg. 523
            // P<>(Burglary | JohnCalls = true, MaryCalls = true) = <0.284, 0.716>
            assertArrayEquals(
                new double[] { 0.2841718353643929, 0.7158281646356071 },
                model.posteriorDistribution(ExampleRV.BURGLARY_RV, ajohnCalls,
                                            amaryCalls).getValues(), DELTA_THRESHOLD);

            // AIMA3e pg. 528
            // P<>(JohnCalls | Burglary = true)
            assertArrayEquals(new double[] { 0.8490169999999999,
                                             0.15098299999999998 },
                              model.posteriorDistribution(ExampleRV.JOHN_CALLS_RV, aburglary)
                              .getValues(), DELTA_THRESHOLD);
        }
Esempio n. 10
0
        //
        // PROTECTED
        //
        protected void test_RollingPairFairDiceModel_Distributions(IFiniteProbabilityModel model)
        {
            AssignmentProposition    ad1_1 = new AssignmentProposition(ExampleRV.DICE_1_RV, 1);
            ICategoricalDistribution dD1_1 = model.priorDistribution(ad1_1);

            assertArrayEquals(new double[] { 1.0 / 6.0 }, dD1_1.getValues(), DELTA_THRESHOLD);

            ICategoricalDistribution dPriorDice1 = model.priorDistribution(ExampleRV.DICE_1_RV);

            assertArrayEquals(new double[] { 1.0 / 6.0, 1.0 / 6.0, 1.0 / 6.0, 1.0 / 6.0, 1.0 / 6.0, 1.0 / 6.0 },
                              dPriorDice1.getValues(), DELTA_THRESHOLD);

            ICategoricalDistribution dPriorDice2 = model.priorDistribution(ExampleRV.DICE_2_RV);

            assertArrayEquals(new double[] { 1.0 / 6.0, 1.0 / 6.0, 1.0 / 6.0, 1.0 / 6.0, 1.0 / 6.0, 1.0 / 6.0 },
                              dPriorDice2.getValues(), DELTA_THRESHOLD);

            ICategoricalDistribution dJointDice1Dice2 = model.jointDistribution(ExampleRV.DICE_1_RV, ExampleRV.DICE_2_RV);

            Assert.AreEqual(36, dJointDice1Dice2.getValues().Length);
            for (int i = 0; i < dJointDice1Dice2.getValues().Length; i++)
            {
                Assert.AreEqual(1.0 / 36.0, dJointDice1Dice2.getValues()[i], DELTA_THRESHOLD);
            }

            ICategoricalDistribution dJointDice2Dice1 = model.jointDistribution(ExampleRV.DICE_2_RV, ExampleRV.DICE_1_RV);

            Assert.AreEqual(36, dJointDice2Dice1.getValues().Length);
            for (int i = 0; i < dJointDice2Dice1.getValues().Length; i++)
            {
                Assert.AreEqual(1.0 / 36.0, dJointDice2Dice1.getValues()[i], DELTA_THRESHOLD);
            }

            //
            // Test Sets of events
            IntegerSumProposition total11 = new IntegerSumProposition("Total",
                                                                      new FiniteIntegerDomain(11), ExampleRV.DICE_1_RV,
                                                                      ExampleRV.DICE_2_RV);

            // P<>(Total = 11) = <2.0/36.0>
            assertArrayEquals(new double[] { 2.0 / 36.0 }, model.priorDistribution(total11).getValues(), DELTA_THRESHOLD);

            // P<>(Dice1, Total = 11)
            // = <0.0, 0.0, 0.0, 0.0, 1.0/36.0, 1.0/36.0>
            assertArrayEquals(new double[] { 0, 0, 0, 0, 1.0 / 36.0, 1.0 / 36.0 },
                              model.priorDistribution(ExampleRV.DICE_1_RV, total11)
                              .getValues(), DELTA_THRESHOLD);

            EquivalentProposition doubles = new EquivalentProposition("Doubles",
                                                                      ExampleRV.DICE_1_RV, ExampleRV.DICE_2_RV);

            // P(Doubles) = <1.0/6.0>
            assertArrayEquals(new double[] { 1.0 / 6.0 }, model
                              .priorDistribution(doubles).getValues(), DELTA_THRESHOLD);

            //
            // Test posterior
            //
            // P<>(Dice1, Total = 11)
            // = <0.0, 0.0, 0.0, 0.0, 0.5, 0.5>
            assertArrayEquals(new double[] { 0, 0, 0, 0, 0.5, 0.5 }, model
                              .posteriorDistribution(ExampleRV.DICE_1_RV, total11)
                              .getValues(), DELTA_THRESHOLD);

            // P<>(Dice1 | Doubles) = <1/6, 1/6, 1/6, 1/6, 1/6, 1/6>
            assertArrayEquals(new double[] { 1.0 / 6.0, 1.0 / 6.0, 1.0 / 6.0, 1.0 / 6.0, 1.0 / 6.0, 1.0 / 6.0 }, model
                              .posteriorDistribution(ExampleRV.DICE_1_RV, doubles)
                              .getValues(), DELTA_THRESHOLD);

            ICategoricalDistribution dPosteriorDice1GivenDice2 = model
                                                                 .posteriorDistribution(ExampleRV.DICE_1_RV, ExampleRV.DICE_2_RV);

            Assert.AreEqual(36, dPosteriorDice1GivenDice2.getValues().Length);
            for (int i = 0; i < dPosteriorDice1GivenDice2.getValues().Length; i++)
            {
                Assert.AreEqual(1.0 / 6.0, dPosteriorDice1GivenDice2.getValues()[i], DELTA_THRESHOLD);
            }

            ICategoricalDistribution dPosteriorDice2GivenDice1 = model
                                                                 .posteriorDistribution(ExampleRV.DICE_2_RV, ExampleRV.DICE_1_RV);

            Assert.AreEqual(36, dPosteriorDice2GivenDice1.getValues().Length);
            for (int i = 0; i < dPosteriorDice2GivenDice1.getValues().Length; i++)
            {
                Assert.AreEqual(1.0 / 6.0, dPosteriorDice2GivenDice1.getValues()[i], DELTA_THRESHOLD);
            }
        }
Esempio n. 11
0
        protected void test_ToothacheCavityCatchModel_Distributions(IFiniteProbabilityModel model)
        {
            AssignmentProposition atoothache    = new AssignmentProposition(ExampleRV.TOOTHACHE_RV, true);
            AssignmentProposition anottoothache = new AssignmentProposition(ExampleRV.TOOTHACHE_RV, false);
            AssignmentProposition acatch        = new AssignmentProposition(ExampleRV.CATCH_RV, true);
            AssignmentProposition anotcatch     = new AssignmentProposition(ExampleRV.CATCH_RV, false);

            // AIMA3e pg. 493
            // P<>(Cavity | toothache) = <0.6, 0.4>
            assertArrayEquals(new double[] { 0.6, 0.4 }, model
                              .posteriorDistribution(ExampleRV.CAVITY_RV, atoothache)
                              .getValues(), DELTA_THRESHOLD);

            // AIMA3e pg. 497
            // P<>(Cavity | toothache AND catch) = <0.871, 0.129>
            assertArrayEquals(new double[] { 0.8709677419354839, 0.12903225806451615 },
                              model.posteriorDistribution(ExampleRV.CAVITY_RV, atoothache,
                                                          acatch).getValues(), DELTA_THRESHOLD);

            // AIMA3e pg. 498
            // (13.17)
            // P<>(toothache AND catch | Cavity)
            // = P<>(toothache | Cavity)P<>(catch | Cavity)
            ConjunctiveProposition toothacheAndCatch = new ConjunctiveProposition(atoothache, acatch);

            assertArrayEquals(model.posteriorDistribution(toothacheAndCatch,
                                                          ExampleRV.CAVITY_RV).getValues(),
                              model.posteriorDistribution(atoothache, ExampleRV.CAVITY_RV)
                              .multiplyBy(
                                  model.posteriorDistribution(acatch,
                                                              ExampleRV.CAVITY_RV)).getValues(),
                              DELTA_THRESHOLD);

            // (13.18)
            // P<>(Cavity | toothache AND catch)
            // = &alpha;P<>(toothache | Cavity)P<>(catch | Cavity)P(Cavity)
            assertArrayEquals(model.posteriorDistribution(ExampleRV.CAVITY_RV,
                                                          toothacheAndCatch).getValues(),
                              model.posteriorDistribution(atoothache, ExampleRV.CAVITY_RV)
                              .multiplyBy(
                                  model.posteriorDistribution(acatch,
                                                              ExampleRV.CAVITY_RV))
                              .multiplyBy(
                                  model.priorDistribution(ExampleRV.CAVITY_RV))
                              .normalize().getValues(), DELTA_THRESHOLD);

            // (13.19)
            // P<>(Toothache, Catch | Cavity)
            // = P<>(Toothache | Cavity)P<>(Catch | Cavity)
            ConjunctiveProposition toothacheAndCatchRV = new ConjunctiveProposition(ExampleRV.TOOTHACHE_RV, ExampleRV.CATCH_RV);

            assertArrayEquals(model.posteriorDistribution(toothacheAndCatchRV,
                                                          ExampleRV.CAVITY_RV).getValues(),
                              model.posteriorDistribution(ExampleRV.TOOTHACHE_RV,
                                                          ExampleRV.CAVITY_RV)
                              .multiplyByPOS(
                                  model.posteriorDistribution(ExampleRV.CATCH_RV,
                                                              ExampleRV.CAVITY_RV),
                                  ExampleRV.TOOTHACHE_RV, ExampleRV.CATCH_RV,
                                  ExampleRV.CAVITY_RV).getValues(),
                              DELTA_THRESHOLD);

            // (product rule)
            // P<>(Toothache, Catch, Cavity)
            // = P<>(Toothache, Catch | Cavity)P<>(Cavity)
            assertArrayEquals(model.priorDistribution(ExampleRV.TOOTHACHE_RV,
                                                      ExampleRV.CATCH_RV, ExampleRV.CAVITY_RV).getValues(),
                              model.posteriorDistribution(toothacheAndCatchRV,
                                                          ExampleRV.CAVITY_RV)
                              .multiplyBy(
                                  model.priorDistribution(ExampleRV.CAVITY_RV))
                              .getValues(), DELTA_THRESHOLD);

            // (using 13.19)
            // P<>(Toothache, Catch | Cavity)P<>(Cavity)
            // = P<>(Toothache | Cavity)P<>(Catch | Cavity)P<>(Cavity)
            assertArrayEquals(model.posteriorDistribution(toothacheAndCatchRV,
                                                          ExampleRV.CAVITY_RV)
                              .multiplyBy(
                                  model.priorDistribution(ExampleRV.CAVITY_RV))
                              .getValues(),
                              model.posteriorDistribution(ExampleRV.TOOTHACHE_RV,
                                                          ExampleRV.CAVITY_RV)
                              .multiplyByPOS(
                                  model.posteriorDistribution(ExampleRV.CATCH_RV,
                                                              ExampleRV.CAVITY_RV)
                                  .multiplyBy(
                                      model.priorDistribution(ExampleRV.CAVITY_RV)),
                                  ExampleRV.TOOTHACHE_RV, ExampleRV.CATCH_RV,
                                  ExampleRV.CAVITY_RV).getValues(),
                              DELTA_THRESHOLD);
            //
            // P<>(Toothache, Catch, Cavity)
            // = P<>(Toothache | Cavity)P<>(Catch | Cavity)P<>(Cavity)
            assertArrayEquals(model.priorDistribution(ExampleRV.TOOTHACHE_RV,
                                                      ExampleRV.CATCH_RV, ExampleRV.CAVITY_RV).getValues(),
                              model.posteriorDistribution(ExampleRV.TOOTHACHE_RV,
                                                          ExampleRV.CAVITY_RV)
                              .multiplyByPOS(
                                  model.posteriorDistribution(ExampleRV.CATCH_RV,
                                                              ExampleRV.CAVITY_RV),
                                  ExampleRV.TOOTHACHE_RV, ExampleRV.CATCH_RV,
                                  ExampleRV.CAVITY_RV)
                              .multiplyBy(
                                  model.priorDistribution(ExampleRV.CAVITY_RV))
                              .getValues(), DELTA_THRESHOLD);

            // AIMA3e pg. 496
            // General case of Bayes' Rule
            // P<>(Y | X) = P<>(X | Y)P<>(Y)/P<>(X)
            // Note: Performing in this order -
            // P<>(Y | X) = (P<>(Y)P<>(X | Y))/P<>(X)
            // as default multiplication of distributions are not commutative (could
            // also use pointwiseProductPOS() to specify the order).
            assertArrayEquals(model.posteriorDistribution(ExampleRV.CAVITY_RV,
                                                          ExampleRV.TOOTHACHE_RV).getValues(),
                              model.priorDistribution(ExampleRV.CAVITY_RV)
                              .multiplyBy(
                                  model.posteriorDistribution(
                                      ExampleRV.TOOTHACHE_RV,
                                      ExampleRV.CAVITY_RV))
                              .divideBy(
                                  model.priorDistribution(ExampleRV.TOOTHACHE_RV))
                              .getValues(), DELTA_THRESHOLD);

            assertArrayEquals(
                model.posteriorDistribution(ExampleRV.CAVITY_RV,
                                            ExampleRV.CATCH_RV).getValues(),
                model.priorDistribution(ExampleRV.CAVITY_RV)
                .multiplyBy(
                    model.posteriorDistribution(ExampleRV.CATCH_RV,
                                                ExampleRV.CAVITY_RV))
                .divideBy(model.priorDistribution(ExampleRV.CATCH_RV))
                .getValues(), DELTA_THRESHOLD);

            // General Bayes' Rule conditionalized on background evidence e (13.3)
            // P<>(Y | X, e) = P<>(X | Y, e)P<>(Y|e)/P<>(X | e)
            // Note: Performing in this order -
            // P<>(Y | X, e) = (P<>(Y|e)P<>(X | Y, e)))/P<>(X | e)
            // as default multiplication of distributions are not commutative (could
            // also use pointwiseProductPOS() to specify the order).
            assertArrayEquals(
                model.posteriorDistribution(ExampleRV.CAVITY_RV,
                                            ExampleRV.TOOTHACHE_RV, acatch).getValues(),
                model.posteriorDistribution(ExampleRV.CAVITY_RV, acatch)
                .multiplyBy(
                    model.posteriorDistribution(
                        ExampleRV.TOOTHACHE_RV,
                        ExampleRV.CAVITY_RV, acatch))
                .divideBy(
                    model.posteriorDistribution(
                        ExampleRV.TOOTHACHE_RV, acatch))
                .getValues(), DELTA_THRESHOLD);
            //
            assertArrayEquals(
                model.posteriorDistribution(ExampleRV.CAVITY_RV,
                                            ExampleRV.TOOTHACHE_RV, anotcatch).getValues(),
                model.posteriorDistribution(ExampleRV.CAVITY_RV, anotcatch)
                .multiplyBy(
                    model.posteriorDistribution(
                        ExampleRV.TOOTHACHE_RV,
                        ExampleRV.CAVITY_RV, anotcatch))
                .divideBy(
                    model.posteriorDistribution(
                        ExampleRV.TOOTHACHE_RV, anotcatch))
                .getValues(), DELTA_THRESHOLD);
            //
            assertArrayEquals(
                model.posteriorDistribution(ExampleRV.CAVITY_RV,
                                            ExampleRV.CATCH_RV, atoothache).getValues(),
                model.posteriorDistribution(ExampleRV.CAVITY_RV, atoothache)
                .multiplyBy(
                    model.posteriorDistribution(ExampleRV.CATCH_RV,
                                                ExampleRV.CAVITY_RV, atoothache))
                .divideBy(
                    model.posteriorDistribution(ExampleRV.CATCH_RV,
                                                atoothache)).getValues(),
                DELTA_THRESHOLD);

            assertArrayEquals(
                model.posteriorDistribution(ExampleRV.CAVITY_RV,
                                            ExampleRV.CATCH_RV, anottoothache).getValues(),
                model.posteriorDistribution(ExampleRV.CAVITY_RV, anottoothache)
                .multiplyBy(
                    model.posteriorDistribution(ExampleRV.CATCH_RV,
                                                ExampleRV.CAVITY_RV, anottoothache))
                .divideBy(
                    model.posteriorDistribution(ExampleRV.CATCH_RV,
                                                anottoothache)).getValues(),
                DELTA_THRESHOLD);
        }