예제 #1
0
    def test_hands(self):
        """Test that hands belong to space of landmarks."""
        data, labels, _ = data_utils.load_hands()
        result = data.shape
        n_hands = 52
        k_landmarks = 22
        dim = 3
        expected = (n_hands, k_landmarks, dim)
        self.assertAllClose(result, expected)

        landmarks_space = Landmarks(ambient_manifold=Euclidean(dim=3),
                                    k_landmarks=k_landmarks)

        result = landmarks_space.belongs(data)
        self.assertTrue(gs.all(result))

        result = gs.logical_and(labels >= 0, labels <= 1)
        self.assertTrue(gs.all(result))
예제 #2
0
    def test_load_optical_nerves(self):
        """Test that optical nerves belong to space of landmarks."""
        data, labels, monkeys = data_utils.load_optical_nerves()
        result = data.shape
        n_monkeys = 11
        n_eyes_per_monkey = 2
        k_landmarks = 5
        dim = 3
        expected = (n_monkeys * n_eyes_per_monkey, k_landmarks, dim)
        self.assertAllClose(result, expected)

        landmarks_space = Landmarks(ambient_manifold=Euclidean(dim=dim),
                                    k_landmarks=k_landmarks)

        result = landmarks_space.belongs(data)
        self.assertTrue(gs.all(result))

        result = gs.logical_and(labels >= 0, labels <= 1)
        self.assertTrue(gs.all(result))

        result = gs.logical_and(monkeys >= 0, monkeys <= 11)
        self.assertTrue(gs.all(result))
예제 #3
0
    def setUp(self):
        s2 = Hypersphere(dim=2)
        r3 = s2.embedding_manifold

        initial_point = [0., 0., 1.]
        initial_tangent_vec_a = [1., 0., 0.]
        initial_tangent_vec_b = [0., 1., 0.]
        initial_tangent_vec_c = [-1., 0., 0.]

        landmarks_a = s2.metric.geodesic(
            initial_point=initial_point,
            initial_tangent_vec=initial_tangent_vec_a)
        landmarks_b = s2.metric.geodesic(
            initial_point=initial_point,
            initial_tangent_vec=initial_tangent_vec_b)
        landmarks_c = s2.metric.geodesic(
            initial_point=initial_point,
            initial_tangent_vec=initial_tangent_vec_c)

        self.n_sampling_points = 10
        sampling_times = gs.linspace(0., 1., self.n_sampling_points)
        landmark_set_a = landmarks_a(sampling_times)
        landmark_set_b = landmarks_b(sampling_times)
        landmark_set_c = landmarks_c(sampling_times)

        self.n_landmark_sets = 5
        self.times = gs.linspace(0., 1., self.n_landmark_sets)
        self.atol = 1e-6
        gs.random.seed(1234)
        self.space_landmarks_in_euclidean_3d = Landmarks(
            ambient_manifold=r3, n_landmarks=self.n_sampling_points)
        self.space_landmarks_in_sphere_2d = Landmarks(
            ambient_manifold=s2, n_landmarks=self.n_sampling_points)
        self.l2_metric_s2 = self.space_landmarks_in_sphere_2d.metric
        self.l2_metric_r3 = self.space_landmarks_in_euclidean_3d.metric
        self.landmarks_a = landmark_set_a
        self.landmarks_b = landmark_set_b
        self.landmarks_c = landmark_set_c
