Exemplo n.º 1
0
    def setUp(self):
        warnings.simplefilter('ignore', category=ImportWarning)

        gs.random.seed(1234)

        n = 3
        group = SpecialEuclidean(n=n)

        # Diagonal left and right invariant metrics
        diag_mat_at_identity = gs.eye(group.dimension)

        left_diag_metric = InvariantMetric(
            group=group,
            inner_product_mat_at_identity=diag_mat_at_identity,
            left_or_right='left')
        right_diag_metric = InvariantMetric(
            group=group,
            inner_product_mat_at_identity=diag_mat_at_identity,
            left_or_right='right')

        # General left and right invariant metrics
        # TODO(nina): Replace the matrix below by a general SPD matrix.
        sym_mat_at_identity = gs.eye(group.dimension)

        left_metric = InvariantMetric(
            group=group,
            inner_product_mat_at_identity=sym_mat_at_identity,
            left_or_right='left')

        right_metric = InvariantMetric(
            group=group,
            inner_product_mat_at_identity=sym_mat_at_identity,
            left_or_right='right')

        metrics = {
            'left_diag': left_diag_metric,
            'right_diag_metric': right_diag_metric,
            'left': left_metric,
            'right': right_metric
        }

        # General case for the point
        point_1 = gs.array([[-0.2, 0.9, 0.5, 5., 5., 5.]])
        point_2 = gs.array([[0., 2., -0.1, 30., 400., 2.]])
        # Edge case for the point, angle < epsilon,
        point_small = gs.array([[-1e-7, 0., -7 * 1e-8, 6., 5., 9.]])

        self.group = group
        self.metrics = metrics

        self.left_diag_metric = left_diag_metric
        self.right_diag_metric = right_diag_metric
        self.left_metric = left_metric
        self.right_metric = right_metric
        self.point_1 = point_1
        self.point_2 = point_2
        self.point_small = point_small
Exemplo n.º 2
0
    def __init__(self, dim, n, lie_algebra=None, **kwargs):
        super(MatrixLieGroup, self).__init__(dim=dim, **kwargs)
        self.lie_algebra = lie_algebra
        self.n = n
        self.left_canonical_metric = InvariantMetric(
            group=self,
            metric_mat_at_identity=gs.eye(self.dim),
            left_or_right="left")

        self.right_canonical_metric = InvariantMetric(
            group=self,
            metric_mat_at_identity=gs.eye(self.dim),
            left_or_right="right")
Exemplo n.º 3
0
    def __init__(self, dim, default_point_type='vector', **kwargs):
        super(LieGroup, self).__init__(
            dim=dim, default_point_type=default_point_type, **kwargs)

        self.left_canonical_metric = InvariantMetric(
            group=self,
            metric_mat_at_identity=gs.eye(self.dim),
            left_or_right='left')

        self.right_canonical_metric = InvariantMetric(
            group=self,
            metric_mat_at_identity=gs.eye(self.dim),
            left_or_right='right')

        self.metrics = []
Exemplo n.º 4
0
    def __init__(self, dimension):
        assert dimension > 0
        Manifold.__init__(self, dimension)

        self.left_canonical_metric = InvariantMetric(
            group=self,
            inner_product_mat_at_identity=gs.eye(self.dimension),
            left_or_right='left')

        self.right_canonical_metric = InvariantMetric(
            group=self,
            inner_product_mat_at_identity=gs.eye(self.dimension),
            left_or_right='right')

        self.metrics = []
Exemplo n.º 5
0
    def test_sectional_curvature(self):
        group = self.matrix_so3
        lie_algebra = SkewSymmetricMatrices(3)
        metric = InvariantMetric(group=group, algebra=lie_algebra)
        x, y, z = lie_algebra.orthonormal_basis(metric.metric_mat_at_identity)

        result = metric.sectional_curvature(x, y)
        expected = 1. / 8
        self.assertAllClose(result, expected)

        point = group.random_uniform()
        translation_map = group.tangent_translation_map(point)
        tan_a = translation_map(-z)
        tan_b = translation_map(y)
        result = metric.sectional_curvature(tan_a, tan_b, point)
        self.assertAllClose(result, expected)

        tan_a = gs.stack([x, y])
        tan_b = gs.stack([z] * 2)
        result = metric.sectional_curvature(tan_a, tan_b)
        self.assertAllClose(result, gs.array([expected] * 2))

        result = metric.sectional_curvature(y, y)
        expected = 0.
        self.assertAllClose(result, expected)
