Пример #1
0
    def test_log_after_exp_with_angles_close_to_pi(
        self, metric, tangent_vec, base_point
    ):
        """
        Test that the Riemannian left exponential and the
        Riemannian left logarithm are inverse.
        Expect their composition to give the identity function.
        """
        group = SpecialEuclidean(3, "vector")
        result = metric.log(metric.exp(tangent_vec, base_point), base_point)

        expected = group.regularize_tangent_vec(
            tangent_vec=tangent_vec, base_point=base_point, metric=metric
        )

        inv_expected = gs.concatenate([-expected[:3], expected[3:6]])

        norm = gs.linalg.norm(expected)
        atol = ATOL
        if norm != 0:
            atol = ATOL * norm

        self.assertTrue(
            gs.allclose(result, expected, atol=atol)
            or gs.allclose(result, inv_expected, atol=atol)
        )
Пример #2
0
 def setUp(self):
     logger = logging.getLogger()
     logger.disabled = True
     self.se_mat = SpecialEuclidean(n=3)
     self.so_vec = SpecialOrthogonal(n=3, point_type='vector')
     self.so = SpecialOrthogonal(n=3)
     self.n_samples = 4
Пример #3
0
    def test_custom_gradient_squared_dist(self):
        def squared_dist_grad_a(point_a, point_b, metric):
            return -2 * metric.log(point_b, point_a)

        def squared_dist_grad_b(point_a, point_b, metric):
            return -2 * metric.log(point_a, point_b)

        @gs.autodiff.custom_gradient(squared_dist_grad_a, squared_dist_grad_b)
        def squared_dist(point_a, point_b, metric):
            dist = metric.squared_dist(point_a, point_b)
            return dist

        space = SpecialEuclidean(n=2)
        const_metric = space.left_canonical_metric
        const_point_b = space.random_point()

        def func(x):
            return squared_dist(x, const_point_b, metric=const_metric)

        arg_point_a = space.random_point()
        expected_value = func(arg_point_a)
        expected_grad = -2 * const_metric.log(const_point_b, arg_point_a)
        result_value, result_grad = gs.autodiff.value_and_grad(func)(arg_point_a)
        self.assertAllClose(result_value, expected_value)
        self.assertAllClose(result_grad, expected_grad)
Пример #4
0
    def test_load_poses(self):
        """Test that the poses belong to SE(3)."""
        se3 = SpecialEuclidean(n=3, point_type="vector")
        data, _ = data_utils.load_poses(only_rotations=False)
        result = se3.belongs(data)

        self.assertTrue(gs.all(result))
Пример #5
0
 def setUp(self):
     self.n = 2
     self.group = SpecialEuclidean(n=self.n)
     self.n_samples = 4
     self.point = self.group.random_point(self.n_samples)
     self.tangent_vec = self.group.to_tangent(
         gs.random.rand(self.n_samples, self.group.n + 1, self.group.n + 1),
         self.point)
Пример #6
0
 def test_right_exp_coincides(self, n, initial_vec):
     group = SpecialEuclidean(n=n)
     vector_group = SpecialEuclidean(n=n, point_type="vector")
     initial_matrix_vec = group.lie_algebra.matrix_representation(initial_vec)
     vector_exp = vector_group.right_canonical_metric.exp(initial_vec)
     result = group.right_canonical_metric.exp(initial_matrix_vec, n_steps=25)
     expected = vector_group.matrix_from_vector(vector_exp)
     self.assertAllClose(result, expected, atol=1e-6)
Пример #7
0
 def test_right_exp_coincides(self):
     vector_group = SpecialEuclidean(n=2, point_type="vector")
     theta = gs.pi / 2
     initial_vec = gs.array([theta, 1.0, 1.0])
     initial_matrix_vec = self.group.lie_algebra.matrix_representation(initial_vec)
     vector_exp = vector_group.right_canonical_metric.exp(initial_vec)
     result = self.group.right_canonical_metric.exp(initial_matrix_vec, n_steps=25)
     expected = vector_group.matrix_from_vector(vector_exp)
     self.assertAllClose(result, expected, atol=1e-6)
