Exemplo n.º 1
0
 def _replace_values(self, samples, new_samples, indcs):
     replaced_indices = [
         i for i, is_replaced in enumerate(indcs) if is_replaced
     ]
     value_indices = list(
         product(replaced_indices, range(self.n), range(self.n)))
     return gs.assignment(samples, gs.flatten(new_samples), value_indices)
Exemplo n.º 2
0
    def setup_data(self):
        """Generate the un-shuffled dataset.

        Returns
        -------
        X : array-like,
           shape = [n_samples * n_classes, n_features, n_features]
            Data.
        y : array-like, shape = [n_samples * n_classes, n_classes]
            Labels.
        """
        mean_covariance_eigenvalues = gs.random.uniform(
            0.1, 5., (self.n_classes, self.n_features))
        var = 1.
        base_rotations = SpecialOrthogonal(n=self.n_features).random_gaussian(
            gs.eye(self.n_features), var, n_samples=self.n_classes)
        var_rotations = gs.random.uniform(.5, .75, (self.n_classes))

        y = gs.zeros((self.n_classes * self.n_samples, self.n_classes))
        X = []
        for i in range(self.n_classes):
            value_x = self.make_data(base_rotations[i],
                                     gs.diag(mean_covariance_eigenvalues[i]),
                                     var_rotations[i])
            value_y = 1
            idx_y = [
                (j, i)
                for j in range(i * self.n_samples, (i + 1) * self.n_samples)
            ]
            y = gs.assignment(y, value_y, idx_y)
            X.append(value_x)
        return gs.concatenate(X, axis=0), y
Exemplo n.º 3
0
    def random_uniform(self, n_samples=1, tol=1e-6):
        """Sample in SE(n) from the uniform distribution.

        Parameters
        ----------
        n_samples : int
            Number of samples.
            Optional, default: 1.
        tol : unused

        Returns
        -------
        samples : array-like, shape=[..., n + 1, n + 1]
            Sample in SE(n).
        """
        random_translation = self.translations.random_uniform(n_samples)
        random_rotation = self.rotations.random_uniform(n_samples)
        random_rotation = gs.to_ndarray(random_rotation, to_ndim=3)

        random_translation = gs.to_ndarray(random_translation, to_ndim=2)
        random_translation = gs.transpose(gs.to_ndarray(
            random_translation, to_ndim=3, axis=1), (0, 2, 1))

        random_point = gs.concatenate(
            (random_rotation, random_translation), axis=2)
        last_line = gs.zeros((n_samples, 1, self.n + 1))
        random_point = gs.concatenate(
            (random_point, last_line), axis=1)
        random_point = gs.assignment(random_point, 1, (-1, -1), axis=0)
        if gs.shape(random_point)[0] == 1:
            random_point = gs.squeeze(random_point, axis=0)
        return random_point
Exemplo n.º 4
0
    def test_assignment(self):
        gs_array_1 = gs.ones(3)
        with pytest.raises(ValueError):
            gs.assignment(gs_array_1, [0.1, 2.0, 1.0], [0, 1])

        np_array_1 = _np.ones(3)
        gs_array_1 = gs.ones_like(gs.array(np_array_1))

        np_array_1[2] = 1.5
        gs_result = gs.assignment(gs_array_1, 1.5, 2)
        self.assertAllCloseToNp(gs_result, np_array_1)

        np_array_1_list = _np.ones(3)
        gs_array_1_list = gs.ones_like(gs.array(np_array_1_list))

        indices = [1, 2]
        np_array_1_list[indices] = 1.5
        gs_result = gs.assignment(gs_array_1_list, 1.5, indices)
        self.assertAllCloseToNp(gs_result, np_array_1_list)

        np_array_2 = _np.zeros((3, 2))
        gs_array_2 = gs.zeros_like(gs.array(np_array_2))

        np_array_2[0, :] = 1
        gs_result = gs.assignment(gs_array_2, 1, 0, axis=1)
        self.assertAllCloseToNp(gs_result, np_array_2)

        np_array_3 = _np.zeros((3, 3))
        gs_array_3 = gs.zeros_like(gs.array(np_array_3))

        np_array_3[0, 1] = 1
        gs_result = gs.assignment(gs_array_3, 1, (0, 1))
        self.assertAllCloseToNp(gs_result, np_array_3)

        np_array_4 = _np.zeros((3, 3, 2))
        gs_array_4 = gs.zeros_like(gs.array(np_array_4))

        np_array_4[0, :, 1] = 1
        gs_result = gs.assignment(gs_array_4, 1, (0, 1), axis=1)
        self.assertAllCloseToNp(gs_result, np_array_4)

        gs_array_4_arr = gs.zeros_like(gs.array(np_array_4))

        gs_result = gs.assignment(gs_array_4_arr, 1, gs.array((0, 1)), axis=1)
        self.assertAllCloseToNp(gs_result, np_array_4)

        np_array_4_list = _np.zeros((3, 3, 2))
        gs_array_4_list = gs.zeros_like(gs.array(np_array_4_list))

        np_array_4_list[(0, 1), :, (1, 1)] = 1
        gs_result = gs.assignment(gs_array_4_list, 1, [(0, 1), (1, 1)], axis=1)
        self.assertAllCloseToNp(gs_result, np_array_4_list)
