Source code for topoembedx.classes.higher_order_laplacian_eigenmaps

"""Higher Order Laplacian Eigenmaps."""

from typing import Literal

import networkx as nx
import numpy as np
import toponetx as tnx
from karateclub import LaplacianEigenmaps
from scipy.sparse import csr_matrix

from topoembedx.neighborhood import neighborhood_from_complex


[docs] class HigherOrderLaplacianEigenmaps(LaplacianEigenmaps): """Higher-Order Laplacian Eigenmaps embedding algorithm. This algorithm is based on the Laplacian Eigenmaps algorithm [1] for graphs. Parameters ---------- dimensions : int, default=3 Dimensionality of embedding. maximum_number_of_iterations : int, default=100 Maximum number of iterations. seed : int, default=42 Random seed value. References ---------- .. [1] Belkin, Mikhail, and Partha Niyogi. "Laplacian Eigenmaps and Spectral Techniques for Embedding and Clustering". Advances in Neural Information Processing Systems, vol. 14, 2001. Neural Information Processing Systems, https://papers.nips.cc/paper_files/paper/2001/hash/f106b7f99d2cb30c3db1c3cc0fde9ccb-Abstract.html. """ A: csr_matrix ind: list def __init__( self, dimensions: int = 3, maximum_number_of_iterations: int = 100, seed: int = 42, ): super().__init__(dimensions=dimensions, seed=seed) self.maximum_number_of_iterations = maximum_number_of_iterations
[docs] def fit( self, domain: tnx.Complex, neighborhood_type: Literal["adj", "coadj"] = "adj", neighborhood_dim=None, ) -> None: """Fit a Higher Order Laplacian Eigenmaps model. Parameters ---------- domain : toponetx.classes.Complex A complex object. The complex object can be one of the following: - CellComplex - CombinatorialComplex - PathComplex - SimplicialComplex - ColoredHyperGraph neighborhood_type : {"adj", "coadj"}, default="adj" The type of neighborhood to compute. "adj" for adjacency matrix, "coadj" for coadjacency matrix. neighborhood_dim : dict The integer parameters needed to specify the neighborhood of the cells to generate the embedding. In TopoNetX (co)adjacency neighborhood matrices are specified via one or two parameters. - For Cell/Simplicial/Path complexes (co)adjacency matrix is specified by a single parameter, this is precisely neighborhood_dim["rank"]. - For Combinatorial/ColoredHyperGraph the (co)adjacency matrix is specified by two parameters, this is precisely neighborhood_dim["rank"] and neighborhood_dim["via_rank"]. Notes ----- Here neighborhood_dim={"rank": 1, "via_rank": -1} specifies the dimension for which the cell embeddings are going to be computed. "rank": 1 means that the embeddings will be computed for the first dimension. The integer "via_rank": -1 is ignored when the input is cell/simplicial complex and must be specified when the input complex is a combinatorial complex or colored hypergraph. """ self.ind, self.A = neighborhood_from_complex( domain, neighborhood_type, neighborhood_dim ) self.A.setdiag(1) g = nx.from_numpy_array(self.A) super().fit(g)
[docs] def get_embedding(self, get_dict: bool = False) -> dict | np.ndarray: """Get embeddings. Parameters ---------- get_dict : bool, default=False Whether to return a dictionary of the embedding. Returns ------- dict or np.ndarray The embedding of the complex. """ emb = super().get_embedding() if get_dict: return dict(zip(self.ind, emb, strict=True)) return emb