def test_logpdf_missing_data(): # Setup model. m = 3 noise = 1e-2 latent_noises = 2e-2 * B.ones(m) kernels = [0.5 * EQ().stretch(0.75) for _ in range(m)] x = B.linspace(0, 10, 20) # Concatenate two orthogonal matrices, to make the missing data # approximation exact. u1 = B.svd(B.randn(m, m))[0] u2 = B.svd(B.randn(m, m))[0] u = Dense(B.concat(u1, u2, axis=0) / B.sqrt(2)) s_sqrt = Diagonal(B.rand(m)) # Construct a reference model. oilmm_pp = ILMMPP(kernels, u @ s_sqrt, noise, latent_noises) # Sample to generate test data. y = oilmm_pp.sample(x, latent=False) # Throw away data, but retain orthogonality. y[5:10, 3:] = np.nan y[10:, :3] = np.nan # Construct OILMM to test. oilmm = OILMM(kernels, u, s_sqrt, noise, latent_noises) # Check that evidence is still exact. approx(oilmm_pp.logpdf(x, y), oilmm.logpdf(x, y), atol=1e-7)
def construct_model(vs): kernels = [ vs.pos(1, name=f"{i}/var") * EQ().stretch(vs.pos(0.02, name=f"{i}/scale")) for i in range(m) ] noise = vs.pos(1e-2, name="noise") latent_noises = vs.pos(1e-2 * B.ones(m), name="latent_noises") u = Dense(vs.orth(shape=(p, m), name="u")) s_sqrt = Diagonal(vs.pos(shape=(m, ), name="s_sqrt")) return OILMM(kernels, u, s_sqrt, noise, latent_noises)
def construct_model(vs, m): kernels = [ vs.pos(0.5, name=f"{i}/k_var") * Matern52().stretch(vs.bnd(2 * 30, name=f"{i}/k_scale")) + vs.pos(0.5, name=f"{i}/k_per_var") * (Matern52().stretch( vs.bnd(1.0, name=f"{i}/k_per_scale")).periodic(365)) for i in range(m) ] noise = vs.pos(1e-2, name="noise") latent_noises = vs.pos(1e-2 * B.ones(m), name="latent_noises") # Construct orthogonal matrix and time it. time_h_start = time.time() u = Dense(vs.orth(shape=(p, m), name="u")) s_sqrt = Diagonal(vs.pos(shape=(m, ), name="s_sqrt")) dur_h = time.time() - time_h_start return OILMM(kernels, u, s_sqrt, noise, latent_noises), dur_h
def test_compare_ilmm(): # Setup models. kernels = [EQ(), 2 * EQ().stretch(1.5)] noise_obs = 0.1 noises_latent = np.array([0.1, 0.2]) u, s_sqrt = B.svd(B.randn(3, 2))[:2] u = Dense(u) s_sqrt = Diagonal(s_sqrt) # Construct models. ilmm = ILMMPP(kernels, u @ s_sqrt, noise_obs, noises_latent) oilmm = OILMM(kernels, u, s_sqrt, noise_obs, noises_latent) # Construct data. x = B.linspace(0, 3, 5) y = ilmm.sample(x, latent=False) x2 = B.linspace(4, 7, 5) y2 = ilmm.sample(x2, latent=False) # Check LML before conditioning. approx(ilmm.logpdf(x, y), oilmm.logpdf(x, y)) approx(ilmm.logpdf(x2, y2), oilmm.logpdf(x2, y2)) ilmm = ilmm.condition(x, y) oilmm = oilmm.condition(x, y) # Check LML after conditioning. approx(ilmm.logpdf(x, y), oilmm.logpdf(x, y)) approx(ilmm.logpdf(x2, y2), oilmm.logpdf(x2, y2)) # Predict. means_pp, lowers_pp, uppers_pp = ilmm.predict(x2) means, lowers, uppers = oilmm.predict(x2) # Check predictions. approx(means_pp, means) approx(lowers_pp, lowers) approx(uppers_pp, uppers)
def construct_model(vs): kernels = [ vs.pos(0.5, name=f"{i}/k_var") * Matern52().stretch(vs.bnd(2 * 30, name=f"{i}/k_scale")) + vs.pos(0.5, name=f"{i}/k_per_var") * (Matern52().stretch( vs.bnd(1.0, name=f"{i}/k_per_scale")).periodic(365)) for i in range(m) ] latent_noises = vs.pos(1e-2 * B.ones(m), name="latent_noises") noise = vs.pos(1e-2, name="noise") # Construct components of mixing matrix from a covariance over # outputs. variance = vs.pos(1, name="h/variance") scales = vs.pos(init=scales_init, name="h/scales") k = variance * Matern52().stretch(scales) u, s, _ = B.svd(B.dense(B.reg(k(loc)))) u = Dense(u[:, :m]) s_sqrt = Diagonal(B.sqrt(s[:m])) return OILMM(kernels, u, s_sqrt, noise, latent_noises)
def construct_model(vs): if args.separable: # Copy same kernel `m` times. kernel = [ Mat52().stretch(vs.bnd(6 * 30, lower=60, name="k_scale")) ] kernels = kernel * m else: # Parametrise different kernels. kernels = [ Mat52().stretch(vs.bnd(6 * 30, lower=60, name=f"{i}/k_scale")) for i in range(m) ] noise = vs.bnd(1e-2, name="noise") latent_noises = vs.bnd(1e-2 * B.ones(m), name="latent_noises") # Construct component of the mixing matrix over simulators. u = vs.orth(init=u_s_init, shape=(p_s, m_s), name="sims/u") s_sqrt = vs.bnd(init=s_sqrt_s_init, shape=(m_s, ), name="sims/s_sqrt") u_s = Dense(u) s_sqrt_s = Diagonal(s_sqrt) # Construct components of the mixing matrix over space from a # covariance. scales = vs.bnd(init=scales_init, name="space/scales") k = Mat52().stretch(scales) u, s, _ = B.svd(B.dense(k(loc))) u_r = Dense(u[:, :m_r]) s_sqrt_r = Diagonal(B.sqrt(s[:m_r])) # Compose. s_sqrt = Kronecker(s_sqrt_s, s_sqrt_r) u = Kronecker(u_s, u_r) return OILMM(kernels, u, s_sqrt, noise, latent_noises)
def construct_iolmm(noise_amplification=1): noise_obs = noise_amplification noises_latent = np.array([0.1, 0.2]) * noise_amplification return OILMM(kernels, u, s_sqrt, noise_obs, noises_latent)