{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import networkx as nx\n",
    "from matplotlib import pyplot\n",
    "import aisa"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# This is an example notebook for AISA\n",
    "\n",
    "In this notebook we show how to use the module `aisa` to create a partition of you graph or dynamics and calculate the related Entrogram.\n",
    "\n",
    "See the following papers for reference:\n",
    "\n",
    "- **Entrograms and coarse graining of dynamics on complex networks**,\n",
    "    *Faccin, Schaub and Delvenne*,\n",
    "    [Journal of Complex Networks, 6(5) p. 661-678 (2018)](https://academic.oup.com/comnet/article-abstract/6/5/661/4587985) [[ArXiv](https://arxiv.org/abs/1711.01987)]\n",
    "\n",
    "- **State aggregations in Markov chains and block models of networks**,\n",
    "    *Faccin, Schaub and Delvenne* [[ArXiv](https://arxiv.org/abs/2005.00337)]\n",
    "\n",
    "## Load a graph\n",
    "\n",
    "for example the Karate Club"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Nodes: 34\n",
      "Edges: 78\n"
     ]
    }
   ],
   "source": [
    "graph = nx.karate_club_graph()\n",
    "print('Nodes:', len(graph))\n",
    "print('Edges:', graph.number_of_edges())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Load the partition"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{0: 'Mr. Hi', 1: 'Mr. Hi', 2: 'Mr. Hi', 3: 'Mr. Hi', 4: 'Mr. Hi', 5: 'Mr. Hi', 6: 'Mr. Hi', 7: 'Mr. Hi', 8: 'Mr. Hi', 9: 'Officer', 10: 'Mr. Hi', 11: 'Mr. Hi', 12: 'Mr. Hi', 13: 'Mr. Hi', 14: 'Officer', 15: 'Officer', 16: 'Mr. Hi', 17: 'Mr. Hi', 18: 'Officer', 19: 'Mr. Hi', 20: 'Officer', 21: 'Mr. Hi', 22: 'Officer', 23: 'Officer', 24: 'Officer', 25: 'Officer', 26: 'Officer', 27: 'Officer', 28: 'Officer', 29: 'Officer', 30: 'Officer', 31: 'Officer', 32: 'Officer', 33: 'Officer'}\n"
     ]
    }
   ],
   "source": [
    "partition = {n: data['club'] for n, data in graph.nodes(data=True)}\n",
    "print(partition)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Compute the Entrogram"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(0.5555265456648661, array([0.03121669, 0.00152005, 0.00047187, 0.00011017]))"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "depth = 4\n",
    "entrogram = aisa.entrogram(graph, partition, depth=depth)\n",
    "entrogram"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Draw the Entrogram"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 5872 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "axis = pyplot.axes()\n",
    "axis.bar(range(depth), entrogram[1])\n",
    "axis.set_xticks(range(depth))\n",
    "axis.set_xticklabels([f'$I_{i}$' for i in range(depth)])\n",
    "pyplot.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Find the best partition\n",
    "according to the time scale parameter $T$ and the model selection parameter $\\beta$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "3 [3]:   7%|▋         | 690/10000 [00:01<00:25, 362.83it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Autoinformation 0.1644140468118871\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    }
   ],
   "source": [
    "best_partition, ai = aisa.best_partition(graph, T=2, beta=0.2)\n",
    "print(\"Autoinformation\", ai)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 49636 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "for node, part in best_partition.items():\n",
    "    graph.nodes[node]['part'] = part\n",
    "nx.draw_networkx(graph, node_color=[best_partition[n] for n in graph.nodes()])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "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.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
