def F_d2quad_df2_func_approx(e_f, e_g, y): e_2f = safe_square(e_f) #return 0.5*(-polygamma(1, e_f)*e_2f - polygamma(0, e_f)*e_f #+polygamma(1, e_f + e_g)*e_2f + polygamma(0, e_f + e_g)*e_f) #return 0.5*(-zeta(2, e_f)*e_2f - psi(e_f)*e_f #+zeta(2, e_f + e_g)*e_2f + psi(e_f + e_g)*e_f) return 0.5*(-approx_2zeta(e_f)*e_2f - psi(e_f)*e_f +approx_2zeta(e_f + e_g)*e_2f + psi(e_f + e_g)*e_f)
def predictive(self, M, V, gh_points=None, Y_metadata=None): # Variational Expectation # gh: Gaussian-Hermite quadrature if gh_points is None: gh_f, gh_w = self._gh_points() else: gh_f, gh_w = gh_points gh_w = gh_w / np.sqrt(np.pi) D = M.shape[1] expanded_F_tuples = [] grid_tuple = [M.shape[0]] for d in range(D): grid_tuple.append(gh_f.shape[0]) expanded_fd_tuple = [1] * (D + 1) expanded_fd_tuple[d + 1] = gh_f.shape[0] expanded_F_tuples.append(tuple(expanded_fd_tuple)) # mean-variance tuple mv_tuple = [1] * (D + 1) mv_tuple[0] = M.shape[0] mv_tuple = tuple(mv_tuple) # building, normalizing and reshaping the grids F = np.zeros((reduce(lambda x, y: x * y, grid_tuple), D)) for d in range(D): fd = np.zeros(tuple(grid_tuple)) fd[:] = np.reshape(gh_f, expanded_F_tuples[d]) * np.sqrt(2 * np.reshape(V[:, d], mv_tuple)) \ + np.reshape(M[:, d], mv_tuple) F[:, d, None] = fd.reshape(reduce(lambda x, y: x * y, grid_tuple), -1, order='C') mean = self.mean(F) mean = mean.reshape(tuple(grid_tuple)) mean_pred = mean.dot(gh_w).dot(gh_w) / np.square(np.sqrt(np.pi)) var = self.variance(F) var = var.reshape(tuple(grid_tuple)) var_int = var.dot(gh_w).dot(gh_w) / np.square(np.sqrt(np.pi)) mean_sq = self.mean_sq(F) mean_sq = mean_sq.reshape(tuple(grid_tuple)) mean_sq_int = mean_sq.dot(gh_w).dot(gh_w) / np.square(np.sqrt(np.pi)) var_pred = var_int + mean_sq_int - safe_square(mean_pred) return mean_pred[:,None] , var_pred[:,None]
def variance(self, f, Y_metadata=None): b = safe_exp(-f) b = np.clip(b, 1e-9, 1e9) # numerical stability var = safe_square(b) return var
def mean_sq(self, f, Y_metadata=None): b = safe_exp(-f) b = np.clip(b, 1e-9, 1e9) # numerical stability mean_sq = safe_square(b) return mean_sq
def logpdf_sampling(self, F, y, Y_metadata=None): e_var = safe_exp(F[:, 1, :]) ym = (np.tile(y, (1, F.shape[2])) - F[:, 0, :]) logpdf = -0.5 * np.log(2 * np.pi) - (0.5 * F[:, 1]) - 0.5 * ( (safe_square(ym)) / e_var) return logpdf
def logpdf(self, F, y, Y_metadata=None): e_var = safe_exp(F[:, 1]) ym = (y - F[:, 0]) logpdf = -0.5 * np.log(2 * np.pi) - (0.5 * F[:, 1]) - 0.5 * ( (safe_square(ym)) / e_var) return logpdf
def d3transf_df3(self,f): shiftedf = (f-self.offset)*self.scale return (safe_square(shiftedf)-1.)*std_norm_pdf(shiftedf)
def F_d2quad_dg2_func_approx_sum(e_f, e_g, y): e_2g = safe_square(e_g) return 0.5*(-approx_2zeta_sum(e_g)*e_2g - psi(e_g)*e_g +approx_2zeta_sum(e_f + e_g)*e_2g + psi(e_f + e_g)*e_g)
def F_d2quad_dg2_func(e_f, e_g, y): e_2g = safe_square(e_g) #return 0.5*(-polygamma(1, e_g)*e_2g - polygamma(0, e_g)*e_g #+polygamma(1, e_f + e_g)*e_2g + polygamma(0, e_f + e_g)*e_g) return 0.5*(-zeta(2, e_g)*e_2g - psi(e_g)*e_g +zeta(2, e_f + e_g)*e_2g + psi(e_f + e_g)*e_g)
def F_d2quad_df2_func_approx_sum(e_f, e_g, y): e_2f = safe_square(e_f) return 0.5*(-approx_2zeta_sum(e_f)*e_2f - psi(e_f)*e_f +approx_2zeta_sum(e_f + e_g)*e_2f + psi(e_f + e_g)*e_f)
def F_d2quad_df2_func(e_f, e_g, y): e_2f = safe_square(e_f) #return 0.5*(-polygamma(1, e_f)*e_2f - polygamma(0, e_f)*e_f #+polygamma(1, e_f + e_g)*e_2f + polygamma(0, e_f + e_g)*e_f) return 0.5*(-zeta(2, e_f)*e_2f - psi(e_f)*e_f +zeta(2, e_f + e_g)*e_2f + psi(e_f + e_g)*e_f)