Skip to content

Matroid lifting (Graph to Combinatorial) #32

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

Merged
merged 33 commits into from
Feb 19, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
2c7728b
Made a basic matroid implementation
gescalona1 Jun 30, 2024
10f2a39
Implemented circuits
gescalona1 Jun 30, 2024
6922597
Implemented matroid rank function
gescalona1 Jun 30, 2024
510c980
Added matroid span
gescalona1 Jun 30, 2024
e16775d
Slight optimized of matroid span
gescalona1 Jun 30, 2024
889c838
Added graphic matroid
gescalona1 Jun 30, 2024
2e22df7
Implemented dual matroid
gescalona1 Jul 1, 2024
b9b883b
Added deletion matroid
gescalona1 Jul 1, 2024
cd74a8d
Added contraction
gescalona1 Jul 1, 2024
f192da6
Remove contraction
gescalona1 Jul 3, 2024
0cbbe35
graph to matroid lifting
gescalona1 Jul 4, 2024
06b14a3
Graph curve lifting
gescalona1 Jul 4, 2024
c466539
Fixed ruff complaints
gescalona1 Jul 4, 2024
2e482af
Reorganized notebook
gescalona1 Jul 4, 2024
3f3e46c
Added HMC model
gescalona1 Jul 5, 2024
afbb83b
Merge branch 'main' into matroid_lifting
gescalona1 Jul 5, 2024
40277fb
Added truncated / sub combinatorial ranking
gescalona1 Jul 6, 2024
599711a
Fixed tests
gescalona1 Jul 6, 2024
f4bcc5b
Fixed notebook tutorial
gescalona1 Jul 6, 2024
9775f6d
Added another test on truncated matroid
gescalona1 Jul 6, 2024
9f6802d
Fixed ruff linting
gescalona1 Jul 6, 2024
4b3a95e
Rewrote Matroid class
gescalona1 Jul 9, 2024
c65dfb7
Added docstring
gescalona1 Jul 9, 2024
456dc06
Reformatted tests
gescalona1 Jul 9, 2024
7ce0071
Cleaned up modules
gescalona1 Jul 10, 2024
9162101
Updated notebook
gescalona1 Jul 10, 2024
d6f8a9a
Updated tests
gescalona1 Jul 10, 2024
2be12b4
Fixed ruff
gescalona1 Jul 10, 2024
4b90134
Added extra data
gescalona1 Jul 11, 2024
7382d7a
Notebook linting
gescalona1 Jul 11, 2024
88c6b87
Removed 10-vertices
gescalona1 Jul 11, 2024
8194217
Fixed ruff linting
gescalona1 Jul 11, 2024
52b0dc2
Merge branch 'main' into matroid_lifting
gbg141 Feb 19, 2025
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
12 changes: 12 additions & 0 deletions configs/datasets/graph_8.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
data_domain: graph
data_type: trivalent
data_name: graphs_8vertices
data_dir: datasets/${data_domain}/${data_type}

