def test_distance_ball_extrinsic_from_ball(self, dim, x_ball, y_ball):

        ball_manifold = PoincareBall(dim)
        space = Hyperboloid(dim)
        x_extr = ball_manifold.to_coordinates(x_ball,
                                              to_coords_type="extrinsic")
        y_extr = ball_manifold.to_coordinates(y_ball,
                                              to_coords_type="extrinsic")
        dst_ball = ball_manifold.metric.dist(x_ball, y_ball)
        dst_extr = space.metric.dist(x_extr, y_extr)
        self.assertAllClose(dst_ball, dst_extr)
Exemple #2
0
class TestPoincareBallMethods(geomstats.tests.TestCase):
    def setUp(self):
        self.manifold = PoincareBall(2)
        self.metric = self.manifold.metric

        self.hyperboloid_manifold = Hyperboloid(2)
        self.hyperboloid_metric = self.hyperboloid_manifold.metric

    def test_squared_dist(self):
        point_a = gs.array([-0.3, 0.7])
        point_b = gs.array([0.2, 0.5])

        distance_a_b = self.metric.dist(point_a, point_b)
        squared_distance = self.metric.squared_dist(point_a, point_b)

        # TODO(nmiolane):
        # Remove this line when poincare ball is properly vectorized
        squared_distance = gs.to_ndarray(squared_distance, to_ndim=2, axis=1)

        self.assertAllClose(distance_a_b**2, squared_distance, atol=1e-8)

    @geomstats.tests.np_and_pytorch_only
    def test_coordinates(self):
        point_a = gs.array([-0.3, 0.7])
        point_b = gs.array([0.2, 0.5])

        point_a_h =\
            self.manifold.to_coordinates(point_a, 'extrinsic')
        point_b_h =\
            self.manifold.to_coordinates(point_b, 'extrinsic')

        dist_in_ball =\
            self.metric.dist(point_a, point_b)
        dist_in_hype =\
            self.hyperboloid_metric.dist(point_a_h, point_b_h)

        # TODO(ninamiolane): Remove this to_ndarray when poincare_ball
        # is properly vectorized
        dist_in_hype = gs.to_ndarray(dist_in_hype, to_ndim=2, axis=1)

        self.assertAllClose(dist_in_ball, dist_in_hype, atol=1e-8)

    def test_dist_poincare(self):

        point_a = gs.array([0.5, 0.5])
        point_b = gs.array([0.5, -0.5])

        dist_a_b =\
            self.manifold.metric.dist(point_a, point_b)

        result = dist_a_b
        expected = gs.array([[2.887270927429199]])

        self.assertAllClose(result, expected)

    def test_dist_vectorization(self):
        point_a = gs.array([0.2, 0.5])
        point_b = gs.array([[0.3, -0.5], [0.2, 0.2]])

        dist_a_b =\
            self.manifold.metric.dist(point_a, point_b)

        result_vect = dist_a_b
        result =\
            [self.manifold.metric.dist(point_a, point_b[i])
             for i in range(len(point_b))]
        result = gs.concatenate(result, axis=0)
        self.assertAllClose(result_vect, result)

    def test_mobius_vectorization(self):
        point_a = gs.array([0.5, 0.5])
        point_b = gs.array([[0.5, -0.3], [0.3, 0.4]])

        dist_a_b =\
            self.manifold.metric.mobius_add(point_a, point_b)

        result_vect = dist_a_b
        result =\
            [self.manifold.metric.mobius_add(point_a, point_b[i])
             for i in range(len(point_b))]
        result = gs.concatenate(result, axis=0)
        self.assertAllClose(result_vect, result)

        dist_a_b =\
            self.manifold.metric.mobius_add(point_b, point_a)

        result_vect = dist_a_b
        result =\
            [self.manifold.metric.mobius_add(point_b[i], point_a)
             for i in range(len(point_b))]
        result = gs.concatenate(result, axis=0)
        self.assertAllClose(result_vect, result)

    def test_log_vectorization(self):
        point_a = gs.array([0.5, 0.5])
        point_b = gs.array([[0.5, -0.5], [0.4, 0.4]])

        dist_a_b =\
            self.manifold.metric.log(point_a, point_b)

        result_vect = dist_a_b
        result =\
            [self.manifold.metric.log(point_a, point_b[i])
             for i in range(len(point_b))]
        result = gs.concatenate(result, axis=0)
        self.assertAllClose(result_vect, result)

        dist_a_b =\
            self.manifold.metric.log(point_b, point_a)

        result_vect = dist_a_b
        result =\
            [self.manifold.metric.log(point_b[i], point_a)
             for i in range(len(point_b))]
        result = gs.concatenate(result, axis=0)
        self.assertAllClose(result_vect, result)

    def test_exp_vectorization(self):
        point_a = gs.array([0.5, 0.5])
        point_b = gs.array([[0.5, -0.5], [0.4, 0.4]])

        dist_a_b =\
            self.manifold.metric.exp(point_a, point_b)

        result_vect = dist_a_b
        result =\
            [self.manifold.metric.exp(point_a, point_b[i])
             for i in range(len(point_b))]
        result = gs.concatenate(result, axis=0)
        self.assertAllClose(result_vect, result)

        dist_a_b =\
            self.manifold.metric.exp(point_b, point_a)

        result_vect = dist_a_b
        result =\
            [self.manifold.metric.exp(point_b[i], point_a)
             for i in range(len(point_b))]
        result = gs.concatenate(result, axis=0)
        self.assertAllClose(result_vect, result)

    def test_log_poincare(self):

        point = gs.array([[0.3, 0.5]])
        base_point = gs.array([[0.3, 0.3]])

        result = self.manifold.metric.log(point, base_point)
        expected = gs.array([[-0.01733576, 0.21958634]])

        self.manifold.metric.coords_type = 'extrinsic'
        self.assertAllClose(result, expected)

    def test_belong_true_poincare(self):
        point = gs.array([[0.3, 0.5]])
        belong = self.manifold.belongs(point)
        self.assertTrue(belong)

    def test_belong_false_poincare(self):
        point = gs.array([[1.2, 0.5]])
        belong = self.manifold.belongs(point)
        self.assertFalse(belong)

    def test_exp_poincare(self):

        point = gs.array([[0.3, 0.5]])
        base_point = gs.array([[0.3, 0.3]])

        tangent_vec = self.manifold.metric.log(point, base_point)
        result = self.manifold.metric.exp(tangent_vec, base_point)

        self.manifold.metric.coords_type = 'extrinsic'
        self.assertAllClose(result, point)

    def test_ball_retraction(self):
        x = gs.array([[0.5, 0.6], [0.2, -0.1], [0.2, -0.4]])
        y = gs.array([[0.3, 0.5], [0.3, -0.6], [0.3, -0.3]])

        ball_metric = self.manifold.metric
        tangent_vec = ball_metric.log(y, x)
        ball_metric.retraction(tangent_vec, x)
