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
Exemple #7
0
 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]])
Exemple #8
0
 def test_dist_square_length_scale(self):
     assert Distances.dist_square_length_scale(self.ls, self.x1) == [[0.0]]