def test_hessian_distance_length_scale_respect_point(self): params = np.array([1.0, 5.0]) point = np.array([[4.5, 7.5]]) inputs = np.array([[5.0, 6.0], [8.0, 9.0]]) result = Distances.gradient_distance_length_scale_respect_point( params, point, inputs, second=True) result = result['second'] dh = 0.00001 finite_diff = FiniteDifferences.second_order_central( lambda x: np.sqrt( Distances.dist_square_length_scale( params, x.reshape((1, len(x))), inputs)), point[0, :], np.array([dh])) for i in xrange(2): for j in xrange(2): print i, j npt.assert_almost_equal( finite_diff[i, j], np.array([[result[0, i, j], result[1, i, j]]]), decimal=5)
def cross_cov(self, inputs_1, inputs_2): """ :param inputs_1: np.array(nxd) :param inputs_2: np.array(mxd) :return: np.array(nxm) """ r2 = np.abs( Distances.dist_square_length_scale(self.length_scale.value, inputs_1, inputs_2)) r = np.sqrt(r2) cov = (1.0 + np.sqrt(5) * r + (5.0 / 3.0) * r2) * np.exp(-np.sqrt(5) * r) return cov
def gradient_respect_distance_cross(cls, ls, inputs_1, inputs_2, second=False): """ :param ls: (ParameterEntity) length_scale :param inputs_1: np.array(nxd) :param inputs_2: np.array(mxd) :param second: (boolean) Computes second derivative if it's True. :return: np.array(nxm) or {'first': np.array(nxm), 'second': np.array(nxm)} """ r2 = np.abs( Distances.dist_square_length_scale(ls.value, inputs_1, inputs_2)) r = np.sqrt(r2) exp_r = np.exp(-np.sqrt(5) * r) part_1 = (1.0 + np.sqrt(5) * r + (5.0 / 3.0) * r2) * exp_r * (-np.sqrt(5)) part_2 = (exp_r * (np.sqrt(5) + (10.0 / 3.0) * r)) derivate_respect_to_r = part_1 + part_2 if not second: return derivate_respect_to_r part_0 = (10.0 / 3.0) * exp_r part_1 = part_1 * (-np.sqrt(5.0)) part_3 = 2.0 * ( (10.0 / 3.0) * r + np.sqrt(5.0)) * exp_r * (-np.sqrt(5.0)) hessian_respect_to_r = part_0 + part_1 + part_3 sol = { 'first': derivate_respect_to_r, 'second': hessian_respect_to_r, } return sol
def grad_respect_point(cls, ls, point, inputs): """ Computes the vector of the gradients of cov(point, inputs) respect point. :param ls: (ParameterEntity) length_scale :param point: np.array(1xd) :param inputs: np.array(nxd) :return: np.array(nxd) """ derivate_respect_to_r = cls.gradient_respect_distance_cross( ls, point, inputs) grad_distance_point = \ Distances.gradient_distance_length_scale_respect_point(ls.value, point, inputs) gradient = grad_distance_point * derivate_respect_to_r.transpose() gradient = np.nan_to_num(gradient) return gradient
def hessian_respect_point(cls, ls, point, inputs): """ Computes the Hessians of cov(point, inputs) respect point. :param ls: (ParameterEntity) length_scale :param point: np.array(1xd) :param inputs: np.array(nxd) :return: np.array(nxdxd) """ derivatives_resp_r = cls.gradient_respect_distance_cross(ls, point, inputs, second=True) hessian_respect_point = Distances.gradient_distance_length_scale_respect_point( ls.value, point, inputs, second=True) hess = hessian_respect_point['second'] part_1 = hess * derivatives_resp_r['first'][0, :][:, np.newaxis, np.newaxis] grad = hessian_respect_point['first'] part_2 = grad[:, :, None] * grad[:, None, :] part_2 *= derivatives_resp_r['second'][0, :][:, np.newaxis, np.newaxis] hessian = part_1 + part_2 # hessian = {} # for i in xrange(inputs.shape[0]): # hess = hessian_respect_point['second'][i] # part_1 = hess * derivatives_resp_r['first'][0, i] # # grad = hessian_respect_point['first'][i:i+1, :] # part_2 = np.dot(grad.transpose(), grad) # part_2 *= derivatives_resp_r['second'][0, i] # # hessian[i] = part_1 + part_2 return hessian
def gradient_respect_parameters_ls(cls, inputs, ls): """ :param inputs: np.array(nxd) :param ls: (ParameterEntity) length_scale :return: { 'length_scale': {'entry (int)': nxn} } """ derivate_respect_to_r = cls.gradient_respect_distance(ls, inputs) grad = {} grad[ls.name] = {} grad_distance_ls = Distances.gradient_distance_length_scale_respect_ls( ls.value, inputs) for i in range(ls.dimension): grad[ls.name][i] = grad_distance_ls[i] * derivate_respect_to_r return grad
def test_gradient_distance_length_scale_respect_point(self): expect(Distances).dist_square_length_scale.once().and_return( np.array([[1.0]])) assert Distances.gradient_distance_length_scale_respect_point(self.ls, self.x1, self.x1)\ == np.array([[0.0]])
def test_dist_square_length_scale(self): assert Distances.dist_square_length_scale(self.ls, self.x1) == [[0.0]]