Example #1
0
    def setUp(self):
        gs.random.seed(1234)
        self.n = 3
        self.n_samples = 2
        self.group = GeneralLinear(n=self.n)
        # We generate invertible matrices using so3_group
        self.so3_group = SpecialOrthogonal(n=self.n)

        warnings.simplefilter('ignore', category=ImportWarning)
Example #2
0
 def test_distance_broadcast(self, n):
     group = SpecialOrthogonal(n=n)
     point = group.random_point(5)
     result = group.bi_invariant_metric.dist_broadcast(point[:3], point)
     expected = []
     for a in point[:3]:
         expected.append(group.bi_invariant_metric.dist(a, point))
     expected = gs.stack(expected)
     self.assertAllClose(result, expected)
Example #3
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)

        plt.figure()
Example #4
0
    def setUp(self):
        self.so3 = SpecialOrthogonal(n=3)
        self.spd = SPDMatrices(3)
        self.spd_metric = SPDMetricAffine(3)

        self.n_samples = 10

        self.X = self.so3.random_uniform(n_samples=self.n_samples)
        self.metric = self.so3.bi_invariant_metric
        self.n_components = 2
Example #5
0
 def orthonormal_basis_test_data(self):
     smoke_data = [
         dict(group=SpecialOrthogonal(3), metric_mat_at_identity=None),
         dict(
             group=SpecialOrthogonal(3),
             metric_mat_at_identity=from_vector_to_diagonal_matrix(
                 gs.array([1.0, 2.0, 3.0])),
         ),
     ]
     return self.generate_tests(smoke_data)
    def setup_method(self):
        warnings.simplefilter("ignore", category=ImportWarning)
        warnings.simplefilter("ignore", category=UserWarning)

        gs.random.seed(1234)

        self.group = SpecialOrthogonal(n=2, point_type="vector")

        # -- Set attributes
        self.n_samples = 4
Example #7
0
    def __init__(self, epsilon=0.):
        super(_SpecialEuclidean3Vectors,
              self).__init__(dim=6, default_point_type='vector')

        self.n = 3
        self.epsilon = epsilon
        self.rotations = SpecialOrthogonal(n=3,
                                           point_type='vector',
                                           epsilon=epsilon)
        self.translations = Euclidean(dim=3)
Example #8
0
    def __init__(self, n, epsilon=0.0):
        dim = n * (n + 1) // 2
        LieGroup.__init__(self, dim=dim, default_point_type="vector")

        self.n = n
        self.epsilon = epsilon
        self.rotations = SpecialOrthogonal(n=n,
                                           point_type="vector",
                                           epsilon=epsilon)
        self.translations = Euclidean(dim=n)
Example #9
0
 def setup_method(self):
     gs.random.seed(123)
     self.sphere = Hypersphere(dim=4)
     self.hyperbolic = Hyperboloid(dim=3)
     self.euclidean = Euclidean(dim=2)
     self.minkowski = Minkowski(dim=2)
     self.so3 = SpecialOrthogonal(n=3, point_type="vector")
     self.so_matrix = SpecialOrthogonal(n=3)
     self.curves_2d = DiscreteCurves(R2)
     self.elastic_metric = ElasticMetric(a=1, b=1, ambient_manifold=R2)
Example #10
0
    def __init__(self, n):
        super().__init__(
            n=n + 1, dim=int((n * (n + 1)) / 2), default_point_type='matrix',
            lie_algebra=SpecialEuclideanMatrixLieAlgebra(n=n))
        self.rotations = SpecialOrthogonal(n=n)
        self.translations = Euclidean(dim=n)
        self.n = n

        self.left_canonical_metric = \
            SpecialEuclideanMatrixCannonicalLeftMetric(group=self)
