Source code for graphein.ml.diffusion

"""Generate diffusion matrices based on NetworkX graph objects.

Author: Arian Jamasb & Eric Ma

Each of the functions here accepts a NetworkX graph object
and returns a 2D xarray.
These arrays can then be stacked to generate a diffusion tensor.
"""

from typing import Dict

import networkx as nx
import numpy as np
import pandas as pd
import xarray as xr

from graphein.protein.edges.distance import compute_distmat
from graphein.utils.utils import format_adjacency, generate_feature_dataframe


[docs] def identity_matrix(G: nx.Graph) -> xr.DataArray: """Return the identity diffusion matrix. This is nothing more than the identity matrix with diagonals of ``1``. :param G: Graph to retrieve identity diffusion matrix from :type G: nx.Graph :returns: Identity diffusion matrix :rtype: xr.DataArray """ return format_adjacency(G, np.eye(len(G)), "identity")
[docs] def adjacency_matrix_power( G: nx.Graph, amat_kwargs: Dict = {}, with_identity: bool = True, power: float = 1, ) -> xr.DataArray: """ Return the matrix power of the adjacency matrix. :param amat_kwargs: Keyword arguments to configure NetworkX's ``adjacency_matrix`` function. Defaults to ``{}`` :type amat_kwargs: Dict[str, Any] :param with_identity: Whether or not to add in the identity matrix to the adjacency matrix. Effectively adding "self loops". Defaults to True. :type with_identity: bool :param power: Matrix power to raise the adjacency matrix, defaults to 1. :type power: float :returns: the matrix power of the adjacency matrix :rtype: xr.DataArray """ adjacency_matrix_kwargs = {"weight": "weight", "nodelist": None} adjacency_matrix_kwargs.update(amat_kwargs) amat = nx.adjacency_matrix(G, **adjacency_matrix_kwargs) if with_identity: amat = amat + np.eye(len(G)) amat = np.linalg.matrix_power(amat, power) return format_adjacency( G, amat, f"adjacency_matrix_power_{power}", )
[docs] def inverse_distance_matrix(G: nx.Graph, power: float) -> xr.DataArray: """ Return the inverse distance matrix. Using the coordinates present on the graph object, calculate the inverse power distance matrix. The resultant array will be symmetric, with entries [i, j] corresponding to 1 / (distance**power), where distance == euclidean distance between the (x, y, z) coordinates of the two graphs. Diagonals (entries [i, i]) are set to 0. :param G: NetworkX Graph object. Assumes that each node has ``x_coord``, ``y_coord``, and ``z_coord`` as node attributes. :type G: nx.Graph :param power: The power for the distance calculation. :type power: float :returns: the inverse distance matrix. :type: xr.DataArray """ def extract_coords(n, d) -> pd.Series: """ Extracts xyz coordinates from a node. :param n: node id :param d: node data :return: pd.Series containing x,y,z coordinates :rtype: pd.Series """ coord_names = ("x_coord", "y_coord", "z_coord") return pd.Series( {coord_name: d[coord_name] for coord_name in coord_names}, name=n ) coords = generate_feature_dataframe(G, funcs=[extract_coords]) distmat = compute_distmat(coords).values I = np.eye(len(G)) distmat = (distmat + I) ** power distmat = 1 / distmat distmat -= I return format_adjacency( G, distmat, f"inverse_distance_matrix_power_{power}" )