示例#1
0
    def test_logm(self):
        """Test of logm method."""
        expected = gs.array([[0.0, 1.0, 0.0], [1.0, 0.0, 0.0], [0.0, 0.0, 1.0]])
        c = math.cosh(1)
        s = math.sinh(1)
        e = math.exp(1)
        v = gs.array([[c, s, 0.0], [s, c, 0.0], [0.0, 0.0, e]])
        result = self.space.logm(v)

        four_dim_expected = gs.broadcast_to(expected, (2, 2) + expected.shape)
        four_dim_v = gs.broadcast_to(v, (2, 2) + v.shape)
        four_dim_result = self.space.logm(four_dim_v)

        self.assertAllClose(result, expected)
        self.assertAllClose(four_dim_result, four_dim_expected)
    def test_expm(self):
        """Test of expm method."""
        sym_n = SymmetricMatrices(self.n)
        v = gs.array([[0.0, 1.0, 0.0], [1.0, 0.0, 0.0], [0.0, 0.0, 1.0]])
        result = sym_n.expm(v)
        c = math.cosh(1)
        s = math.sinh(1)
        e = math.exp(1)
        expected = gs.array([[c, s, 0.0], [s, c, 0.0], [0.0, 0.0, e]])

        four_dim_v = gs.broadcast_to(v, (2, 2) + v.shape)
        four_dim_expected = gs.broadcast_to(expected, (2, 2) + expected.shape)
        four_dim_result = sym_n.expm(four_dim_v)

        self.assertAllClose(result, expected)
        self.assertAllClose(four_dim_result, four_dim_expected)
示例#3
0
    def tangent_natural_to_standard(self, vec, base_point):
        """Convert tangent vector from natural coordinates to standard coordinates.

        The change of variable is symmetric.

        Parameters
        ----------
        base_point : array-like, shape=[..., 2]
            Point of the Gamma manifold, given in natural coordinates.
        vec : array-like, shape=[..., 2]
            Tangent vector at base_point, given in natural coordinates.

        Returns
        -------
        vec : array-like, shape=[..., 2]
            Tangent vector at base_point, given in standard coordinates.
        """
        vec = gs.to_ndarray(vec, to_ndim=2)
        base_point = gs.broadcast_to(base_point, vec.shape)

        n_points = base_point.shape[0]

        kappa, scale = (
            base_point[..., 0],
            base_point[..., 1],
        )

        jac = gs.array([[gs.ones(n_points),
                         gs.zeros(n_points)], [1 / scale, -kappa / scale**2]])
        jac = gs.transpose(jac, [2, 0, 1])

        vec = gs.einsum("...jk,...k->...j", jac, vec)

        return gs.squeeze(vec)
示例#4
0
    def exp(self,
            tangent_vec,
            base_point,
            n_steps=N_STEPS,
            step="euler",
            point_type=None,
            **kwargs):
        """Exponential map associated to the affine connection.

        Exponential map at base_point of tangent_vec computed by integration
        of the geodesic equation (initial value problem), using the
        christoffel symbols.

        Parameters
        ----------
        tangent_vec : array-like, shape=[..., dim]
            Tangent vector at the base point.
        base_point : array-like, shape=[..., dim]
            Point on the manifold.
        n_steps : int
            Number of discrete time steps to take in the integration.
            Optional, default: N_STEPS.
        step : str, {'euler', 'rk4'}
            The numerical scheme to use for integration.
            Optional, default: 'euler'.
        point_type : str, {'vector', 'matrix'}
            Type of representation used for points.
            Optional, default: None.

        Returns
        -------
        exp : array-like, shape=[..., dim]
            Point on the manifold.
        """
        base_point = gs.broadcast_to(base_point, tangent_vec.shape)

        initial_state = gs.stack([base_point, tangent_vec])

        flow = integrate(self.geodesic_equation,
                         initial_state,
                         n_steps=n_steps,
                         step=step)

        exp = flow[-1][0]
        return exp
示例#5
0
    def test_permute_vectorization(self, space, graph, id_permutation):
        permuted_graph = space.permute(graph, id_permutation)

        if graph.ndim == 2 and id_permutation.ndim == 1:
            n_out = 1
            expected = graph
        else:
            n_out = max(
                1 if graph.ndim == 2 else graph.shape[0],
                1 if id_permutation.ndim == 1 else id_permutation.shape[0],
            )
            expected = gs.broadcast_to(graph, (n_out, *graph.shape[-2:]))

        if n_out == 1:
            self.assertTrue(permuted_graph.shape == graph.shape)
        else:
            self.assertTrue(permuted_graph.shape[0] == n_out)

        self.assertAllClose(permuted_graph, expected)
示例#6
0
    def tangent_diffeomorphism(self, tangent_vec, base_point):
        r"""Tangent diffeomorphism at base point.

        Let :math:`f` be the diffeomorphism
        :math:`f: M \rightarrow N` of the manifold
        :math:`M` into the manifold `N`.

        df_p is a linear map from T_pM to T_f(p)N called
        the tangent immesion

        Parameters
        ----------
        tangent_vec : array-like, shape=[..., *shape]
            Tangent vector at base point.

        base_point : array-like, shape=[..., *shape]
            Base point.

        Returns
        -------
        image_tangent_vec : array-like, shape=[..., *i_shape]
            Image tangent vector at image of the base point.
        """
        base_point = gs.broadcast_to(base_point, tangent_vec.shape)
        rad = base_point.shape[:-len(self.shape)]

        J_flat = gs.reshape(
            self.jacobian_diffeomorphism(base_point),
            (-1, self.embedding_space_shape_dim, self.shape_dim),
        )
        tv_flat = gs.reshape(tangent_vec, (-1, self.shape_dim))

        image_tv = gs.reshape(
            gs.einsum("...ij,...j->...i", J_flat, tv_flat),
            rad + self.embedding_metric.shape,
        )

        return image_tv
示例#7
0
    def inner_product(self, tangent_vec_a, tangent_vec_b, base_point=None):
        """Compute the inner-product of two tangent vectors at a base point.

        Parameters
        ----------
        tangent_vec_a : array-like, shape=[..., n_samples]
            First tangent vector at base point.
        tangent_vec_b : array-like, shape=[..., n_samples]
            Second tangent vector at base point.
        base_point : array-like, shape=[..., n_samples], optional
            Point on the hypersphere.

        Returns
        -------
        inner_prod : array-like, shape=[...,]
            Inner-product of the two tangent vectors.
        """
        tangent_vec_a, tangent_vec_b = gs.broadcast_arrays(tangent_vec_a, tangent_vec_b)
        x = gs.broadcast_to(self.x, tangent_vec_a.shape)

        l2_norm = gs.trapz(tangent_vec_a * tangent_vec_b, x=x, axis=-1)

        return l2_norm