Exemplo n.º 5
0
    def log(self, point, base_point):
        """Compute Riemannian logarithm of a point wrt a base point.

        If point_type = 'poincare' then base_point belongs
        to the Poincare ball and point is a vector in the Euclidean
        space of the same dimension as the ball.

        Parameters
        ----------
        point : array-like, shape=[..., dim]
            Point in hyperbolic space.
        base_point : array-like, shape=[..., dim]
            Point in hyperbolic space.

        Returns
        -------
        log : array-like, shape=[..., dim]
            Tangent vector at the base point equal to the Riemannian logarithm
            of point at the base point.
        """
        add_base_point = self.mobius_add(-base_point, point)
        norm_add =\
            gs.expand_dims(gs.linalg.norm(
                           add_base_point, axis=-1), axis=-1)

        norm_base_point =\
            gs.expand_dims(gs.linalg.norm(
                           base_point, axis=-1), axis=-1)

        log = (1 - norm_base_point**2) * gs.arctanh(norm_add)

        mask_0 = gs.isclose(gs.squeeze(norm_add, axis=-1), 0.)
        mask_non0 = ~mask_0
        add_base_point = gs.assignment(
            add_base_point,
            gs.zeros_like(add_base_point[mask_0]),
            mask_0)
        add_base_point = gs.assignment(
            add_base_point,
            add_base_point[mask_non0] / norm_add[mask_non0],
            mask_non0)

        log = gs.einsum(
            '...i,...j->...j', log, add_base_point)
        return log
Exemplo n.º 6
0
    def exp(self, tangent_vec, base_point):
        """Compute the Riemannian exponential of a tangent vector.

        Parameters
        ----------
        tangent_vec : array-like, shape=[..., dim]
            Tangent vector at a base point.
        base_point : array-like, shape=[..., dim]
            Point in hyperbolic space.

        Returns
        -------
        exp : array-like, shape=[..., dim]
            Point in hyperbolic space equal to the Riemannian exponential
            of tangent_vec at the base point.
        """
        norm_base_point = gs.linalg.norm(base_point, axis=-1)
        norm_tan = gs.linalg.norm(tangent_vec, axis=-1)

        den = 1 - norm_base_point ** 2
        lambda_base_point = 1 / den

        zero_tan = gs.isclose(gs.sum(tangent_vec ** 2, axis=-1), 0.)

        if gs.any(zero_tan):
            norm_tan = gs.assignment(norm_tan, EPSILON, zero_tan)

        direction = gs.einsum('...i,...->...i', tangent_vec, 1 / norm_tan)

        factor = gs.tanh(
            gs.einsum('...,...->...', lambda_base_point, norm_tan))

        exp = self.mobius_add(
            base_point,
            gs.einsum('...i,...->...i', direction, factor))

        if gs.any(zero_tan):
            exp = gs.assignment(
                exp, base_point[zero_tan], zero_tan)

        return exp
Exemplo n.º 7
0
    def test_assignment_with_matrices(self):
        np_array = _np.zeros((2, 3, 3))
        gs_array = gs.zeros((2, 3, 3))

        np_array[:, 0, 1] = 44.0

        gs_array = gs.assignment(gs_array, 44.0, (0, 1), axis=0)

        self.assertAllCloseToNp(gs_array, np_array)

        n_samples = 3
        theta = _np.random.rand(5)
        phi = _np.random.rand(5)
        np_array = _np.zeros((n_samples, 5, 4))
        gs_array = gs.array(np_array)
        np_array[0, :, 0] = gs.cos(theta) * gs.cos(phi)
        np_array[0, :, 1] = -gs.sin(theta) * gs.sin(phi)
        gs_array = gs.assignment(gs_array, gs.cos(theta) * gs.cos(phi), (0, 0), axis=1)
        gs_array = gs.assignment(gs_array, -gs.sin(theta) * gs.sin(phi), (0, 1), axis=1)

        self.assertAllCloseToNp(gs_array, np_array)