예제 #4
0
class TestLandmarks(geomstats.tests.TestCase):
    @geomstats.tests.np_and_pytorch_only
    def setUp(self):
        s2 = Hypersphere(dim=2)
        r3 = s2.embedding_manifold

        initial_point = [0., 0., 1.]
        initial_tangent_vec_a = [1., 0., 0.]
        initial_tangent_vec_b = [0., 1., 0.]
        initial_tangent_vec_c = [-1., 0., 0.]

        landmarks_a = s2.metric.geodesic(
            initial_point=initial_point,
            initial_tangent_vec=initial_tangent_vec_a)
        landmarks_b = s2.metric.geodesic(
            initial_point=initial_point,
            initial_tangent_vec=initial_tangent_vec_b)
        landmarks_c = s2.metric.geodesic(
            initial_point=initial_point,
            initial_tangent_vec=initial_tangent_vec_c)

        self.n_sampling_points = 10
        sampling_times = gs.linspace(0., 1., self.n_sampling_points)
        landmark_set_a = landmarks_a(sampling_times)
        landmark_set_b = landmarks_b(sampling_times)
        landmark_set_c = landmarks_c(sampling_times)

        self.n_landmark_sets = 5
        self.times = gs.linspace(0., 1., self.n_landmark_sets)
        self.atol = 1e-6
        gs.random.seed(1234)
        self.space_landmarks_in_euclidean_3d = Landmarks(ambient_manifold=r3)
        self.space_landmarks_in_sphere_2d = Landmarks(ambient_manifold=s2)
        self.l2_metric_s2 = self.space_landmarks_in_sphere_2d.l2_metric
        self.l2_metric_r3 = self.space_landmarks_in_euclidean_3d.l2_metric
        self.landmarks_a = landmark_set_a
        self.landmarks_b = landmark_set_b
        self.landmarks_c = landmark_set_c

    @geomstats.tests.np_and_pytorch_only
    def test_belongs(self):
        result = self.space_landmarks_in_sphere_2d.belongs(self.landmarks_a)
        expected = True
        self.assertAllClose(result, expected)

    # TODO (ninamiolane): Uncomment when belongs is vectorized
    # @geomstats.tests.np_and_pytorch_only
    # def test_belongs_vectorization(self):
    #     landmark_sets = gs.array([self.landmarks_a, self.landmarks_b])
    #     result = self.space_landmarks_in_sphere_2d.belongs(landmark_sets)
    #     expected = gs.array([True, True])
    #     self.assertAllClose(result, expected)

    @geomstats.tests.np_only
    def test_l2_metric_log_and_squared_norm_and_dist(self):
        """Test that squared norm of logarithm is squared dist."""
        tangent_vec = self.l2_metric_s2.log(landmarks=self.landmarks_b,
                                            base_landmarks=self.landmarks_a)
        log_ab = tangent_vec
        result = self.l2_metric_s2.squared_norm(vector=log_ab,
                                                base_point=self.landmarks_a)
        expected = self.l2_metric_s2.dist(self.landmarks_a,
                                          self.landmarks_b)**2

        self.assertAllClose(result, expected)

    @geomstats.tests.np_only
    def test_l2_metric_log_and_exp(self):
        """Test that exp and log are inverse maps."""
        tangent_vec = self.l2_metric_s2.log(landmarks=self.landmarks_b,
                                            base_landmarks=self.landmarks_a)
        result = self.l2_metric_s2.exp(tangent_vec=tangent_vec,
                                       base_landmarks=self.landmarks_a)
        expected = self.landmarks_b

        self.assertAllClose(result, expected, atol=self.atol)

    @geomstats.tests.np_only
    def test_l2_metric_inner_product_vectorization(self):
        """Test the vectorization inner_product."""
        n_samples = self.n_landmark_sets
        landmarks_ab = self.l2_metric_s2.geodesic(self.landmarks_a,
                                                  self.landmarks_b)
        landmarks_bc = self.l2_metric_s2.geodesic(self.landmarks_b,
                                                  self.landmarks_c)
        landmarks_ab = landmarks_ab(self.times)
        landmarks_bc = landmarks_bc(self.times)

        tangent_vecs = self.l2_metric_s2.log(landmarks=landmarks_bc,
                                             base_landmarks=landmarks_ab)

        result = self.l2_metric_s2.inner_product(tangent_vecs, tangent_vecs,
                                                 landmarks_ab)

        self.assertAllClose(gs.shape(result), (n_samples, ))

    @geomstats.tests.np_only
    def test_l2_metric_dist_vectorization(self):
        """Test the vectorization of dist."""
        n_samples = self.n_landmark_sets
        landmarks_ab = self.l2_metric_s2.geodesic(self.landmarks_a,
                                                  self.landmarks_b)
        landmarks_bc = self.l2_metric_s2.geodesic(self.landmarks_b,
                                                  self.landmarks_c)
        landmarks_ab = landmarks_ab(self.times)
        landmarks_bc = landmarks_bc(self.times)

        result = self.l2_metric_s2.dist(landmarks_ab, landmarks_bc)
        self.assertAllClose(gs.shape(result), (n_samples, ))

    @geomstats.tests.np_and_tf_only
    def test_l2_metric_exp_vectorization(self):
        """Test the vectorization of exp."""
        landmarks_ab = self.l2_metric_s2.geodesic(self.landmarks_a,
                                                  self.landmarks_b)
        landmarks_bc = self.l2_metric_s2.geodesic(self.landmarks_b,
                                                  self.landmarks_c)
        landmarks_ab = landmarks_ab(self.times)
        landmarks_bc = landmarks_bc(self.times)

        tangent_vecs = self.l2_metric_s2.log(landmarks=landmarks_bc,
                                             base_landmarks=landmarks_ab)

        result = self.l2_metric_s2.exp(tangent_vec=tangent_vecs,
                                       base_landmarks=landmarks_ab)
        self.assertAllClose(gs.shape(result), gs.shape(landmarks_ab))

    @geomstats.tests.np_only
    def test_l2_metric_log_vectorization(self):
        """Test the vectorization of log."""
        landmarks_ab = self.l2_metric_s2.geodesic(self.landmarks_a,
                                                  self.landmarks_b)
        landmarks_bc = self.l2_metric_s2.geodesic(self.landmarks_b,
                                                  self.landmarks_c)
        landmarks_ab = landmarks_ab(self.times)
        landmarks_bc = landmarks_bc(self.times)

        tangent_vecs = self.l2_metric_s2.log(landmarks=landmarks_bc,
                                             base_landmarks=landmarks_ab)

        result = tangent_vecs
        self.assertAllClose(gs.shape(result), gs.shape(landmarks_ab))

    @geomstats.tests.np_only
    def test_l2_metric_geodesic(self):
        """Test the geodesic method of L2Metric."""
        landmarks_ab = self.l2_metric_s2.geodesic(self.landmarks_a,
                                                  self.landmarks_b)
        landmarks_bc = self.l2_metric_s2.geodesic(self.landmarks_b,
                                                  self.landmarks_c)
        landmarks_ab = landmarks_ab(self.times)
        landmarks_bc = landmarks_bc(self.times)

        result = landmarks_ab
        expected = gs.zeros(landmarks_ab.shape)
        for k in range(self.n_sampling_points):
            geod = self.l2_metric_s2.ambient_metric.geodesic(
                initial_point=self.landmarks_a[k, :],
                end_point=self.landmarks_b[k, :])
            expected[:, k, :] = geod(self.times)

        self.assertAllClose(result, expected)

        geod = self.l2_metric_s2.geodesic(initial_landmarks=landmarks_ab,
                                          end_landmarks=landmarks_bc)