Exemple #3
0
class TestPoincareBall(geomstats.tests.TestCase):
    def setUp(self):
        self.manifold = PoincareBall(2)
        self.metric = self.manifold.metric

        self.hyperboloid_manifold = Hyperboloid(2)
        self.hyperboloid_metric = self.hyperboloid_manifold.metric

    def test_squared_dist(self):
        point_a = gs.array([-0.3, 0.7])
        point_b = gs.array([0.2, 0.5])

        distance_a_b = self.metric.dist(point_a, point_b)
        squared_distance = self.metric.squared_dist(point_a, point_b)

        self.assertAllClose(distance_a_b**2, squared_distance, atol=1e-8)

    @geomstats.tests.np_and_pytorch_only
    def test_coordinates(self):
        point_a = gs.array([-0.3, 0.7])
        point_b = gs.array([0.2, 0.5])

        point_a_h =\
            self.manifold.to_coordinates(point_a, 'extrinsic')
        point_b_h =\
            self.manifold.to_coordinates(point_b, 'extrinsic')

        dist_in_ball =\
            self.metric.dist(point_a, point_b)
        dist_in_hype =\
            self.hyperboloid_metric.dist(point_a_h, point_b_h)

        self.assertAllClose(dist_in_ball, dist_in_hype, atol=1e-8)

    def test_dist_poincare(self):

        point_a = gs.array([0.5, 0.5])
        point_b = gs.array([0.5, -0.5])

        dist_a_b =\
            self.manifold.metric.dist(point_a, point_b)

        result = dist_a_b
        expected = 2.887270927429199

        self.assertAllClose(result, expected)

    def test_dist_vectorization(self):
        point_a = gs.array([0.2, 0.5])
        point_b = gs.array([[0.3, -0.5], [0.2, 0.2]])

        dist_a_b =\
            self.manifold.metric.dist(point_a, point_b)

        result_vect = dist_a_b
        result =\
            [self.manifold.metric.dist(point_a, point_b[i])
             for i in range(len(point_b))]
        result = gs.stack(result, axis=0)
        self.assertAllClose(result_vect, result)

    def test_dist_broadcast(self):

        point_a = gs.array([[0.2, 0.5], [0.3, 0.1]])
        point_b = gs.array([[0.3, -0.5], [0.2, 0.2]])
        point_c = gs.array([[0.2, 0.3], [0.5, 0.5], [-0.4, 0.1]])
        point_d = gs.array([0.1, 0.2, 0.3])

        dist_a_b =\
            self.manifold.metric.dist_broadcast(point_a, point_b)

        dist_b_c = gs.flatten(
            self.manifold.metric.dist_broadcast(point_b, point_c))

        result_vect = gs.concatenate((dist_a_b, dist_b_c), axis=0)

        result_a_b =\
            [self.manifold.metric.dist_broadcast(point_a[i], point_b[i])
             for i in range(len(point_b))]

        result_b_c = \
            [self.manifold.metric.dist_broadcast(point_b[i], point_c[j])
             for i in range(len(point_b))
             for j in range(len(point_c))
             ]
        result = result_a_b + result_b_c
        result = gs.stack(result, axis=0)

        self.assertAllClose(result_vect, result)
        with self.assertRaises(ValueError):
            self.manifold.metric.dist_broadcast(point_a, point_d)

    @geomstats.tests.np_and_pytorch_only
    def test_dist_pairwise(self):

        point = gs.array([[0.1, 0.2], [0.3, 0.4], [0.5, 0.5]])

        result = self.manifold.metric.dist_pairwise(point)

        expected = gs.array([[0., 0.65821943, 1.34682524],
                             [0.65821943, 0., 0.71497076],
                             [1.34682524, 0.71497076, 0.]])

        self.assertAllClose(result, expected, rtol=1e-3)

    def test_mobius_vectorization(self):
        point_a = gs.array([0.5, 0.5])
        point_b = gs.array([[0.5, -0.3], [0.3, 0.4]])

        dist_a_b =\
            self.manifold.metric.mobius_add(point_a, point_b)

        result_vect = dist_a_b
        result =\
            [self.manifold.metric.mobius_add(point_a, point_b[i])
             for i in range(len(point_b))]
        result = gs.stack(result, axis=0)
        self.assertAllClose(result_vect, result)

        dist_a_b =\
            self.manifold.metric.mobius_add(point_b, point_a)

        result_vect = dist_a_b
        result =\
            [self.manifold.metric.mobius_add(point_b[i], point_a)
             for i in range(len(point_b))]
        result = gs.stack(result, axis=0)
        self.assertAllClose(result_vect, result)

    def test_log_vectorization(self):
        point_a = gs.array([0.5, 0.5])
        point_b = gs.array([[0.5, -0.5], [0.4, 0.4]])

        dist_a_b =\
            self.manifold.metric.log(point_a, point_b)

        result_vect = dist_a_b
        result =\
            [self.manifold.metric.log(point_a, point_b[i])
             for i in range(len(point_b))]
        result = gs.stack(result, axis=0)
        self.assertAllClose(result_vect, result)

        dist_a_b =\
            self.manifold.metric.log(point_b, point_a)

        result_vect = dist_a_b
        result =\
            [self.manifold.metric.log(point_b[i], point_a)
             for i in range(len(point_b))]
        result = gs.stack(result, axis=0)
        self.assertAllClose(result_vect, result)

    def test_exp_vectorization(self):
        point_a = gs.array([0.5, 0.5])
        point_b = gs.array([[0.0, 0.0], [0.5, -0.5], [0.4, 0.4]])

        dist_a_b =\
            self.manifold.metric.exp(point_a, point_b)

        result_vect = dist_a_b
        result =\
            [self.manifold.metric.exp(point_a, point_b[i])
             for i in range(len(point_b))]
        result = gs.stack(result, axis=0)
        self.assertAllClose(result_vect, result)

        dist_a_b =\
            self.manifold.metric.exp(point_b, point_a)

        result_vect = dist_a_b
        result =\
            [self.manifold.metric.exp(point_b[i], point_a)
             for i in range(len(point_b))]
        result = gs.stack(result, axis=0)
        self.assertAllClose(result_vect, result)

    def test_log_poincare(self):

        point = gs.array([0.3, 0.5])
        base_point = gs.array([0.3, 0.3])

        result = self.manifold.metric.log(point, base_point)
        expected = gs.array([-0.01733576, 0.21958634])

        self.manifold.metric.coords_type = 'extrinsic'
        self.assertAllClose(result, expected)

    def test_belong_true_poincare(self):
        point = gs.array([0.3, 0.5])
        belong = self.manifold.belongs(point)
        self.assertTrue(belong)

    def test_belong_false_poincare(self):
        point = gs.array([1.2, 0.5])
        belong = self.manifold.belongs(point)
        self.assertFalse(belong)

    def test_projection(self):
        point = gs.array([1.2, 0.5])
        projected_point = self.manifold.projection(point)
        self.assertTrue(gs.sum(projected_point * projected_point) < 1.)

    def test_exp_poincare(self):

        point = gs.array([0.3, 0.5])
        base_point = gs.array([0.3, 0.3])

        tangent_vec = self.manifold.metric.log(point, base_point)
        result = self.manifold.metric.exp(tangent_vec, base_point)

        self.manifold.metric.coords_type = 'extrinsic'
        self.assertAllClose(result, point)

    def test_ball_retraction(self):
        x = gs.array([[0.5, 0.6], [0.2, -0.1], [0.2, -0.4]])
        y = gs.array([[0.3, 0.5], [0.3, -0.6], [0.3, -0.3]])

        ball_metric = self.manifold.metric
        tangent_vec = ball_metric.log(y, x)
        ball_metric.retraction(tangent_vec, x)
