Ejemplo n.º 1
0
 def test_kl_divergence_between_vacuous_factors(self):
     """
     Test that the distance between two vacuous factors is zero.
     """
     g_1 = Gaussian.make_vacuous(var_names=["a", "b"])
     g_2 = Gaussian.make_vacuous(var_names=["a", "b"])
     self.assertTrue(g_1.kl_divergence(g_2) == 0.0)
Ejemplo n.º 2
0
 def test_vacuous_equals(self):
     """
     Test that vauous gaussians are equal.
     """
     g_1 = Gaussian.make_vacuous(var_names=["a", "b"])
     g_2 = Gaussian.make_vacuous(var_names=["a", "b"])
     self.assertTrue(g_1.equals(g_2))
Ejemplo n.º 3
0
    def test_observe(self):
        """
        Test that the Gaussian reduce function returns the correct result.
        """
        # Note these equations where written independently from the actuall implementation.
        # TODO: consider extending this test and hard-coding the expected parameters

        kmat = np.array([[6, 2, 1], [2, 8, 3], [1, 3, 9]])
        hvec = np.array([[1], [2], [3]])
        g_val = 1.5

        z_observed = np.array([[6]])

        expected_prec = np.array([[6, 2], [2, 8]])
        expeted_h = np.array([[-5], [-16]])
        expected_g = -142.5
        expected_gaussian = Gaussian(prec=expected_prec,
                                     h_vec=expeted_h,
                                     g_val=expected_g,
                                     var_names=["x", "y"])
        gaussian = Gaussian(prec=kmat,
                            h_vec=hvec,
                            g_val=g_val,
                            var_names=["x", "y", "z"])
        actual_gaussian = gaussian.reduce(vrs=["z"], values=z_observed)
        self.assertTrue(actual_gaussian.equals(expected_gaussian))

        # Test that the result is still correct with a different parameter order.

        gaussian_copy = gaussian.copy()
        gaussian_copy._reorder_parameters(["x", "z", "y"])

        actual_gaussian = gaussian_copy.reduce(vrs=["z"], values=z_observed)
        self.assertTrue(actual_gaussian.equals(expected_gaussian))
Ejemplo n.º 4
0
    def test_marginalise_with_conditional(self):
        """
        Test that marginalising an unconditioned non-linear Gaussian results in a vacuous Gaussian.
        """
        ab_vars = ["a", "b"]
        cd_vars = ["c", "d"]
        a_mat = np.array([[2, 0], [0, 1]])

        def transform(x_val, _):
            return a_mat.dot(x_val)

        noise_cov = np.array([[1, 0], [0, 1]])
        nlg_factor = NonLinearGaussian(conditioning_vars=ab_vars,
                                       conditional_vars=cd_vars,
                                       transform=transform,
                                       noise_cov=noise_cov)
        cov = np.array([[2, 1], [1, 3]])
        mean = np.array([[2], [1]])
        conditional_gaussian = Gaussian(cov=cov,
                                        mean=mean,
                                        log_weight=0.0,
                                        var_names=cd_vars)

        nlg_factor = nlg_factor.multiply(conditional_gaussian)

        actual_cd_marginal = nlg_factor.marginalize(vrs=cd_vars, keep=True)
        expected_cd_marginal = conditional_gaussian.copy()
        self.assertTrue(actual_cd_marginal.equals(expected_cd_marginal))
Ejemplo n.º 5
0
 def test_cov_exists_precision(self):
     """
     Check that the _cov_exists function returns True for a Gaussian that has a covariance that is well defined
     through the precision.
     """
     gaussian = Gaussian(prec=1.0, h_vec=0.0, g_val=0.0, var_names=["a"])
     self.assertTrue(gaussian._cov_exists())
Ejemplo n.º 6
0
 def test_get_prec(self):
     """
     Test that the correct K is returned.
     """
     gaussian_a = Gaussian(prec=2.0, h_vec=1.0, g_val=0.0, var_names=["a"])
     self.assertTrue(
         np.array_equal(gaussian_a.get_prec(), np.array([[2.0]])))
Ejemplo n.º 7
0
 def test_equals(self):
     """
     Test that the equals function can identify Gaussians that differ only in their variables.
     """
     gaussian_1 = Gaussian(cov=1, mean=1, log_weight=1.0, var_names=["a"])
     gaussian_2 = Gaussian(cov=0, mean=1, log_weight=1.0, var_names=["b"])
     self.assertFalse(gaussian_1.equals(gaussian_2))
