def test_equals_false_covform(self): """ Test that the equals function can identify different Gaussians (with differences in the various covariance form parameters). """ gaussian_a = Gaussian(cov=[[7.0, 2.0], [2.0, 1.0]], mean=[4.0, 1.0], log_weight=0.0, var_names=["a", "b"]) gaussian_b = Gaussian(cov=[[2.0, 1.0], [1.0, 2.0]], mean=[4.0, 1.0], log_weight=0.0, var_names=["a", "b"]) self.assertFalse(gaussian_a.equals(gaussian_b)) gaussian_a = Gaussian(cov=[[7.0, 2.0], [2.0, 1.0]], mean=[4.0, 1.0], log_weight=0.0, var_names=["a", "b"]) gaussian_b = Gaussian(cov=[[7.0, 2.0], [2.0, 1.0]], mean=[0.0, 0.0], log_weight=0.0, var_names=["a", "b"]) self.assertFalse(gaussian_a.equals(gaussian_b)) gaussian_a = Gaussian(cov=[[7.0, 2.0], [2.0, 1.0]], mean=[4.0, 1.0], log_weight=0.0, var_names=["a", "b"]) gaussian_b = Gaussian(cov=[[7.0, 2.0], [2.0, 1.0]], mean=[4.0, 1.0], log_weight=1.0, var_names=["a", "b"]) self.assertFalse(gaussian_a.equals(gaussian_b))
def test_equals_false_canform(self): """ Test that the equals function can identify different Gaussians (with differences in the various canonical form parameters). """ gaussian_a = Gaussian(prec=[[7.0, 2.0], [2.0, 1.0]], h_vec=[4.0, 1.0], g_val=0.0, var_names=["a", "b"]) gaussian_b = Gaussian(prec=[[2.0, 1.0], [1.0, 2.0]], h_vec=[4.0, 1.0], g_val=0.0, var_names=["a", "b"]) self.assertFalse(gaussian_a.equals(gaussian_b)) gaussian_a = Gaussian(prec=[[7.0, 2.0], [2.0, 1.0]], h_vec=[4.0, 1.0], g_val=0.0, var_names=["a", "b"]) gaussian_b = Gaussian(prec=[[7.0, 2.0], [2.0, 1.0]], h_vec=[0.0, 0.0], g_val=0.0, var_names=["a", "b"]) self.assertFalse(gaussian_a.equals(gaussian_b)) gaussian_a = Gaussian(prec=[[7.0, 2.0], [2.0, 1.0]], h_vec=[4.0, 1.0], g_val=0.0, var_names=["a", "b"]) gaussian_b = Gaussian(prec=[[7.0, 2.0], [2.0, 1.0]], h_vec=[4.0, 1.0], g_val=1.0, var_names=["a", "b"]) self.assertFalse(gaussian_a.equals(gaussian_b))
def test_reorder_parameters(self): """ Test that _reorder_parameters properly reorders the values in the canonical parameters. """ gaussian_a = Gaussian(prec=[[1.0, 2.0], [2.0, 3.0]], h_vec=[1.0, 2.0], g_val=1.0, var_names=["a", "b"]) gaussian_b = Gaussian(prec=[[3.0, 2.0], [2.0, 1.0]], h_vec=[2.0, 1.0], g_val=1.0, var_names=["b", "a"]) gaussian_b._reorder_parameters(["a", "b"]) self.assertTrue(gaussian_a.equals(gaussian_b)) gaussian_a = Gaussian(cov=[[1.0, 2.0], [2.0, 3.0]], mean=[1.0, 2.0], log_weight=1.0, var_names=["a", "b"]) gaussian_b = Gaussian(cov=[[3.0, 2.0], [2.0, 1.0]], mean=[2.0, 1.0], log_weight=1.0, var_names=["b", "a"]) gaussian_b._reorder_parameters(["a", "b"]) self.assertTrue(gaussian_a.equals(gaussian_b))
def test_cancel_2d(self): """ Test that the Gaussian division function returns the correct result for two dimensional Gaussians. """ gaussian_a = Gaussian(prec=[[7.0, 2.0], [2.0, 6.0]], h_vec=[4.0, 3.0], g_val=3.0, var_names=["a", "b"]) gaussian_b = Gaussian(prec=[[4.0, 1.0], [1.0, 4.0]], h_vec=[1.0, 2.0], g_val=2.0, var_names=["a", "b"]) expected_quotient = Gaussian(prec=[[3.0, 1.0], [1.0, 2.0]], h_vec=[3.0, 1.0], g_val=1.0, var_names=["a", "b"]) actual_quotient = gaussian_a.divide(gaussian_b) self.assertTrue(expected_quotient.equals(actual_quotient)) gaussian_a_reordered = Gaussian(prec=[[6.0, 2.0], [2.0, 7.0]], h_vec=[3.0, 4.0], g_val=3.0, var_names=["b", "a"]) actual_quotient = gaussian_a_reordered.divide(gaussian_b) actual_quotient._reorder_parameters(["a", "b"]) self.assertTrue(expected_quotient.equals(actual_quotient))
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)
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))
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()))
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()))
def test_multiply_1d(self): """ Test that the Gaussian multiplication function returns the correct result for one dimensional Gaussians. """ gaussian_a = Gaussian(prec=5.0, h_vec=4.0, g_val=3.0, var_names=["a"]) gaussian_b = Gaussian(prec=3.0, h_vec=2.0, g_val=1.0, var_names=["a"]) expected_product = Gaussian(prec=8.0, h_vec=6.0, g_val=4.0, var_names=["a"]) actual_product = gaussian_a.multiply(gaussian_b) self.assertTrue(expected_product.equals(actual_product))
def test_cancel_1d(self): """ Test that the Gaussian division function returns the correct result for one dimensional Gaussians. """ gaussian_a = Gaussian(prec=6.0, h_vec=4.0, g_val=2.0, var_names=["a"]) gaussian_b = Gaussian(prec=3.0, h_vec=2.0, g_val=1.0, var_names=["a"]) expected_quotient = Gaussian(prec=3.0, h_vec=2.0, g_val=1.0, var_names=["a"]) actual_quotient = gaussian_a.divide(gaussian_b) self.assertTrue(expected_quotient.equals(actual_quotient))
def test_equals_canform_true(self): """ Test that the equals function can identify identical and effectively identical Gaussians in covariance 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"]) same_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(same_gaussian)) # Test approximately equals error = 1e-7 effectively_same_gaussian = Gaussian( prec=[[7.0 + error, 2.0 + error], [2.0 + error, 1.0 + error]], h_vec=[4.0 + error, 1.0 + error], g_val=0.0 + error, var_names=["a", "b"], ) self.assertTrue(gaussian.equals(effectively_same_gaussian))
def test_marginalise_2d(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"]) actual_result = gaussian.marginalize(vrs=["a"], keep=True) self.assertTrue(expected_result.equals(actual_result))
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))
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))
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))
def test_multiply_2d(self): """ Test that the Gaussian multiplication function returns the correct result for two dimensional Gaussians. """ gaussian_a = Gaussian(prec=[[5.0, 2.0], [2.0, 6.0]], h_vec=[1.0, 2.0], g_val=3.0, var_names=["a", "b"]) gaussian_b = Gaussian(prec=[[4.0, 1.0], [1.0, 4.0]], h_vec=[2.0, 3.0], g_val=2.0, var_names=["a", "b"]) expected_product = Gaussian(prec=[[9.0, 3.0], [3.0, 10.0]], h_vec=[3.0, 5.0], g_val=5.0, var_names=["a", "b"]) actual_product = gaussian_a.multiply(gaussian_b) self.assertTrue(expected_product.equals(actual_product))
def test_correct_marginal_special_evidence(self): """ Test that the get_marginal function returns the correct marginal after a graph with special evidence has been processed. """ factors = [self.p_a, self.p_b_g_a, self.p_c_g_a] cga = ClusterGraph(factors, special_evidence={"a": 3.0}) cga.process_graph(max_iter=1) vrs = ["b"] cov = [[1.9]] mean = [[2.7002]] log_weight = -2.5202640960492313 expected_posterior_marginal = Gaussian(var_names=vrs, cov=cov, mean=mean, log_weight=log_weight) actual_posterior_marginal = cga.get_marginal(vrs=["b"]) actual_posterior_marginal._update_covform() self.assertTrue( expected_posterior_marginal.equals(actual_posterior_marginal))
def test_multiply(self): """ Test that the multiply function results in the correct joint distribution when the absorbed factor has the same scope as the conditioning scope. """ 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"]) # expected parameters # TODO: Consider replacing this with hardcoded specific params. expected_joint_cov, expected_joint_mean = con_params_to_joint( conditioning_cov, conditioning_mean, a_mat, noise_cov) expected_joint = Gaussian(cov=expected_joint_cov, mean=expected_joint_mean, log_weight=0.0, var_names=["a", "b", "c", "d"]) nlg_factor = nlg_factor.multiply(conditioning_gaussian) actual_joint = nlg_factor.joint_distribution self.assertTrue(expected_joint.equals(actual_joint))
def test_copy_1d_covform(self): """ Test that the copy function returns a identical copy of a one dimensional Gaussian in covariance form. """ gaussian = Gaussian(cov=7.0, mean=4.0, log_weight=0.0, var_names=["a"]) self.assertTrue(gaussian.equals(gaussian.copy()))