Exemplo n.º 6
0
    def test_curvature(self):
        group = self.matrix_so3
        metric = InvariantMetric(group=group)
        x, y, z = metric.normal_basis(group.lie_algebra.basis)

        result = metric.curvature_at_identity(x, y, x)
        expected = 1.0 / 8 * y
        self.assertAllClose(result, expected)

        tan_a = gs.stack([x, x])
        tan_b = gs.stack([y] * 2)
        result = metric.curvature(tan_a, tan_b, tan_a)
        self.assertAllClose(result, gs.array([expected] * 2))

        point = group.random_uniform()
        translation_map = group.tangent_translation_map(point)
        tan_a = translation_map(x)
        tan_b = translation_map(y)
        result = metric.curvature(tan_a, tan_b, tan_a, point)
        expected = translation_map(expected)
        self.assertAllClose(result, expected)

        result = metric.curvature(y, y, z)
        expected = gs.zeros_like(z)
        self.assertAllClose(result, expected)
Exemplo n.º 7
0
 def curvature_test_data(self):
     group = self.matrix_so3
     metric = InvariantMetric(group)
     x, y, z = metric.normal_basis(group.lie_algebra.basis)
     smoke_data = [
         dict(
             group=group,
             tangent_vec_a=x,
             tangent_vec_b=y,
             tangent_vec_c=x,
             expected=1.0 / 8 * y,
         ),
         dict(
             group=group,
             tangent_vec_a=gs.stack([x, x]),
             tangent_vec_b=gs.stack([y] * 2),
             tangent_vec_c=gs.stack([x, x]),
             expected=gs.array([1.0 / 8 * y] * 2),
         ),
         dict(
             group=group,
             tangent_vec_a=y,
             tangent_vec_b=y,
             tangent_vec_c=z,
             expected=gs.zeros_like(z),
         ),
     ]
     return self.generate_tests(smoke_data)
Exemplo n.º 8
0
    def test_structure_constant(self):
        group = self.matrix_so3
        metric = InvariantMetric(group=group)
        basis = metric.normal_basis(group.lie_algebra.basis)
        x, y, z = basis
        result = metric.structure_constant(x, y, z)
        expected = 2.0**0.5 / 2.0
        self.assertAllClose(result, expected)

        result = -metric.structure_constant(y, x, z)
        self.assertAllClose(result, expected)

        result = metric.structure_constant(y, z, x)
        self.assertAllClose(result, expected)

        result = -metric.structure_constant(z, y, x)
        self.assertAllClose(result, expected)

        result = metric.structure_constant(z, x, y)
        self.assertAllClose(result, expected)

        result = -metric.structure_constant(x, z, y)
        self.assertAllClose(result, expected)

        result = metric.structure_constant(x, x, z)
        expected = 0.0
        self.assertAllClose(result, expected)
Exemplo n.º 9
0
    def test_integrated_parallel_transport(self, group, n, n_samples):
        metric = InvariantMetric(group=group)
        point = group.identity
        tan_b = Matrices(n + 1, n + 1).random_point(n_samples)
        tan_b = group.to_tangent(tan_b)

        # use a vector orthonormal to tan_b
        tan_a = Matrices(n + 1, n + 1).random_point(n_samples)
        tan_a = group.to_tangent(tan_a)
        coef = metric.inner_product(tan_a, tan_b) / metric.squared_norm(tan_b)
        tan_a -= gs.einsum("...,...ij->...ij", coef, tan_b)
        tan_b = gs.einsum("...ij,...->...ij", tan_b,
                          1.0 / metric.norm(tan_b, base_point=point))
        tan_a = gs.einsum("...ij,...->...ij", tan_a,
                          1.0 / metric.norm(tan_a, base_point=point))

        expected = group.left_canonical_metric.parallel_transport(
            tan_a, point, tan_b)
        result, end_point_result = metric.parallel_transport(
            tan_a, point, tan_b, n_steps=20, step="rk4", return_endpoint=True)
        expected_end_point = metric.exp(tan_b, point, n_steps=20)

        self.assertAllClose(end_point_result,
                            expected_end_point,
                            atol=gs.atol * 1000)
        self.assertAllClose(expected, result, atol=gs.atol * 1000)