Ejemplo n.º 8
0
def get_gaussian_set_a():
    """
    A helper function for generating a set of Gaussians for tests.
    """
    g_1 = Gaussian(mean=[[1.0], [2.0]], cov=[[5.0, 0.0], [0.0, 4.0]], log_weight=0.0, var_names=["a", "b"])
    g_2 = Gaussian(mean=[[3.0], [5.0]], cov=[[1.0, 0.0], [0.0, 2.0]], log_weight=0.0, var_names=["b", "c"])
    g_3 = Gaussian(mean=[[0.0], [3.0]], cov=[[3.0, 0.0], [0.0, 4.0]], log_weight=0.0, var_names=["d", "e"])
    return g_1, g_2, g_3
Ejemplo n.º 9
0
 def test_get_log_weight_from_canform():
     """
     Test that the _update_covform function is called before returning the log-weight parameter.
     """
     gaussian_a = Gaussian(prec=2.0, h_vec=1.0, g_val=0.0, var_names=["a"])
     expect(Gaussian, times=1)._update_covform()
     gaussian_a.get_log_weight()
     verifyNoUnwantedInteractions()
     unstub()
Ejemplo n.º 10
0
 def test_get_log_weight(self):
     """
     Test that the correct log-weight is returned.
     """
     gaussian_a = Gaussian(cov=2.0,
                           mean=1.0,
                           log_weight=0.0,
                           var_names=["a"])
     self.assertEqual(gaussian_a.get_log_weight(), 0.0)
Ejemplo n.º 11
0
 def test_copy_2d_canform(self):
     """
     Test that the copy function returns a identical copy of a Gaussian in canonical form.
     """
     gaussian = Gaussian(prec=[[7.0, 2.0], [2.0, 1.0]],
                         h_vec=[4.0, 1.0],
                         g_val=0.0,
                         var_names=["a", "b"])
     self.assertTrue(gaussian.equals(gaussian.copy()))
Ejemplo n.º 12
0
 def test_copy_2d_covform(self):
     """
     Test that the copy function returns a identical copy of a two dimensional Gaussian in covariance form.
     """
     gaussian = Gaussian(cov=[[7.0, 2.0], [2.0, 1.0]],
                         mean=[4.0, 1.0],
                         log_weight=0.0,
                         var_names=["a", "b"])
     self.assertTrue(gaussian.equals(gaussian.copy()))
Ejemplo n.º 13
0
 def test_impossible_update_canform(self):
     """
     Test that the _update_canform raises a LinAlgError when the covariance matrix is not invertible.
     """
     gaussian = Gaussian(cov=np.zeros([2, 2]),
                         mean=[0.0, 0.0],
                         log_weight=0.0,
                         var_names=["a", "b"])
     with self.assertRaises(np.linalg.LinAlgError):
         gaussian._update_canform()
Ejemplo n.º 14
0
 def test_get_mean(self):
     """
     Test that the correct mean is returned.
     """
     gaussian_a = Gaussian(cov=2.0,
                           mean=1.0,
                           log_weight=0.0,
                           var_names=["a"])
     self.assertTrue(
         np.array_equal(gaussian_a.get_mean(), np.array([[1.0]])))
Ejemplo n.º 15
0
 def test_impossible_update_covform(self):
     """
     Test that the _update_covform raises a LinAlgError when the precision matrix is not invertible.
     """
     gaussian = Gaussian(prec=np.zeros([2, 2]),
                         h_vec=[0.0, 0.0],
                         g_val=0.0,
                         var_names=["a", "b"])
     with self.assertRaises(Exception):
         gaussian._update_covform()
Ejemplo n.º 16
0
 def test_equals_different_factor(self):
     """
     Test that the equals function raises a value error when compared to a different type of factor.
     """
     gaussian_1 = Gaussian(cov=1, mean=1, log_weight=1.0, var_names=["a"])
     categorical_factor = Categorical(var_names=["a", "b"],
                                      probs_table={(0, 0): 0.1},
                                      cardinalities=[2, 2])
     with self.assertRaises(ValueError):
         gaussian_1.equals(categorical_factor)
Ejemplo n.º 17
0
 def test_copy_no_form(self):
     """
     Test that the copy function raises an exception when a Gaussian does not have either of its form updated.
     """
     gaussian_no_form = Gaussian(cov=1.0,
                                 mean=0.0,
                                 log_weight=0.0,
                                 var_names=["a"])
     gaussian_no_form.covform = False
     with self.assertRaises(Exception):
         gaussian_no_form.copy()
Ejemplo n.º 18
0
 def test_log_potential_no_form(self):
     """
     Test that the log_potential function raises an exception if the Gaussian has no form.
     """
     gaussian = Gaussian(cov=1.0,
                         mean=1.0,
                         log_weight=np.log(1.0),
                         var_names=["a"])
     gaussian.covform = False
     with self.assertRaises(Exception):
         gaussian.log_potential(x_val=0)