Example #11
0
 def __init__(self, n):
     super(_SpecialEuclideanMatrices,
           self).__init__(default_point_type='matrix', n=n + 1)
     self.rotations = SpecialOrthogonal(n=n)
     self.translations = Euclidean(dim=n)
     self.n = n
     self.dim = int((n * (n + 1)) / 2)
     translation_mask = gs.hstack(
         [gs.ones((self.n, ) * 2), 2 * gs.ones((self.n, 1))])
     translation_mask = gs.concatenate(
         [translation_mask, gs.zeros((1, self.n + 1))], axis=0)
     self.translation_mask = translation_mask
Example #12
0
 def test_geodesic_invalid_initial_conditions(self):
     space = SpecialOrthogonal(n=4)
     initial_point = space.random_uniform(2)
     vector = gs.random.rand(2, 4, 4)
     initial_tangent_vec = space.to_tangent(vector=vector,
                                            base_point=initial_point)
     end_point = space.random_uniform(2)
     self.assertRaises(
         RuntimeError, lambda: space.bi_invariant_metric.geodesic(
             initial_point=initial_point,
             initial_tangent_vec=initial_tangent_vec,
             end_point=end_point))
 def random_point_belongs_test_data(self):
     smoke_space_args_list = [
         (SpecialOrthogonal(2), 2),
         (SpecialOrthogonal(2), 2),
     ]
     smoke_n_points_list = [1, 2]
     return self._random_point_belongs_test_data(
         smoke_space_args_list,
         smoke_n_points_list,
         self.space_args_list,
         self.n_points_list,
     )
Example #14
0
    def __init__(self, n):
        super().__init__(
            n=n + 1, dim=int((n * (n + 1)) / 2),
            embedding_space=GeneralLinear(n + 1, positive_det=True),
            submersion=submersion, value=gs.eye(n + 1),
            tangent_submersion=tangent_submersion,
            lie_algebra=SpecialEuclideanMatrixLieAlgebra(n=n))
        self.rotations = SpecialOrthogonal(n=n)
        self.translations = Euclidean(dim=n)
        self.n = n

        self.left_canonical_metric = \
            SpecialEuclideanMatrixCannonicalLeftMetric(group=self)
        self.metric = self.left_canonical_metric
Example #15
0
    def test_squared_dist_is_less_than_squared_pi(self, point_1, point_2):
        """
        This test only concerns the canonical metric.
        For other metrics, the scaling factor can give
        distances above pi.
        """
        group = SpecialOrthogonal(3, "vector")
        metric = self.metric(SpecialOrthogonal(3, "vector"))
        point_1 = group.regularize(point_1)
        point_2 = group.regularize(point_2)

        sq_dist = metric.squared_dist(point_1, point_2)
        diff = sq_dist - gs.pi**2
        self.assertTrue(diff <= 0 or abs(diff) < EPSILON,
                        "sq_dist = {}".format(sq_dist))
Example #16
0
    def test_squared_dist_is_symmetric(
        self, metric_mat_at_identity, left_or_right, point_1, point_2
    ):
        group = SpecialOrthogonal(3, "vector")
        metric = self.metric(
            SpecialOrthogonal(n=3, point_type="vector"),
            metric_mat_at_identity=metric_mat_at_identity,
            left_or_right=left_or_right,
        )
        point_1 = group.regularize(point_1)
        point_2 = group.regularize(point_2)

        sq_dist_1_2 = gs.mod(metric.squared_dist(point_1, point_2) + 1e-4, gs.pi**2)
        sq_dist_2_1 = gs.mod(metric.squared_dist(point_2, point_1) + 1e-4, gs.pi**2)
        self.assertAllClose(sq_dist_1_2, sq_dist_2_1, atol=1e-4)
 def exp_test_data(self):
     theta = gs.pi / 5.0
     rot_vec_base_point = theta / gs.sqrt(3.0) * gs.array([1.0, 1.0, 1.0])
     rot_vec_2 = gs.pi / 4 * gs.array([1.0, 0.0, 0.0])
     phi = (gs.pi / 10) / (gs.tan(gs.array(gs.pi / 10)))
     skew = gs.array([[0.0, -1.0, 1.0], [1.0, 0.0, -1.0], [-1.0, 1.0, 0.0]])
     jacobian = (phi * gs.eye(3) + (1 - phi) / 3 * gs.ones([3, 3]) + gs.pi /
                 (10 * gs.sqrt(3.0)) * skew)
     inv_jacobian = gs.linalg.inv(jacobian)
     expected = SpecialOrthogonal(3, "vector").compose(
         (gs.pi / 5.0) / gs.sqrt(3.0) * gs.array([1.0, 1.0, 1.0]),
         gs.dot(inv_jacobian, rot_vec_2),
     )
     smoke_data = [
         dict(
             tangent_vec=gs.array([0.0, 0.0, 0.0]),
             base_point=rot_vec_base_point,
             expected=rot_vec_base_point,
         ),
         dict(
             tangent_vec=rot_vec_2,
             base_point=rot_vec_base_point,
             expected=expected,
         ),
     ]
     return self.generate_tests(smoke_data)
