Source code for geomstats.geometry.complex_manifold

"""Complex manifold module.

In other words, a topological space that locally resembles
Hermitian space near each point.

Lead author: Yann Cabanes.
"""

import abc
import inspect

import geomstats.backend as gs


[docs] class ComplexManifold(abc.ABC): r"""Class for complex manifolds. Parameters ---------- dim : int Dimension of the manifold. shape : tuple of int Shape of one element of the manifold. Optional, default : None. intrinsic : bool Coordinates type. equip : bool If True, equip space with default metric. """ def __init__( self, dim, shape, intrinsic=True, equip=True, ): self.dim = dim self.shape = shape self.intrinsic = intrinsic self.point_ndim = len(self.shape) if equip: self.equip_with_metric()
[docs] def equip_with_metric(self, Metric=None, **metric_kwargs): """Equip manifold with Metric. Parameters ---------- Metric : Connection object or instance or ScalarProductMetric instance If None, default metric will be used. """ if Metric is None: out = self.default_metric() if isinstance(out, tuple): Metric, kwargs = out kwargs.update(metric_kwargs) metric_kwargs = kwargs else: Metric = out if inspect.isclass(Metric): self.metric = Metric(self, **metric_kwargs) else: if self.metric._space is not self: raise ValueError( "Cannot equip space with metric instantiated with another space." ) self.metric = Metric return self
[docs] @abc.abstractmethod def belongs(self, point, atol=gs.atol): """Evaluate if a point belongs to the manifold. Parameters ---------- point : array-like, shape=[..., *point_shape] Point to evaluate. atol : float Absolute tolerance. Optional, default: backend atol. Returns ------- belongs : array-like, shape=[...,] Boolean evaluating if point belongs to the manifold. """
[docs] @abc.abstractmethod def is_tangent(self, vector, base_point, atol=gs.atol): """Check whether the vector is tangent at base_point. Parameters ---------- vector : array-like, shape=[..., *point_shape] Vector. base_point : array-like, shape=[..., *point_shape] Point on the manifold. atol : float Absolute tolerance. Optional, default: backend atol. Returns ------- is_tangent : bool Boolean denoting if vector is a tangent vector at the base point. """
[docs] @abc.abstractmethod def to_tangent(self, vector, base_point): """Project a vector to a tangent space of the manifold. Parameters ---------- vector : array-like, shape=[..., *point_shape] Vector. base_point : array-like, shape=[..., *point_shape] Point on the manifold. Returns ------- tangent_vec : array-like, shape=[..., *point_shape] Tangent vector at base point. """
[docs] @abc.abstractmethod def random_point(self, n_samples=1, bound=1.0): """Sample random points on the manifold according to some distribution. If the manifold is compact, preferably a uniform distribution will be used. Parameters ---------- n_samples : int Number of samples. Optional, default: 1. bound : float Bound of the interval in which to sample for non compact manifolds. Optional, default: 1. Returns ------- samples : array-like, shape=[..., *point_shape] Points sampled on the manifold. """
[docs] def regularize(self, point): """Regularize a point to the canonical representation for the manifold. Parameters ---------- point : array-like, shape=[..., dim] Point. Returns ------- regularized_point : array-like, shape=[..., *point_shape] Regularized point. """ return gs.copy(point)
[docs] def random_tangent_vec(self, base_point, n_samples=1): """Generate random tangent vec. Parameters ---------- n_samples : int Number of samples. Optional, default: 1. base_point : array-like, shape=[..., *point_shape] Point. Returns ------- tangent_vec : array-like, shape=[..., *point_shape] Tangent vec at base point. """ if ( n_samples > 1 and base_point.ndim > len(self.shape) and n_samples != len(base_point) ): raise ValueError( "The number of base points must be the same as the " "number of samples, when different from 1." ) batch_size = () if n_samples == 1 else (n_samples,) vector = gs.random.normal( size=batch_size + self.shape, dtype=gs.get_default_cdtype() ) return self.to_tangent(vector, base_point)
[docs] def projection(self, point): """Project a point to the manifold. Parameters ---------- point: array-like, shape[..., *point_shape] Point. Returns ------- point: array-like, shape[..., *point_shape] Point. """ if self.intrinsic: return gs.copy(point) raise NotImplementedError("`projection` is not implemented yet")