Giter Site home page Giter Site logo

peekxc / splex Goto Github PK

View Code? Open in Web Editor NEW
0.0 2.0 0.0 2.46 MB

Package documentation

Home Page: https://peekxc.github.io/splex/

License: Apache License 2.0

Python 8.79% C++ 6.21% Jupyter Notebook 84.95% CSS 0.04%
graph-datastructures simplicial-complex topological-data-analysis

splex's Introduction

Tests coverage_badge python_badge coverage_badge coverage_badge coverage_badge

splex is a Python package aimed at providing common, pythonic interface for constructing and manipulating abstract simplicial complexes that is both efficient and representation independent, similar to how NetworkX handles graph data.

Longer term, the goal of splex is to provide simple and performant implementations of common operations on complexes in ways that are highly interoperable with the rest of the scientific Python ecosystem (e.g. SciPy, NumPy).

For example, one objective to provide efficient ways to construct boundary (+Laplacian) sparse matrices and operators from any simplicial complex. Other operations, such as e.g. random complex generation, geometric realizations, and sparsification algorithms are also planned.

NOTE: splex is early-stage software primarily used for research currently, and many common simplicial operations are not yet provided (e.g. simplicial maps, sparsification)---if you’re interested in using splex but need some specific functionality, please open an issue.

Installation

python -m pip install -e git+https://github.com/peekxc/splex.git#egg=splex

Documentation

Documentation available here

Quickstart

s = Simplex([0,1,2])                       # Explicit simplex class for value and set-like semantics
S = simplicial_complex([[0,1,2], [4,5]])   # Complexes are constructible from myriad of types
K = filtration(S, weight=lambda s: max(s)) # Filtrations are easy to specify via functions 

## All the types are pythonic and easy to use  
K.print()
K.add(...)
K.remove(...)
K.update(...)

## But also come with specific functionality 
K.reindex(...)

## Complexes are representation-independent..
S = simplicial_complex(S, form='tree') # convert to tree-based
S = simplicial_complex(S, form='rank') # convert to array-based

## as are generic functions
from splex.generics import faces, card, dim
for s in faces(S):
  ...

For more details, see the documentation.

Motivation

What if there was a natural type for representing simplices?

s, t = Simplex([0,1,2]),  Simplex([0,1])

print(s.dim(), ":", s)
# 2 : (0,1,2)

t < s, t <= s, s < t
# True, True, False

t in s.boundary()
# True 

print(list(s.faces()))
# [(0), (1), (2), (0,1), (0,2), (1,2), (0,1,2)]

What if said type was flexible and easy to work with, supporting no-fuss construction

Simplex(2) == Simplex([2])                      # value-types are always unboxed 
Simplex([1,2]) == Simplex([1, 2, 2])            # simplices have unique entries, are hashable 
Simplex((1,5,3)) == Simplex(np.array([5,3,1]))  # arrays and tuples supported out of the box 
Simplex((0,1,2)) == Simplex(range(3))           # ... as are generators, iterables, collections, etc

What if it was easy to use with other native Python tools?

s = Simplex([0,1,3,4])
np.array(s)          # native __array__ conversion enabled
len(s)               # __len__ is as expected 
3 in s               # __contains__ acts vertex-wise
list(iter(s))        # __iter__ also acts vertex-wise
s[0]                 # __getitem__ as well 
s[0] = 5             # __setitem__ is *not*: Simplices are immutable!

# Which means native support for the expected protocols 
isinstance(s, Sized)     # True 
isinstance(s, Container) # True 
isinstance(s, Iterable)  # True 
isinstance(s, Mapping)   # False 

What if there was a similar construction for simplicial complexes?

S = simplicial_complex([[0,1,2,3], [4,5], [6]])
print(S)
# 3-d complex with (7, 7, 4, 1)-simplices of dimension (0, 1, 2, 3)

[s for s in S.faces()] # [(0), (1), ..., (1,2,3), (0,1,2,3)]
S.add([5,6]) # adds Simplex([5,6]) to the complex 

.. and for filtered complexes as well?

K = filtration(enumerate(S)) # index-ordered filtration
print(K)
# 3-d filtered complex with (7, 7, 4, 1)-simplices of dimension (0, 1, 2, 3)
print(format(K))
# 3-d filtered complex with (7, 7, 4, 1)-simplices of dimension (0, 1, 2, 3)
# I: 0   ≤ 1   ≤ 2   ≤ 3   ≤ 4   ≤  ...  ≤ 17      ≤ 18       
# S: (0) ⊆ (1) ⊆ (2) ⊆ (3) ⊆ (4) ⊆  ...  ⊆ (1,2,3) ⊆ (0,1,2,3)

[s for s in K.faces()] # [(0), (1), ..., (1,2,3), (0,1,2,3)]

What if there were multiple choices in representation...

SS = simplicial_complex([[0,1,2,3]], form="set")  # simplices stored as collections in a set 
ST = simplicial_complex([[0,1,2,3]], form="tree") # simplices stored as nodes in a tree 
SR = simplicial_complex([[0,1,2,3]], form="rank") # simplices stored as integers in an array 
# ... 

...but every representation was supported through generics

faces(SS)           # calls overloaded .faces()
faces(ST)           # same as above, but using a simplex tree
faces(SR)           # same as above, but using a rank complex 
faces([[0,1,2,3]])  # same as above! Falls back to combinations! 
# same goes for .card(), .dim(), .boundary(), ...

What if extending support to all such types generically was as easy as

def faces(S: ComplexLike) -> Iterator[SimplexConvertible]:
  if hasattr(S, "faces"):
    yield from S.faces()
  else:
    ...

...where ComplexLike is a protocol defining a minimal interface needed for Python types to be interpreted as complexes. This is duck typing---no nominal inheritance needed! Just define your type, make it pythonic via abc.collections and go.

from typing import *
from splex.meta import SimplexConvertible, ComplexLike 

class MyCellComplex:
  def __iter__(self) -> Iterator[SimplexConvertible]:
    ... # < specific implementation > 

splex's People

Contributors

peekxc avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.