Example #18
0
    def __init__(self, n, point_type=None, epsilon=0.):
        assert isinstance(n, int) and n > 1

        self.n = n
        self.dimension = int((n * (n - 1)) / 2 + n)

        self.epsilon = epsilon

        self.default_point_type = point_type
        if point_type is None:
            self.default_point_type = 'vector' if n == 3 else 'matrix'

        super(SpecialEuclidean, self).__init__(dimension=self.dimension)

        self.rotations = SpecialOrthogonal(n=n, epsilon=epsilon)
        self.translations = Euclidean(dimension=n)
 def belongs_test_data(self):
     smoke_data = [
         dict(
             base=SpecialOrthogonal(3),
             power=2,
             point=gs.stack([gs.eye(3) + 1.0, gs.eye(3)])[None],
             expected=gs.array(False),
         ),
         dict(
             base=SpecialOrthogonal(3),
             power=2,
             point=gs.array([gs.eye(3), gs.eye(3)]),
             expected=gs.array(True),
         ),
     ]
     return self.generate_tests(smoke_data)
Example #20
0
 def __init__(self, n, k):
     super(BuresWassersteinBundle, self).__init__(
         n=n,
         k=k,
         group=SpecialOrthogonal(k),
         ambient_metric=MatricesMetric(n, k),
     )
    def log_test_data(self):
        theta = gs.pi / 5.0
        rot_vec_base_point = theta / gs.sqrt(3.0) * gs.array([1.0, 1.0, 1.0])
        # Note: the rotation vector for the reference point
        # needs to be regularized.

        # The Logarithm of a point at itself gives 0.
        expected = gs.array([0.0, 0.0, 0.0])

        # General case: this is the inverse test of test 1 for Riemannian exp
        expected = gs.pi / 4 * gs.array([1.0, 0.0, 0.0])
        phi = (gs.pi / 10) / (gs.tan(gs.array(gs.pi / 10)))
        skew = gs.array([[0.0, -1.0, 1.0], [1.0, 0.0, -1.0], [-1.0, 1.0, 0.0]])
        jacobian = (phi * gs.eye(3) + (1 - phi) / 3 * gs.ones([3, 3]) + gs.pi /
                    (10 * gs.sqrt(3.0)) * skew)
        inv_jacobian = gs.linalg.inv(jacobian)
        aux = gs.dot(inv_jacobian, expected)
        rot_vec_2 = SpecialOrthogonal(3, "vector").compose(
            rot_vec_base_point, aux)

        smoke_data = [
            dict(
                point=rot_vec_base_point,
                base_point=rot_vec_base_point,
                expected=gs.array([0.0, 0.0, 0.0]),
            ),
            dict(
                point=rot_vec_2,
                base_point=rot_vec_base_point,
                expected=expected,
            ),
        ]
        return self.generate_tests(smoke_data)
    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()