Exemplo n.º 8
0
    def random_uniform(self, n_samples=1, point_type=None):
        """Sample in SE(n) with the uniform distribution.

        Parameters
        ----------
        n_samples: int, optional
            default: 1
        point_type: str, {'vector', 'matrix'}, optional
            default: self.default_point_type

        Returns
        -------
        random_point: array-like,
            shape=[n_samples, {dim, [n + 1, n + 1]}]
            An array of random elements in SE(n) having the given point_type.
        """
        if point_type is None:
            point_type = self.default_point_type

        random_translation = self.translations.random_uniform(n_samples)

        if point_type == 'vector':
            random_rot_vec = self.rotations.random_uniform(
                n_samples, point_type=point_type)
            return gs.concatenate([random_rot_vec, random_translation],
                                  axis=-1)

        if point_type == 'matrix':
            random_rotation = self.rotations.random_uniform(
                n_samples, point_type=point_type)
            random_rotation = gs.to_ndarray(random_rotation, to_ndim=3)

            random_translation = gs.to_ndarray(random_translation, to_ndim=2)
            random_translation = gs.transpose(
                gs.to_ndarray(random_translation, to_ndim=3, axis=1),
                (0, 2, 1))

            random_point = gs.concatenate(
                (random_rotation, random_translation), axis=2)
            last_line = gs.zeros((n_samples, 1, self.n + 1))
            random_point = gs.concatenate((random_point, last_line), axis=1)
            random_point = gs.assignment(random_point, 1, (-1, -1), axis=0)
            if gs.shape(random_point)[0] == 1:
                random_point = gs.squeeze(random_point, axis=0)
            return random_point

        raise ValueError('Invalid point_type, expected \'vector\' or '
                         '\'matrix\'.')
Exemplo n.º 9
0
    def projection(self, point):
        r"""Project a matrix to the space of PSD matrices of rank k.

        The nearest symmetric positive semidefinite matrix in the
        Frobenius norm to an arbitrary real matrix A is shown to be (B + H)/2,
        where H is the symmetric polar factor of B=(A + A')/2.
        As [Higham1988] is turning the matrix into a PSD, the rank
        is then forced to be k.

        Parameters
        ----------
        point : array-like, shape=[..., n, n]
            Matrix to project.

        Returns
        -------
        projected: array-like, shape=[..., n, n]
            PSD matrix rank k.

        References
        ----------
        [Higham1988]_    Highamm, N. J.
                        “Computing a nearest symmetric positive semidefinite matrix.”
                        Linear Algebra and Its Applications 103 (May 1, 1988):
                        103-118. https://doi.org/10.1016/0024-3795(88)90223-6
        """
        sym = Matrices.to_symmetric(point)
        _, s, v = gs.linalg.svd(sym)
        h = gs.matmul(Matrices.transpose(v), s[..., None] * v)
        sym_proj = (sym + h) / 2
        eigvals, eigvecs = gs.linalg.eigh(sym_proj)
        i = gs.array([0] * (self.n - self.rank) + [2 * gs.atol] * self.rank)
        regularized = (
            gs.assignment(eigvals, 0, gs.arange((self.n - self.rank)), axis=0) + i
        )
        reconstruction = gs.einsum("...ij,...j->...ij", eigvecs, regularized)

        return Matrices.mul(reconstruction, Matrices.transpose(eigvecs))