Ejemplo n.º 19
0
 def test_get_complex_log_weight(self):
     """
     Test that the _get_complex_log_weight returns the correct value.
     """
     gaussian_ab = Gaussian(prec=[[-1.0, 0.0], [0.0, 1.0]],
                            h_vec=[0.0, 0.0],
                            g_val=0.0,
                            var_names=["a", "b"])
     actual_complex_weight = gaussian_ab._get_complex_weight()
     expected_complex_weight = cmath.exp(0.5 * cmath.log(
         (-1.0) * (2.0 * np.pi)**2))
     self.assertAlmostEqual(actual_complex_weight, expected_complex_weight)
Ejemplo n.º 20
0
 def test_get_g_from_covform():
     """
     Test that the _update_canform function is called before returning the g parameter.
     """
     gaussian_a = Gaussian(cov=2.0,
                           mean=1.0,
                           log_weight=0.0,
                           var_names=["a"])
     expect(Gaussian, times=1)._update_canform()
     gaussian_a.get_g()
     verifyNoUnwantedInteractions()
     unstub()
Ejemplo n.º 21
0
 def test_potential(self):
     """
     Check that the potential method returns the correct value.
     """
     cov = np.array([[2.0, 1.0], [1.0, 2.0]])
     mean = np.array([[4.0], [5.0]])
     gaussian = Gaussian(cov=cov,
                         mean=mean,
                         log_weight=np.log(1.0),
                         var_names=["a", "b"])
     actual_max_potential = gaussian.potential(x_val=mean)
     expected_max_potential = 1.0 / np.sqrt(np.linalg.det(2 * np.pi * cov))
     self.assertEqual(actual_max_potential, expected_max_potential)
Ejemplo n.º 22
0
 def test_constructor_insufficient_parameters(self):
     """
     Test that the constructor raises an exception when insufficient parameters are supplied
     """
     # no var_names
     with self.assertRaises(Exception):
         Gaussian()
     # incomplete covariance form parameters
     with self.assertRaises(ValueError):
         Gaussian(cov=5, var_names=["a"])
     # incomplete canonical form parameters
     with self.assertRaises(ValueError):
         Gaussian(prec=5, var_names=["a"])
Ejemplo n.º 23
0
    def test_equals_different_order(self):
        """
        Test that the equals function can identify identical Gaussians with different order variables.
        """
        gaussian_1 = Gaussian(cov=[[1, 0], [0, 2]],
                              mean=[1, 2],
                              log_weight=1.0,
                              var_names=["a", "b"])
        gaussian_2 = Gaussian(cov=[[2, 0], [0, 1]],
                              mean=[2, 1],
                              log_weight=1.0,
                              var_names=["b", "a"])

        self.assertTrue(gaussian_1.equals(gaussian_2))
Ejemplo n.º 24
0
 def test_invert(self):
     """
     Test that the _invert method returns a Gaussian with the negated parameters.
     """
     gaussian = Gaussian(prec=[[1.0, 2.0], [2.0, 3.0]],
                         h_vec=[4.0, 5.0],
                         g_val=6.0,
                         var_names=["a", "b"])
     expected_inv_gaussian = Gaussian(prec=[[-1.0, -2.0], [-2.0, -3.0]],
                                      h_vec=[-4.0, -5.0],
                                      g_val=-6.0,
                                      var_names=["a", "b"])
     actual_inv_gaussian = gaussian._invert()
     self.assertTrue(actual_inv_gaussian.equals(expected_inv_gaussian))
Ejemplo n.º 25
0
    def test_form_conversion(self):
        """
        Test that conversion from one form to the other and back results in the same Gaussian parameters.
        """
        gaussian_ab = Gaussian(cov=[[7.0, 2.0], [2.0, 1.0]],
                               mean=[4.0, 1.0],
                               log_weight=0.0,
                               var_names=["a", "b"])
        gaussian_ab_copy = gaussian_ab.copy()

        gaussian_ab_copy._update_canform()
        gaussian_ab_copy.covform = False
        gaussian_ab_copy._update_covform()

        self.assertTrue(gaussian_ab.equals(gaussian_ab_copy))
Ejemplo n.º 26
0
 def test__repr__(self):
     """
     Test that the __repr__ method returns the correct result.
     """
     gaussian = Gaussian(prec=[[1.0, 0.0], [0.0, 1.0]],
                         h_vec=[0.0, 0.0],
                         g_val=0.0,
                         var_names=["a", "b"])
     expected_repr_string = (
         "vars = ['a', 'b']\nprec = \n[[1. 0.]\n [0. 1.]]\nh = \n[[0.]\n [0.]]\ng = \n0.0\n"
         + "is_vacuous: False\ncov        = \n[[1. 0.]\n [0. 1.]]" +
         "\nmean       = \n[[0.]\n [0.]]\nlog_weight = \n1.8378770664093453\n"
     )
     actual_repr_string = gaussian.__repr__()
     self.assertEqual(actual_repr_string, expected_repr_string)
