def _build_prior(self, name, Xs, jitter, **kwargs): self.N = int(np.prod([len(X) for X in Xs])) mu = self.mean_func(cartesian(*Xs)) chols = [cholesky(stabilize(cov(X), jitter)) for cov, X in zip(self.cov_funcs, Xs)] v = pm.Normal(name + "_rotated_", mu=0.0, sigma=1.0, size=self.N, **kwargs) f = pm.Deterministic(name, mu + at.flatten(kron_dot(chols, v))) return f
def test_kron_dot(): np.random.seed(1) # Create random matrices Ks = [np.random.rand(3, 3) for i in range(3)] # Create random vector with correct shape tot_size = np.prod([k.shape[1] for k in Ks]) x = np.random.rand(tot_size).reshape((tot_size, 1)) # Construct entire kronecker product then multiply big = kronecker(*Ks) slow_ans = at.dot(big, x) # Use tricks to avoid construction of entire kronecker product fast_ans = kron_dot(Ks, x) np.testing.assert_array_almost_equal(slow_ans.eval(), fast_ans.eval())
def _build_conditional(self, Xnew, pred_noise, diag): Xs, y, sigma = self.Xs, self.y, self.sigma # Old points X = cartesian(*Xs) delta = y - self.mean_func(X) Kns = [f(x) for f, x in zip(self.cov_funcs, Xs)] eigs_sep, Qs = zip(*map(eigh, Kns)) # Unzip QTs = list(map(at.transpose, Qs)) eigs = kron_diag(*eigs_sep) # Combine separate eigs if sigma is not None: eigs += sigma ** 2 # New points Km = self.cov_func(Xnew, diag=diag) Knm = self.cov_func(X, Xnew) Kmn = Knm.T # Build conditional mu alpha = kron_dot(QTs, delta) alpha = alpha / eigs[:, None] alpha = kron_dot(Qs, alpha) mu = at.dot(Kmn, alpha).ravel() + self.mean_func(Xnew) # Build conditional cov A = kron_dot(QTs, Knm) A = A / at.sqrt(eigs[:, None]) if diag: Asq = at.sum(at.square(A), 0) cov = Km - Asq if pred_noise: cov += sigma else: Asq = at.dot(A.T, A) cov = Km - Asq if pred_noise: cov += sigma * at.identity_like(cov) return mu, cov