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)
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)
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()
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
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
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)
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)
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)
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)
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
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, )
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
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))
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)
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)
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()
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
def __init__(self, n): super(BuresWassersteinBundle, self).__init__( n=n, base=SPDMatrices(n), group=SpecialOrthogonal(n), ambient_metric=MatricesMetric(n, n), )
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])
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
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)
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