Example #23
0
    def setup_data(self):
        """Generate the un-shuffled dataset.

        Returns
        -------
        X : array-like,
           shape = [n_samples * n_classes, n_features, n_features]
            Data.
        y : array-like, shape = [n_samples * n_classes, n_classes]
            Labels.
        """
        mean_covariance_eigenvalues = gs.random.uniform(
            0.1, 5., (self.n_classes, self.n_features))
        var = 1.
        base_rotations = SpecialOrthogonal(n=self.n_features).random_gaussian(
            gs.eye(self.n_features), var, n_samples=self.n_classes)
        var_rotations = gs.random.uniform(.5, .75, (self.n_classes))

        y = gs.zeros((self.n_classes * self.n_samples, self.n_classes))
        X = []
        for i in range(self.n_classes):
            value_x = self.make_data(base_rotations[i],
                                     gs.diag(mean_covariance_eigenvalues[i]),
                                     var_rotations[i])
            value_y = 1
            idx_y = [
                (j, i)
                for j in range(i * self.n_samples, (i + 1) * self.n_samples)
            ]
            y = gs.assignment(y, value_y, idx_y)
            X.append(value_x)
        return gs.concatenate(X, axis=0), y
Example #24
0
 def __init__(self, n):
     super(BuresWassersteinBundle, self).__init__(
         n=n,
         base=SPDMatrices(n),
         group=SpecialOrthogonal(n),
         ambient_metric=MatricesMetric(n, n),
     )
Example #25
0
class TestTangentPCA(geomstats.tests.TestCase):
    _multiprocess_can_split_ = True

    def setUp(self):
        self.so3 = SpecialOrthogonal(n=3)
        self.n_samples = 10

        self.X = self.so3.random_uniform(n_samples=self.n_samples)
        self.metric = self.so3.bi_invariant_metric
        self.n_components = 2

    @geomstats.tests.np_only
    def test_tangent_pca_error(self):
        X = self.X
        trans = TangentPCA(self.metric, n_components=self.n_components)
        trans.fit(X)
        X_diff_size = gs.ones((self.n_samples, gs.shape(X)[1] + 1))
        self.assertRaises(ValueError, trans.transform, X_diff_size)

    @geomstats.tests.np_only
    def test_tangent_pca(self):
        X = self.X
        trans = TangentPCA(self.metric, n_components=gs.shape(X)[1])

        trans.fit(X)
        self.assertEquals(trans.n_features_, gs.shape(X)[1])
Example #26
0
    def setUp(self):
        gs.random.seed(0)
        n = 3
        self.base = SPDMatrices(n)
        self.base_metric = SPDMetricBuresWasserstein(n)
        self.group = SpecialOrthogonal(n)
        self.bundle = FiberBundle(GeneralLinear(n),
                                  base=self.base,
                                  group=self.group)
        self.quotient_metric = QuotientMetric(self.bundle,
                                              ambient_metric=MatricesMetric(
                                                  n, n))

        def submersion(point):
            return GeneralLinear.mul(point, GeneralLinear.transpose(point))

        def tangent_submersion(tangent_vec, base_point):
            product = GeneralLinear.mul(base_point,
                                        GeneralLinear.transpose(tangent_vec))
            return 2 * GeneralLinear.to_symmetric(product)

        def horizontal_lift(tangent_vec, point, base_point=None):
            if base_point is None:
                base_point = submersion(point)
            sylvester = gs.linalg.solve_sylvester(base_point, base_point,
                                                  tangent_vec)
            return GeneralLinear.mul(sylvester, point)

        self.bundle.submersion = submersion
        self.bundle.tangent_submersion = tangent_submersion
        self.bundle.horizontal_lift = horizontal_lift
        self.bundle.lift = gs.linalg.cholesky
