Skip to content

Commit 153b620

Browse files
Implementation of the eccentricity-based lifting of graphs to simplicial complexes
1 parent 37897eb commit 153b620

File tree

6 files changed

+402
-485
lines changed

6 files changed

+402
-485
lines changed

configs/transforms/liftings/graph2simplicial/graph_induced_lifting.yaml renamed to configs/transforms/liftings/graph2simplicial/eccentricity_lifting.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
transform_type: 'lifting'
2-
transform_name: "SimplicialGraphInducedLifting"
2+
transform_name: "SimplicialEccentricityLifting"
33
complex_dim: 3
44
preserve_edge_attr: False
55
signed: True

modules/transforms/data_transform.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,16 @@
1515
from modules.transforms.liftings.graph2simplicial.clique_lifting import (
1616
SimplicialCliqueLifting,
1717
)
18-
from modules.transforms.liftings.graph2simplicial.graph_induced_lifting import (
19-
SimplicialGraphInducedLifting,
18+
from modules.transforms.liftings.graph2simplicial.eccentricity_lifting import (
19+
SimplicialEccentricityLifting,
2020
)
2121

2222
TRANSFORMS = {
2323
# Graph -> Hypergraph
2424
"HypergraphKNNLifting": HypergraphKNNLifting,
2525
# Graph -> Simplicial Complex
2626
"SimplicialCliqueLifting": SimplicialCliqueLifting,
27-
"SimplicialGraphInducedLifting": SimplicialGraphInducedLifting,
27+
"SimplicialEccentricityLifting": SimplicialEccentricityLifting,
2828
# Graph -> Cell Complex
2929
"CellCycleLifting": CellCycleLifting,
3030
# Feature Liftings

modules/transforms/liftings/graph2simplicial/graph_induced_lifting.py renamed to modules/transforms/liftings/graph2simplicial/eccentricity_lifting.py

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
from modules.transforms.liftings.graph2simplicial.base import Graph2SimplicialLifting
88

99

10-
class SimplicialGraphInducedLifting(Graph2SimplicialLifting):
11-
r"""Lifts graphs to simplicial complex domain by identifying connected subgraphs as simplices.
10+
class SimplicialEccentricityLifting(Graph2SimplicialLifting):
11+
r"""Lifts graphs to simplicial complex domain using eccentricity.
1212
1313
Parameters
1414
----------
@@ -33,15 +33,20 @@ def lift_topology(self, data: torch_geometric.data.Data) -> dict:
3333
The lifted topology.
3434
"""
3535
graph = self._generate_graph_from_data(data)
36-
simplicial_complex = SimplicialComplex(graph)
37-
all_nodes = list(graph.nodes)
36+
simplicial_complex = SimplicialComplex()
37+
eccentricities = nx.eccentricity(graph)
3838
simplices = [set() for _ in range(2, self.complex_dim + 1)]
3939

40-
for k in range(2, self.complex_dim + 1):
41-
for combination in combinations(all_nodes, k + 1):
42-
subgraph = graph.subgraph(combination)
43-
if nx.is_connected(subgraph):
44-
simplices[k - 2].add(tuple(sorted(combination)))
40+
for node in graph.nodes:
41+
simplicial_complex.add_node(node, features=data.x[node])
42+
43+
for node, ecc in eccentricities.items():
44+
neighborhood = list(
45+
nx.single_source_shortest_path_length(graph, node, cutoff=ecc).keys()
46+
)
47+
for k in range(1, self.complex_dim):
48+
for combination in combinations(neighborhood, k + 1):
49+
simplices[k - 1].add(tuple(sorted(combination)))
4550

4651
for set_k_simplices in simplices:
4752
simplicial_complex.add_simplices_from(list(set_k_simplices))

test/transforms/liftings/graph2simplicial/test_graph_induced_lifting.py renamed to test/transforms/liftings/graph2simplicial/test_eccentricity_lifting.py

Lines changed: 28 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,21 @@
33
import torch
44

55
from modules.data.utils.utils import load_manual_graph
6-
from modules.transforms.liftings.graph2simplicial.graph_induced_lifting import (
7-
SimplicialGraphInducedLifting,
6+
from modules.transforms.liftings.graph2simplicial.eccentricity_lifting import (
7+
SimplicialEccentricityLifting,
88
)
99

1010

11-
class TestSimplicialCliqueLifting:
12-
"""Test the SimplicialCliqueLifting class."""
11+
class TestSimplicialEccentricityLifting:
12+
"""Test the SimplicialEccentricityLifting class."""
1313

1414
def setup_method(self):
1515
# Load the graph
1616
self.data = load_manual_graph()
1717

1818
# Initialise the SimplicialCliqueLifting class
19-
self.lifting_signed = SimplicialGraphInducedLifting(complex_dim=3, signed=True)
20-
self.lifting_unsigned = SimplicialGraphInducedLifting(
19+
self.lifting_signed = SimplicialEccentricityLifting(complex_dim=3, signed=True)
20+
self.lifting_unsigned = SimplicialEccentricityLifting(
2121
complex_dim=3, signed=False
2222
)
2323

@@ -57,14 +57,19 @@ def test_lift_topology(self):
5757

5858
expected_incidence_2_singular_values_unsigned = torch.tensor(
5959
[
60-
4.1190,
60+
4.2426,
6161
3.1623,
6262
3.1623,
6363
3.1623,
64-
3.0961,
65-
3.0000,
66-
3.0000,
67-
2.7564,
64+
3.1623,
65+
3.1623,
66+
3.1623,
67+
3.1623,
68+
2.0000,
69+
2.0000,
70+
2.0000,
71+
2.0000,
72+
2.0000,
6873
2.0000,
6974
2.0000,
7075
2.0000,
@@ -80,11 +85,6 @@ def test_lift_topology(self):
8085
2.0000,
8186
2.0000,
8287
2.0000,
83-
1.7321,
84-
1.6350,
85-
1.4142,
86-
1.4142,
87-
1.0849,
8888
]
8989
)
9090

@@ -106,18 +106,18 @@ def test_lift_topology(self):
106106
2.8284e00,
107107
2.8284e00,
108108
2.8284e00,
109-
2.6458e00,
110-
2.6458e00,
111-
2.2361e00,
112-
1.7321e00,
113-
1.7321e00,
114-
9.3758e-07,
115-
4.7145e-07,
116-
4.3417e-07,
117-
4.0241e-07,
118-
3.1333e-07,
119-
2.2512e-07,
120-
1.9160e-07,
109+
2.8284e00,
110+
2.8284e00,
111+
2.8284e00,
112+
2.8284e00,
113+
2.8284e00,
114+
7.0866e-07,
115+
4.0955e-07,
116+
3.2154e-07,
117+
2.9976e-07,
118+
2.8069e-07,
119+
2.3097e-07,
120+
9.4821e-08,
121121
]
122122
)
123123

@@ -129,91 +129,3 @@ def test_lift_topology(self):
129129
assert torch.allclose(
130130
expected_incidence_2_singular_values_signed, S_signed, atol=1.0e-04
131131
), "Something is wrong with signed incidence_2 (edges to triangles)."
132-
133-
expected_incidence_3_singular_values_unsigned = torch.tensor(
134-
[
135-
3.8466,
136-
3.1379,
137-
3.0614,
138-
2.8749,
139-
2.8392,
140-
2.8125,
141-
2.5726,
142-
2.3709,
143-
2.2858,
144-
2.2369,
145-
2.1823,
146-
2.0724,
147-
2.0000,
148-
2.0000,
149-
2.0000,
150-
1.8937,
151-
1.7814,
152-
1.7321,
153-
1.7256,
154-
1.5469,
155-
1.5340,
156-
1.4834,
157-
1.4519,
158-
1.4359,
159-
1.4142,
160-
1.0525,
161-
1.0000,
162-
1.0000,
163-
1.0000,
164-
1.0000,
165-
0.9837,
166-
0.9462,
167-
0.8853,
168-
0.7850,
169-
]
170-
)
171-
172-
expected_incidence_3_singular_values_signed = torch.tensor(
173-
[
174-
2.8284e00,
175-
2.8284e00,
176-
2.8284e00,
177-
2.8284e00,
178-
2.8284e00,
179-
2.8284e00,
180-
2.8284e00,
181-
2.8284e00,
182-
2.8284e00,
183-
2.6933e00,
184-
2.6458e00,
185-
2.6458e00,
186-
2.6280e00,
187-
2.4495e00,
188-
2.3040e00,
189-
1.9475e00,
190-
1.7321e00,
191-
1.7321e00,
192-
1.7321e00,
193-
1.4823e00,
194-
1.0000e00,
195-
1.0000e00,
196-
1.0000e00,
197-
1.0000e00,
198-
1.0000e00,
199-
1.0000e00,
200-
1.0000e00,
201-
1.0000e00,
202-
1.0000e00,
203-
7.3584e-01,
204-
2.7959e-07,
205-
2.1776e-07,
206-
1.4498e-07,
207-
5.5373e-08,
208-
]
209-
)
210-
211-
U, S_unsigned, V = torch.svd(lifted_data_unsigned.incidence_3.to_dense())
212-
U, S_signed, V = torch.svd(lifted_data_signed.incidence_3.to_dense())
213-
214-
assert torch.allclose(
215-
expected_incidence_3_singular_values_unsigned, S_unsigned, atol=1.0e-04
216-
), "Something is wrong with unsigned incidence_3 (triangles to tetrahedrons)."
217-
assert torch.allclose(
218-
expected_incidence_3_singular_values_signed, S_signed, atol=1.0e-04
219-
), "Something is wrong with signed incidence_3 (triangles to tetrahedrons)."

tutorials/graph2simplicial/eccentricity_lifting.ipynb

Lines changed: 356 additions & 0 deletions
Large diffs are not rendered by default.

tutorials/graph2simplicial/graph_induced_lifting.ipynb

Lines changed: 0 additions & 356 deletions
This file was deleted.

0 commit comments

Comments
 (0)