Exemplo n.º 10
0
    def test_structure_constant(self):
        group = self.matrix_so3
        lie_algebra = SkewSymmetricMatrices(3)
        metric = InvariantMetric(group=group, algebra=lie_algebra)
        basis = lie_algebra.orthonormal_basis(metric.metric_mat_at_identity)
        x, y, z = basis
        result = metric.structure_constant(-z, y, -x)
        expected = 2.**.5 / 2.
        self.assertAllClose(result, expected)

        result = -metric.structure_constant(y, -z, -x)
        self.assertAllClose(result, expected)

        result = metric.structure_constant(y, -x, -z)
        self.assertAllClose(result, expected)

        result = -metric.structure_constant(-x, y, -z)
        self.assertAllClose(result, expected)

        result = metric.structure_constant(-x, -z, y)
        self.assertAllClose(result, expected)

        result = -metric.structure_constant(-z, -x, y)
        self.assertAllClose(result, expected)

        result = metric.structure_constant(x, x, z)
        expected = 0.
        self.assertAllClose(result, expected)
Exemplo n.º 11
0
 def test_curvature(self, group, tangent_vec_a, tangent_vec_b,
                    tangent_vec_c, expected):
     metric = InvariantMetric(group)
     result = metric.curvature(tangent_vec_a,
                               tangent_vec_b,
                               tangent_vec_c,
                               base_point=None)
     self.assertAllClose(result, expected)
Exemplo n.º 12
0
 def test_dual_adjoint_structure_constant(self, group, tangent_vec_a,
                                          tangent_vec_b, tangent_vec_c):
     metric = InvariantMetric(group=group)
     result = metric.inner_product_at_identity(
         metric.dual_adjoint(tangent_vec_a, tangent_vec_b), tangent_vec_c)
     expected = metric.structure_constant(tangent_vec_a, tangent_vec_c,
                                          tangent_vec_b)
     self.assertAllClose(result, expected)
Exemplo n.º 13
0
    def __init__(self, dim, default_point_type='vector'):
        Manifold.__init__(self, dim=dim)

        self.left_canonical_metric = InvariantMetric(
            group=self,
            inner_product_mat_at_identity=gs.eye(self.dim),
            left_or_right='left',
        )

        self.right_canonical_metric = InvariantMetric(
            group=self,
            inner_product_mat_at_identity=gs.eye(self.dim),
            left_or_right='right',
        )

        self.metrics = []
        self.default_point_type = default_point_type
Exemplo n.º 14
0
    def regularize_tangent_vec(self,
                               tangent_vec,
                               base_point,
                               metric=None,
                               point_type=None):
        """Regularize a tangent vector at a base point.

        Parameters
        ----------
        tangent_vec: array-like, shape=[n_samples, {dimension, [n + 1, n + 1]}]
        base_point : array-like, shape=[n_samples, {dimension, [n + 1, n + 1]}]
        metric : RiemannianMetric, optional
            default: self.left_canonical_metric
        point_type: str, {'vector', 'matrix'}, optional
            default: self.default_point_type

        Returns
        -------
        regularized_vec : the regularized tangent vector
        """
        if point_type is None:
            point_type = self.default_point_type

        if metric is None:
            metric = self.left_canonical_metric

        if point_type == 'vector':
            tangent_vec = gs.to_ndarray(tangent_vec, to_ndim=2)
            base_point = gs.to_ndarray(base_point, to_ndim=2)

            rotations = self.rotations
            dim_rotations = rotations.dimension

            rot_tangent_vec = tangent_vec[:, :dim_rotations]
            rot_base_point = base_point[:, :dim_rotations]

            metric_mat = metric.inner_product_mat_at_identity
            rot_metric_mat = metric_mat[:, :dim_rotations, :dim_rotations]
            rot_metric = InvariantMetric(
                group=rotations,
                inner_product_mat_at_identity=rot_metric_mat,
                left_or_right=metric.left_or_right)

            regularized_vec = gs.zeros_like(tangent_vec)
            rotations_vec = rotations.regularize_tangent_vec(
                tangent_vec=rot_tangent_vec,
                base_point=rot_base_point,
                metric=rot_metric,
                point_type=point_type)

            regularized_vec = gs.concatenate(
                [rotations_vec, tangent_vec[:, dim_rotations:]], axis=1)

        elif point_type == 'matrix':
            regularized_vec = tangent_vec

        return regularized_vec