Exemplo n.º 10
0
    def embed(self, graph):
        """Compute embedding.

        Optimize a loss function to obtain a representable embedding.

        Parameters
        ----------
        graph : object
            An instance of the Graph class.

        Returns
        -------
        embeddings : array-like, shape=[n_samples, dim]
            Return the embedding of the data. Each data sample
            is represented as a point belonging to the manifold.
        """
        nb_vertices_by_edges = [len(e_2) for _, e_2 in graph.edges.items()]
        logging.info("Number of edges: %s", len(graph.edges))
        logging.info(
            "Mean vertices by edges: %s",
            (sum(nb_vertices_by_edges, 0) / len(graph.edges)),
        )

        negative_table_parameter = 5
        negative_sampling_table = []

        for i, nb_v in enumerate(nb_vertices_by_edges):
            negative_sampling_table += ([i] * int(
                (nb_v**(3.0 / 4.0))) * negative_table_parameter)

        negative_sampling_table = gs.array(negative_sampling_table)
        random_walks = graph.random_walk()
        embeddings = gs.random.normal(size=(graph.n_nodes, self.manifold.dim))
        embeddings = embeddings * 0.2

        for epoch in range(self.max_epochs):
            total_loss = []
            for path in random_walks:

                for example_index, one_path in enumerate(path):
                    context_index = path[
                        max(0, example_index -
                            self.n_context):min(example_index +
                                                self.n_context, len(path))]
                    negative_index = gs.random.randint(
                        negative_sampling_table.shape[0],
                        size=(len(context_index), self.n_negative),
                    )

                    negative_index = gs.expand_dims(gs.flatten(negative_index),
                                                    axis=-1)

                    negative_index = gs.get_slice(negative_sampling_table,
                                                  negative_index)

                    example_embedding = embeddings[gs.cast(one_path,
                                                           dtype=gs.int64)]

                    for one_context_i, one_negative_i in zip(
                            context_index, negative_index):
                        context_embedding = embeddings[one_context_i]

                        negative_embedding = gs.get_slice(
                            embeddings,
                            gs.squeeze(gs.cast(one_negative_i,
                                               dtype=gs.int64)),
                        )

                        l, g_ex = self.loss(example_embedding,
                                            context_embedding,
                                            negative_embedding)
                        total_loss.append(l)

                        example_to_update = embeddings[one_path]

                        valeur = self.manifold.metric.exp(
                            -self.lr * g_ex, example_to_update)

                        embeddings = gs.assignment(
                            embeddings,
                            valeur,
                            gs.to_ndarray(one_path, to_ndim=1),
                            axis=1,
                        )

            logging.info(
                "iteration %d loss_value %f",
                epoch,
                sum(total_loss, 0) / len(total_loss),
            )
        return embeddings
Exemplo n.º 11
0
    def test_assignment_with_booleans_many_indices(self):
        np_array = _np.array([[22., 55.], [33., 88.], [77., 99.]])
        gs_array = gs.array([[22., 55.], [33., 88.], [77., 99.]])

        np_mask = _np.array([True, False, True])
        gs_mask = gs.array([True, False, True])

        np_array[np_mask] = _np.zeros_like(np_array[np_mask])
        np_array[~np_mask] = 4 * _np.ones_like(np_array[~np_mask])
        np_result = np_array

        values_mask = gs.zeros_like(gs_array[gs_mask])
        gs_result = gs.assignment(gs_array, values_mask, gs_mask)
        gs_result = gs.assignment(gs_result,
                                  4 * gs.ones_like(gs_array[~gs_mask]),
                                  ~gs_mask)
        self.assertAllCloseToNp(gs_result, np_result)

        np_array = _np.array([[22., 55.], [33., 88.], [77., 99.]])
        gs_array = gs.array([[22., 55.], [33., 88.], [77., 99.]])

        np_mask = _np.array([False, True, True])
        gs_mask = gs.array([False, True, True])

        np_array[np_mask] = _np.zeros_like(np_array[np_mask])
        np_array[~np_mask] = 4 * _np.ones_like(np_array[~np_mask])
        np_result = np_array

        values_mask = gs.zeros_like(gs_array[gs_mask])
        gs_result = gs.assignment(gs_array, values_mask, gs_mask)
        gs_result = gs.assignment(gs_result,
                                  4 * gs.ones_like(gs_array[~gs_mask]),
                                  ~gs_mask)
        self.assertAllCloseToNp(gs_result, np_result)

        np_array = _np.array([[22., 55.], [33., 88.], [77., 99.]])
        gs_array = gs.array([[22., 55.], [33., 88.], [77., 99.]])
        np_mask = _np.array([True, True, True])
        gs_mask = gs.array([True, True, True])

        np_array[np_mask] = _np.zeros_like(np_array[np_mask])
        np_array[~np_mask] = 4 * _np.ones_like(np_array[~np_mask])
        np_result = np_array

        values_mask = gs.zeros_like(gs_array[gs_mask])
        gs_result = gs.assignment(gs_array, values_mask, gs_mask)
        gs_result = gs.assignment(gs_result,
                                  4 * gs.ones_like(gs_array[~gs_mask]),
                                  ~gs_mask)
        self.assertAllCloseToNp(gs_result, np_result)

        np_array = _np.array([[22., 55.], [33., 88.], [77., 99.]])
        gs_array = gs.array([[22., 55.], [33., 88.], [77., 99.]])
        np_mask = _np.array([True, True, True])
        gs_mask = gs.array([True, True, True])

        np_array[np_mask] = _np.zeros_like(np_array[np_mask])
        np_array[~np_mask] = 4 * np_array[~np_mask]
        np_result = np_array

        values_mask = gs.zeros_like(gs_array[gs_mask])
        gs_result = gs.assignment(gs_array, values_mask, gs_mask)
        gs_result = gs.assignment(gs_result, 4 * gs_array[~gs_mask], ~gs_mask)
        self.assertAllCloseToNp(gs_result, np_result)

        np_array = _np.array([[22., 55.], [33., 88.], [77., 99.]])
        gs_array = gs.array([[22., 55.], [33., 88.], [77., 99.]])
        np_mask = _np.array([False, False, False])
        gs_mask = gs.array([False, False, False])

        np_array[np_mask] = _np.zeros_like(np_array[np_mask])
        np_array[~np_mask] = 4 * np_array[~np_mask]
        np_result = np_array

        values_mask = gs.zeros_like(gs_array[gs_mask])
        gs_result = gs.assignment(gs_array, values_mask, gs_mask)
        gs_result = gs.assignment(gs_result, 4 * gs_array[~gs_mask], ~gs_mask)
        self.assertAllCloseToNp(gs_result, np_result)

        np_array = _np.array([[22., 55.], [33., 88.], [77., 99.]])
        gs_array = gs.array([[22., 55.], [33., 88.], [77., 99.]])
        np_mask = _np.array([[False, False], [False, True], [True, True]])
        gs_mask = gs.array([[False, False], [False, True], [True, True]])

        np_array[np_mask] = _np.zeros_like(np_array[np_mask])
        np_array[~np_mask] = 4 * np_array[~np_mask]
        np_result = np_array

        values_mask = gs.zeros_like(gs_array[gs_mask])
        gs_result = gs.assignment(gs_array, values_mask, gs_mask)
        gs_result = gs.assignment(gs_result, 4 * gs_array[~gs_mask], ~gs_mask)
        self.assertAllCloseToNp(gs_result, np_result)