Exemple #4
0
class TestHyperbolicCoords(geomstats.tests.TestCase):
    def setUp(self):
        gs.random.seed(1234)
        self.dimension = 2

        self.extrinsic_manifold = Hyperboloid(dim=self.dimension)
        self.extrinsic_metric = self.extrinsic_manifold.metric

        self.ball_manifold = PoincareBall(dim=self.dimension)
        self.ball_metric = self.ball_manifold.metric

        self.intrinsic_manifold = Hyperboloid(dim=self.dimension,
                                              coords_type="intrinsic")
        self.intrinsic_metric = self.intrinsic_manifold.metric

        self.n_samples = 10

    def test_extrinsic_ball_extrinsic(self):
        x_in = gs.array([0.5, 7])
        x = self.intrinsic_manifold.to_coordinates(x_in,
                                                   to_coords_type="extrinsic")
        x_b = self.extrinsic_manifold.to_coordinates(x, to_coords_type="ball")
        x2 = self.ball_manifold.to_coordinates(x_b, to_coords_type="extrinsic")
        self.assertAllClose(x, x2)

    def test_belongs_intrinsic(self):
        x_in = gs.array([0.5, 7])
        is_in = self.intrinsic_manifold.belongs(x_in)
        self.assertTrue(is_in)

    def test_belongs_extrinsic(self):
        x_true = self.intrinsic_manifold.to_coordinates(
            gs.array([0.5, 7]), "extrinsic")
        x_false = gs.array([0.5, 7, 3.0])
        is_in = self.extrinsic_manifold.belongs(x_true)
        self.assertTrue(is_in)
        is_out = self.extrinsic_manifold.belongs(x_false)
        self.assertFalse(is_out)

    def test_belongs_ball(self):
        x_true = gs.array([0.5, 0.5])
        x_false = gs.array([0.8, 0.8])
        is_in = self.ball_manifold.belongs(x_true)
        self.assertTrue(is_in)
        is_out = self.ball_manifold.belongs(x_false)
        self.assertFalse(is_out)

    def test_extrinsic_half_plane_extrinsic(self):
        x_in = gs.array([0.5, 7], dtype=gs.float64)
        x = self.intrinsic_manifold.to_coordinates(x_in,
                                                   to_coords_type="extrinsic")
        x_up = self.extrinsic_manifold.to_coordinates(
            x, to_coords_type="half-space")

        x2 = Hyperbolic.change_coordinates_system(x_up, "half-space",
                                                  "extrinsic")
        self.assertAllClose(x, x2)

    def test_intrinsic_extrinsic_intrinsic(self):
        x_intr = gs.array([0.5, 7])
        x_extr = self.intrinsic_manifold.to_coordinates(
            x_intr, to_coords_type="extrinsic")
        x_intr2 = self.extrinsic_manifold.to_coordinates(
            x_extr, to_coords_type="intrinsic")
        self.assertAllClose(x_intr, x_intr2)

    def test_ball_extrinsic_ball(self):
        x = gs.array([0.5, 0.2])
        x_e = self.ball_manifold.to_coordinates(x, to_coords_type="extrinsic")
        x2 = self.extrinsic_manifold.to_coordinates(x_e, to_coords_type="ball")
        self.assertAllClose(x, x2)

    def test_distance_ball_extrinsic_from_ball(self):
        x_ball = gs.array([0.7, 0.2])
        y_ball = gs.array([0.2, 0.2])
        x_extr = self.ball_manifold.to_coordinates(x_ball,
                                                   to_coords_type="extrinsic")
        y_extr = self.ball_manifold.to_coordinates(y_ball,
                                                   to_coords_type="extrinsic")
        dst_ball = self.ball_metric.dist(x_ball, y_ball)
        dst_extr = self.extrinsic_metric.dist(x_extr, y_extr)

        self.assertAllClose(dst_ball, dst_extr)

    def test_distance_ball_extrinsic_from_extr(self):
        x_int = gs.array([10, 0.2])
        y_int = gs.array([1, 6.0])
        x_extr = self.intrinsic_manifold.to_coordinates(
            x_int, to_coords_type="extrinsic")
        y_extr = self.intrinsic_manifold.to_coordinates(
            y_int, to_coords_type="extrinsic")
        x_ball = self.extrinsic_manifold.to_coordinates(x_extr,
                                                        to_coords_type="ball")
        y_ball = self.extrinsic_manifold.to_coordinates(y_extr,
                                                        to_coords_type="ball")
        dst_ball = self.ball_metric.dist(x_ball, y_ball)
        dst_extr = self.extrinsic_metric.dist(x_extr, y_extr)

        self.assertAllClose(dst_ball, dst_extr)

    def test_distance_ball_extrinsic_from_extr_4_dim(self):
        x_int = gs.array([10, 0.2, 3, 4])
        y_int = gs.array([1, 6, 2.0, 1])

        ball_manifold = PoincareBall(4)
        extrinsic_manifold = Hyperboloid(4)

        ball_metric = ball_manifold.metric
        extrinsic_metric = extrinsic_manifold.metric

        x_extr = extrinsic_manifold.from_coordinates(
            x_int, from_coords_type="intrinsic")
        y_extr = extrinsic_manifold.from_coordinates(
            y_int, from_coords_type="intrinsic")
        x_ball = extrinsic_manifold.to_coordinates(x_extr,
                                                   to_coords_type="ball")
        y_ball = extrinsic_manifold.to_coordinates(y_extr,
                                                   to_coords_type="ball")
        dst_ball = ball_metric.dist(x_ball, y_ball)
        dst_extr = extrinsic_metric.dist(x_extr, y_extr)

        self.assertAllClose(dst_ball, dst_extr)

    def test_log_exp_ball_extrinsic_from_extr(self):
        """Compare log exp in different parameterizations."""
        x_int = gs.array([4.0, 0.2])
        y_int = gs.array([3.0, 3])
        x_extr = self.intrinsic_manifold.to_coordinates(
            x_int, to_coords_type="extrinsic")
        y_extr = self.intrinsic_manifold.to_coordinates(
            y_int, to_coords_type="extrinsic")
        x_ball = self.extrinsic_manifold.to_coordinates(x_extr,
                                                        to_coords_type="ball")
        y_ball = self.extrinsic_manifold.to_coordinates(y_extr,
                                                        to_coords_type="ball")

        x_ball_log_exp = self.ball_metric.exp(
            self.ball_metric.log(y_ball, x_ball), x_ball)

        x_extr_a = self.extrinsic_metric.exp(
            self.extrinsic_metric.log(y_extr, x_extr), x_extr)
        x_extr_b = self.extrinsic_manifold.from_coordinates(
            x_ball_log_exp, from_coords_type="ball")
        self.assertAllClose(x_extr_a, x_extr_b, atol=3e-4)

    def test_log_exp_ball(self):
        x = gs.array([0.1, 0.2])
        y = gs.array([0.2, 0.5])

        log = self.ball_metric.log(point=y, base_point=x)
        exp = self.ball_metric.exp(tangent_vec=log, base_point=x)
        self.assertAllClose(exp, y)

    def test_log_exp_ball_vectorization(self):
        x = gs.array([0.1, 0.2])
        y = gs.array([[0.2, 0.5], [0.1, 0.7]])

        log = self.ball_metric.log(y, x)
        exp = self.ball_metric.exp(log, x)
        self.assertAllClose(exp, y)

    def test_log_exp_ball_null_tangent(self):
        x = gs.array([[0.1, 0.2], [0.1, 0.2]])
        tangent_vec = gs.array([[0.0, 0.0], [0.0, 0.0]])
        exp = self.ball_metric.exp(tangent_vec, x)
        self.assertAllClose(exp, x)