Exemplo n.º 15
0
    def test_orthonormal_basis(self, group, metric_mat_at_identity):
        lie_algebra = group.lie_algebra
        metric = InvariantMetric(group, metric_mat_at_identity)
        basis = metric.normal_basis(lie_algebra.basis)
        result = metric.inner_product_at_identity(basis[0], basis[1])
        self.assertAllClose(result, 0.0)

        result = metric.inner_product_at_identity(basis[1], basis[1])
        self.assertAllClose(result, 1.0)
Exemplo n.º 16
0
 def test_orthonormal_basis_se3(self, group, metric_mat_at_identity):
     lie_algebra = group.lie_algebra
     metric = InvariantMetric(group, metric_mat_at_identity)
     basis = metric.normal_basis(lie_algebra.basis)
     for i, x in enumerate(basis):
         for y in basis[i:]:
             result = metric.inner_product_at_identity(x, y)
             expected = 0.0 if gs.any(x != y) else 1.0
             self.assertAllClose(result, expected)
Exemplo n.º 17
0
 def test_connection_translation_map(self, group, tangent_vec_a,
                                     tangent_vec_b, point, expected):
     metric = InvariantMetric(group)
     translation_map = group.tangent_translation_map(point)
     tan_a = translation_map(tangent_vec_a)
     tan_b = translation_map(tangent_vec_b)
     result = metric.connection(tan_a, tan_b, point)
     expected = translation_map(expected)
     self.assertAllClose(result, expected, rtol=1e-3, atol=1e-3)
Exemplo n.º 18
0
    def test_orthonormal_basis(self):
        group = SpecialOrthogonal(3)
        lie_algebra = SkewSymmetricMatrices(3)
        metric = InvariantMetric(group=group)
        basis = metric.normal_basis(lie_algebra.basis)
        result = metric.inner_product_at_identity(basis[0], basis[1])
        self.assertAllClose(result, 0.0)

        result = metric.inner_product_at_identity(basis[1], basis[1])
        self.assertAllClose(result, 1.0)

        metric_mat = from_vector_to_diagonal_matrix(gs.array([1.0, 2.0, 3.0]))
        metric = InvariantMetric(group=group, metric_mat_at_identity=metric_mat)
        basis = metric.normal_basis(lie_algebra.basis)
        result = metric.inner_product_at_identity(basis[0], basis[1])
        self.assertAllClose(result, 0.0)

        result = metric.inner_product_at_identity(basis[1], basis[1])
        self.assertAllClose(result, 1.0)
