def exp(self, tangent_vec, base_point=None): """Compute Riemannian exponential of tangent vector at base point. Riemannian exponential at point base_point of tangent vector tangent_vec wrt the Riemannian metric. Parameters ---------- tangent_vec base_point Returns ------- exp """ if base_point is None: base_point = [ None, ] * self.n_metrics exp = gs.asarray([ self.metrics[i].exp(tangent_vec[i], base_point[i]) for i in range(self.n_metrics) ]) return exp
def exp(self, tangent_vec, base_point=None): """Compute the Riemannian exponential of a tangent vector. Parameters ---------- tangent_vec : array-like, shape=[n_samples, dimension] Tangent vector at a base point. base_point : array-like, shape=[n_samples, dimension] Point on the manifold. Returns ------- exp : array-like, shape=[n_samples, dimension] Point on the manifold equal to the Riemannian exponential of tangent_vec at the base point. """ if base_point is None: base_point = [ None, ] * self.n_metrics exp = gs.asarray([ metric.exp(tangent_vec[i], base_point[i]) for i, metric in enumerate(self.metrics) ]) return exp
def log(self, point, base_point=None): """Compute the Riemannian logarithm of a point. Parameters ---------- point : array-like, shape=[n_samples, dimension] Point on the manifold base_point : array-like, shape=[n_samples, dimension] Point on the manifold Returns ------- log : array-like, shape=[n_samples, dimension] Tangent vector at the base point equal to the Riemannian logarithm of point at the base point. """ if base_point is None: base_point = [ None, ] * self.n_metrics log = gs.asarray([ metric.log(point[i], base_point[i]) for i, metric in enumerate(self.metrics) ]) return log
def belongs(self, point, tolerance=TOLERANCE): """Evaluate if a point belongs to the Hypersphere. i.e. evaluate if its squared norm in the Euclidean space is 1. Parameters ---------- point : array-like, shape=[n_samples, dimension + 1] Input points. tolerance : float, optional Returns ------- belongs : array-like, shape=[n_samples, 1] """ point = gs.asarray(point) point_dim = point.shape[-1] if point_dim != self.dimension + 1: if point_dim is self.dimension: logging.warning('Use the extrinsic coordinates to ' 'represent points on the hypersphere.') return gs.array([[False]]) sq_norm = self.embedding_metric.squared_norm(point) diff = gs.abs(sq_norm - 1) return gs.less_equal(diff, tolerance)
def geodesic(self, initial_point, end_point=None, initial_tangent_vec=None, point_type=None): """Compute geodesic curve for a product metric. This geodesic is seen as the product of the geodesic on each space. Parameters ---------- initial_point end_point initial_tangent_vec point_type Returns ------- geodesics : array-like """ if point_type is None: point_type = self.default_point_type assert point_type in ['vector', 'matrix'] geodesics = gs.asarray([[self.manifold[i].metric.geodesic( initial_point, end_point=end_point, initial_tangent_vec=initial_tangent_vec, point_type=point_type) for i in range(self.n_manifolds)]]) return geodesics
def belongs(self, point, tolerance=TOLERANCE): """Test if a point belongs to the hypersphere. This tests whether the point's squared norm in Euclidean space is 1. Parameters ---------- point : array-like, shape=[n_samples, dimension + 1] Points in Euclidean space. tolerance : float, optional Tolerance at which to evaluate norm == 1 (default: TOLERANCE). Returns ------- belongs : array-like, shape=[n_samples, 1] Array of booleans evaluating if each point belongs to the hypersphere. """ point = gs.asarray(point) point_dim = point.shape[-1] if point_dim != self.dimension + 1: if point_dim is self.dimension: logging.warning('Use the extrinsic coordinates to ' 'represent points on the hypersphere.') return gs.array([[False]]) sq_norm = self.embedding_metric.squared_norm(point) diff = gs.abs(sq_norm - 1) return gs.less_equal(diff, tolerance)
def belongs(self, point, tolerance=TOLERANCE): """ Evaluate if a point belongs to the Hypersphere, i.e. evaluate if its squared norm in the Euclidean space is 1. """ point = gs.asarray(point) point_dim = point.shape[-1] if point_dim != self.dimension + 1: if point_dim is self.dimension: logging.warning('Use the extrinsic coordinates to ' 'represent points on the hypersphere.') return gs.array([[False]]) sq_norm = self.embedding_metric.squared_norm(point) diff = gs.abs(sq_norm - 1) return gs.less_equal(diff, tolerance)
def log(self, point, base_point=None): """ Riemannian logarithm at point base_point of tangent vector tangent_vec wrt the Riemannian metric. """ if base_point is None: base_point = [ None, ] * self.n_metrics log = gs.asarray([ self.metrics[i].log(point[i], base_point[i]) for i in range(self.n_metrics) ]) return log
def exp(self, tangent_vec, base_point=None): """ Riemannian exponential at point base_point of tangent vector tangent_vec wrt the Riemannian metric. """ if base_point is None: base_point = [ None, ] * self.n_metrics exp = gs.asarray([ self.metrics[i].exp(tangent_vec[i], base_point[i]) for i in range(self.n_metrics) ]) return exp
def belongs(self, point, tolerance=TOLERANCE): """ By definition, a point on the Hypersphere has squared norm 1 in the embedding Euclidean space. Note: point must be given in extrinsic coordinates. """ point = gs.asarray(point) point_dim = point.shape[-1] if point_dim != self.dimension + 1: if point_dim is self.dimension: logging.warning('Use the extrinsic coordinates to ' 'represent points on the hypersphere.') return False sq_norm = self.embedding_metric.squared_norm(point) diff = gs.abs(sq_norm - 1) return gs.less_equal(diff, tolerance)
def geodesic(self, initial_point, end_point=None, initial_tangent_vec=None, point_type='vector'): """ Geodesic curve for a product metric seen as the product of the geodesic on each space. """ geodesics = gs.asarray([[ self.manifold[i].metric.geodesic( initial_point, end_point=end_point, initial_tangent_vec=initial_tangent_vec, point_type=point_type) for i in range(self.n_manifolds) ]]) return geodesics
def squared_dist(self, point_a, point_b): """ Squared geodesic distance between two points. Parameters ---------- point_a: array-like, shape=[n_samples, dimension] or shape=[1, dimension] point_b: array-like, shape=[n_samples, dimension] or shape=[1, dimension] """ sq_distances = gs.asarray([ self.metrics[i].squared_dist(point_a[i], point_b[i]) for i in range(self.n_metrics) ]) return sum(sq_distances)
def squared_dist(self, point_a, point_b): """Compute the squared geodesic distance between two points. Parameters ---------- point_a : array-like, shape=[n_samples, dimension] First point on the manifold. point_b : array-like, shape=[n_samples, dimension] Second point on the manifold. Returns ------- sq_dist : array-like, shape=[n_samples, 1] Geodesic distance between the two points. """ sq_distances = gs.asarray([ metric.squared_dist(point_a[i], point_b[i]) for i, metric in enumerate(self.metrics) ]) return sum(sq_distances)
def log(self, point, base_point=None): """Compute Riemannian logarithm of a point wrt a base point. Parameters ---------- point base_point Returns ------- log """ if base_point is None: base_point = [ None, ] * self.n_metrics log = gs.asarray([ self.metrics[i].log(point[i], base_point[i]) for i in range(self.n_metrics) ]) return log
"""Module providing an implementation of MatrixLieAlgebras. There are two main forms of representation for elements of a MatrixLieAlgebra implemented here. The first one is as a matrix, as elements of R^(n x n). The second is by choosing a base and remembering the coefficients of an element in that base. This base will be provided in child classes (e.g. SkewSymmetricMatrices). """ import geomstats.backend as gs BCH_INFO = gs.asarray( [[int(x) for x in i.strip().split()] for i in open("geomstats/geometry/bch_coefficients.dat").readlines()]) class MatrixLieAlgebra: """Class implementing matrix Lie algebra related functions.""" def __init__(self, dimension, n): """Construct the MatrixLieAlgebra object. Parameters ---------- dimension: int The dimension of the Lie algebra as a real vector space n: int The amount of rows and columns in the matrx representation of the Lie algebra """ self.dimension = dimension self.n = n self.basis = None