Quick Start

You can construct a SimplexTree by supplying simplices. Any collection of integer-valued Iterable’s will do, e.g. a list of lists:

from simplextree import SimplexTree
st = SimplexTree([[0,1,2], [0,1], [4,5]]) 
print(st) 
Simplex Tree with (5, 4, 1) (0, 1, 2)-simplices

Batch insertion, removal, and membership queries are supported

st.insert([[1,4], [1,5], [6]])
print(st)
Simplex Tree with (6, 6, 1) (0, 1, 2)-simplices
st.remove([[6]])
print(st)
Simplex Tree with (5, 6, 1) (0, 1, 2)-simplices
print(st.find([[6], [0,1]]))
[False  True]

Collections of simplices are returned as simple lists-of-lists:

print(st.simplices())
[(0,), (1,), (2,), (4,), (5,), (0, 1), (0, 2), (1, 2), (1, 4), (1, 5), (4, 5), (0, 1, 2)]

Various parameters can be given to restrict a given subset to certain subsets or orders:

print(st.simplices(p=1)) 
[(0, 1), (0, 2), (1, 2), (1, 4), (1, 5), (4, 5)]

Familiar Pythonic Collection semantics are supported, including __contains__, __iter__ support, and __len__:

print([0,1,2] in st)
print([len(simplex) for simplex in st])
print(len(st))
True
[1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3]
12

The cofaces of any simplex can be listed with cofaces:

print("Cofaces([1]): " + str(st.cofaces([1])))
Cofaces([1]): [(1,), (1, 2), (1, 4), (1, 5), (0, 1), (0, 1, 2)]

The maximal simplices can be listed with maximal:

print("Maximal: " + str(st.maximal()))
Maximal: [(0, 1, 2), (1, 4), (1, 5), (4, 5)]

Basic properties are also available as attributes

st.n_simplices, st.dimension, st.vertices, st.connected_components
(array([5, 6, 1], dtype=uint64), 2, [0, 1, 2, 4, 5], [1, 1, 1, 1, 1])

Interoperability with numpy is provided whenever possible

import numpy as np 
all(np.all(st.triangles == np.array(st.simplices(p=2)), axis=0))
True

Other complex-wide operations are supported, like k-expansions

st.insert([[1,4]]) 
st.expand(2)       
print(st)
Simplex Tree with (5, 6, 2) (0, 1, 2)-simplices

The trie-structure can also be inspected on the python side with print_tree:

st.print_tree()
0 (h = 2): .( 1 2 )..( 2 )
1 (h = 2): .( 2 4 5 )..( 5 )
2 (h = 0): 
4 (h = 1): .( 5 )
5 (h = 0): 

Yet another way is to traverse the complex in a depth-first manner (prefix-order), printing every simplex as it appears in the traversal:

st.traverse("dfs", f=print)
(0,)
(0, 1)
(0, 1, 2)
(0, 2)
(1,)
(1, 2)
(1, 4)
(1, 4, 5)
(1, 5)
(2,)
(4,)
(4, 5)
(5,)

Several traversal orderings are provided, e.g. breadth-first could be used as well (level-order):

st.traverse("bfs", f=print)
(0,)
(1,)
(2,)
(4,)
(5,)
(0, 1)
(0, 2)
(1, 2)
(1, 4)
(1, 5)
(4, 5)
(0, 1, 2)
(1, 4, 5)

In fact, most operations on the Simplex tree are actually implemented using traversals. For example,

st.traverse(“maximal”, f=print)