Exemplo n.º 19
0
    def regularize_tangent_vec(self,
                               tangent_vec,
                               base_point,
                               metric=None,
                               point_type=None):
        """Regularize a tangent vector at a base point.

        Parameters
        ----------
        tangent_vec: array-like, shape=[n_samples, {dim, [n + 1, n + 1]}]
        base_point : array-like, shape=[n_samples, {dim, [n + 1, n + 1]}]
        metric : RiemannianMetric, optional
            default: self.left_canonical_metric
        point_type: str, {'vector', 'matrix'}, optional
            default: self.default_point_type

        Returns
        -------
        regularized_vec : the regularized tangent vector
        """
        if metric is None:
            metric = self.left_canonical_metric

        if point_type == 'vector':
            rotations = self.rotations
            dim_rotations = rotations.dim

            rot_tangent_vec = tangent_vec[:, :dim_rotations]
            rot_base_point = base_point[:, :dim_rotations]

            metric_mat = metric.inner_product_mat_at_identity
            rot_metric_mat = metric_mat[:dim_rotations, :dim_rotations]
            rot_metric = InvariantMetric(
                group=rotations,
                inner_product_mat_at_identity=rot_metric_mat,
                left_or_right=metric.left_or_right)

            rotations_vec = rotations.regularize_tangent_vec(
                tangent_vec=rot_tangent_vec,
                base_point=rot_base_point,
                metric=rot_metric,
                point_type=point_type)

            return gs.concatenate(
                [rotations_vec, tangent_vec[:, dim_rotations:]], axis=1)

        if point_type == 'matrix':
            tangent_vec_at_id = self.compose(self.inverse(base_point),
                                             tangent_vec)
            regularized = self.regularize_tangent_vec_at_identity(
                tangent_vec_at_id, point_type=point_type)
            return self.compose(base_point, regularized)

        raise ValueError('Invalid point_type, expected \'vector\' or '
                         '\'matrix\'.')
Exemplo n.º 20
0
 def test_curvature_translation_point(self, group, tangent_vec_a,
                                      tangent_vec_b, tangent_vec_c, point,
                                      expected):
     metric = InvariantMetric(group)
     translation_map = group.tangent_translation_map(point)
     tan_a = translation_map(tangent_vec_a)
     tan_b = translation_map(tangent_vec_b)
     tan_c = translation_map(tangent_vec_c)
     result = metric.curvature(tan_a, tan_b, tan_c, point)
     expected = translation_map(expected)
     self.assertAllClose(result, expected)
Exemplo n.º 21
0
 def test_dist_pairwise_parallel(self):
     gs.random.seed(0)
     n_samples = 2
     group = self.matrix_so3
     metric = InvariantMetric(group=group)
     points = group.random_uniform(n_samples)
     result = metric.dist_pairwise(points, n_jobs=2)
     is_sym = Matrices.is_symmetric(result)
     belongs = Matrices(n_samples, n_samples).belongs(result)
     self.assertTrue(is_sym)
     self.assertTrue(belongs)
Exemplo n.º 22
0
 def test_dual_adjoint(self):
     group = self.matrix_so3
     metric = InvariantMetric(group=group)
     basis = metric.orthonormal_basis(group.lie_algebra.basis)
     for x in basis:
         for y in basis:
             for z in basis:
                 result = metric.inner_product_at_identity(
                     metric.dual_adjoint(x, y), z)
                 expected = metric.structure_constant(x, z, y)
                 self.assertAllClose(result, expected)
Exemplo n.º 23
0
    def test_integrated_exp_and_log_at_id(self):
        group = self.matrix_so3
        metric = InvariantMetric(group=group)
        basis = group.lie_algebra.basis

        vector = gs.random.rand(2, len(basis))
        tangent_vec = gs.einsum("...j,jkl->...kl", vector, basis)
        identity = self.matrix_so3.identity

        exp = metric.exp(tangent_vec, identity, n_steps=100, step="rk4")
        result = metric.log(exp, identity, n_steps=15, step="rk4", verbose=False)
        self.assertAllClose(tangent_vec, result, atol=1e-5)
Exemplo n.º 24
0
    def test_orthonormal_basis_se3(self):
        group = SpecialEuclidean(3)
        lie_algebra = group.lie_algebra
        metric = InvariantMetric(group=group)
        basis = metric.normal_basis(lie_algebra.basis)
        for i, x in enumerate(basis):
            for y in basis[i:]:
                result = metric.inner_product_at_identity(x, y)
                expected = 0.0 if gs.any(x != y) else 1.0
                self.assertAllClose(result, expected)

        metric_mat = from_vector_to_diagonal_matrix(
            gs.cast(gs.arange(1, group.dim + 1), gs.float32)
        )
        metric = InvariantMetric(group=group, metric_mat_at_identity=metric_mat)
        basis = metric.normal_basis(lie_algebra.basis)
        for i, x in enumerate(basis):
            for y in basis[i:]:
                result = metric.inner_product_at_identity(x, y)
                expected = 0.0 if gs.any(x != y) else 1.0
                self.assertAllClose(result, expected)