Пример #8
0
    def setUp(self):
        self.n_samples = 10
        self.SO3_GROUP = SpecialOrthogonal(n=3)
        self.SE3_GROUP = SpecialEuclidean(n=3)
        self.S1 = Hypersphere(dim=1)
        self.S2 = Hypersphere(dim=2)
        self.H2 = Hyperbolic(dim=2)

        plt.figure()
Пример #9
0
 def setup_method(self):
     gs.random.seed(12)
     self.n = 2
     self.group = SpecialEuclidean(n=self.n)
     self.n_samples = 3
     self.point = self.group.random_point(self.n_samples)
     self.tangent_vec = self.group.to_tangent(
         gs.random.rand(self.n_samples, self.group.n + 1, self.group.n + 1),
         self.point,
     )
Пример #10
0
 def test_left_exp_coincides(self):
     vector_group = SpecialEuclidean(n=2, point_type='vector')
     theta = gs.pi / 3
     initial_vec = gs.array([theta, 2., 2.])
     initial_matrix_vec = self.group.lie_algebra.matrix_representation(
         initial_vec)
     vector_exp = vector_group.left_canonical_metric.exp(initial_vec)
     result = self.group.left_canonical_metric.exp(initial_matrix_vec)
     expected = vector_group.matrix_from_vector(vector_exp)
     self.assertAllClose(result, expected)
Пример #11
0
    def setUp(self):
        self.n_samples = 10
        self.SO3_GROUP = SpecialOrthogonal(n=3, point_type='vector')
        self.SE3_GROUP = SpecialEuclidean(n=3, point_type='vector')
        self.S1 = Hypersphere(dim=1)
        self.S2 = Hypersphere(dim=2)
        self.H2 = Hyperbolic(dim=2)
        self.H2_half_plane = PoincareHalfSpace(dim=2)

        plt.figure()
Пример #12
0
    def setup_method(self):
        gs.random.seed(1234)
        self.n_samples = 20

        # Set up for hypersphere
        self.dim_sphere = 4
        self.shape_sphere = (self.dim_sphere + 1, )
        self.sphere = Hypersphere(dim=self.dim_sphere)
        X = gs.random.rand(self.n_samples)
        self.X_sphere = X - gs.mean(X)
        self.intercept_sphere_true = self.sphere.random_point()
        self.coef_sphere_true = self.sphere.projection(
            gs.random.rand(self.dim_sphere + 1))

        self.y_sphere = self.sphere.metric.exp(
            self.X_sphere[:, None] * self.coef_sphere_true,
            base_point=self.intercept_sphere_true,
        )

        self.param_sphere_true = gs.vstack(
            [self.intercept_sphere_true, self.coef_sphere_true])
        self.param_sphere_guess = gs.vstack([
            self.y_sphere[0],
            self.sphere.to_tangent(gs.random.normal(size=self.shape_sphere),
                                   self.y_sphere[0]),
        ])

        # Set up for special euclidean
        self.se2 = SpecialEuclidean(n=2)
        self.metric_se2 = self.se2.left_canonical_metric
        self.metric_se2.default_point_type = "matrix"

        self.shape_se2 = (3, 3)
        X = gs.random.rand(self.n_samples)
        self.X_se2 = X - gs.mean(X)

        self.intercept_se2_true = self.se2.random_point()
        self.coef_se2_true = self.se2.to_tangent(
            5.0 * gs.random.rand(*self.shape_se2), self.intercept_se2_true)

        self.y_se2 = self.metric_se2.exp(
            self.X_se2[:, None, None] * self.coef_se2_true[None],
            self.intercept_se2_true,
        )

        self.param_se2_true = gs.vstack([
            gs.flatten(self.intercept_se2_true),
            gs.flatten(self.coef_se2_true),
        ])
        self.param_se2_guess = gs.vstack([
            gs.flatten(self.y_se2[0]),
            gs.flatten(
                self.se2.to_tangent(gs.random.normal(size=self.shape_se2),
                                    self.y_se2[0])),
        ])
