def test_message_to_parent(self): """ Test the message to parents of Gate node. """ # Unobserved and broadcasting Z = 2 X = GaussianARD(0, 1, shape=(), plates=(3, )) F = Gate(Z, X) Y = GaussianARD(F, 1) m = F._message_to_parent(0) self.assertEqual(len(m), 1) self.assertAllClose(m[0], 0 * np.ones(3)) m = F._message_to_parent(1) self.assertEqual(len(m), 2) self.assertAllClose(m[0] * np.ones(3), [0, 0, 0]) self.assertAllClose(m[1] * np.ones(3), [0, 0, 0]) # Gating scalar node Z = 2 X = GaussianARD([1, 2, 3], 1, shape=(), plates=(3, )) F = Gate(Z, X) Y = GaussianARD(F, 1) Y.observe(10) m = F._message_to_parent(0) self.assertAllClose( m[0], [10 * 1 - 0.5 * 2, 10 * 2 - 0.5 * 5, 10 * 3 - 0.5 * 10]) m = F._message_to_parent(1) self.assertAllClose(m[0], [0, 0, 10]) self.assertAllClose(m[1], [0, 0, -0.5]) # Fixed X Z = 2 X = [1, 2, 3] F = Gate(Z, X, moments=GaussianMoments(0)) Y = GaussianARD(F, 1) Y.observe(10) m = F._message_to_parent(0) self.assertAllClose( m[0], [10 * 1 - 0.5 * 1, 10 * 2 - 0.5 * 4, 10 * 3 - 0.5 * 9]) m = F._message_to_parent(1) self.assertAllClose(m[0], [0, 0, 10]) self.assertAllClose(m[1], [0, 0, -0.5]) # Uncertain gating Z = Categorical([0.2, 0.3, 0.5]) X = GaussianARD([1, 2, 3], 1, shape=(), plates=(3, )) F = Gate(Z, X) Y = GaussianARD(F, 1) Y.observe(10) m = F._message_to_parent(0) self.assertAllClose( m[0], [10 * 1 - 0.5 * 2, 10 * 2 - 0.5 * 5, 10 * 3 - 0.5 * 10]) m = F._message_to_parent(1) self.assertAllClose(m[0], [0.2 * 10, 0.3 * 10, 0.5 * 10]) self.assertAllClose(m[1], [-0.5 * 0.2, -0.5 * 0.3, -0.5 * 0.5]) # Plates in Z Z = [2, 0] X = GaussianARD([1, 2, 3], 1, shape=(), plates=(3, )) F = Gate(Z, X) Y = GaussianARD(F, 1) Y.observe([10, 20]) m = F._message_to_parent(0) self.assertAllClose( m[0], [[10 * 1 - 0.5 * 2, 10 * 2 - 0.5 * 5, 10 * 3 - 0.5 * 10], [20 * 1 - 0.5 * 2, 20 * 2 - 0.5 * 5, 20 * 3 - 0.5 * 10]]) m = F._message_to_parent(1) self.assertAllClose(m[0], [20, 0, 10]) self.assertAllClose(m[1], [-0.5, 0, -0.5]) # Plates in X Z = 2 X = GaussianARD([[1, 2, 3], [4, 5, 6]], 1, shape=(), plates=( 2, 3, )) F = Gate(Z, X) Y = GaussianARD(F, 1) Y.observe([10, 20]) m = F._message_to_parent(0) self.assertAllClose(m[0], [ 10 * 1 - 0.5 * 2 + 20 * 4 - 0.5 * 17, 10 * 2 - 0.5 * 5 + 20 * 5 - 0.5 * 26, 10 * 3 - 0.5 * 10 + 20 * 6 - 0.5 * 37 ]) m = F._message_to_parent(1) self.assertAllClose(m[0], [[0, 0, 10], [0, 0, 20]]) self.assertAllClose(m[1] * np.ones((2, 3)), [[0, 0, -0.5], [0, 0, -0.5]]) # Gating non-default plate Z = 2 X = GaussianARD([[1], [2], [3]], 1, shape=(), plates=(3, 1)) F = Gate(Z, X, gated_plate=-2) Y = GaussianARD(F, 1) Y.observe([10]) m = F._message_to_parent(0) self.assertAllClose( m[0], [10 * 1 - 0.5 * 2, 10 * 2 - 0.5 * 5, 10 * 3 - 0.5 * 10]) m = F._message_to_parent(1) self.assertAllClose(m[0], [[0], [0], [10]]) self.assertAllClose(m[1], [[0], [0], [-0.5]]) # Gating non-scalar node Z = 2 X = GaussianARD([[1, 4], [2, 5], [3, 6]], 1, shape=(2, ), plates=(3, )) F = Gate(Z, X) Y = GaussianARD(F, 1) Y.observe([10, 20]) m = F._message_to_parent(0) self.assertAllClose(m[0], [ 10 * 1 - 0.5 * 2 + 20 * 4 - 0.5 * 17, 10 * 2 - 0.5 * 5 + 20 * 5 - 0.5 * 26, 10 * 3 - 0.5 * 10 + 20 * 6 - 0.5 * 37 ]) m = F._message_to_parent(1) I = np.identity(2) self.assertAllClose(m[0], [[0, 0], [0, 0], [10, 20]]) self.assertAllClose(m[1], [0 * I, 0 * I, -0.5 * I]) # Broadcasting the moments on the cluster axis Z = 2 X = GaussianARD(2, 1, shape=(), plates=(3, )) F = Gate(Z, X) Y = GaussianARD(F, 1) Y.observe(10) m = F._message_to_parent(0) self.assertAllClose( m[0], [10 * 2 - 0.5 * 5, 10 * 2 - 0.5 * 5, 10 * 2 - 0.5 * 5]) m = F._message_to_parent(1) self.assertAllClose(m[0], [0, 0, 10]) self.assertAllClose(m[1], [0, 0, -0.5]) pass
def test_message_to_parent(self): """ Test the message to parents of Gate node. """ # Unobserved and broadcasting Z = 2 X = GaussianARD(0, 1, shape=(), plates=(3,)) F = Gate(Z, X) Y = GaussianARD(F, 1) m = F._message_to_parent(0) self.assertEqual(len(m), 1) self.assertAllClose(m[0], 0*np.ones(3)) m = F._message_to_parent(1) self.assertEqual(len(m), 2) self.assertAllClose(m[0]*np.ones(3), [0, 0, 0]) self.assertAllClose(m[1]*np.ones(3), [0, 0, 0]) # Gating scalar node Z = 2 X = GaussianARD([1,2,3], 1, shape=(), plates=(3,)) F = Gate(Z, X) Y = GaussianARD(F, 1) Y.observe(10) m = F._message_to_parent(0) self.assertAllClose(m[0], [10*1-0.5*2, 10*2-0.5*5, 10*3-0.5*10]) m = F._message_to_parent(1) self.assertAllClose(m[0], [0, 0, 10]) self.assertAllClose(m[1], [0, 0, -0.5]) # Fixed X Z = 2 X = [1,2,3] F = Gate(Z, X, moments=GaussianMoments(0)) Y = GaussianARD(F, 1) Y.observe(10) m = F._message_to_parent(0) self.assertAllClose(m[0], [10*1-0.5*1, 10*2-0.5*4, 10*3-0.5*9]) m = F._message_to_parent(1) self.assertAllClose(m[0], [0, 0, 10]) self.assertAllClose(m[1], [0, 0, -0.5]) # Uncertain gating Z = Categorical([0.2, 0.3, 0.5]) X = GaussianARD([1,2,3], 1, shape=(), plates=(3,)) F = Gate(Z, X) Y = GaussianARD(F, 1) Y.observe(10) m = F._message_to_parent(0) self.assertAllClose(m[0], [10*1-0.5*2, 10*2-0.5*5, 10*3-0.5*10]) m = F._message_to_parent(1) self.assertAllClose(m[0], [0.2*10, 0.3*10, 0.5*10]) self.assertAllClose(m[1], [-0.5*0.2, -0.5*0.3, -0.5*0.5]) # Plates in Z Z = [2, 0] X = GaussianARD([1,2,3], 1, shape=(), plates=(3,)) F = Gate(Z, X) Y = GaussianARD(F, 1) Y.observe([10, 20]) m = F._message_to_parent(0) self.assertAllClose(m[0], [[10*1-0.5*2, 10*2-0.5*5, 10*3-0.5*10], [20*1-0.5*2, 20*2-0.5*5, 20*3-0.5*10]]) m = F._message_to_parent(1) self.assertAllClose(m[0], [20, 0, 10]) self.assertAllClose(m[1], [-0.5, 0, -0.5]) # Plates in X Z = 2 X = GaussianARD([[1,2,3], [4,5,6]], 1, shape=(), plates=(2,3,)) F = Gate(Z, X) Y = GaussianARD(F, 1) Y.observe([10, 20]) m = F._message_to_parent(0) self.assertAllClose(m[0], [10*1-0.5*2 + 20*4-0.5*17, 10*2-0.5*5 + 20*5-0.5*26, 10*3-0.5*10 + 20*6-0.5*37]) m = F._message_to_parent(1) self.assertAllClose(m[0], [[0, 0, 10], [0, 0, 20]]) self.assertAllClose(m[1]*np.ones((2,3)), [[0, 0, -0.5], [0, 0, -0.5]]) # Gating non-default plate Z = 2 X = GaussianARD([[1],[2],[3]], 1, shape=(), plates=(3,1)) F = Gate(Z, X, gated_plate=-2) Y = GaussianARD(F, 1) Y.observe([10]) m = F._message_to_parent(0) self.assertAllClose(m[0], [10*1-0.5*2, 10*2-0.5*5, 10*3-0.5*10]) m = F._message_to_parent(1) self.assertAllClose(m[0], [[0], [0], [10]]) self.assertAllClose(m[1], [[0], [0], [-0.5]]) # Gating non-scalar node Z = 2 X = GaussianARD([[1,4],[2,5],[3,6]], 1, shape=(2,), plates=(3,)) F = Gate(Z, X) Y = GaussianARD(F, 1) Y.observe([10,20]) m = F._message_to_parent(0) self.assertAllClose(m[0], [10*1-0.5*2 + 20*4-0.5*17, 10*2-0.5*5 + 20*5-0.5*26, 10*3-0.5*10 + 20*6-0.5*37]) m = F._message_to_parent(1) I = np.identity(2) self.assertAllClose(m[0], [[0,0], [0,0], [10,20]]) self.assertAllClose(m[1], [0*I, 0*I, -0.5*I]) # Broadcasting the moments on the cluster axis Z = 2 X = GaussianARD(2, 1, shape=(), plates=(3,)) F = Gate(Z, X) Y = GaussianARD(F, 1) Y.observe(10) m = F._message_to_parent(0) self.assertAllClose(m[0], [10*2-0.5*5, 10*2-0.5*5, 10*2-0.5*5]) m = F._message_to_parent(1) self.assertAllClose(m[0], [0, 0, 10]) self.assertAllClose(m[1], [0, 0, -0.5]) pass