def compute_covariance_of_points(self, points1, points2): r"""Compute the variance (matrix) of this GP at each point of ``Xs`` (``points_to_sample``). .. Warning:: ``points_to_sample`` should not contain duplicate points. The variance matrix is symmetric although we currently return the full representation. .. Note:: Comments are copied from :mod:`moe.optimal_learning.python.interfaces.gaussian_process_interface.GaussianProcessInterface.compute_variance_of_points` :param points_to_sample: num_to_sample points (in dim dimensions) being sampled from the GP :type points_to_sample: array of float64 with shape (num_to_sample, dim) :return: var_star: variance matrix of this GP :rtype: array of float64 with shape (num_to_sample, num_to_sample) """ var_star = python_utils.build_mix_covariance_matrix(self._covariance, points1, points2) # this is K_star_star if self.num_sampled == 0: return numpy.diag(numpy.diag(var_star)) K_star1 = python_utils.build_mix_covariance_matrix( self._covariance, self._points_sampled, points1, ) K_star2 = python_utils.build_mix_covariance_matrix( self._covariance, self._points_sampled, points2 ) V1 = scipy.linalg.solve_triangular( self._K_chol[0], K_star1, lower=self._K_chol[1], overwrite_b=True, ) V2 = scipy.linalg.solve_triangular( self._K_chol[0], K_star2, lower=self._K_chol[1], overwrite_b=True, ) # cheaper to go through scipy.linalg.get_blas_funcs() which can compute A = alpha*B*C + beta*A in one pass var_star -= numpy.dot(V1.T, V2) return var_star
def _compute_grad_covariance_of_points_per_point(self, points_to_sample, discrete_pts, var_of_grad): r"""Compute the gradient of the covariance (matrix) of this GP among ``Xs`` (``points_to_sample``) and discrete points wrt a single point of ``Xs``. See :meth:`~moe.optimal_learning.python.python_version.gaussian_process.GaussianProcess.compute_grad_variance_of_points` for more details. :param points_to_sample: num_to_sample points (in dim dimensions) being sampled from the GP :type points_to_sample: array of float64 with shape (num_to_sample, dim) :param discrete_pts: points to approximate KG :type discrete_pts: array of float64 with shape (num_pts, dim) :param var_of_grad: index of ``points_to_sample`` to be differentiated against :type var_of_grad: int in {0, .. ``num_to_sample``-1} :return: grad_var: gradient of the variance matrix of this GP :rtype: array of float64 with shape (num_to_sample, num_to_sample, dim) """ # TODO(GH-62): This can be improved/optimized. see: gpp_math.cpp, GaussianProcess::ComputeGradVarianceOfPoints num_to_sample = points_to_sample.shape[0] num_pts = discrete_pts.shape[0] # Compute grad variance grad_var = numpy.zeros((num_to_sample, num_pts, self.dim)) K_star = python_utils.build_mix_covariance_matrix( self._covariance, self._points_sampled, discrete_pts, ) K_inv_times_K_star = scipy.linalg.cho_solve(self._K_chol, K_star, overwrite_b=True) for i, point_one in enumerate(points_to_sample): for j, point_two in enumerate(discrete_pts): if var_of_grad == i: grad_var[i, j, ...] = self._covariance.grad_covariance(point_one, point_two) for idx_two, sampled_two in enumerate(self._points_sampled): grad_var[i, j, ...] -= K_inv_times_K_star[idx_two, j] * self._covariance.grad_covariance(point_one, sampled_two) return grad_var
def compute_variance_of_points(self, points_to_sample): r"""Compute the variance (matrix) of this GP at each point of ``Xs`` (``points_to_sample``). .. Warning:: ``points_to_sample`` should not contain duplicate points. The variance matrix is symmetric although we currently return the full representation. .. Note:: Comments are copied from :mod:`moe.optimal_learning.python.interfaces.gaussian_process_interface.GaussianProcessInterface.compute_variance_of_points` :param points_to_sample: num_to_sample points (in dim dimensions) being sampled from the GP :type points_to_sample: array of float64 with shape (num_to_sample, dim) :return: var_star: variance matrix of this GP :rtype: array of float64 with shape (num_to_sample, num_to_sample) """ var_star = python_utils.build_covariance_matrix(self._covariance, points_to_sample) # this is K_star_star if self.num_sampled == 0: return numpy.diag(numpy.diag(var_star)) K_star = python_utils.build_mix_covariance_matrix( self._covariance, self._points_sampled, points_to_sample, ) V = scipy.linalg.solve_triangular( self._K_chol[0], K_star, lower=self._K_chol[1], overwrite_b=True, ) # cheaper to go through scipy.linalg.get_blas_funcs() which can compute A = alpha*B*C + beta*A in one pass var_star -= numpy.dot(V.T, V) return var_star
def _compute_grad_variance_of_points_per_point(self, points_to_sample, var_of_grad): r"""Compute the gradient of the variance (matrix) of this GP at a single point of ``Xs`` (``points_to_sample``) wrt ``Xs``. See :meth:`~moe.optimal_learning.python.python_version.gaussian_process.GaussianProcess.compute_grad_variance_of_points` for more details. :param points_to_sample: num_to_sample points (in dim dimensions) being sampled from the GP :type points_to_sample: array of float64 with shape (num_to_sample, dim) :param var_of_grad: index of ``points_to_sample`` to be differentiated against :type var_of_grad: integer in {0, .. ``num_to_sample``-1} :return: grad_var: gradient of the variance matrix of this GP :rtype: array of float64 with shape (num_to_sample, num_to_sample, dim) """ # TODO(GH-62): This can be improved/optimized. see: gpp_math.cpp, GaussianProcess::ComputeGradVarianceOfPoints num_to_sample = points_to_sample.shape[0] # Compute grad variance grad_var = numpy.zeros((num_to_sample, num_to_sample, self.dim)) K_star = python_utils.build_mix_covariance_matrix( self._covariance, self._points_sampled, points_to_sample, ) K_inv_times_K_star = scipy.linalg.cho_solve(self._K_chol, K_star, overwrite_b=True) for i, point_one in enumerate(points_to_sample): for j, point_two in enumerate(points_to_sample): if var_of_grad == i and var_of_grad == j: grad_var[i, j, ...] = self._covariance.grad_covariance(point_one, point_two) for idx_two, sampled_two in enumerate(self._points_sampled): grad_var[i, j, ...] -= 2.0 * K_inv_times_K_star[idx_two, i] * self._covariance.grad_covariance(point_one, sampled_two) elif var_of_grad == i: grad_var[i, j, ...] = self._covariance.grad_covariance(point_one, point_two) for idx_two, sampled_two in enumerate(self._points_sampled): grad_var[i, j, ...] -= K_inv_times_K_star[idx_two, j] * self._covariance.grad_covariance(point_one, sampled_two) elif var_of_grad == j: grad_var[i, j, ...] = self._covariance.grad_covariance(point_two, point_one) for idx_one, sampled_one in enumerate(self._points_sampled): grad_var[i, j, ...] -= K_inv_times_K_star[idx_one, i] * self._covariance.grad_covariance(point_two, sampled_one) return grad_var
def compute_mean_of_points(self, points_to_sample): r"""Compute the mean of this GP at each of point of ``Xs`` (``points_to_sample``). .. Warning:: ``points_to_sample`` should not contain duplicate points. .. Note:: Comments are copied from :mod:`moe.optimal_learning.python.interfaces.gaussian_process_interface.GaussianProcessInterface.compute_mean_of_points` :param points_to_sample: num_to_sample points (in dim dimensions) being sampled from the GP :type points_to_sample: array of float64 with shape (num_to_sample, dim) :return: mean: where mean[i] is the mean at points_to_sample[i] :rtype: array of float64 with shape (num_to_sample) """ if self.num_sampled == 0: return numpy.zeros(points_to_sample.shape[0]) K_star = python_utils.build_mix_covariance_matrix( self._covariance, self._points_sampled, points_to_sample, ) mu_star = numpy.dot(K_star.T, self._K_inv_y) return mu_star