def __init__(self, kernel, X, Y, noise_var, n_features, normalize_Y=False): self.input_dim = kernel.input_dim self.lengthscale = kernel.lengthscale self.signal_var = kernel.variance self.noise_var = noise_var self.X = X self.Y = Y if Y.ndim == 2 else np.atleast_2d(Y).T self.normalize_Y = normalize_Y if self.normalize_Y: self.Y, self.y_mean = shift_y(Y) self.n_features = n_features self.w = None self.b = None self.phi = self._compute_phi() phi_train = self.phi(X) A = phi_train @ phi_train.T + self.noise_var * np.eye(self.n_features) chol_A = misc.compute_stable_cholesky(A) B = np.eye(self.X.shape[0]) + phi_train.T @ phi_train / self.noise_var chol_B = misc.compute_stable_cholesky(B) v = linalg.cho_solve(chol_B, phi_train.T) a_inv = (np.eye(self.n_features) - phi_train @ v / self.noise_var) self.theta_mu = linalg.cho_solve(chol_A, phi_train @ self.Y) self.theta_var = a_inv
def sample_posterior_handle_with_filtered_counterpart( self, n_samples, input_var): """ Generate handle to n_samples function samples that can be evaluated at x. Additionally generate a handle to the Gaussian-filtered counterpart of this sample. """ chol = misc.compute_stable_cholesky(self.theta_var)[0] theta_samples = self.theta_mu + chol @ np.random.randn( self.n_features, n_samples) def handle_to_function_samples(x): if x.ndim == 1 and self.input_dim == 1: x = np.atleast_2d(x).T elif x.ndim == 1 and self.input_dim > 1: x = np.atleast_2d(x) h = self.phi(x).T @ theta_samples return deshift_y(h, self.y_mean) if self.normalize_Y else h def handle_to_filtered_function_samples(x): if x.ndim == 1 and self.input_dim == 1: x = np.atleast_2d(x).T elif x.ndim == 1 and self.input_dim > 1: x = np.atleast_2d(x) phi_filt = self._compute_phi_filt(input_var) h = phi_filt(x).T @ theta_samples return deshift_y(h, self.y_mean) if self.normalize_Y else h return handle_to_function_samples, handle_to_filtered_function_samples
def predictive_cond_dist(x, ngp, g_star, nm3, nv3): n_eval = x.shape[0] X = ngp.X Y = gp_module.deshift_y(ngp.Y, ngp.y_mean) if ngp.normalize_Y else ngp.Y m5, v5 = np.empty((n_eval, )), np.empty((n_eval, )) k_f = ngp.kernel.K k_g = ngp.kernel_g.K k_fg = ngp.kernel_fg.K for i, xi in enumerate(x): xi = np.atleast_2d(xi) kf_Xx = k_f(X, xi) kgf_xx = k_fg(xi) kz = np.vstack((kf_Xx, kgf_xx)) kg_xx = k_g(xi) kf_XX_noise = k_f(X) + ngp.noise_var * np.eye(X.shape[0]) kfg_Xx = k_fg(X, xi) tmp1 = np.hstack((kf_XX_noise, kfg_Xx)) tmp2 = np.hstack((kfg_Xx.T, kg_xx)) Kz = np.vstack((tmp1, tmp2)) Kz_chol = misc.compute_stable_cholesky(Kz) s = linalg.cho_solve(Kz_chol, kz) # s = inv(Kz) @ kz cov4 = k_f(xi) - s.T @ kz a1 = s.T[:, :-1] a2 = s.T[:, -1:] m5[i] = a1 @ Y + a2 * nm3[i] v5[i] = cov4 + a2**2 * nv3[i] return m5, v5
def set_xy(self, X, Y): self.X = X self.Y = Y if self.normalize_Y: self.Y, self.y_mean = shift_y(Y) K = self.kernel.K(X) + self.noise_var * np.eye(X.shape[0]) self.chol = misc.compute_stable_cholesky(K) self.alpha = linalg.cho_solve(self.chol, self.Y)
def __init__(self, kernel, X, Y, noise_var, normalize_Y=False): self.kernel = kernel self.input_dim = kernel.input_dim self.X = X self.Y = Y self.noise_var = noise_var self.normalize_Y = normalize_Y if self.normalize_Y: self.Y, self.y_mean = shift_y(Y) K = self.kernel.K(X) + self.noise_var * np.eye(X.shape[0]) self.chol = misc.compute_stable_cholesky(K) self.alpha = linalg.cho_solve(self.chol, self.Y)
def sample_posterior_handle(self, n_samples): """ Generate handle to n_samples function samples that can be evaluated at x. """ chol = misc.compute_stable_cholesky(self.theta_var)[0] theta_samples = self.theta_mu + chol @ np.random.randn( self.n_features, n_samples) def handle_to_function_samples(x): if x.ndim == 1 and self.input_dim == 1: x = np.atleast_2d(x).T elif x.ndim == 1 and self.input_dim > 1: x = np.atleast_2d(x) h = self.phi(x).T @ theta_samples return deshift_y(h, self.y_mean) if self.normalize_Y else h return handle_to_function_samples
def trunc_gauss_approx_g(x, ngp, max_val, mu1, cov1): k_f = ngp.kernel.K k_fg = ngp.kernel_fg.K k_g = ngp.kernel_g.K X = ngp.X Y = gp_module.deshift_y(ngp.Y, ngp.y_mean) if ngp.normalize_Y else ngp.Y n_data = X.shape[0] # Step 1: p( g | y, g*) \propto p( g | y ) \prod Indicator(g* > g_i) # This is pre-computed and given via mu1, cov1 # Step 2: p0( g(x) | y, g*) = \int p( g(x) | g, y ) p( g | y, g*) dg # Pre-calculate bunch of kernel matrices kfg_XX = k_fg(X) kf_XX_noisy = k_f(X) + ngp.noise_var * np.eye(n_data) K = np.vstack((np.hstack((k_g(X), kfg_XX)), np.hstack( (kfg_XX, kf_XX_noisy)))) k_xX = np.hstack((k_g(x, X), k_fg(X, x).T)) # p( g(x) | g, y ) = N( g(x) | mu_g, cov_g ) K_chol = misc.compute_stable_cholesky(K) s = linalg.cho_solve(K_chol, k_xX.T) covg = k_g(x) - s.T @ k_xX.T a1 = s.T[:, :n_data] a2 = s.T[:, n_data:] # p0(g(x) | y, g *) = N( g(x) | mu2, v2 ) mu2 = a1 @ mu1[:, None] + a2 @ Y cov2 = covg + a1 @ cov1 @ a1.T m2 = mu2.squeeze() v2 = np.diag(cov2) # Step 3: p( g(x) | y, g*) = N( g(x) | mu3, v3 ) alpha = (max_val - m2) / np.sqrt(v2) r = stats.norm.pdf(alpha) / stats.norm.cdf(alpha) m3 = m2 - np.sqrt(v2 * r) v3 = v2 - v2 * r * (r + alpha) return m3, v3