예제 #5
0
class TestDataL2Metric(_RiemannianMetricTestData):

    dim_list = random.sample(range(2, 4), 2)
    n_landmarks_list = random.sample(range(2, 5), 2)
    metric_args_list = [
        (Hypersphere(dim), n_landmarks)
        for dim, n_landmarks in zip(dim_list, n_landmarks_list)
    ] + [(Euclidean(dim + 1), n_landmarks)
         for dim, n_landmarks in zip(dim_list, n_landmarks_list)]
    space_list = [Landmarks(*metric_arg) for metric_arg in metric_args_list]
    shape_list = [(n_landmark, dim + 1)
                  for dim, n_landmark in zip(dim_list, n_landmarks_list)] * 2
    n_points_list = random.sample(range(2, 5), 2)
    n_tangent_vecs_list = random.sample(range(2, 5), 2)
    n_points_a_list = random.sample(range(2, 5), 2)
    n_points_b_list = [1]
    alpha_list = [1] * 4
    n_rungs_list = [1] * 4
    scheme_list = ["pole"] * 4

    s2 = Hypersphere(dim=2)
    r3 = s2.embedding_space

    initial_point = [0.0, 0.0, 1.0]
    initial_tangent_vec_a = [1.0, 0.0, 0.0]
    initial_tangent_vec_b = [0.0, 1.0, 0.0]
    initial_tangent_vec_c = [-1.0, 0.0, 0.0]

    landmarks_a = s2.metric.geodesic(initial_point=initial_point,
                                     initial_tangent_vec=initial_tangent_vec_a)
    landmarks_b = s2.metric.geodesic(initial_point=initial_point,
                                     initial_tangent_vec=initial_tangent_vec_b)
    landmarks_c = s2.metric.geodesic(initial_point=initial_point,
                                     initial_tangent_vec=initial_tangent_vec_c)

    n_sampling_points = 10
    sampling_times = gs.linspace(0.0, 1.0, n_sampling_points)
    landmark_set_a = landmarks_a(sampling_times)
    landmark_set_b = landmarks_b(sampling_times)
    landmark_set_c = landmarks_c(sampling_times)

    n_landmark_sets = 5
    times = gs.linspace(0.0, 1.0, n_landmark_sets)
    space_landmarks_in_sphere_2d = Landmarks(ambient_manifold=s2,
                                             k_landmarks=n_sampling_points)
    l2_metric_s2 = space_landmarks_in_sphere_2d.metric

    def exp_shape_test_data(self):
        return self._exp_shape_test_data(self.metric_args_list,
                                         self.space_list, self.shape_list)

    def log_shape_test_data(self):
        return self._log_shape_test_data(self.metric_args_list,
                                         self.space_list)

    def squared_dist_is_symmetric_test_data(self):
        return self._squared_dist_is_symmetric_test_data(
            self.metric_args_list,
            self.space_list,
            self.n_points_a_list,
            self.n_points_b_list,
            atol=gs.atol * 1000,
        )

    def exp_belongs_test_data(self):
        return self._exp_belongs_test_data(
            self.metric_args_list,
            self.space_list,
            self.shape_list,
            self.n_tangent_vecs_list,
            belongs_atol=gs.atol * 10000,
        )

    def log_is_tangent_test_data(self):
        return self._log_is_tangent_test_data(
            self.metric_args_list,
            self.space_list,
            self.n_points_list,
            is_tangent_atol=gs.atol * 1000,
        )

    def geodesic_ivp_belongs_test_data(self):
        return self._geodesic_ivp_belongs_test_data(
            self.metric_args_list,
            self.space_list,
            self.shape_list,
            self.n_points_list,
            belongs_atol=gs.atol * 1000,
        )

    def geodesic_bvp_belongs_test_data(self):
        return self._geodesic_bvp_belongs_test_data(
            self.metric_args_list,
            self.space_list,
            self.n_points_list,
            belongs_atol=gs.atol * 100,
        )

    def exp_after_log_test_data(self):
        return self._exp_after_log_test_data(
            self.metric_args_list,
            self.space_list,
            self.n_tangent_vecs_list,
            rtol=gs.rtol * 1000,
            atol=gs.atol * 1000,
        )

    def log_after_exp_test_data(self):
        return self._log_after_exp_test_data(
            self.metric_args_list,
            self.space_list,
            self.shape_list,
            self.n_points_list,
            amplitude=30,
            rtol=gs.rtol * 10000,
            atol=gs.atol * 100000,
        )

    def exp_ladder_parallel_transport_test_data(self):
        return self._exp_ladder_parallel_transport_test_data(
            self.metric_args_list,
            self.space_list,
            self.shape_list,
            self.n_tangent_vecs_list,
            self.n_rungs_list,
            self.alpha_list,
            self.scheme_list,
        )

    def exp_geodesic_ivp_test_data(self):
        return self._exp_geodesic_ivp_test_data(
            self.metric_args_list,
            self.space_list,
            self.shape_list,
            self.n_tangent_vecs_list,
            self.n_points_list,
            rtol=gs.rtol * 10000,
            atol=gs.atol * 10000,
        )

    def parallel_transport_ivp_is_isometry_test_data(self):
        return self._parallel_transport_ivp_is_isometry_test_data(
            self.metric_args_list,
            self.space_list,
            self.shape_list,
            self.n_tangent_vecs_list,
            is_tangent_atol=gs.atol * 1000,
            atol=gs.atol * 100,
        )

    def parallel_transport_bvp_is_isometry_test_data(self):
        return self._parallel_transport_bvp_is_isometry_test_data(
            self.metric_args_list,
            self.space_list,
            self.shape_list,
            self.n_tangent_vecs_list,
            is_tangent_atol=gs.atol * 100,
            atol=gs.atol * 100,
        )

    def dist_is_symmetric_test_data(self):
        return self._dist_is_symmetric_test_data(
            self.metric_args_list,
            self.space_list,
            self.n_points_a_list,
            self.n_points_b_list,
        )

    def dist_is_positive_test_data(self):
        return self._dist_is_positive_test_data(
            self.metric_args_list,
            self.space_list,
            self.n_points_a_list,
            self.n_points_b_list,
        )

    def squared_dist_is_positive_test_data(self):
        return self._squared_dist_is_positive_test_data(
            self.metric_args_list,
            self.space_list,
            self.n_points_a_list,
            self.n_points_b_list,
        )

    def dist_is_norm_of_log_test_data(self):
        return self._dist_is_norm_of_log_test_data(
            self.metric_args_list,
            self.space_list,
            self.n_points_a_list,
            self.n_points_b_list,
        )

    def dist_point_to_itself_is_zero_test_data(self):
        return self._dist_point_to_itself_is_zero_test_data(
            self.metric_args_list, self.space_list, self.n_points_list)

    def inner_product_is_symmetric_test_data(self):
        return self._inner_product_is_symmetric_test_data(
            self.metric_args_list,
            self.space_list,
            self.shape_list,
            self.n_tangent_vecs_list,
        )

    def triangle_inequality_of_dist_test_data(self):
        return self._triangle_inequality_of_dist_test_data(
            self.metric_args_list, self.space_list, self.n_points_list)

    def l2_metric_inner_product_vectorization_test_data(self):
        smoke_data = [
            dict(
                l2_metric=self.l2_metric_s2,
                times=self.times,
                landmark_sets=self.n_landmark_sets,
                landmarks_a=self.landmark_set_a,
                landmarks_b=self.landmark_set_b,
                landmarks_c=self.landmark_set_c,
            )
        ]
        return self.generate_tests(smoke_data)

    def l2_metric_exp_vectorization_test_data(self):
        smoke_data = [
            dict(
                l2_metric=self.l2_metric_s2,
                times=self.times,
                landmarks_a=self.landmark_set_a,
                landmarks_b=self.landmark_set_b,
                landmarks_c=self.landmark_set_c,
            )
        ]
        return self.generate_tests(smoke_data)

    def l2_metric_log_vectorization_test_data(self):
        smoke_data = [
            dict(
                l2_metric=self.l2_metric_s2,
                times=self.times,
                landmarks_a=self.landmark_set_a,
                landmarks_b=self.landmark_set_b,
                landmarks_c=self.landmark_set_c,
            )
        ]
        return self.generate_tests(smoke_data)

    def l2_metric_geodesic_test_data(self):
        smoke_data = [
            dict(
                l2_metric=self.l2_metric_s2,
                times=self.times,
                n_sampling_points=self.n_sampling_points,
                landmarks_a=self.landmark_set_a,
                landmarks_b=self.landmark_set_b,
            )
        ]
        return self.generate_tests(smoke_data)