class TestHyperbolicMethods(geomstats.tests.TestCase):
    def setUp(self):
        gs.random.seed(1234)
        self.dimension = 2

        self.extrinsic_manifold = Hyperboloid(
            dim=self.dimension)
        self.extrinsic_metric = self.extrinsic_manifold.metric

        self.ball_manifold = PoincareBall(
            dim=self.dimension)
        self.ball_metric = self.ball_manifold.metric

        self.intrinsic_manifold = Hyperboloid(
            dim=self.dimension, coords_type='intrinsic')
        self.intrinsic_metric = self.intrinsic_manifold.metric

        self.n_samples = 10

    @geomstats.tests.np_and_pytorch_only
    def test_extrinsic_ball_extrinsic(self):
        x_in = gs.array([[0.5, 7]])
        x = self.intrinsic_manifold.to_coordinates(
            x_in, to_coords_type='extrinsic')
        x_b = self.extrinsic_manifold.to_coordinates(x, to_coords_type='ball')
        x2 = self.ball_manifold.to_coordinates(x_b, to_coords_type='extrinsic')
        self.assertAllClose(x, x2, atol=1e-8)

    @geomstats.tests.np_and_pytorch_only
    def test_belongs_intrinsic(self):
        x_in = gs.array([[0.5, 7]])
        is_in = self.intrinsic_manifold.belongs(x_in)
        self.assertTrue(is_in)

    @geomstats.tests.np_and_pytorch_only
    def test_belongs_extrinsic(self):
        x_true = self.intrinsic_manifold.to_coordinates(gs.array([[0.5, 7]]),
                                                        'extrinsic')
        x_false = gs.array([[0.5, 7, 3.]])
        is_in = self.extrinsic_manifold.belongs(x_true)
        self.assertTrue(is_in)
        is_out = self.extrinsic_manifold.belongs(x_false)
        self.assertFalse(is_out)

    @geomstats.tests.np_and_pytorch_only
    def test_belongs_ball(self):
        x_true = gs.array([[0.5, 0.5]])
        x_false = gs.array([[0.8, 0.8]])
        is_in = self.ball_manifold.belongs(x_true)
        self.assertTrue(is_in)
        is_out = self.ball_manifold.belongs(x_false)
        self.assertFalse(is_out)

    @geomstats.tests.np_and_pytorch_only
    def test_extrinsic_half_plane_extrinsic(self):
        x_in = gs.array([[0.5, 7]])
        x = self.intrinsic_manifold.to_coordinates(
            x_in, to_coords_type='extrinsic')
        x_up = self.extrinsic_manifold.to_coordinates(
            x, to_coords_type='half-plane')

        x2 = Hyperbolic.change_coordinates_system(x_up,
                                                  "half-plane",
                                                  "extrinsic")
        self.assertAllClose(x, x2, atol=1e-8)

    @geomstats.tests.np_and_pytorch_only
    def test_intrinsic_extrinsic_intrinsic(self):
        x_intr = gs.array([[0.5, 7]])
        x_extr = self.intrinsic_manifold.to_coordinates(
            x_intr, to_coords_type='extrinsic')
        x_intr2 = self.extrinsic_manifold.to_coordinates(
            x_extr, to_coords_type='intrinsic')
        self.assertAllClose(x_intr, x_intr2, atol=1e-8)

    @geomstats.tests.np_and_pytorch_only
    def test_ball_extrinsic_ball(self):
        x = gs.array([[0.5, 0.2]])
        x_e = self.ball_manifold.to_coordinates(x, to_coords_type='extrinsic')
        x2 = self.extrinsic_manifold.to_coordinates(x_e, to_coords_type='ball')
        self.assertAllClose(x, x2, atol=1e-10)

    @geomstats.tests.np_and_pytorch_only
    def test_distance_ball_extrinsic_from_ball(self):
        x_ball = gs.array([[0.7, 0.2]])
        y_ball = gs.array([[0.2, 0.2]])
        x_extr = self.ball_manifold.to_coordinates(
            x_ball, to_coords_type='extrinsic')
        y_extr = self.ball_manifold.to_coordinates(
            y_ball, to_coords_type='extrinsic')
        dst_ball = self.ball_metric.dist(x_ball, y_ball)
        dst_extr = self.extrinsic_metric.dist(x_extr, y_extr)

        # TODO(nmiolane): Remove this when ball is properly vectorized
        dst_extr = gs.to_ndarray(dst_extr, to_ndim=2, axis=1)

        self.assertAllClose(dst_ball, dst_extr)

    @geomstats.tests.np_and_pytorch_only
    def test_distance_ball_extrinsic_from_extr(self):
        x_int = gs.array([[10, 0.2]])
        y_int = gs.array([[1, 6.]])
        x_extr = self.intrinsic_manifold.to_coordinates(
            x_int, to_coords_type='extrinsic')
        y_extr = self.intrinsic_manifold.to_coordinates(
            y_int, to_coords_type='extrinsic')
        x_ball = self.extrinsic_manifold.to_coordinates(
            x_extr, to_coords_type='ball')
        y_ball = self.extrinsic_manifold.to_coordinates(
            y_extr, to_coords_type='ball')
        dst_ball = self.ball_metric.dist(x_ball, y_ball)
        dst_extr = self.extrinsic_metric.dist(x_extr, y_extr)
        # TODO(nmiolane): Remove this when ball is properly vectorized
        dst_extr = gs.to_ndarray(dst_extr, to_ndim=2, axis=1)

        self.assertAllClose(dst_ball, dst_extr)

    @geomstats.tests.np_and_pytorch_only
    def test_distance_ball_extrinsic_from_extr_4_dim(self):
        x_int = gs.array([[10, 0.2, 3, 4]])
        y_int = gs.array([[1, 6, 2., 1]])

        ball_manifold = PoincareBall(4)
        extrinsic_manifold = Hyperboloid(4)

        ball_metric = ball_manifold.metric
        extrinsic_metric = extrinsic_manifold.metric

        x_extr = extrinsic_manifold.from_coordinates(
            x_int, from_coords_type='intrinsic')
        y_extr = extrinsic_manifold.from_coordinates(
            y_int, from_coords_type='intrinsic')
        x_ball = extrinsic_manifold.to_coordinates(
            x_extr, to_coords_type='ball')
        y_ball = extrinsic_manifold.to_coordinates(
            y_extr, to_coords_type='ball')
        dst_ball = ball_metric.dist(x_ball, y_ball)
        dst_extr = extrinsic_metric.dist(x_extr, y_extr)
        # TODO(nmiolane): Remove this when ball is properly vectorized
        dst_extr = gs.to_ndarray(dst_extr, to_ndim=2, axis=1)

        self.assertAllClose(dst_ball, dst_extr)

    @geomstats.tests.np_and_pytorch_only
    def test_log_exp_ball_extrinsic_from_extr(self):
        """Compare log exp in different parameterizations."""
        # TODO(Hazaatiti): Fix this test
        # x_int = gs.array([[4., 0.2]])
        # y_int = gs.array([[3., 3]])
        # x_extr = self.intrinsic_manifold.to_coordinates(
        #     x_int, to_point_type='extrinsic')
        # y_extr = self.intrinsic_manifold.to_coordinates(
        #     y_int, to_point_type='extrinsic')
        # x_ball = self.extrinsic_manifold.to_coordinates(
        #     x_extr, to_point_type='ball')
        # y_ball = self.extrinsic_manifold.to_coordinates(
        #     y_extr, to_point_type='ball')

        # x_ball_log_exp = self.ball_metric.exp(
        #     self.ball_metric.log(y_ball, x_ball), x_ball)

        # x_extr_a = self.extrinsic_metric.exp(
        #     self.extrinsic_metric.log(y_extr, x_extr), x_extr)
        # x_extr_b = self.extrinsic_manifold.from_coordinates(
        #     x_ball_log_exp, from_point_type='ball')
        # self.assertAllClose(x_extr_a, x_extr_b, atol=1e-4)

    @geomstats.tests.np_only
    def test_log_exp_ball(self):
        x = gs.array([[0.1, 0.2]])
        y = gs.array([[0.2, 0.5]])

        log = self.ball_metric.log(point=y, base_point=x)
        exp = self.ball_metric.exp(tangent_vec=log, base_point=x)
        self.assertAllClose(exp, y, atol=1e-1)

    @geomstats.tests.np_only
    def test_log_exp_ball_vectorization(self):
        x = gs.array([[0.1, 0.2]])
        y = gs.array([[0.2, 0.5], [0.1, 0.7]])

        log = self.ball_metric.log(y, x)
        exp = self.ball_metric.exp(log, x)
        self.assertAllClose(exp, y, atol=1e-1)

    @geomstats.tests.np_only
    def test_log_exp_ball_null_tangent(self):
        x = gs.array([[0.1, 0.2], [0.1, 0.2]])
        tangent_vec = gs.array([[0.0, 0.0], [0.0, 0.0]])
        exp = self.ball_metric.exp(tangent_vec, x)
        self.assertAllClose(exp, x, atol=1e-10)
