Source code for rllm.utils.undirected

import torch
from torch import Tensor


[docs] def is_undirected(adj: Tensor): r"""Check if the given adjacency matrix represents an undirected graph. Args: adj (Tensor): The adjacency matrix in sparse COO format. Returns: bool: :obj:`True` if the graph is undirected, :obj:`False` otherwise. """ M, N = adj.shape if M != N: return False # Ensure the adjacency matrix is in coalesced format adj = adj.coalesce() edge_index = adj.indices() values = adj.values() # Sort the source and target indices src1, indices1 = torch.sort(edge_index[0]) tgt1 = edge_index[1][indices1] src2, indices2 = torch.sort(edge_index[1]) tgt2 = edge_index[0][indices2] # Check if the sorted source and target indices match if not torch.equal(src1, src2): return False if not torch.equal(tgt1, tgt2): return False # Check if the edge values match if not torch.equal(values[indices1], values[indices2]): return False return True
[docs] def to_undirected(adj: Tensor): r"""Convert the given adjacency matrix to an undirected graph representation by adding reverse edges. Args: adj (Tensor): The adjacency matrix in sparse COO format. Returns: Tensor: The symmetrized (undirected) adjacency matrix in sparse COO format. """ # Determine the size of the adjacency matrix N = max(adj.shape[0], adj.shape[1]) # Ensure the adjacency matrix is in coalesced format adj = adj.coalesce() row, col = adj.indices() values = adj.values() # Concatenate the indices and values to form an undirected graph row, col = torch.cat([row, col], dim=0), torch.cat([col, row], dim=0) edge_index = torch.stack([row, col], dim=0) values = torch.cat([values, values], dim=0) # Create and return the undirected adjacency matrix return torch.sparse_coo_tensor(edge_index, values, (N, N)).coalesce()