Example #27
0
 def test_coincides_with_frechet_so(self):
     point = self.so.random_uniform(self.n_samples)
     estimator = ExponentialBarycenter(self.so, max_iter=32, epsilon=1e-12)
     estimator.fit(point)
     result = estimator.estimate_
     print(self.so.default_point_type)
     so_vector = SpecialOrthogonal(3, default_point_type='vector')
     frechet_estimator = FrechetMean(so_vector.bi_invariant_metric,
                                     max_iter=32,
                                     epsilon=1e-10,
                                     point_type='vector')
     vector_point = so_vector.rotation_vector_from_matrix(point)
     frechet_estimator.fit(vector_point)
     mean = frechet_estimator.estimate_
     expected = so_vector.matrix_from_rotation_vector(mean)
     result = estimator.estimate_
     self.assertAllClose(result, expected)
 def skew_to_vector_and_vector_to_skew_test_data(self):
     random_data = []
     random_data += [
         dict(
             n=2,
             point_type="vector",
             mat=SpecialOrthogonal(2, "vector").random_point(),
         )
     ]
     random_data += [
         dict(
             n=3,
             point_type="vector",
             mat=SpecialOrthogonal(3, "vector").random_point(),
         )
     ]
     return self.generate_tests([], random_data)
 def log_at_antipodals_value_error_test_data(self):
     smoke_data = [
         dict(
             n=3,
             point=gs.eye(3),
             base_point=gs.array([[1.0, 0.0, 0.0], [0.0, -1.0, 0.0],
                                  [0.0, 0.0, -1.0]]),
             expected=pytest.raises(ValueError),
         ),
         dict(
             n=3,
             mat1=SpecialOrthogonal(3).random_uniform(),
             mat2=SpecialOrthogonal(3).random_uniform(),
             expected=does_not_raise(),
         ),
     ]
     return self.generate_tests(smoke_data)
Example #30
0
    def random_gaussian_rotation_orbit_noisy(self, mean_spd=None,
                                             eigensummary=None,
                                             var_rotations=1.,
                                             var_eigenvalues=None,
                                             n_samples=1):
        r"""
        Define a Gaussian-like random sample of SPD matrices.

        Formally speaking, sample an orbit for given rotations in the SPD
        manifold. For all means and purposes, it looks rather Gaussian.

        Parameters
        ----------
        mean_spd : array-like, shape = [n, n]
            Mean SPD matrix.
        var_rotations : float
            Variance in rotation.
        var_eigenvalues : array-like, shape = [n,]
            Additional variance in eigenvalues.
        eigensummary : EigenSummary
            Represents the mean SPD matrix decomposed in eigenspace and
            eigenvalues.

        Notes
        -----
        :math:'mean_spd' is the mean SPD matrix; :math:'var_rotations' is the
        scalar variance by which the mean is rotated:
        :math:'\Sigma_{mid} \sim \mathcal{N}(\Sigma_{in}, \sigma_{eig}';
        :math:'X_{out} = R \Sigma_{in} R^T'.
        mean_spd and eigensummary are mutually exclusive; an error is thrown
        if both are not None, or if both are None.
        """
        n = self.n
        if var_eigenvalues is None:
            var_eigenvalues = gs.ones(n)

        if mean_spd is not None and eigensummary is not None:
            raise NotImplementedError
        if mean_spd is None and eigensummary is None:
            raise NotImplementedError
        if eigensummary is None:
            eigenvalues, eigenspace = gs.linalg.eigh(mean_spd)
            eigenvalues = gs.diag(eigenvalues)
        if mean_spd is None:
            eigenvalues, eigenspace\
                = eigensummary.eigenvalues, eigensummary.eigenspace
        rotations = SpecialOrthogonal(n).random_gaussian(
            eigenspace, var_rotations, n_samples=n_samples)

        eigenvalues =\
            gs.abs(gs.diag(gs.random.multivariate_normal(
                gs.diag(eigenvalues), gs.diag(var_eigenvalues))))
        spd_mat = Matrices.mul(rotations, eigenvalues, Matrices.transpose(
            rotations))

        return spd_mat