def natural_predict_forward_temps(J, J11, J12, h): J, J11, J12 = -2*J, -2*J11, -J12 L = np.linalg.cholesky(J + J11) v = solve_triangular(L, h) lognorm = 1./2*np.dot(v,v) - np.sum(np.log(np.diag(L))) v2 = solve_triangular(L, v, trans='T') temp = solve_triangular(L, J12) return L, v, v2, temp, h, lognorm
def condition_on(mu, sigma, A, y, sigma_obs): temp1 = np.dot(A, sigma) sigma_pred = np.dot(temp1, A.T) + sigma_obs L = np.linalg.cholesky(sigma_pred) v = solve_triangular(L, y - np.dot(A, mu)) ll = -1./2 * np.dot(v, v) - np.sum(np.log(np.diag(L))) \ - y.shape[0]/2.*np.log(2*np.pi) mu_cond = mu + np.dot(temp1.T, solve_triangular(L, v, 'T')) temp2 = solve_triangular(L, temp1) sigma_cond = sigma - np.dot(temp2.T, temp2) return (mu_cond, sigma_cond), ll
def natural_predict(J, h, J11, J12, J22, logZ): # convert from natural parameter to the usual J definitions J, J11, J12, J22 = -2*J, -2*J11, -J12, -2*J22 L = np.linalg.cholesky(J + J11) v = solve_triangular(L, h) lognorm = 1./2*np.dot(v,v) - np.sum(np.log(np.diag(L))) h_predict = -np.dot(J12.T, solve_triangular(L, v, trans='T')) temp = solve_triangular(L, J12) J_predict = J22 - np.dot(temp.T, temp) assert np.all(np.linalg.eigvals(J_predict) > 0) return (-1./2*J_predict, h_predict), lognorm + logZ
def test_solve_triangular_grads(): npr.seed(0) n = 3 foo = lambda L, v, trans: to_scalar(solve_triangular(L, v, trans)) L = np.linalg.cholesky(rand_psd(n)) for v in [npr.randn(n), npr.randn(n,n)]: for trans in ['N', 'T']: ans = solve_triangular(L, v, trans) a = grad(foo, 0)(L, v, trans) b = solve_triangular_grad_arg0(randn_like(ans), ans, L, v, trans) check(a, b) a = grad(foo, 1)(L, v, trans) b = solve_triangular_grad_arg1(randn_like(ans), ans, L, v, trans) check(a, b)
def natural_sample(J, h, num_samples=None, rng=rng): sample_shape = (num_samples,) + h.shape if num_samples else h.shape J = -2*J if J.ndim == 1: return h / J + rng.normal(size=sample_shape) / np.sqrt(J) else: L = np.linalg.cholesky(J) noise = solve_triangular(L, rng.normal(size=sample_shape).T, trans='T') return solve_posdef_from_cholesky(L, h.T).T + noise.T
def test_dpotrs_grad(): npr.seed(0) n = 3 s = 5 J = rand_psd(n) h = npr.randn(n, s) L = np.linalg.cholesky(J) dpotrs = lambda (L, h): solve_triangular(L, solve_triangular(L, h), 'T') ans = dpotrs((L, h)) dotter = npr.randn(*ans.shape) assert np.allclose(ans, np.linalg.solve(J, h)) g_L_1, g_h_1 = grad(lambda x: np.sum(dotter * dpotrs(x)))((L, h)) g_L_2, g_h_2 = dpotrs_grad(dotter, ans, L, h) assert np.allclose(g_L_1, g_L_2) assert np.allclose(g_h_1, g_h_2)
def natural_rts_backward_step(next_smooth, next_pred, filtered, pair_param): # p = "predicted", f = "filtered", s = "smoothed", n = "next" (Jns, hns, mun), (Jnp, hnp), (Jf, hf) = next_smooth, next_pred, filtered J11, J12, J22, _ = pair_param # convert from natural parameter to the usual J definitions Jns, Jnp, Jf, J11, J12, J22 = -2*Jns, -2*Jnp, -2*Jf, -2*J11, -J12, -2*J22 J11, J12, J22 = Jf + J11, J12, Jns - Jnp + J22 L = np.linalg.cholesky(J22) temp = solve_triangular(L, J12.T) Js = J11 - np.dot(temp.T, temp) hs = hf - np.dot(temp.T, solve_triangular(L, hns - hnp)) mu, sigma = info_to_mean((Js, hs)) ExnxT = -solve_posdef_from_cholesky(L, np.dot(J12.T, sigma)) + np.outer(mun, mu) ExxT = sigma + np.outer(mu, mu) return -1./2*Js, hs, (mu, ExxT, ExnxT)
def test_natural_lognorm_grad(): npr.seed(0) n = 3 J = rand_psd(n) h = npr.randn(n) def natural_lognorm((J, h)): L = np.linalg.cholesky(J) v = solve_triangular(L, h) return 1./2*np.dot(v, v) - np.sum(np.log(np.diag(L))) g_J_1, g_h_1 = grad(lambda x: np.pi*natural_lognorm(x))((J, h)) L = np.linalg.cholesky(J) v = solve_triangular(L, h) g_J_2, g_h_2 = natural_lognorm_grad(np.pi, L, v) assert np.allclose(g_J_1, g_J_2) assert np.allclose(g_h_1, g_h_2)
def natural_lognorm(J, h): J = -2*J L = np.linalg.cholesky(J) v = solve_triangular(L, h) return 1./2*np.dot(v, v) - np.sum(np.log(np.diag(L)))
def natural_sample(J, h, eps): mu = np.linalg.solve(J, h) L = np.linalg.cholesky(J) noise = solve_triangular(L, eps, 'T') return mu + noise
def natural_sample(J, h, eps): L = np.linalg.cholesky(J) mu = solve_posdef_from_cholesky(L, h) noise = solve_triangular(L, eps, 'T') return mu + noise
def step1(L, hns, hnp, Jf, hf): temp = solve_triangular(L, J12.T) Js = Jf + J11 - np.dot(temp.T, temp) hs = hf - np.dot(temp.T, solve_triangular(L, hns - hnp)) return Js, hs