Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

First Implementation of a Simplex Trie #220

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions test/classes/test_combinatorial_complex.py
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,7 @@ def test_remove_nodes(self):
frozenset({6}): {"weight": 1},
}
}

example.remove_nodes(HyperEdge([3]))
assert example._complex_set.hyperedge_dict == {
0: {frozenset({4}): {"weight": 1}, frozenset({6}): {"weight": 1}}
Expand Down
16 changes: 5 additions & 11 deletions test/classes/test_reportviews.py
Original file line number Diff line number Diff line change
Expand Up @@ -578,12 +578,9 @@ class TestReportViews_SimplexView:

def test_getitem(self):
"""Test __getitem__ method of the SimplexView."""
assert self.simplex_view.__getitem__((1, 2)) == {
"is_maximal": True,
"membership": set(),
}
assert self.simplex_view[(1, 2)] == {}
with pytest.raises(KeyError):
self.simplex_view.__getitem__([5])
_ = self.simplex_view[(5,)]

def test_str(self):
"""Test __str__ method of the SimplexView."""
Expand Down Expand Up @@ -612,15 +609,12 @@ def test_repr(self):

def test_getitem(self):
"""Test __getitem__ method of the NodeView."""
assert self.node_view.__getitem__(Simplex([1])) == {
"is_maximal": False,
"membership": {frozenset({1, 2})},
}
assert self.node_view[Simplex([1])] == {}
with pytest.raises(KeyError):
self.node_view.__getitem__([1, 2])
_ = self.node_view[(1, 2)]

# test for nodes of ColoredHyperGraph.
assert self.node_view_1.__getitem__([1]) == {"weight": 1}
assert self.node_view_1[(1,)] == {"weight": 1}


class TestReportViews_PathView:
Expand Down
131 changes: 131 additions & 0 deletions test/classes/test_simplex_trie.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
"""Tests for the `simplex_trie` module."""

import pytest

from toponetx.classes.simplex_trie import SimplexTrie


class TestSimplexTrie:
"""Tests for the `SimplexTree` class."""

def test_insert(self) -> None:
"""Test that the internal data structures of the simplex trie are correct after insertion."""
trie = SimplexTrie()
trie.insert((1, 2, 3))

assert trie.shape == [3, 3, 1]

assert set(trie.root.children.keys()) == {1, 2, 3}
assert set(trie.root.children[1].children.keys()) == {2, 3}
assert set(trie.root.children[1].children[2].children.keys()) == {3}
assert set(trie.root.children[2].children.keys()) == {3}

# the label list should contain the nodes of each depth according to their label
label_to_simplex = {
1: {1: [(1,)], 2: [(2,)], 3: [(3,)]},
2: {2: [(1, 2)], 3: [(1, 3), (2, 3)]},
3: {3: [(1, 2, 3)]},
}

assert len(trie.label_lists) == len(label_to_simplex)
for depth, label_list in trie.label_lists.items():
assert depth in label_to_simplex
assert len(label_list) == len(label_to_simplex[depth])
for label, nodes in label_list.items():
assert len(nodes) == len(label_to_simplex[depth][label])
for node, expected in zip(nodes, label_to_simplex[depth][label]):
assert node.simplex.elements == expected

def test_iter(self) -> None:
"""Test the iteration of the trie."""
trie = SimplexTrie()
trie.insert((1, 2, 3))
trie.insert((2, 3, 4))
trie.insert((0, 1))

# We guarantee a specific ordering of the simplices when iterating. Hence, we explicitly compare lists here.
assert list(map(lambda node: node.simplex.elements, trie)) == [
(0,),
(1,),
(2,),
(3,),
(4,),
(0, 1),
(1, 2),
(1, 3),
(2, 3),
(2, 4),
(3, 4),
(1, 2, 3),
(2, 3, 4),
]

def test_cofaces(self) -> None:
"""Test the cofaces method."""
trie = SimplexTrie()
trie.insert((1, 2, 3))
trie.insert((1, 2, 4))

# no ordering is guaranteed for the cofaces method
assert set(map(lambda node: node.simplex.elements, trie.cofaces((1,)))) == {
(1,),
(1, 2),
(1, 3),
(1, 4),
(1, 2, 3),
(1, 2, 4),
}
assert set(map(lambda node: node.simplex.elements, trie.cofaces((2,)))) == {
(2,),
(1, 2),
(2, 3),
(2, 4),
(1, 2, 3),
(1, 2, 4),
}

def test_is_maximal(self) -> None:
"""Test the `is_maximal` method."""
trie = SimplexTrie()
trie.insert((1, 2, 3))
trie.insert((1, 2, 4))

assert trie.is_maximal((1, 2, 3))
assert trie.is_maximal((1, 2, 4))
assert not trie.is_maximal((1, 2))
assert not trie.is_maximal((1, 3))
assert not trie.is_maximal((1, 4))
assert not trie.is_maximal((2, 3))

with pytest.raises(ValueError):
trie.is_maximal((5,))

def test_skeleton(self) -> None:
"""Test the skeleton method."""
trie = SimplexTrie()
trie.insert((1, 2, 3))
trie.insert((1, 2, 4))

# no ordering is guaranteed for the skeleton method
assert set(map(lambda node: node.simplex.elements, trie.skeleton(0))) == {
(1,),
(2,),
(3,),
(4,),
}
assert set(map(lambda node: node.simplex.elements, trie.skeleton(1))) == {
(1, 2),
(1, 3),
(1, 4),
(2, 3),
(2, 4),
}
assert set(map(lambda node: node.simplex.elements, trie.skeleton(2))) == {
(1, 2, 3),
(1, 2, 4),
}

with pytest.raises(ValueError):
_ = next(trie.skeleton(-1))
with pytest.raises(ValueError):
_ = next(trie.skeleton(3))
Loading
Loading