Пример #13
0
 def left_metric_wrong_group_test_data(self):
     smoke_data = [
         dict(group=SpecialEuclidean(2), expected=does_not_raise()),
         dict(group=SpecialEuclidean(3), expected=does_not_raise()),
         dict(
             group=SpecialEuclidean(2, point_type="vector"),
             expected=pytest.raises(ValueError),
         ),
         dict(group=SpecialOrthogonal(3), expected=pytest.raises(ValueError)),
     ]
     return self.generate_tests(smoke_data)
Пример #14
0
 def test_fit_matrix_se(self):
     se_mat = SpecialEuclidean(n=3, default_point_type='matrix')
     X = se_mat.random_uniform(self.n_samples)
     estimator = ExponentialBarycenter(se_mat)
     estimator.fit(X)
     mean = estimator.estimate_
     tpca = TangentPCA(metric=se_mat, point_type='matrix')
     tangent_projected_data = tpca.fit_transform(X, base_point=mean)
     result = tpca.inverse_transform(tangent_projected_data)
     expected = X
     self.assertAllClose(result, expected)
Пример #15
0
 def orthonormal_basis_se3_test_data(self):
     smoke_data = [
         dict(group=SpecialEuclidean(3), metric_mat_at_identity=None),
         dict(
             group=SpecialEuclidean(3),
             metric_mat_at_identity=from_vector_to_diagonal_matrix(
                 gs.cast(gs.arange(1,
                                   SpecialEuclidean(3).dim + 1),
                         gs.float32)),
         ),
     ]
     return self.generate_tests(smoke_data)
Пример #16
0
    def test_value_and_grad_dist(self):
        space = SpecialEuclidean(3)
        metric = space.metric
        point = space.random_point()
        id = space.identity
        result_loss, result_grad = gs.autodiff.value_and_grad(
            lambda v: metric.squared_dist(v, id)
        )(point)

        expected_loss = metric.squared_dist(point, id)
        expected_grad = -2 * metric.log(id, point)

        self.assertAllClose(result_loss, expected_loss)
        self.assertAllClose(result_grad, expected_grad)
Пример #17
0
 def test_exp_after_log(self, metric, point, base_point):
     """
     Test that the Riemannian right exponential and the
     Riemannian right logarithm are inverse.
     Expect their composition to give the identity function.
     """
     group = SpecialEuclidean(3, "vector")
     result = metric.exp(metric.log(point, base_point), base_point)
     expected = group.regularize(point)
     expected = gs.cast(expected, gs.float64)
     norm = gs.linalg.norm(expected)
     atol = ATOL
     if norm != 0:
         atol = ATOL * norm
     self.assertAllClose(result, expected, atol=atol)
Пример #18
0
    def test_exp_after_log_right_with_angles_close_to_pi(
            self, metric, point, base_point):
        group = SpecialEuclidean(3, "vector")
        result = metric.exp(metric.log(point, base_point), base_point)
        expected = group.regularize(point)

        inv_expected = gs.concatenate([-expected[:3], expected[3:6]])

        norm = gs.linalg.norm(expected)
        atol = ATOL
        if norm != 0:
            atol = ATOL * norm

        self.assertTrue(
            gs.allclose(result, expected, atol=atol)
            or gs.allclose(result, inv_expected, atol=atol))
