Skip to content

Instantly share code, notes, and snippets.

@dmikushin
Forked from V0XNIHILI/matrix_as_graph.ipynb
Created January 29, 2024 16:48
Show Gist options
  • Save dmikushin/6d9a0742532450c732ef5fb73af1e8f4 to your computer and use it in GitHub Desktop.
Save dmikushin/6d9a0742532450c732ef5fb73af1e8f4 to your computer and use it in GitHub Desktop.
Matrix multiplication in graph form
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Matrix multiplication in graph form\n",
"\n",
"I pondered about the idea of multiplying matrices in graph form and found this amazing page (https://www.math3ma.com/blog/matrices-probability-graphs) where they explain very clearly how to do this. Based on this explanation, I built a program to do the procedure for multiplying matrices in graph format automatically."
]
},
{
"cell_type": "code",
"execution_count": 324,
"metadata": {},
"outputs": [],
"source": [
"import networkx as nx\n",
"import numpy as np"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Matrices to multiply"
]
},
{
"cell_type": "code",
"execution_count": 325,
"metadata": {},
"outputs": [],
"source": [
"matrix1 = np.array([[-1, 2], [4, -3], [1, 2]])\n",
"matrix2 = np.array([[5, 1], [-7, -1]])\n",
"matrix3 = np.array([[5, 1], [6, 7]])\n",
"matrix4 = np.array([[1, 7, 8, -2], [-7, 5, 6, 3]])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Utility functions"
]
},
{
"cell_type": "code",
"execution_count": 327,
"metadata": {},
"outputs": [],
"source": [
"def create_graph_from_matrix(matrix: np.ndarray) -> nx.DiGraph:\n",
" G = nx.DiGraph()\n",
"\n",
" for dim, axis, layer in zip(matrix.shape, [\"i\", \"j\"], [0, 1]):\n",
" G.add_nodes_from([f\"{axis}_{dim_entry+1}\" for dim_entry in range(dim)], layer=layer)\n",
"\n",
" for i, j in np.ndindex(matrix.shape):\n",
" if matrix[i, j] != 0:\n",
" G.add_edge(f\"i_{i+1}\", f\"j_{j+1}\", weight=matrix[i, j])\n",
"\n",
" return G"
]
},
{
"cell_type": "code",
"execution_count": 331,
"metadata": {},
"outputs": [],
"source": [
"def get_max_k(nodes: list):\n",
" return max(map(lambda x: int(x.split('k')[1].split('_')[0]), filter(lambda x: x.startswith('k'), nodes)), default=-1)\n",
" \n",
"def new_node_name(old_name: str, step: int) -> str:\n",
" axis, index = old_name.split(\"_\")\n",
" \n",
" if axis == \"i\":\n",
" return f\"j_{index}\"\n",
"\n",
" if axis == \"j\":\n",
" return f\"final_i_{index}\"\n",
"\n",
" if axis.startswith('k'):\n",
" old_index = int(old_name.split(\"k\")[1].split(\"_\")[0])\n",
"\n",
" return f\"k{old_index + step}_{old_name.split('_')[1]}\"\n",
"\n",
"def get_layer_index(node: str, max_k: int):\n",
" if node.startswith('i'):\n",
" return 0\n",
"\n",
" if node.startswith('k'):\n",
" return int(node.split('k')[1].split('_')[0]) + 1\n",
"\n",
" if node.startswith('j'):\n",
" return max_k + 2\n",
"\n",
"def multiply_graphs(G1: nx.DiGraph, G2: nx.DiGraph) -> nx.DiGraph:\n",
" max_index = get_max_k(G1.nodes)\n",
"\n",
" G_2_relabeled = nx.relabel_nodes(G2, {node: new_node_name(node, max_index + 2) for node in G2.nodes})\n",
" G_composed = nx.compose(G1, G_2_relabeled)\n",
" G_composed_relabeled = nx.relabel_nodes(G_composed, {node: node.replace(\"j\", f\"k{max_index+1}\").replace(\"final_i\", \"j\") for node in G_composed.nodes})\n",
"\n",
" max_relabeled_index = get_max_k(G_composed_relabeled.nodes)\n",
"\n",
" attrs = {node: {\"layer\": get_layer_index(node, max_relabeled_index)} for node in G_composed_relabeled.nodes}\n",
"\n",
" nx.set_node_attributes(G_composed_relabeled, attrs)\n",
"\n",
" return G_composed_relabeled"
]
},
{
"cell_type": "code",
"execution_count": 332,
"metadata": {},
"outputs": [],
"source": [
"def plot_matrix(G: nx.DiGraph):\n",
" pos = nx.multipartite_layout(G, subset_key='layer')\n",
" \n",
" nx.draw(G, with_labels=True, pos=pos)\n",
"\n",
" edge_labels = nx.get_edge_attributes(G, \"weight\")\n",
" nx.draw_networkx_edge_labels(G, pos, edge_labels, label_pos=0.6)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Graph multiplication"
]
},
{
"cell_type": "code",
"execution_count": 333,
"metadata": {},
"outputs": [],
"source": [
"G1 = create_graph_from_matrix(matrix1)\n",
"G2 = create_graph_from_matrix(matrix2)\n",
"G3 = create_graph_from_matrix(matrix3)\n",
"G4 = create_graph_from_matrix(matrix4)"
]
},
{
"cell_type": "code",
"execution_count": 341,
"metadata": {},
"outputs": [],
"source": [
"G = multiply_graphs(multiply_graphs(multiply_graphs(G1, G2), G3), G4)"
]
},
{
"cell_type": "code",
"execution_count": 342,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"plot_matrix(G)"
]
},
{
"cell_type": "code",
"execution_count": 339,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[ 167, -991, -1144, 106],\n",
" [ -383, 2179, 2516, -224],\n",
" [ 61, -437, -504, 54]])"
]
},
"execution_count": 339,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"((matrix1 @ matrix2) @ matrix3) @ matrix4"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3.9.12 64-bit",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.12"
},
"orig_nbformat": 4,
"vscode": {
"interpreter": {
"hash": "aee8b7b246df8f9039afb4144a1f6fd8d2ca17a180786b69acc140d282b71a49"
}
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment