Beispiel #1
0
    def test_belongs(self):
        base_point_square = gs.zeros((self.n, self.n))
        base_point_nonsquare = gs.zeros((self.m, self.n))

        result = self.space.belongs(base_point_square)
        expected = True
        self.assertAllClose(result, expected)
        result = self.space_nonsquare.belongs(base_point_square)
        expected = False
        self.assertAllClose(result, expected)

        result = self.space.belongs(base_point_nonsquare)
        expected = False
        self.assertAllClose(result, expected)
        result = self.space_nonsquare.belongs(base_point_nonsquare)
        expected = True
        self.assertAllClose(result, expected)

        result = self.space.belongs(gs.zeros((2, 2, 3)))
        self.assertFalse(gs.all(result))

        result = self.space.belongs(gs.zeros((2, 3, 3)))
        self.assertTrue(gs.all(result))
 def test_product_distance_extrinsic_representation(self):
     point_type = 'extrinsic'
     point_a_intrinsic = gs.array([0.01, 0.0])
     point_b_intrinsic = gs.array([0.0, 0.0])
     hyperbolic_space = Hyperbolic(dimension=2, point_type=point_type)
     point_a = hyperbolic_space.intrinsic_to_extrinsic_coords(
         point_a_intrinsic)
     point_b = hyperbolic_space.intrinsic_to_extrinsic_coords(
         point_b_intrinsic)
     duplicate_point_a = gs.zeros((2, ) + point_a.shape)
     duplicate_point_a[0] = point_a
     duplicate_point_a[1] = point_a
     duplicate_point_b = gs.zeros((2, ) + point_b.shape)
     duplicate_point_b[0] = point_b
     duplicate_point_b[1] = point_b
     single_disk = PoincarePolydisk(n_disks=1, point_type=point_type)
     two_disks = PoincarePolydisk(n_disks=2, point_type=point_type)
     distance_single_disk = single_disk.metric.dist(point_a, point_b)
     distance_two_disks = two_disks.metric.dist(duplicate_point_a,
                                                duplicate_point_b)
     result = distance_two_disks
     expected = 3**0.5 * distance_single_disk
     self.assertAllClose(result, expected)
Beispiel #3
0
            def initialize(point_0, point_1, init="polynomial"):
                """Initialize the solution of the boundary value problem."""
                if init == "polynomial":
                    _, curve, velocity = self._approx_geodesic_bvp(
                        point_0, point_1, n_times=n_steps)
                    return gs.vstack((curve.T, velocity.T))

                lin_init = gs.zeros([2 * self.dim, n_steps])
                lin_init[:self.dim, :] = gs.transpose(
                    gs.linspace(point_0, point_1, n_steps))
                lin_init[self.dim:, :-1] = n_steps * (lin_init[:self.dim, 1:] -
                                                      lin_init[:self.dim, :-1])
                lin_init[self.dim:, -1] = lin_init[self.dim:, -2]
                return lin_init
Beispiel #4
0
    def test_variance(self):
        points = gs.array([
            [1., 2.],
            [2., 3.],
            [3., 4.],
            [4., 5.]])
        weights = gs.array([1., 2., 1., 2.])
        base_point = gs.zeros(2)
        result = self.metric.variance(points, weights, base_point)
        # we expect the average of the points' sq norms.
        expected = (1 * 5. + 2 * 13. + 1 * 25. + 2 * 41.) / 6.
        expected = helper.to_scalar(expected)

        self.assertAllClose(result, expected)
Beispiel #5
0
    def exp(self, tangent_vec, base_point):
        """Compute Riemannian exponential of tan. vector wrt to base point."""
        tangent_vec = gs.to_ndarray(tangent_vec, to_ndim=3)
        n_tangent_vecs, _, _ = tangent_vec.shape

        base_point = gs.to_ndarray(base_point, to_ndim=3)
        n_base_points, n, p = base_point.shape

        assert (n_tangent_vecs == n_base_points
                or n_tangent_vecs == 1
                or n_base_points == 1)

        if n_tangent_vecs == 1:
            tangent_vec = gs.tile(tangent_vec, (n_base_points, 1, 1))

        if n_base_points == 1:
            base_point = gs.tile(base_point, (n_tangent_vecs, 1, 1))

        matrix_a = gs.einsum(
            'nij, njk->nik',
            gs.transpose(base_point, axes=(0, 2, 1)), tangent_vec)
        matrix_k = (tangent_vec
                    - gs.einsum('nij,njk->nik', base_point, matrix_a))

        matrix_q, matrix_r = gs.linalg.qr(matrix_k)

        matrix_ar = gs.concatenate(
            [matrix_a,
             -gs.transpose(matrix_r, axes=(0, 2, 1))],
            axis=2)

        zeros = gs.zeros(
            (gs.maximum(n_base_points, n_tangent_vecs), p, p))

        matrix_rz = gs.concatenate(
            [matrix_r,
             zeros],
            axis=2)
        block = gs.concatenate([matrix_ar, matrix_rz], axis=1)
        matrix_mn_e = gs.linalg.expm(block)

        exp = gs.einsum(
            'nij,njk->nik',
            gs.concatenate(
                [base_point,
                 matrix_q],
                axis=2),
            matrix_mn_e[:, :, 0:p])

        return exp
        def coefficients(ind_k):
            param_k = base_point[..., ind_k]
            param_sum = gs.sum(base_point, -1)
            c1 = 1 / gs.polygamma(1, param_k) / (
                1 / gs.polygamma(1, param_sum)
                - gs.sum(1 / gs.polygamma(1, base_point), -1))
            c2 = - c1 * gs.polygamma(2, param_sum) / gs.polygamma(1, param_sum)

            mat_ones = gs.ones((n_points, self.dim, self.dim))
            mat_diag = from_vector_to_diagonal_matrix(
                - gs.polygamma(2, base_point) / gs.polygamma(1, base_point))
            arrays = [gs.zeros((1, ind_k)),
                      gs.ones((1, 1)),
                      gs.zeros((1, self.dim - ind_k - 1))]
            vec_k = gs.tile(gs.hstack(arrays), (n_points, 1))
            val_k = gs.polygamma(2, param_k) / gs.polygamma(1, param_k)
            vec_k = gs.einsum('i,ij->ij', val_k, vec_k)
            mat_k = from_vector_to_diagonal_matrix(vec_k)

            mat = gs.einsum('i,ijk->ijk', c2, mat_ones)\
                - gs.einsum('i,ijk->ijk', c1, mat_diag) + mat_k

            return 1 / 2 * mat
Beispiel #7
0
    def tangent_spherical_to_extrinsic(self, tangent_vec_spherical,
                                       base_point_spherical):
        """Convert tangent vector from spherical to extrinsic coordinates.

        Convert from the spherical coordinates in the hypersphere
        to the extrinsic coordinates in Euclidean space for a tangent
        vector. Only implemented in dimension 2.

        Parameters
        ----------
        tangent_vec_spherical : array-like, shape=[..., dim]
            Tangent vector to the sphere, in spherical coordinates.
        base_point_spherical : array-like, shape=[..., dim]
            Point on the sphere, in spherical coordinates.

        Returns
        -------
        tangent_vec_extrinsic : array-like, shape=[..., dim + 1]
            Tangent vector to the sphere, at base point,
            in extrinsic coordinates in Euclidean space.
        """
        if self.dim != 2:
            raise NotImplementedError(
                'The conversion from spherical coordinates'
                ' to extrinsic coordinates is implemented'
                ' only in dimension 2.')

        n_samples = base_point_spherical.shape[0]
        theta = base_point_spherical[:, 0]
        phi = base_point_spherical[:, 1]

        zeros = gs.zeros(n_samples)

        jac = gs.concatenate([
            gs.array([[[
                gs.cos(theta[i]) * gs.cos(phi[i]),
                -gs.sin(theta[i]) * gs.sin(phi[i])
            ],
                       [
                           gs.cos(theta[i]) * gs.sin(phi[i]),
                           gs.sin(theta[i]) * gs.cos(phi[i])
                       ], [-gs.sin(theta[i]), zeros[i]]]])
            for i in range(n_samples)
        ],
                             axis=0)

        tangent_vec_extrinsic = gs.einsum('...ij,...j->...i', jac,
                                          tangent_vec_spherical)

        return tangent_vec_extrinsic
 def inner_product_shape_test_data(self):
     space = NFoldManifold(SpecialOrthogonal(3), 2)
     n_samples = 4
     point = gs.stack([gs.eye(3)] * space.n_copies * n_samples)
     point = gs.reshape(point, (n_samples, *space.shape))
     tangent_vec = space.to_tangent(gs.zeros((n_samples, *space.shape)),
                                    point)
     smoke_data = [
         dict(space=space,
              n_samples=4,
              point=point,
              tangent_vec=tangent_vec)
     ]
     return self.generate_tests(smoke_data)
 def test_horizontal_geodesic(self, n_sampling_points, curve_a, n_times):
     """Test horizontal geodesic.
     Check that the time derivative of the geodesic is
     horizontal at all time.
     """
     curve_b = gs.transpose(
         gs.stack((
             gs.zeros(n_sampling_points),
             gs.zeros(n_sampling_points),
             gs.linspace(1.0, 0.5, n_sampling_points),
         )))
     quotient_srv_metric_r3 = DiscreteCurves(
         ambient_manifold=r3).quotient_square_root_velocity_metric
     horizontal_geod_fun = quotient_srv_metric_r3.horizontal_geodesic(
         curve_a, curve_b)
     times = gs.linspace(0.0, 1.0, n_times)
     horizontal_geod = horizontal_geod_fun(times)
     velocity_vec = n_times * (horizontal_geod[1:] - horizontal_geod[:-1])
     _, _, vertical_norms = quotient_srv_metric_r3.split_horizontal_vertical(
         velocity_vec, horizontal_geod[:-1])
     result = gs.sum(vertical_norms**2, axis=1)**(1 / 2)
     expected = gs.zeros(n_times - 1)
     self.assertAllClose(result, expected, atol=1e-3)
Beispiel #10
0
    def __init__(self, n):
        dim = int(n * (n + 1) / 2)
        super(SpecialEuclideanMatrixLieAlgebra, self).__init__(dim, n)

        self.skew = SkewSymmetricMatrices(n)
        basis = homogeneous_representation(self.skew.basis,
                                           gs.zeros((self.skew.dim, n)),
                                           (self.skew.dim, n + 1, n + 1), 0.)
        basis = list(basis)

        for row in gs.arange(n):
            basis.append(gs.array_from_sparse([(row, n)], [1.],
                                              (n + 1, n + 1)))
        self.basis = gs.stack(basis)
def from_vector_to_diagonal_matrix(vector, num_diag=0):
    """Create diagonal matrices from rows of a matrix.

    Parameters
    ----------
    vector : array-like, shape=[m, n]
    num_diag : int
        number of diagonal in result matrix. If 0, the result matrix is a
        diagonal matrix; if positive, the result matrix has an upper-right
        non-zero diagonal; if negative, the result matrix has a lower-left
        non-zero diagonal.
        Optional, Default: 0.

    Returns
    -------
    diagonals : array-like, shape=[m, n, n]
        3-dimensional array where the `i`-th n-by-n array `diagonals[i, :, :]`
        is a diagonal matrix containing the `i`-th row of `vector`.
    """
    num_columns = gs.shape(vector)[-1]
    identity = gs.eye(num_columns)
    identity = gs.cast(identity, vector.dtype)
    diagonals = gs.einsum("...i,ij->...ij", vector, identity)
    diagonals = gs.to_ndarray(diagonals, to_ndim=3)
    num_lines = diagonals.shape[0]
    if num_diag > 0:
        left_zeros = gs.zeros((num_lines, num_columns, num_diag))
        lower_zeros = gs.zeros((num_lines, num_diag, num_columns + num_diag))
        diagonals = gs.concatenate((left_zeros, diagonals), axis=2)
        diagonals = gs.concatenate((diagonals, lower_zeros), axis=1)
    elif num_diag < 0:
        num_diag = gs.abs(num_diag)
        right_zeros = gs.zeros((num_lines, num_columns, num_diag))
        upper_zeros = gs.zeros((num_lines, num_diag, num_columns + num_diag))
        diagonals = gs.concatenate((diagonals, right_zeros), axis=2)
        diagonals = gs.concatenate((upper_zeros, diagonals), axis=1)
    return gs.squeeze(diagonals) if gs.ndim(vector) == 1 else diagonals