Exemplo n.º 25
0
 def test_dual_adjoint(self):
     group = self.matrix_so3
     lie_algebra = SkewSymmetricMatrices(3)
     metric = InvariantMetric(group=group, algebra=lie_algebra)
     basis = lie_algebra.orthonormal_basis(metric.metric_mat_at_identity)
     for x in basis:
         for y in basis:
             for z in basis:
                 result = metric.inner_product_at_identity(
                     metric.dual_adjoint(x, y), z)
                 expected = metric.structure_constant(x, z, y)
                 self.assertAllClose(result, expected)
Exemplo n.º 26
0
    def __init__(self,
                 dim,
                 default_point_type="vector",
                 lie_algebra=None,
                 **kwargs):
        super(LieGroup, self).__init__(dim=dim,
                                       default_point_type=default_point_type,
                                       **kwargs)

        self.lie_algebra = lie_algebra
        self.left_canonical_metric = InvariantMetric(
            group=self,
            metric_mat_at_identity=gs.eye(self.dim),
            left_or_right="left")

        self.right_canonical_metric = InvariantMetric(
            group=self,
            metric_mat_at_identity=gs.eye(self.dim),
            left_or_right="right")

        self.metric = self.left_canonical_metric
        self.metrics = []
Exemplo n.º 27
0
 def connection_test_data(self):
     group = self.matrix_so3
     metric = InvariantMetric(group)
     x, y, z = metric.normal_basis(group.lie_algebra.basis)
     smoke_data = [
         dict(
             group=group,
             tangent_vec_a=x,
             tangent_vec_b=y,
             expected=1.0 / 2**0.5 / 2.0 * z,
         )
     ]
     return self.generate_tests(smoke_data)
Exemplo n.º 28
0
    def test_integrated_exp_at_id(self):
        group = self.matrix_so3
        metric = InvariantMetric(group=group)
        basis = metric.normal_basis(group.lie_algebra.basis)

        vector = gs.random.rand(2, len(basis))
        tangent_vec = gs.einsum("...j,jkl->...kl", vector, basis)
        identity = self.matrix_so3.identity
        result = metric.exp(tangent_vec, identity, n_steps=100, step="rk4")
        expected = group.exp(tangent_vec, identity)
        self.assertAllClose(expected, result, atol=1e-5)

        result = metric.exp(tangent_vec, identity, n_steps=100, step="rk2")
        self.assertAllClose(expected, result, atol=1e-5)
Exemplo n.º 29
0
    def test_integrated_se3_exp_at_id(self, group):
        lie_algebra = group.lie_algebra
        metric = InvariantMetric(group=group)
        canonical_metric = group.left_canonical_metric
        basis = metric.normal_basis(lie_algebra.basis)

        vector = gs.random.rand(len(basis))
        tangent_vec = gs.einsum("...j,jkl->...kl", vector, basis)
        identity = group.identity
        result = metric.exp(tangent_vec, identity, n_steps=100, step="rk4")
        expected = canonical_metric.exp(tangent_vec, identity)
        self.assertAllClose(expected, result, atol=1e-4)

        result = metric.exp(tangent_vec, identity, n_steps=100, step="rk2")
        self.assertAllClose(expected, result, atol=1e-4)
Exemplo n.º 30
0
    def test_curvature_derivative_at_identity(self):
        group = self.matrix_so3
        metric = InvariantMetric(group=group)
        basis = metric.normal_basis(group.lie_algebra.basis)

        result = True
        for x in basis:
            for i, y in enumerate(basis):
                for z in basis[i:]:
                    for t in basis:
                        nabla_r = metric.curvature_derivative_at_identity(x, y, z, t)
                        if not gs.all(gs.isclose(nabla_r, 0.0)):
                            print(nabla_r)
                            result = False
        self.assertTrue(result)