def random_walk(self, walk_length=5, n_walks_per_node=1): """Compute a set of random walks on a graph. For each node of the graph, generates a a number of random walks of a specified length. Two consecutive nodes in the random walk, are necessarily related with an edge. The walks capture the structure of the graph. Parameters ---------- walk_length : int Length of a random walk in terms of number of edges. n_walks_per_node : int Number of generated walks starting from each node of the graph. Returns ------- self : array-like, Shape=[n_walks_per_node*self.n_edges), walk_length] array containing random walks. """ paths = gs.empty((self.n_nodes * n_walks_per_node, walk_length + 1), dtype=int) for index in range(len(self.edges)): for i in range(n_walks_per_node): paths[index * n_walks_per_node + i] =\ self._walk(index, walk_length) return paths
def inner_product(self, tangent_vec_a, tangent_vec_b, base_point=None, point_type=None): """Compute the inner-product of two tangent vectors at a base point. Inner product defined by the Riemannian metric at point `base_point` between tangent vectors `tangent_vec_a` and `tangent_vec_b`. Parameters ---------- tangent_vec_a : array-like, shape=[..., dim + 1] First tangent vector at base point. tangent_vec_b : array-like, shape=[..., dim + 1] Second tangent vector at base point. base_point : array-like, shape=[..., dim + 1] Point on the manifold. Optional, default: None. point_type : str, {'vector', 'matrix'} Type of representation used for points. Optional, default: None. Returns ------- inner_prod : array-like, shape=[...,] Inner-product of the two tangent vectors. """ if base_point is None: base_point = gs.empty((self.n_metrics, self.dim)) if point_type is None: point_type = self.default_point_type geomstats.errors.check_parameter_accepted_values( point_type, "point_type", ["vector", "matrix"]) tangent_vec_a = gs.to_ndarray(tangent_vec_a, to_ndim=2) tangent_vec_b = gs.to_ndarray(tangent_vec_b, to_ndim=2) base_point = gs.to_ndarray(base_point, to_ndim=2) if point_type == "vector": intrinsic = self.is_intrinsic(tangent_vec_b) args = { "tangent_vec_a": tangent_vec_a, "tangent_vec_b": tangent_vec_b, "base_point": base_point, } inner_prod = self._iterate_over_metrics("inner_product", args, intrinsic) return gs.sum(gs.stack(inner_prod, axis=1), axis=1) inner_products = [ metric.inner_product( tangent_vec_a[..., i, :], tangent_vec_b[..., i, :], base_point[..., i, :], ) for i, metric in enumerate(self.metrics) ] return sum(inner_products)
def _infer_dimension_(spectrum, n_samples, n_features): """Infers the dimension of a dataset of shape (n_samples, n_features) The dataset is described by its spectrum `spectrum`. """ n_spectrum = len(spectrum) ll = gs.empty(n_spectrum) for rank in range(n_spectrum): ll[rank] = _assess_dimension_(spectrum, rank, n_samples, n_features) return ll.argmax()
def belongs(self, point, point_type=None): """Test if a point belongs to the manifold. Parameters ---------- point : array-like, shape=[n_samples, dim] or shape=[n_samples, dim_2, dim_2] Point. point_type : str, {'vector', 'matrix'} Representation of point. Returns ------- belongs : array-like, shape=[n_samples, 1] Array of booleans evaluating if the corresponding points belong to the manifold. """ if point_type is None: point_type = self.default_point_type assert point_type in ['vector', 'matrix'] if point_type == 'vector': point = gs.to_ndarray(point, to_ndim=2) else: point = gs.to_ndarray(point, to_ndim=3) belongs = gs.empty((point.shape[0], len(self.manifolds))) cum_dim = 0 # FIXME: this only works if the points are in intrinsic representation for i, manifold_i in enumerate(self.manifolds): cum_dim_next = cum_dim + manifold_i.dimension point_i = point[:, cum_dim:cum_dim_next] belongs_i = manifold_i.belongs(point_i) belongs[:, i] = belongs_i cum_dim = cum_dim_next belongs = gs.all(belongs, axis=1) belongs = gs.to_ndarray(belongs, to_ndim=2) return belongs
def belongs(self, point, point_type=None): """Check if the point belongs to the manifold. Parameters ---------- point point_type : str, {'vector', 'matrix'} Returns ------- belongs: array-like, shape=[n_samples, 1] """ if point_type is None: point_type = self.default_point_type assert point_type in ['vector', 'matrix'] if point_type == 'vector': point = gs.to_ndarray(point, to_ndim=2) else: point = gs.to_ndarray(point, to_ndim=3) n_manifolds = self.n_manifolds belongs = gs.empty((point.shape[0], n_manifolds)) cum_dim = 0 # FIXME: this only works if the points are in intrinsic representation for i in range(n_manifolds): manifold_i = self.manifolds[i] cum_dim_next = cum_dim + manifold_i.dimension point_i = point[:, cum_dim:cum_dim_next] belongs_i = manifold_i.belongs(point_i) belongs[:, i] = belongs_i cum_dim = cum_dim_next belongs = gs.all(belongs, axis=1) belongs = gs.to_ndarray(belongs, to_ndim=2) return belongs