Beispiel #12
0
    def log(self, curve, base_curve):
        """Compute Riemannian logarithm of a curve wrt a base curve.

        Parameters
        ----------
        curve :
        base_curve :

        Returns
        -------
        log :
        """
        if not isinstance(self.ambient_metric, EuclideanMetric):
            raise AssertionError('The logarithm map is only implemented '
                                 'for dicretized curves embedded in a '
                                 'Euclidean space.')
        curve = gs.to_ndarray(curve, to_ndim=3)
        base_curve = gs.to_ndarray(base_curve, to_ndim=3)
        n_curves, n_sampling_points, n_coords = curve.shape

        curve_srv = self.square_root_velocity(curve)
        base_curve_srv = self.square_root_velocity(base_curve)

        base_curve_velocity = (n_sampling_points - 1) * (base_curve[:, 1:, :] -
                                                         base_curve[:, :-1, :])
        base_curve_velocity_norm = self.pointwise_norm(base_curve_velocity,
                                                       base_curve[:, :-1, :])

        inner_prod = self.pointwise_inner_product(curve_srv - base_curve_srv,
                                                  base_curve_velocity,
                                                  base_curve[:, :-1, :])
        coef_1 = gs.sqrt(base_curve_velocity_norm)
        coef_2 = 1 / base_curve_velocity_norm**(3 / 2) * inner_prod

        term_1 = gs.einsum('ij,ijk->ijk', coef_1, curve_srv - base_curve_srv)
        term_2 = gs.einsum('ij,ijk->ijk', coef_2, base_curve_velocity)
        log_derivative = term_1 + term_2

        log_starting_points = self.ambient_metric.log(
            point=curve[:, 0, :], base_point=base_curve[:, 0, :])
        log_starting_points = gs.transpose(
            gs.tile(log_starting_points, (1, 1, 1)), (1, 0, 2))

        log_cumsum = gs.hstack(
            [gs.zeros((n_curves, 1, n_coords)),
             gs.cumsum(log_derivative, -2)])
        log = log_starting_points + 1 / (n_sampling_points - 1) * log_cumsum

        return log
Beispiel #13
0
    def test_variance_euclidean(self):
        points = gs.array([
            [1., 2.],
            [2., 3.],
            [3., 4.],
            [4., 5.]])
        weights = gs.array([1., 2., 1., 2.])
        base_point = gs.zeros(2)
        result = variance(
            points, weights=weights, base_point=base_point,
            metric=self.euclidean.metric)
        # we expect the average of the points' sq norms.
        expected = gs.array((1 * 5. + 2 * 13. + 1 * 25. + 2 * 41.) / 6.)

        self.assertAllClose(result, expected)
Beispiel #14
0
    def belongs(self, mat, tolerance=TOLERANCE):
        """
        Check if a matrix belongs to the manifold of
        symmetric positive definite matrices.
        """
        mat = gs.to_ndarray(mat, to_ndim=3)
        n_mats, mat_dim, _ = mat.shape

        mask_is_symmetric = is_symmetric(mat, tolerance=tolerance)
        eigenvalues = gs.zeros((n_mats, mat_dim))
        eigenvalues[mask_is_symmetric] = gs.linalg.eigvalsh(
            mat[mask_is_symmetric])

        mask_pos_eigenvalues = gs.all(eigenvalues > 0)
        return mask_is_symmetric & mask_pos_eigenvalues
Beispiel #15
0
    def get_identity(self, point_type=None):
        """Get the identity of the group.

        Parameters
        ----------
        point_type : str, {'vector', 'matrix'}
            The point_type of the returned value.
            Optional, default: self.default_point_type

        Returns
        -------
        identity : array-like, shape=[n]
        """
        identity = gs.zeros(self.dim)
        return identity
Beispiel #16
0
    def symmetric_matrix_from_vector(self, vec):
        """Convert a vector into a symmetric matrix."""
        vec = gs.to_ndarray(vec, to_ndim=2)
        _, vec_dim = vec.shape
        mat_dim = int((gs.sqrt(8 * vec_dim + 1) - 1) / 2)
        mat = gs.zeros((mat_dim, ) * 2)

        lower_triangle_indices = gs.tril_indices(mat_dim)
        diag_indices = gs.diag_indices(mat_dim)

        mat[lower_triangle_indices] = 2 * vec
        mat[diag_indices] = vec

        mat = self.embedding_manifold.make_symmetric(mat)
        return mat
    def __init__(self, n):
        assert isinstance(n, int) and n > 1

        if n is not 3:
            raise NotImplementedError('Only SE(3) is implemented.')

        self.n = n
        self.dimension = int((n * (n - 1)) / 2 + n)
        super(SpecialEuclideanGroup,
              self).__init__(dimension=self.dimension,
                             identity=gs.zeros(self.dimension))
        # TODO(xxx): keep the names rotations and translations here?
        self.rotations = SpecialOrthogonalGroup(n=n)
        self.translations = EuclideanSpace(dimension=n)
        self.point_representation = 'vector' if n == 3 else 'matrix'
Beispiel #18
0
    def _create_basis(self):
        """Create the canonical basis."""
        n = self.n
        basis = homogeneous_representation(
            self.skew.basis,
            gs.zeros((self.skew.dim, n)),
            (self.skew.dim, n + 1, n + 1),
            0.0,
        )
        basis = list(basis)

        for row in gs.arange(n):
            basis.append(
                gs.array_from_sparse([(row, n)], [1.0], (n + 1, n + 1)))
        return gs.stack(basis)
Beispiel #19
0
    def predict(self, data):
        """Predict the closest cluster for each sample in X.

        Parameters
        ----------
        data : array-like, shape=[n_samples, dim,]
            Training data, where n_samples is the number of samples and
            dim is the number of dimensions.

        Returns
        -------
        labels : array-like, shape=[n_samples,]
            Index of the cluster each sample belongs to.
        """
        labels = gs.zeros(len(data))

        for point_index, point_value in enumerate(data):
            distances = gs.zeros(len(self.cluster_centers_))
            for cluster_index, cluster_value in enumerate(self.cluster_centers_):
                distances[cluster_index] = self.metric.dist(point_value, cluster_value)

            labels[point_index] = gs.argmin(distances)

        return labels
 def lie_bracket_test_data(self):
     group = SpecialOrthogonal(3, point_type="vector")
     smoke_data = [
         dict(
             tangent_vec_a=gs.array([0.0, 0.0, -1.0]),
             tangent_vec_b=gs.array([0.0, 0.0, -1.0]),
             base_point=group.identity,
             expected=gs.zeros(3),
         ),
         dict(
             tangent_vec_a=gs.array([0.0, 0.0, 1.0]),
             tangent_vec_b=gs.array([0.0, 1.0, 0.0]),
             base_point=group.identity,
             expected=gs.array([-1.0, 0.0, 0.0]),
         ),
         dict(
             tangent_vec_a=gs.array([[0.0, 0.0, 1.0], [0.0, 0.0, 1.0]]),
             tangent_vec_b=gs.array([[0.0, 0.0, 1.0], [0.0, 1.0, 0.0]]),
             base_point=gs.array([group.identity, group.identity]),
             expected=gs.array([gs.zeros(3),
                                gs.array([-1.0, 0.0, 0.0])]),
         ),
     ]
     return self.generate_tests(smoke_data)
Beispiel #21
0
    def exponential_matrix(self, rot_vec):
        """
        Compute the exponential of the rotation matrix represented by rot_vec.
        """

        rot_vec = self.rotations.regularize(rot_vec)
        n_rot_vecs, _ = rot_vec.shape

        angle = gs.linalg.norm(rot_vec, axis=1)
        angle = gs.to_ndarray(angle, to_ndim=2, axis=1)

        skew_rot_vec = so_group.skew_matrix_from_vector(rot_vec)

        coef_1 = gs.empty_like(angle)
        coef_2 = gs.empty_like(coef_1)

        mask_0 = gs.equal(angle, 0)
        mask_0 = gs.squeeze(mask_0, axis=1)
        mask_close_to_0 = gs.isclose(angle, 0)
        mask_close_to_0 = gs.squeeze(mask_close_to_0, axis=1)
        mask_else = ~mask_0 & ~mask_close_to_0

        coef_1[mask_close_to_0] = (1. / 2.
                                   - angle[mask_close_to_0] ** 2 / 24.)
        coef_2[mask_close_to_0] = (1. / 6.
                                   - angle[mask_close_to_0] ** 3 / 120.)

        # TODO(nina): check if the discountinuity as 0 is expected.
        coef_1[mask_0] = 0
        coef_2[mask_0] = 0

        coef_1[mask_else] = (angle[mask_else] ** (-2)
                             * (1. - gs.cos(angle[mask_else])))
        coef_2[mask_else] = (angle[mask_else] ** (-2)
                             * (1. - (gs.sin(angle[mask_else])
                                      / angle[mask_else])))

        term_1 = gs.zeros((n_rot_vecs, self.n, self.n))
        term_2 = gs.zeros_like(term_1)

        for i in range(n_rot_vecs):
            term_1[i] = gs.eye(self.n) + skew_rot_vec[i] * coef_1[i]
            term_2[i] = gs.matmul(skew_rot_vec[i], skew_rot_vec[i]) * coef_2[i]

        exponential_mat = term_1 + term_2
        assert exponential_mat.ndim == 3

        return exponential_mat
Beispiel #22
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\'.')
Beispiel #23
0
 def is_centered_test_data(self):
     random_data = [
         dict(
             k_landmarks=4,
             m_ambient=3,
             point=gs.ones((4, 3)),
             expected=gs.array(False),
         ),
         dict(
             k_landmarks=4,
             m_ambient=3,
             point=gs.zeros((4, 3)),
             expected=gs.array(True),
         ),
     ]
     return self.generate_tests([], random_data)
Beispiel #24
0
    def __init__(self, n_meridians=40, n_circles_latitude=None, points=None):
        if n_circles_latitude is None:
            n_circles_latitude = max(n_meridians / 2, 4)

        u, v = np.mgrid[0:2 * gs.pi:n_meridians * 1j,
                        0:gs.pi:n_circles_latitude * 1j]

        self.center = gs.zeros(3)
        self.radius = 1
        self.sphere_x = self.center[0] + self.radius * gs.cos(u) * gs.sin(v)
        self.sphere_y = self.center[1] + self.radius * gs.sin(u) * gs.sin(v)
        self.sphere_z = self.center[2] + self.radius * gs.cos(v)

        self.points = []
        if points is not None:
            self.add_points(points)
Beispiel #25
0
    def torsion(self, base_point):
        """Compute torsion tensor associated with the Levi-Civita connection.

        The torsion tensor associated with the Levi-Civita connection is zero.

        Parameters
        ----------
        base_point: array-like, shape=[n_samples, dimension]
                                or shape=[1, dimension]

        Returns
        -------
        torsion: array-like, shape=[dimension, dimension, dimension]
        """
        torsion = gs.zeros((self.dimension, ) * 3)
        return torsion
Beispiel #26
0
    def __init__(self, n_meridians=40, n_circles_latitude=None, points=None):
        if n_circles_latitude is None:
            n_circles_latitude = max(n_meridians / 2, 4)

        u, v = gs.meshgrid(gs.arange(0, 2 * gs.pi, 2 * gs.pi / n_meridians),
                           gs.arange(0, gs.pi, gs.pi / n_circles_latitude))

        self.center = gs.zeros(3)
        self.radius = 1
        self.sphere_x = self.center[0] + self.radius * gs.cos(u) * gs.sin(v)
        self.sphere_y = self.center[1] + self.radius * gs.sin(u) * gs.sin(v)
        self.sphere_z = self.center[2] + self.radius * gs.cos(v)

        self.points = []
        if points is not None:
            self.add_points(points)
Beispiel #27
0
    def get_identity(self, point_type='vector'):
        """Get the identity of the group.

        Parameters
        ----------
        point_type : str,
            Point_type of the returned value. Unused here.

        Returns
        -------
        identity : array-like, shape=[3,]
        """
        identity = gs.zeros(self.dim)
        if point_type == 'matrix':
            identity = gs.eye(self.n)
        return identity
Beispiel #28
0
    def baker_campbell_hausdorff(self, matrix_a, matrix_b, order=2):
        """Calculate the Baker-Campbell-Hausdorff approximation of given order.

        The implementation is based on [CM2009a]_ with the pre-computed
        constants taken from [CM2009b]_. Our coefficients are truncated to
        enable us to calculate BCH up to order 15.

        This represents Z = log(exp(X)exp(Y)) as an infinite linear combination
        of the form Z = sum z_i e_i where z_i are rational numbers and e_i are
        iterated Lie brackets starting with e_1 = X, e_2 = Y, each e_i is given
        by some i',i'': e_i = [e_i', e_i''].

        Parameters
        ----------
        matrix_a, matrix_b : array-like, shape=[n_sample, n, n]
        order : int
            The order to which the approximation is calculated. Note that this
            is NOT the same as using only e_i with i < order.

        References
        ----------
        .. [CM2009a] F. Casas and A. Murua. An efficient algorithm for
           computing the Baker–Campbell–Hausdorff series and some of its
           applications. Journal of Mathematical Physics 50, 2009
        .. [CM2009b] http://www.ehu.eus/ccwmuura/research/bchHall20.dat
        """
        if order > 15:
            raise NotImplementedError("BCH is not implemented for order > 15.")

        number_of_hom_degree = gs.array(
            [2, 1, 2, 3, 6, 9, 18, 30, 56, 99, 186, 335, 630, 1161, 2182])
        n_terms = gs.sum(number_of_hom_degree[:order])

        ei = gs.zeros((n_terms, self.n, self.n))
        ei[0] = matrix_a
        ei[1] = matrix_b
        result = matrix_a + matrix_b

        for i in gs.arange(2, n_terms):
            i_p = BCH_COEFFICIENTS[i, 1] - 1
            i_pp = BCH_COEFFICIENTS[i, 2] - 1

            ei[i] = self.lie_bracket(ei[i_p], ei[i_pp])
            result += (BCH_COEFFICIENTS[i, 3] / float(BCH_COEFFICIENTS[i, 4]) *
                       ei[i])

        return result