Ejemplo n.º 27
0
    def test_multiply_both_sides(self):
        """
        Test that the multiply function results in the correct joint distribution when a factor with the conditional scope
        is received first and a conditioning scope factor is received afterwards.
        """

        conditional_update_cov = np.array([[2, 1], [1, 4]])
        conditional_update_mean = np.array([[5], [4]])

        conditional_update_factor = Gaussian(cov=conditional_update_cov,
                                             mean=conditional_update_mean,
                                             log_weight=0.0,
                                             var_names=["c", "d"])
        a_mat = np.array([[2, 0], [0, 1]])

        def transform(x_val, _):
            return a_mat.dot(x_val)

        noise_cov = np.array([[1, 0], [0, 1]])
        nlg_factor = NonLinearGaussian(
            conditioning_vars=["a", "b"],
            conditional_vars=["c", "d"],
            transform=transform,
            noise_cov=noise_cov,
        )

        conditioning_cov = np.array([[3, 1], [1, 5]])
        conditioning_mean = np.array([[2], [3]])
        conditioning_gaussian = Gaussian(cov=conditioning_cov,
                                         mean=conditioning_mean,
                                         log_weight=0.0,
                                         var_names=["a", "b"])
        # TODO: Consider replacing this with hardcoded specific params.
        joint_cov, joint_mean = con_params_to_joint(conditioning_cov,
                                                    conditioning_mean, a_mat,
                                                    noise_cov)

        expected_joint = Gaussian(cov=joint_cov,
                                  mean=joint_mean,
                                  log_weight=0.0,
                                  var_names=["a", "b", "c", "d"])
        expected_joint = expected_joint.multiply(
            conditional_update_factor.copy())

        nlg_factor = nlg_factor.multiply(conditional_update_factor)
        nlg_factor = nlg_factor.multiply(conditioning_gaussian)
        conditional_update_factor.show()
        self.assertTrue(expected_joint.equals(nlg_factor.joint_distribution))
Ejemplo n.º 28
0
    def marginalize(self, vrs, keep=True):
        """
        Integrate out variables from this factor.

        :param vrs: (list) a subset of variables in the factor's scope
        :param keep: Whether to keep or sum out vrs
        :return: the resulting marginal
        :rtype: Gaussian
        """

        vrs_to_keep = super().get_marginal_vars(vrs, keep=keep)
        assert set(vrs_to_keep) <= set(self.var_names), "Error: asked to keep vars not in factor."
        self_copy = self.copy()
        self_copy._recompute_joint()
        if self_copy._joint_distribution._is_vacuous:
            if set(vrs_to_keep) <= set(self_copy.conditioning_vars):
                if self_copy.conditioning_factor is not None:
                    if set(vrs_to_keep) <= set(self_copy.conditioning_factor.var_names):
                        marginal = self_copy.conditioning_factor.marginalize(vrs_to_keep, keep=True)
                        return marginal
            if set(vrs_to_keep) <= set(self_copy.conditional_vars):
                if self_copy.conditional_update_factor is not None:
                    if set(vrs_to_keep) <= set(self_copy.conditional_update_factor.var_names):
                        marginal = self_copy.conditional_update_factor.marginalize(vrs_to_keep, keep=True)
                        marginal._add_log_weight(self.log_weight)
                        return marginal
            else:
                return Gaussian.make_vacuous(vrs_to_keep)
        return self_copy._joint_distribution.marginalize(vrs_to_keep, keep=True)
Ejemplo n.º 29
0
 def test_is_vacuous_vacuous(self):
     """
     Test that the is_vacuous property function identifies a Gaussian as vacuous if the vacuous member variable is
     set to True.
     """
     dims = 3
     var_names = [str(i) for i in range(dims)]
     prec = np.eye(dims) * 1.0
     h_vec = np.zeros([dims, 1])
     g_val = 0.0
     gauss = Gaussian(var_names=var_names,
                      prec=prec,
                      h_vec=h_vec,
                      g_val=g_val)
     gauss._is_vacuous = True
     self.assertTrue(gauss.is_vacuous)
Ejemplo n.º 30
0
 def test_marginalise_2d_canform(self):
     """
     Test that the Gaussian marginalisation function returns the correct result for a two dimensional Gaussians.
     """
     gaussian = Gaussian(cov=[[7.0, 2.0], [2.0, 1.0]],
                         mean=[4.0, 1.0],
                         log_weight=0.0,
                         var_names=["a", "b"])
     expected_result = Gaussian(cov=7.0,
                                mean=4.0,
                                log_weight=0.0,
                                var_names=["a"])
     expected_result._update_canform()
     gaussian._update_canform()
     actual_result = gaussian.marginalize(vrs=["a"], keep=True)
     self.assertTrue(expected_result.equals(actual_result))