# Dataset parameters
num_features: 1
num_classes: 2
task: classification
loss_type: cross_entropy
monitor_metric: accuracy
task_level: node
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
transform_type: 'lifting'
transform_name: "CurveLifting"
feature_lifting: ProjectionSum
max_rank: 2
6 changes: 6 additions & 0 deletions modules/data/load/loaders.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@
)
from modules.data.utils.custom_dataset import CustomDataset
from modules.data.utils.utils import (
load_8_vertex_cubic_graphs,
load_cell_complex_dataset,
load_double_house_graph,
load_gudhi_dataset,
load_hypergraph_pickle_dataset,
load_manual_graph,
Expand Down Expand Up @@ -139,6 +141,10 @@ def load(self) -> torch_geometric.data.Dataset:
data = load_manual_graph()
dataset = CustomDataset([data], self.data_dir)

elif self.parameters.data_name in ["graphs_8vertices"]:
graphs = load_8_vertex_cubic_graphs()
dataset = CustomDataset(graphs, self.data_dir)

elif self.parameters.data_name in ["manual_rings"]:
data = load_manual_mol()
dataset = CustomDataset([data], self.data_dir)
Expand Down
135 changes: 135 additions & 0 deletions modules/data/utils/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import toponetx.datasets.graph as graph
import torch
import torch_geometric
import torch_geometric.data
from gudhi.datasets.generators import points
from gudhi.datasets.remote import (
fetch_bunny,
Expand All @@ -23,6 +24,45 @@
rootutils.setup_root("./", indicator=".project-root", pythonpath=True)


def get_ccc_connectivity(complex, max_rank):
r"""

Parameters
----------
complex : topnetx.CombinatorialComplex, topnetx.SimplicialComplex
Combinatorial Complex complex.
max_rank : int
Maximum rank of the complex.

Returns
-------
dict
Dictionary containing the connectivity matrices.
"""
practical_shape = list(
np.pad(list(complex.shape), (0, max_rank + 1 - len(complex.shape)))
)

connectivity = {}
# compute incidence matrices
for rank_idx in range(1, max_rank + 1):
matrix = complex.incidence_matrix(rank=rank_idx - 1, to_rank=rank_idx)
connectivity[f"incidence_{rank_idx}"] = from_sparse(matrix)

# compute adjacent matrices
for rank_idx in range(max_rank + 1):
matrix = complex.adjacency_matrix(rank_idx, rank_idx + 1)
connectivity[f"adjacency_{rank_idx}"] = from_sparse(matrix)

for rank_idx in range(1, max_rank + 1):
matrix = complex.laplacian_matrix(rank_idx)
connectivity[f"laplacian_{rank_idx}"] = matrix

connectivity["shape"] = practical_shape

return connectivity


def get_complex_connectivity(complex, max_rank, signed=False):
r"""Gets the connectivity matrices for the complex.

Expand Down Expand Up @@ -365,6 +405,100 @@ def load_manual_graph():
)



def load_k4_graph() -> torch_geometric.data.Data:
"""K_4 is a complete graph with 4 vertices."""
vertices = [i for i in range(4)]
y = [0, 1, 1, 1]
edges = [
[0, 1],
[0, 2],
[0, 3],
[1, 2],
[1, 3],
[2, 3],
]
G = nx.Graph()
G.add_nodes_from(vertices)
G.add_edges_from(edges)
G.to_undirected()
edge_list = torch.Tensor(list(G.edges())).T.long()
x = torch.tensor([1, 5, 10, 50]).unsqueeze(1).float()
return torch_geometric.data.Data(
x=x, edge_index=edge_list, num_nodes=len(vertices), y=torch.tensor(y)
)


def load_double_house_graph() -> torch_geometric.data.Data:
"""Double house graph is a featured graph in Geiger et al."""
vertices = [i for i in range(8)]
y = [0, 1, 1, 1, 0, 0, 0, 0]
edges = [
[0, 1],
[0, 2],
[0, 7],
[1, 2],
[1, 3],
[2, 4],
[3, 5],
[3, 4],
[4, 6],
[5, 6],
[5, 7],
[6, 7],
]
G = nx.Graph()
G.add_nodes_from(vertices)
G.add_edges_from([[v1, v2] for (v1, v2) in edges])
G.to_undirected()
edge_list = torch.Tensor(list(G.edges())).T.long()
x = torch.tensor([1, 5, 10, 50, 100, 500, 1000, 5000]).unsqueeze(1).float()
return torch_geometric.data.Data(
x=x, edge_index=edge_list, num_nodes=len(vertices), y=torch.tensor(y)
)


def load_8_vertex_cubic_graphs() -> list[torch_geometric.data.Data]:
"""Downloaded from https://mathrepo.mis.mpg.de/GraphCurveMatroids/"""
# fmt: off
edgesets = [
[{1, 2}, {1, 3}, {1, 4}, {2, 3}, {2, 4}, {3, 5}, {4, 6}, {5, 7}, {5, 8}, {6, 7}, {6, 8}, {7, 8}],
[{1, 2}, {1, 3}, {1, 4}, {2, 3}, {2, 5}, {3, 6}, {4, 5}, {4, 7}, {5, 8}, {6, 7}, {6, 8}, {7, 8}],
[{1, 2}, {1, 3}, {1, 4}, {2, 3}, {2, 5}, {3, 6}, {4, 7}, {4, 8}, {5, 7}, {5, 8}, {6, 7}, {6, 8}],
[{1, 2}, {1, 3}, {1, 4}, {2, 5}, {2, 6}, {3, 5}, {3, 7}, {4, 6}, {4, 7}, {5, 8}, {6, 8}, {7, 8}],
[{1, 2}, {1, 3}, {1, 4}, {2, 5}, {2, 6}, {3, 5}, {3, 7}, {4, 6}, {4, 8}, {5, 8}, {6, 7}, {7, 8}],
]
# fmt: on

list_data = []
for i, edgeset in enumerate(edgesets):
n = 8 if i < 5 else 10
vertices = [i for i in range(n)]
x = (
torch.tensor([1, 5, 10, 50, 100, 500, 1000, 5000]).unsqueeze(1).float()
if i < 5
else torch.tensor([1, 5, 10, 50, 100, 500, 1000, 5000, 10000, 50000])
.unsqueeze(1)
.float()
)
y = (
torch.tensor([0, 1, 1, 1, 0, 0, 0, 0])
if i < 5
else torch.tensor([0, 1, 1, 1, 0, 0, 0, 0, 1, 1])
)
edgeset = [[v1 - 1, v2 - 1] for (v1, v2) in edgeset]
G = nx.Graph()
G.add_nodes_from(vertices)
# offset by 1, since the graphs presented start at 1.
G.add_edges_from(edgeset)
G.to_undirected()
edge_list = torch.Tensor(list(G.edges())).T.long()

data = torch_geometric.data.Data(x=x, edge_index=edge_list, num_nodes=n, y=y)

list_data.append(data)
return list_data

def load_manual_mol():
"""Create a manual graph for testing the ring implementation.
Actually is the 471 molecule of QM9 dataset."""
Expand Down Expand Up @@ -486,6 +620,7 @@ def load_manual_mol():
)



def get_Planetoid_pyg(cfg):
r"""Loads Planetoid graph datasets from torch_geometric.

Expand Down
Loading
Loading