Пример #19
0
    def setUp(self):
        self.n_samples = 10
        self.SO3_GROUP = SpecialOrthogonal(n=3, point_type='vector')
        self.SE3_GROUP = SpecialEuclidean(n=3, point_type='vector')
        self.S1 = Hypersphere(dim=1)
        self.S2 = Hypersphere(dim=2)
        self.H2 = Hyperbolic(dim=2)
        self.H2_half_plane = PoincareHalfSpace(dim=2)
        self.M32 = Matrices(m=3, n=2)
        self.S32 = PreShapeSpace(k_landmarks=3, m_ambient=2)
        self.KS = visualization.KendallSphere()
        self.M33 = Matrices(m=3, n=3)
        self.S33 = PreShapeSpace(k_landmarks=3, m_ambient=3)
        self.KD = visualization.KendallDisk()

        plt.figure()
Пример #20
0
    def test_left_metric_wrong_group(self):
        group = self.group.rotations
        with pytest.raises(ValueError):
            SpecialEuclideanMatrixCannonicalLeftMetric(group)

        group = SpecialEuclidean(3, point_type="vector")
        with pytest.raises(ValueError):
            SpecialEuclideanMatrixCannonicalLeftMetric(group)
Пример #21
0
 def inner_product_matrix_and_its_inverse_test_data(self):
     group = SpecialEuclidean(n=3, point_type="vector")
     smoke_data = [
         dict(group=group,
              metric_mat_at_identity=None,
              left_or_right="left")
     ]
     return self.generate_tests(smoke_data)
Пример #22
0
    def test_log_after_exp(self, metric, tangent_vec, base_point):
        """
        Test that the Riemannian left exponential and the
        Riemannian left logarithm are inverse.
        Expect their composition to give the identity function.
        """
        group = SpecialEuclidean(3, "vector")
        result = metric.log(metric.exp(tangent_vec, base_point), base_point)

        expected = group.regularize_tangent_vec(
            tangent_vec=tangent_vec, base_point=base_point, metric=metric
        )

        norm = gs.linalg.norm(expected)
        atol = ATOL
        if norm != 0:
            atol = ATOL * norm
        self.assertAllClose(result, expected, atol=atol)
Пример #23
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
Пример #24
0
class TestVisualization(geomstats.tests.TestCase):
    def setUp(self):
        self.n_samples = 10
        self.SO3_GROUP = SpecialOrthogonal(n=3, point_type='vector')
        self.SE3_GROUP = SpecialEuclidean(n=3, point_type='vector')
        self.S1 = Hypersphere(dim=1)
        self.S2 = Hypersphere(dim=2)
        self.H2 = Hyperbolic(dim=2)
        self.H2_half_plane = PoincareHalfSpace(dim=2)

        plt.figure()

    @staticmethod
    def test_tutorial_matplotlib():
        visualization.tutorial_matplotlib()

    def test_plot_points_so3(self):
        points = self.SO3_GROUP.random_uniform(self.n_samples)
        visualization.plot(points, space='SO3_GROUP')

    def test_plot_points_se3(self):
        points = self.SE3_GROUP.random_uniform(self.n_samples)
        visualization.plot(points, space='SE3_GROUP')

    @geomstats.tests.np_and_pytorch_only
    def test_plot_points_s1(self):
        points = self.S1.random_uniform(self.n_samples)
        visualization.plot(points, space='S1')

    def test_plot_points_s2(self):
        points = self.S2.random_uniform(self.n_samples)
        visualization.plot(points, space='S2')

    def test_plot_points_h2_poincare_disk(self):
        points = self.H2.random_uniform(self.n_samples)
        visualization.plot(points, space='H2_poincare_disk')

    def test_plot_points_h2_poincare_half_plane_ext(self):
        points = self.H2.random_uniform(self.n_samples)
        visualization.plot(points,
                           space='H2_poincare_half_plane',
                           point_type='extrinsic')

    def test_plot_points_h2_poincare_half_plane_none(self):
        points = self.H2_half_plane.random_uniform(self.n_samples)
        visualization.plot(points, space='H2_poincare_half_plane')

    def test_plot_points_h2_poincare_half_plane_hs(self):
        points = self.H2_half_plane.random_uniform(self.n_samples)
        visualization.plot(points,
                           space='H2_poincare_half_plane',
                           point_type='half_space')

    def test_plot_points_h2_klein_disk(self):
        points = self.H2.random_uniform(self.n_samples)
        visualization.plot(points, space='H2_klein_disk')