Beispiel #29
0
    def matrix_from_tait_bryan_angles_extrinsic_zyx(self, tait_bryan_angles):
        """
        Convert a rotation given in terms of the tait bryan angles,
        [angle_1, angle_2, angle_3] in extrinsic (fixed) coordinate system
        in order zyx, into a rotation matrix.

        rot_mat = X(angle_1).Y(angle_2).Z(angle_3)
        where:
        - X(angle_1) is a rotation of angle angle_1 around axis x.
        - Y(angle_2) is a rotation of angle angle_2 around axis y.
        - Z(angle_3) is a rotation of angle angle_3 around axis z.
        """
        assert self.n == 3, ('The Tait-Bryan angles representation'
                             ' does not exist'
                             ' for rotations in %d dimensions.' % self.n)
        tait_bryan_angles = gs.to_ndarray(tait_bryan_angles, to_ndim=2)
        n_tait_bryan_angles, _ = tait_bryan_angles.shape

        rot_mat = gs.zeros((n_tait_bryan_angles, ) + (self.n, ) * 2)
        angle_1 = tait_bryan_angles[:, 0]
        angle_2 = tait_bryan_angles[:, 1]
        angle_3 = tait_bryan_angles[:, 2]

        for i in range(n_tait_bryan_angles):
            cos_angle_1 = gs.cos(angle_1[i])
            sin_angle_1 = gs.sin(angle_1[i])
            cos_angle_2 = gs.cos(angle_2[i])
            sin_angle_2 = gs.sin(angle_2[i])
            cos_angle_3 = gs.cos(angle_3[i])
            sin_angle_3 = gs.sin(angle_3[i])

            column_1 = [[cos_angle_2 * cos_angle_3],
                        [(cos_angle_1 * sin_angle_3 +
                          cos_angle_3 * sin_angle_1 * sin_angle_2)],
                        [(sin_angle_1 * sin_angle_3 -
                          cos_angle_1 * cos_angle_3 * sin_angle_2)]]

            column_2 = [[-cos_angle_2 * sin_angle_3],
                        [(cos_angle_1 * cos_angle_3 -
                          sin_angle_1 * sin_angle_2 * sin_angle_3)],
                        [(cos_angle_3 * sin_angle_1 +
                          cos_angle_1 * sin_angle_2 * sin_angle_3)]]

            column_3 = [[sin_angle_2], [-cos_angle_2 * sin_angle_1],
                        [cos_angle_1 * cos_angle_2]]
            rot_mat[i] = gs.hstack((column_1, column_2, column_3))
        return rot_mat
Beispiel #30
0
    def sample(self, n_samples):
        """Generate samples for SPD manifold"""
        if isinstance(self.manifold.metric, SPDMetricLogEuclidean):
            sym_matrix = self.manifold.logm(self.mean)
            mean_euclidean = gs.hstack((
                gs.diagonal(sym_matrix)[None, :],
                gs.sqrt(2.0) * gs.triu_to_vec(sym_matrix, k=1)[None, :],
            ))[0]
            _samples = self.samples_sym(mean_euclidean, self.cov, n_samples)

        else:
            samples_sym = self.samples_sym(gs.zeros(self.manifold.dim),
                                           self.cov, n_samples)
            mean_half = self.manifold.powerm(self.mean, 0.5)
            _samples = Matrices.mul(mean_half, samples_sym, mean_half)

        return self.manifold.expm(_samples)