def test_multi_logpdf(): model = Graph() p1 = GP(EQ(), graph=model) p2 = GP(2 * Exp(), graph=model) p3 = p1 + p2 x1 = np.linspace(0, 2, 5) x2 = np.linspace(1, 3, 6) x3 = np.linspace(2, 4, 7) y1, y2, y3 = model.sample(p1(x1), p2(x2), p3(x3)) # Test case that only one process is fed. yield assert_allclose, p1(x1).logpdf(y1), model.logpdf(p1(x1), y1) yield assert_allclose, p1(x1).logpdf(y1), model.logpdf((p1(x1), y1)) # Test that all inputs must be specified. yield raises, ValueError, lambda: model.logpdf((x1, y1), (p2(x2), y2)) yield raises, ValueError, lambda: model.logpdf((p1(x1), y1), (x2, y2)) # Compute the logpdf with the product rule. logpdf1 = p1(x1).logpdf(y1) + \ p2(x2).logpdf(y2) + \ (p3 | ((p1(x1), y1), (p2(x2), y2)))(x3).logpdf(y3) logpdf2 = model.logpdf((p1(x1), y1), (p2(x2), y2), (p3(x3), y3)) yield assert_allclose, logpdf1, logpdf2
def test_logpdf(): m = Measure() p1 = GP(EQ(), measure=m) p2 = GP(Exp(), measure=m) e = GP(Delta(), measure=m) p3 = p1 + p2 x1 = B.linspace(0, 2, 5) x2 = B.linspace(1, 3, 6) x3 = B.linspace(2, 4, 7) y1, y2, y3 = m.sample(p1(x1), p2(x2), p3(x3)) # Test case that only one process is fed. approx(p1(x1).logpdf(y1), m.logpdf(p1(x1), y1)) approx(p1(x1).logpdf(y1), m.logpdf((p1(x1), y1))) # Compute the logpdf with the product rule. d1 = m d2 = d1 | (p1(x1), y1) d3 = d2 | (p2(x2), y2) approx( d1(p1)(x1).logpdf(y1) + d2(p2)(x2).logpdf(y2) + d3(p3)(x3).logpdf(y3), m.logpdf((p1(x1), y1), (p2(x2), y2), (p3(x3), y3)), ) # Check that `Measure.logpdf` allows `Obs` and `SparseObs`. obs = Obs(p3(x3), y3) approx(m.logpdf(obs), p3(x3).logpdf(y3)) obs = SparseObs(p3(x3), e, p3(x3), y3) approx(m.logpdf(obs), (p3 + e)(x3).logpdf(y3))
def test_multi_conditioning(): model = Graph() p1 = GP(EQ(), graph=model) p2 = GP(2 * Exp().stretch(2), graph=model) p3 = GP(.5 * RQ(1e-1).stretch(.5), graph=model) p = p1 + p2 + p3 x1 = np.linspace(0, 2, 10) x2 = np.linspace(1, 3, 10) x3 = np.linspace(0, 3, 10) s1, s2 = model.sample(p1(x1), p2(x2)) post1 = ((p | (p1(x1), s1)) | ((p2 | (p1(x1), s1))(x2), s2))(x3) post2 = (p | ((p1(x1), s1), (p2(x2), s2)))(x3) post3 = (p | ((p2(x2), s2), (p1(x1), s1)))(x3) yield assert_allclose, post1.mean, post2.mean, 'means 1', 1e-6, 1e-6 yield assert_allclose, post1.mean, post3.mean, 'means 2', 1e-6, 1e-6 yield assert_allclose, post1.var, post2.var yield assert_allclose, post1.var, post3.var
def test_conditioning(): m = Measure() p1 = GP(EQ(), measure=m) p2 = GP(Exp(), measure=m) p_sum = p1 + p2 # Sample some data to condition on. x1 = B.linspace(0, 2, 2) y1 = p1(x1).sample() x_sum = B.linspace(3, 5, 3) y_sum = p_sum(x_sum).sample() # Determine FDDs to check. x_check = B.linspace(0, 5, 5) fdds_check = [ cross(p1, p2, p_sum)(x_check), p1(x_check), p2(x_check), p_sum(x_check), ] assert_equal_measures( fdds_check, m.condition(p_sum(x_sum), y_sum), m.condition((p_sum(x_sum), y_sum)), m | (p_sum(x_sum), y_sum), m | ((p_sum(x_sum), y_sum), ), m | Obs(p_sum(x_sum), y_sum), m | Obs((p_sum(x_sum), y_sum)), ) assert_equal_measures( fdds_check, m.condition((p1(x1), y1), (p_sum(x_sum), y_sum)), m | ((p1(x1), y1), (p_sum(x_sum), y_sum)), m | Obs((p1(x1), y1), (p_sum(x_sum), y_sum)), )
def test_sparse_conditioning_and_elbo(): m = Measure() p1 = GP(EQ(), measure=m) p2 = GP(Exp(), measure=m) e = GP(Delta(), measure=m) p_sum = p1 + p2 # Sample some data to condition on. x1 = B.linspace(0, 2, 2) y1 = (p1 + e)(x1).sample() x_sum = B.linspace(3, 5, 3) y_sum = (p_sum + e)(x_sum).sample() # Determine FDDs to check. x_check = B.linspace(0, 5, 5) fdds_check = [ cross(p1, p2, p_sum)(x_check), p1(x_check), p2(x_check), p_sum(x_check), ] # Check conditioning and ELBO on one data set. assert_equal_measures( fdds_check, m | ((p_sum + e)(x_sum), y_sum), m | SparseObs(p_sum(x_sum), e, p_sum(x_sum), y_sum), m | SparseObs((p_sum(x_sum), ), e, p_sum(x_sum), y_sum), m | SparseObs((p_sum(x_sum), p1(x1)), e, p_sum(x_sum), y_sum), m | SparseObs(p_sum(x_sum), (e, p_sum(x_sum), y_sum)), m | SparseObs((p_sum(x_sum), ), (e, p_sum(x_sum), y_sum)), m.condition( SparseObs( (p_sum(x_sum), p1(x1)), (e, p_sum(x_sum), y_sum), )), ) approx( m.logpdf(Obs((p_sum + e)(x_sum), y_sum)), SparseObs(p_sum(x_sum), (e, p_sum(x_sum), y_sum)).elbo(m), ) # Check conditioning and ELBO on two data sets. assert_equal_measures( fdds_check, m | (((p_sum + e)(x_sum), y_sum), ((p1 + e)(x1), y1)), m.condition( SparseObs((p_sum(x_sum), p1(x1)), (e, p_sum(x_sum), y_sum), (e, p1(x1), y1))), ) approx( m.logpdf(Obs(((p_sum + e)(x_sum), y_sum), ((p1 + e)(x1), y1))), SparseObs((p_sum(x_sum), p1(x1)), (e, p_sum(x_sum), y_sum), (e, p1(x1), y1)).elbo(m), ) # The following lose information, so check them separately. assert_equal_measures( fdds_check, m | SparseObs(p_sum(x_sum), (e, p_sum(x_sum), y_sum), (e, p1(x1), y1)), m | SparseObs((p_sum(x_sum), ), (e, p_sum(x_sum), y_sum), (e, p1(x1), y1)), ) # Test lazy computation. obs = SparseObs(p_sum(x_sum), e, p_sum(x_sum), y_sum) for name in ["K_z", "elbo", "mu", "A"]: approx( getattr(SparseObs(p_sum(x_sum), e, p_sum(x_sum), y_sum), name)(m), getattr(obs, name)(m), ) # Test requirement that noise must be diagonal. with pytest.raises(RuntimeError): SparseObs(p_sum(x_sum), p_sum, p_sum(x_sum), y_sum).elbo(m)