Exemplo n.º 12
0
    def test_assignment_with_booleans_single_index(self):
        np_array = _np.array([[2., 5.]])
        gs_array = gs.array([[2., 5.]])
        np_mask = _np.array([True])
        gs_mask = gs.array([True])

        np_array[np_mask] = _np.zeros_like(np_array[np_mask])
        np_array[~np_mask] = 4 * _np.ones_like(np_array[~np_mask])
        np_result = np_array

        values_mask = gs.zeros_like(gs_array[gs_mask])
        gs_result = gs.assignment(
            gs_array, values_mask, gs_mask)
        gs_result = gs.assignment(
            gs_result, 4 * gs.ones_like(gs_array[~gs_mask]), ~gs_mask)
        self.assertAllCloseToNp(gs_result, np_result)

        np_array = _np.array([[2., 5.]])
        gs_array = gs.array([[2., 5.]])
        np_mask = _np.array([True])
        gs_mask = gs.array([True])

        np_array[np_mask] = _np.zeros_like(np_array[np_mask])
        np_array[~np_mask] = 4 * np_array[~np_mask]
        np_result = np_array

        values_mask = gs.zeros_like(gs_array[gs_mask])
        gs_result = gs.assignment(
            gs_array, values_mask, gs_mask)
        gs_result = gs.assignment(
            gs_result, 4 * gs_array[~gs_mask], ~gs_mask)
        self.assertAllCloseToNp(gs_result, np_result)

        np_array = _np.array([[2., 5.]])
        gs_array = gs.array([[2., 5.]])
        np_mask = _np.array([False])
        gs_mask = gs.array([False])

        np_array[np_mask] = _np.zeros_like(np_array[np_mask])
        np_array[~np_mask] = 4 * _np.ones_like(np_array[~np_mask])
        np_result = np_array

        values_mask = gs.zeros_like(gs_array[gs_mask])
        gs_result = gs.assignment(
            gs_array, values_mask, gs_mask)
        gs_result = gs.assignment(
            gs_result, 4 * gs.ones_like(gs_array[~gs_mask]), ~gs_mask)
        self.assertAllCloseToNp(gs_result, np_result)

        np_array = _np.array([[2., 5.]])
        gs_array = gs.array([[2., 5.]])
        np_mask = _np.array([False])
        gs_mask = gs.array([False])

        np_array[np_mask] = _np.zeros_like(np_array[np_mask])
        np_array[~np_mask] = 4 * np_array[~np_mask]
        np_result = np_array

        values_mask = gs.zeros_like(gs_array[gs_mask])
        gs_result = gs.assignment(
            gs_array, values_mask, gs_mask)
        gs_result = gs.assignment(
            gs_result, 4 * gs_array[~gs_mask], ~gs_mask)
        self.assertAllCloseToNp(gs_result, np_result)