Exemple #6
0
class TestPoincareBall(geomstats.tests.TestCase):
    def setUp(self):
        self.manifold = PoincareBall(2)
        self.metric = self.manifold.metric

        self.hyperboloid_manifold = Hyperboloid(2)
        self.hyperboloid_metric = self.hyperboloid_manifold.metric

    def test_squared_dist(self):
        point_a = gs.array([-0.3, 0.7])
        point_b = gs.array([0.2, 0.5])

        distance_a_b = self.metric.dist(point_a, point_b)
        squared_distance = self.metric.squared_dist(point_a, point_b)

        self.assertAllClose(distance_a_b ** 2, squared_distance)

    def test_coordinates(self):
        point_a = gs.array([-0.3, 0.7])
        point_b = gs.array([0.2, 0.5])

        point_a_h = self.manifold.to_coordinates(point_a, "extrinsic")
        point_b_h = self.manifold.to_coordinates(point_b, "extrinsic")

        dist_in_ball = self.metric.dist(point_a, point_b)
        dist_in_hype = self.hyperboloid_metric.dist(point_a_h, point_b_h)

        self.assertAllClose(dist_in_ball, dist_in_hype)

    def test_dist_poincare(self):

        point_a = gs.array([0.5, 0.5])
        point_b = gs.array([0.5, -0.5])

        dist_a_b = self.manifold.metric.dist(point_a, point_b)

        result = dist_a_b
        expected = 2.887270927429199

        self.assertAllClose(result, expected)

    def test_dist_vectorization(self):
        point_a = gs.array([0.2, 0.5])
        point_b = gs.array([[0.3, -0.5], [0.2, 0.2]])

        dist_a_b = self.manifold.metric.dist(point_a, point_b)

        result_vect = dist_a_b
        result = [
            self.manifold.metric.dist(point_a, point_b[i]) for i in range(len(point_b))
        ]
        result = gs.stack(result, axis=0)
        self.assertAllClose(result_vect, result)

    def test_dist_broadcast(self):

        point_a = gs.array([[0.2, 0.5], [0.3, 0.1]])
        point_b = gs.array([[0.3, -0.5], [0.2, 0.2]])
        point_c = gs.array([[0.2, 0.3], [0.5, 0.5], [-0.4, 0.1]])
        point_d = gs.array([0.1, 0.2, 0.3])

        dist_a_b = self.manifold.metric.dist_broadcast(point_a, point_b)

        dist_b_c = gs.flatten(self.manifold.metric.dist_broadcast(point_b, point_c))

        result_vect = gs.concatenate((dist_a_b, dist_b_c), axis=0)

        result_a_b = [
            self.manifold.metric.dist_broadcast(point_a[i], point_b[i])
            for i in range(len(point_b))
        ]

        result_b_c = [
            self.manifold.metric.dist_broadcast(point_b[i], point_c[j])
            for i in range(len(point_b))
            for j in range(len(point_c))
        ]
        result = result_a_b + result_b_c
        result = gs.stack(result, axis=0)

        self.assertAllClose(result_vect, result)
        with self.assertRaises(ValueError):
            self.manifold.metric.dist_broadcast(point_a, point_d)

    def test_dist_pairwise(self):

        point = gs.array([[0.1, 0.2], [0.3, 0.4], [0.5, 0.5]])

        result = self.manifold.metric.dist_pairwise(point)

        expected = gs.array(
            [
                [0.0, 0.65821943, 1.34682524],
                [0.65821943, 0.0, 0.71497076],
                [1.34682524, 0.71497076, 0.0],
            ]
        )

        self.assertAllClose(result, expected, rtol=1e-3)

    def test_mobius_vectorization(self):
        point_a = gs.array([0.5, 0.5])
        point_b = gs.array([[0.5, -0.3], [0.3, 0.4]])

        dist_a_b = self.manifold.metric.mobius_add(point_a, point_b)

        result_vect = dist_a_b
        result = [
            self.manifold.metric.mobius_add(point_a, point_b[i])
            for i in range(len(point_b))
        ]
        result = gs.stack(result, axis=0)
        self.assertAllClose(result_vect, result)

        dist_a_b = self.manifold.metric.mobius_add(point_b, point_a)

        result_vect = dist_a_b
        result = [
            self.manifold.metric.mobius_add(point_b[i], point_a)
            for i in range(len(point_b))
        ]
        result = gs.stack(result, axis=0)
        self.assertAllClose(result_vect, result)

    def test_log_vectorization(self):
        point_a = gs.array([0.5, 0.5])
        point_b = gs.array([[0.5, -0.5], [0.4, 0.4]])

        dist_a_b = self.manifold.metric.log(point_a, point_b)

        result_vect = dist_a_b
        result = [
            self.manifold.metric.log(point_a, point_b[i]) for i in range(len(point_b))
        ]
        result = gs.stack(result, axis=0)
        self.assertAllClose(result_vect, result)

        dist_a_b = self.manifold.metric.log(point_b, point_a)

        result_vect = dist_a_b
        result = [
            self.manifold.metric.log(point_b[i], point_a) for i in range(len(point_b))
        ]
        result = gs.stack(result, axis=0)
        self.assertAllClose(result_vect, result)

    def test_exp_vectorization(self):
        point_a = gs.array([0.5, 0.5])
        point_b = gs.array([[0.0, 0.0], [0.5, -0.5], [0.4, 0.4]])

        dist_a_b = self.manifold.metric.exp(point_a, point_b)

        result_vect = dist_a_b
        result = [
            self.manifold.metric.exp(point_a, point_b[i]) for i in range(len(point_b))
        ]
        result = gs.stack(result, axis=0)
        self.assertAllClose(result_vect, result)

        dist_a_b = self.manifold.metric.exp(point_b, point_a)

        result_vect = dist_a_b
        result = [
            self.manifold.metric.exp(point_b[i], point_a) for i in range(len(point_b))
        ]
        result = gs.stack(result, axis=0)
        self.assertAllClose(result_vect, result)

    def test_log_poincare(self):

        point = gs.array([0.3, 0.5])
        base_point = gs.array([0.3, 0.3])

        result = self.manifold.metric.log(point, base_point)
        expected = gs.array([-0.01733576, 0.21958634])

        self.manifold.metric.coords_type = "extrinsic"
        self.assertAllClose(result, expected)

    def test_belong_true_poincare(self):
        point = gs.array([0.3, 0.5])
        belong = self.manifold.belongs(point)
        self.assertTrue(belong)

    def test_belong_false_poincare(self):
        point = gs.array([1.2, 0.5])
        belong = self.manifold.belongs(point)
        self.assertFalse(belong)

    def test_projection(self):
        point = gs.array([1.2, 0.5])
        projected_point = self.manifold.projection(point)
        self.assertTrue(gs.sum(projected_point * projected_point) < 1.0)

    def test_exp_poincare(self):

        point = gs.array([0.3, 0.5])
        base_point = gs.array([0.3, 0.3])

        tangent_vec = self.manifold.metric.log(point, base_point)
        result = self.manifold.metric.exp(tangent_vec, base_point)

        self.manifold.metric.coords_type = "extrinsic"
        self.assertAllClose(result, point)

    def test_ball_retraction(self):
        x = gs.array([[0.5, 0.6], [0.2, -0.1], [0.2, -0.4]])
        y = gs.array([[0.3, 0.5], [0.3, -0.6], [0.3, -0.3]])

        ball_metric = self.manifold.metric
        tangent_vec = ball_metric.log(y, x)
        ball_metric.retraction(tangent_vec, x)

    def test_ball_geodesic(self):
        path_function = self.manifold.metric.geodesic(
            gs.array([0.1, 0.1]), gs.array([0.2, 0.2])
        )
        steps = gs.array(gs.linspace(-1000.0, 1000.0, 10000))
        path_function(steps)

    def test_mobius_out_of_the_ball(self):
        x, y = gs.array([0.7, 0.9]), gs.array([0.2, 0.2])

        with self.assertRaises(ValueError):
            self.manifold.metric.mobius_add(x, y, project_first=False)