Пример #25
0
    def test_left_metric_wrong_group(self):
        group = self.group.rotations
        self.assertRaises(
            ValueError,
            lambda: SpecialEuclideanMatrixCannonicalLeftMetric(group))

        group = SpecialEuclidean(3, point_type='vector')
        self.assertRaises(
            ValueError,
            lambda: SpecialEuclideanMatrixCannonicalLeftMetric(group))
Пример #26
0
 def inner_product_mat_at_identity_shape_test_data(self):
     group = SpecialEuclidean(n=3, point_type="vector")
     sym_mat_at_identity = gs.eye(group.dim)
     smoke_data = [
         dict(
             group=group,
             metric_mat_at_identity=sym_mat_at_identity,
             left_or_right="left",
         )
     ]
     return self.generate_tests(smoke_data)
Пример #27
0
    def test_custom_gradient_in_action(self):
        space = SpecialEuclidean(n=2)
        const_metric = space.left_canonical_metric
        const_point_b = space.random_point()

        def func(x):
            return const_metric.squared_dist(x, const_point_b)

        arg_point_a = space.random_point()
        func_with_grad = gs.autodiff.value_and_grad(func)
        result_value, result_grad = func_with_grad(arg_point_a)
        expected_value = const_metric.squared_dist(arg_point_a, const_point_b)
        expected_grad = -2 * const_metric.log(const_point_b, arg_point_a)

        self.assertAllClose(result_value, expected_value)
        self.assertAllClose(result_grad, expected_grad)

        loss, grad = func_with_grad(const_point_b)
        self.assertAllClose(loss, 0.0)
        self.assertAllClose(grad, gs.zeros_like(grad))
Пример #28
0
 def inverse_shape_test_data(self):
     n_list = random.sample(range(2, 50), 10)
     n_samples = 10
     random_data = [
         dict(
             n=n,
             points=SpecialEuclidean(n).random_point(n_samples),
             expected=(n_samples, n + 1, n + 1),
         ) for n in n_list
     ]
     return self.generate_tests([], random_data)
Пример #29
0
 def exp_after_log_right_with_angles_close_to_pi_test_data(self):
     smoke_data = []
     for metric in list(
             self.metrics.values()) + [SpecialEuclidean(3, "vector")]:
         for base_point in self.elements.values():
             for element_type in self.angles_close_to_pi:
                 point = self.elements[element_type]
                 smoke_data.append(
                     dict(
                         metric=metric,
                         point=point,
                         base_point=base_point,
                     ))
     return self.generate_tests(smoke_data)
Пример #30
0
    def setUp(self):
        warnings.simplefilter("ignore", category=ImportWarning)
        gs.random.seed(1234)

        group = SpecialEuclidean(n=2, point_type="vector")

        point_1 = gs.array([0.1, 0.2, 0.3])
        point_2 = gs.array([0.5, 5.0, 60.0])

        translation_large = gs.array([0.0, 5.0, 6.0])
        translation_small = gs.array([0.0, 0.6, 0.7])

        elements_all = {
            "translation_large": translation_large,
            "translation_small": translation_small,
            "point_1": point_1,
            "point_2": point_2,
        }
        elements = elements_all
        if geomstats.tests.tf_backend():
            # Tf is extremely slow
            elements = {"point_1": point_1, "point_2": point_2}

        elements_matrices_all = {
            key: group.matrix_from_vector(elements_all[key])
            for key in elements_all
        }
        elements_matrices = elements_matrices_all

        self.group = group
        self.elements_all = elements_all
        self.elements = elements
        self.elements_matrices_all = elements_matrices_all
        self.elements_matrices = elements_matrices

        self.n_samples = 4