예제 #6
0
class TestLandmarks(geomstats.tests.TestCase):
    def setup_method(self):
        s2 = Hypersphere(dim=2)
        r3 = s2.embedding_space

        initial_point = [0.0, 0.0, 1.0]
        initial_tangent_vec_a = [1.0, 0.0, 0.0]
        initial_tangent_vec_b = [0.0, 1.0, 0.0]
        initial_tangent_vec_c = [-1.0, 0.0, 0.0]

        landmarks_a = s2.metric.geodesic(
            initial_point=initial_point,
            initial_tangent_vec=initial_tangent_vec_a)
        landmarks_b = s2.metric.geodesic(
            initial_point=initial_point,
            initial_tangent_vec=initial_tangent_vec_b)
        landmarks_c = s2.metric.geodesic(
            initial_point=initial_point,
            initial_tangent_vec=initial_tangent_vec_c)

        self.n_sampling_points = 10
        sampling_times = gs.linspace(0.0, 1.0, self.n_sampling_points)
        landmark_set_a = landmarks_a(sampling_times)
        landmark_set_b = landmarks_b(sampling_times)
        landmark_set_c = landmarks_c(sampling_times)

        self.n_landmark_sets = 5
        self.times = gs.linspace(0.0, 1.0, self.n_landmark_sets)
        gs.random.seed(1234)
        self.space_landmarks_in_euclidean_3d = Landmarks(
            ambient_manifold=r3, k_landmarks=self.n_sampling_points)
        self.space_landmarks_in_sphere_2d = Landmarks(
            ambient_manifold=s2, k_landmarks=self.n_sampling_points)
        self.l2_metric_s2 = self.space_landmarks_in_sphere_2d.metric
        self.l2_metric_r3 = self.space_landmarks_in_euclidean_3d.metric
        self.landmarks_a = landmark_set_a
        self.landmarks_b = landmark_set_b
        self.landmarks_c = landmark_set_c

    def test_belongs(self):
        result = self.space_landmarks_in_sphere_2d.belongs(self.landmarks_a)
        expected = True
        self.assertAllClose(result, expected)

    def test_belongs_vectorization(self):
        landmark_sets = gs.array([self.landmarks_a, self.landmarks_b])
        result = self.space_landmarks_in_sphere_2d.belongs(landmark_sets)
        expected = gs.array([True, True])
        self.assertAllClose(result, expected)

    def test_l2_metric_log_and_squared_norm_and_dist(self):
        """Test that squared norm of logarithm is squared dist."""
        tangent_vec = self.l2_metric_s2.log(point=self.landmarks_b,
                                            base_point=self.landmarks_a)
        log_ab = tangent_vec
        result = self.l2_metric_s2.squared_norm(vector=log_ab,
                                                base_point=self.landmarks_a)
        expected = self.l2_metric_s2.dist(self.landmarks_a,
                                          self.landmarks_b)**2

        self.assertAllClose(result, expected)

    def test_l2_metric_log_and_exp(self):
        """Test that exp and log are inverse maps."""
        tangent_vec = self.l2_metric_s2.log(point=self.landmarks_b,
                                            base_point=self.landmarks_a)
        result = self.l2_metric_s2.exp(tangent_vec=tangent_vec,
                                       base_point=self.landmarks_a)
        expected = self.landmarks_b

        self.assertAllClose(result, expected)

    @geomstats.tests.np_autograd_and_tf_only
    def test_l2_metric_inner_product_vectorization(self):
        """Test the vectorization inner_product."""
        n_samples = self.n_landmark_sets
        landmarks_ab = self.l2_metric_s2.geodesic(self.landmarks_a,
                                                  self.landmarks_b)
        landmarks_bc = self.l2_metric_s2.geodesic(self.landmarks_b,
                                                  self.landmarks_c)
        landmarks_ab = landmarks_ab(self.times)
        landmarks_bc = landmarks_bc(self.times)

        tangent_vecs = self.l2_metric_s2.log(point=landmarks_bc,
                                             base_point=landmarks_ab)

        result = self.l2_metric_s2.inner_product(tangent_vecs, tangent_vecs,
                                                 landmarks_ab)

        self.assertAllClose(gs.shape(result), (n_samples, ))

    @geomstats.tests.np_autograd_and_tf_only
    def test_l2_metric_dist_vectorization(self):
        """Test the vectorization of dist."""
        n_samples = self.n_landmark_sets
        landmarks_ab = self.l2_metric_s2.geodesic(self.landmarks_a,
                                                  self.landmarks_b)
        landmarks_bc = self.l2_metric_s2.geodesic(self.landmarks_b,
                                                  self.landmarks_c)
        landmarks_ab = landmarks_ab(self.times)
        landmarks_bc = landmarks_bc(self.times)

        result = self.l2_metric_s2.dist(landmarks_ab, landmarks_bc)
        self.assertAllClose(gs.shape(result), (n_samples, ))

    @geomstats.tests.np_autograd_and_tf_only
    def test_l2_metric_exp_vectorization(self):
        """Test the vectorization of exp."""
        landmarks_ab = self.l2_metric_s2.geodesic(self.landmarks_a,
                                                  self.landmarks_b)
        landmarks_bc = self.l2_metric_s2.geodesic(self.landmarks_b,
                                                  self.landmarks_c)
        landmarks_ab = landmarks_ab(self.times)
        landmarks_bc = landmarks_bc(self.times)

        tangent_vecs = self.l2_metric_s2.log(point=landmarks_bc,
                                             base_point=landmarks_ab)

        result = self.l2_metric_s2.exp(tangent_vec=tangent_vecs,
                                       base_point=landmarks_ab)
        self.assertAllClose(gs.shape(result), gs.shape(landmarks_ab))

    @geomstats.tests.np_autograd_and_tf_only
    def test_l2_metric_log_vectorization(self):
        """Test the vectorization of log."""
        landmarks_ab = self.l2_metric_s2.geodesic(self.landmarks_a,
                                                  self.landmarks_b)
        landmarks_bc = self.l2_metric_s2.geodesic(self.landmarks_b,
                                                  self.landmarks_c)
        landmarks_ab = landmarks_ab(self.times)
        landmarks_bc = landmarks_bc(self.times)

        tangent_vecs = self.l2_metric_s2.log(point=landmarks_bc,
                                             base_point=landmarks_ab)

        result = tangent_vecs
        self.assertAllClose(gs.shape(result), gs.shape(landmarks_ab))

    @geomstats.tests.np_autograd_and_tf_only
    def test_l2_metric_geodesic(self):
        """Test the geodesic method of L2Metric."""
        landmarks_ab = self.l2_metric_s2.geodesic(self.landmarks_a,
                                                  self.landmarks_b)
        landmarks_ab = landmarks_ab(self.times)

        result = landmarks_ab
        expected = []
        for k in range(self.n_sampling_points):
            geod = self.l2_metric_s2.ambient_metric.geodesic(
                initial_point=self.landmarks_a[k, :],
                end_point=self.landmarks_b[k, :])
            expected.append(geod(self.times))
        expected = gs.stack(expected, axis=1)

        self.assertAllClose(result, expected)