def intrinsic_to_extrinsic_coords(self, point_intrinsic): """Convert point from intrinsic to extrinsic coordinates. Convert from the intrinsic coordinates in the hypersphere, to the extrinsic coordinates in Euclidean space. Parameters ---------- point_intrinsic : array-like, shape=[..., dim] Point on the hypersphere, in intrinsic coordinates. Returns ------- point_extrinsic : array-like, shape=[..., dim + 1] Point on the hypersphere, in extrinsic coordinates in Euclidean space. """ sq_coord_0 = 1. - gs.sum(point_intrinsic ** 2, axis=-1) if gs.any(gs.less(sq_coord_0, 0.)): raise ValueError('Square-root of a negative number.') coord_0 = gs.sqrt(sq_coord_0) point_extrinsic = gs.concatenate([ coord_0[..., None], point_intrinsic], axis=-1) return point_extrinsic
def __init__(self, group, inner_product_mat_at_identity=None, left_or_right='left'): if inner_product_mat_at_identity is None: inner_product_mat_at_identity = gs.eye(self.group.dimension) inner_product_mat_at_identity = gs.to_ndarray( inner_product_mat_at_identity, to_ndim=3) mat_shape = inner_product_mat_at_identity.shape assert mat_shape == (1, ) + (group.dimension, ) * 2, mat_shape assert left_or_right in ('left', 'right') eigenvalues = gs.linalg.eigvalsh(inner_product_mat_at_identity) mask_pos_eigval = gs.greater(eigenvalues, 0.) n_pos_eigval = gs.sum(gs.cast(mask_pos_eigval, gs.int32)) mask_neg_eigval = gs.less(eigenvalues, 0.) n_neg_eigval = gs.sum(gs.cast(mask_neg_eigval, gs.int32)) mask_null_eigval = gs.isclose(eigenvalues, 0.) n_null_eigval = gs.sum(gs.cast(mask_null_eigval, gs.int32)) self.group = group if inner_product_mat_at_identity is None: inner_product_mat_at_identity = gs.eye(self.group.dimension) self.inner_product_mat_at_identity = inner_product_mat_at_identity self.left_or_right = left_or_right self.signature = (n_pos_eigval, n_null_eigval, n_neg_eigval)
def __init__(self, group, algebra=None, metric_mat_at_identity=None, left_or_right='left', **kwargs): super(InvariantMetric, self).__init__(dim=group.dim, **kwargs) self.group = group self.lie_algebra = algebra if metric_mat_at_identity is None: metric_mat_at_identity = gs.eye(self.group.dim) geomstats.errors.check_parameter_accepted_values( left_or_right, 'left_or_right', ['left', 'right']) eigenvalues = gs.linalg.eigvalsh(metric_mat_at_identity) mask_pos_eigval = gs.greater(eigenvalues, 0.) n_pos_eigval = gs.sum(gs.cast(mask_pos_eigval, gs.int32)) mask_neg_eigval = gs.less(eigenvalues, 0.) n_neg_eigval = gs.sum(gs.cast(mask_neg_eigval, gs.int32)) mask_null_eigval = gs.isclose(eigenvalues, 0.) n_null_eigval = gs.sum(gs.cast(mask_null_eigval, gs.int32)) self.metric_mat_at_identity = metric_mat_at_identity self.left_or_right = left_or_right self.signature = (n_pos_eigval, n_null_eigval, n_neg_eigval)
def projection(self, point): """Project a matrix on SO(n) using the Frobenius norm. Parameters ---------- mat : array-like, shape=[..., n, n] Returns ------- rot_mat : array-like, shape=[..., n, n] """ mat = point n_mats, n, _ = mat.shape if n == 3: mat_unitary_u, _, mat_unitary_v = gs.linalg.svd(mat) rot_mat = gs.einsum('nij,njk->nik', mat_unitary_u, mat_unitary_v) mask = gs.less(gs.linalg.det(rot_mat), 0.) mask_float = gs.cast(mask, gs.float32) + self.epsilon diag = gs.array([[1., 1., -1.]]) diag = gs.to_ndarray( algebra_utils.from_vector_to_diagonal_matrix(diag), to_ndim=3) + self.epsilon new_mat_diag_s = gs.tile(diag, [n_mats, 1, 1]) aux_mat = gs.einsum( 'nij,njk->nik', mat_unitary_u, new_mat_diag_s) rot_mat += gs.einsum( 'n,njk->njk', mask_float, gs.einsum( 'nij,njk->nik', aux_mat, mat_unitary_v)) else: aux_mat = gs.matmul(gs.transpose(mat, axes=(0, 2, 1)), mat) inv_sqrt_mat = gs.linalg.inv( gs.linalg.sqrtm(aux_mat)) rot_mat = gs.matmul(mat, inv_sqrt_mat) return rot_mat
def __init__(self, group, inner_product_mat_at_identity=None, left_or_right='left'): self.group = group if inner_product_mat_at_identity is None: inner_product_mat_at_identity = gs.eye(self.group.dim) geomstats.error.check_parameter_accepted_values( left_or_right, 'left_or_right', ['left', 'right']) eigenvalues = gs.linalg.eigvalsh(inner_product_mat_at_identity) mask_pos_eigval = gs.greater(eigenvalues, 0.) n_pos_eigval = gs.sum(gs.cast(mask_pos_eigval, gs.int32)) mask_neg_eigval = gs.less(eigenvalues, 0.) n_neg_eigval = gs.sum(gs.cast(mask_neg_eigval, gs.int32)) mask_null_eigval = gs.isclose(eigenvalues, 0.) n_null_eigval = gs.sum(gs.cast(mask_null_eigval, gs.int32)) self.inner_product_mat_at_identity = inner_product_mat_at_identity self.left_or_right = left_or_right self.signature = (n_pos_eigval, n_null_eigval, n_neg_eigval)