{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Bitcoin Alpha network"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "autoscroll": false,
    "collapsed": false,
    "ein.tags": "worksheet-0",
    "slideshow": {
     "slide_type": "-"
    }
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "autoscroll": false,
    "collapsed": false,
    "ein.tags": "worksheet-0",
    "slideshow": {
     "slide_type": "-"
    }
   },
   "outputs": [],
   "source": [
    "import igraph as ig\n",
    "import dionysus as d"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "plt.style.use(\"fivethirtyeight\")\n",
    "plt.rcParams[\"figure.figsize\"] = 10, 6"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Data import"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "autoscroll": false,
    "collapsed": false,
    "ein.tags": "worksheet-0",
    "slideshow": {
     "slide_type": "-"
    }
   },
   "outputs": [],
   "source": [
    "G = ig.read(\"data/bitcoin/bitcoinalpha.graphml\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "autoscroll": false,
    "collapsed": false,
    "ein.tags": "worksheet-0",
    "slideshow": {
     "slide_type": "-"
    }
   },
   "outputs": [],
   "source": [
    "G.to_undirected(combine_edges=\"first\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'IGRAPH U-W- 3783 14124 -- \\n+ attr: id (v), label (v), Edge Label (e), id (e), rating (e), time (e), weight (e)'"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "G.summary()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Weight rank clique filtration and persistent homology"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "from filtration import wrcf"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_diagram(graph, weight=\"weight\"):\n",
    "    filt = wrcf(graph, weight=weight)\n",
    "    pers = d.homology_persistence(filt)\n",
    "    return(d.init_diagrams(pers, filt))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 10.,   9.,   8.,   7.,   6.,   5.,   4.,   3.,   2.,   1.,  -1.,\n",
       "        -2.,  -3.,  -4.,  -5.,  -6.,  -7.,  -8.,  -9., -10.])"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.unique(G.es[\"rating\"])[::-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "dgms = get_diagram(G, weight=\"rating\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[Diagram with 3783 points,\n",
       " Diagram with 29472 points,\n",
       " Diagram with 1410 points,\n",
       " Diagram with 175 points,\n",
       " Diagram with 10 points,\n",
       " Diagram with 0 points,\n",
       " Diagram with 0 points,\n",
       " Diagram with 0 points,\n",
       " Diagram with 0 points,\n",
       " Diagram with 0 points]"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dgms"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 17172 characters]\n",
      "text/plain": [
       "<Figure size 720x432 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "d.plot.plot_bars(dgms[1])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Normalize the time scale"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1289192400.0, 1453438800.0)"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "time_min = min(G.es[\"time\"])\n",
    "time_max = max(G.es[\"time\"])\n",
    "time_min, time_max"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "G.es[\"time\"] = (np.array(G.es[\"time\"]) - time_min) / (time_max - time_min)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 15760 characters]\n",
      "text/plain": [
       "<Figure size 720x432 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.hist(G.es[\"time\"], bins=50);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Discretize the time scale using non-overlapping windows"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {},
   "outputs": [],
   "source": [
    "N = 8 # Number of windows"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "metadata": {},
   "outputs": [],
   "source": [
    "subgs = list(range(N))\n",
    "for i in range(N):\n",
    "    subgs[i] = G.subgraph_edges(G.es(lambda e: (e[\"time\"] < (i+1)/N) & (e[\"time\"] > i/N)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'IGRAPH U-W- 3783 14124 -- \\n+ attr: id (v), label (v), Edge Label (e), id (e), rating (e), time (e), weight (e)'"
      ]
     },
     "execution_count": 71,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "G.summary()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "IGRAPH U-W- 1203 3017 -- \n",
      "+ attr: id (v), label (v), Edge Label (e), id (e), rating (e), time (e), weight (e)\n",
      "IGRAPH U-W- 779 1714 -- \n",
      "+ attr: id (v), label (v), Edge Label (e), id (e), rating (e), time (e), weight (e)\n",
      "IGRAPH U-W- 999 2820 -- \n",
      "+ attr: id (v), label (v), Edge Label (e), id (e), rating (e), time (e), weight (e)\n",
      "IGRAPH U-W- 1201 2959 -- \n",
      "+ attr: id (v), label (v), Edge Label (e), id (e), rating (e), time (e), weight (e)\n",
      "IGRAPH U-W- 776 1721 -- \n",
      "+ attr: id (v), label (v), Edge Label (e), id (e), rating (e), time (e), weight (e)\n",
      "IGRAPH U-W- 562 1285 -- \n",
      "+ attr: id (v), label (v), Edge Label (e), id (e), rating (e), time (e), weight (e)\n",
      "IGRAPH U-W- 231 447 -- \n",
      "+ attr: id (v), label (v), Edge Label (e), id (e), rating (e), time (e), weight (e)\n",
      "IGRAPH U-W- 95 155 -- \n",
      "+ attr: id (v), label (v), Edge Label (e), id (e), rating (e), time (e), weight (e)\n"
     ]
    }
   ],
   "source": [
    "for g in subgs:\n",
    "    print(g.summary())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Apply persistent homology to each window"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {},
   "outputs": [],
   "source": [
    "from dask.distributed import Client"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "metadata": {},
   "outputs": [],
   "source": [
    "client = Client(processes=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 75,
   "metadata": {},
   "outputs": [],
   "source": [
    "dgms = client.map(get_diagram, subgs)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 90,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'inproc://129.67.184.177/6482/23': 32}"
      ]
     },
     "execution_count": 90,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "client.ncores()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 76,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[[Diagram with 1203 points,\n",
       "  Diagram with 945 points,\n",
       "  Diagram with 8 points,\n",
       "  Diagram with 0 points,\n",
       "  Diagram with 0 points],\n",
       " [Diagram with 779 points,\n",
       "  Diagram with 399 points,\n",
       "  Diagram with 7 points,\n",
       "  Diagram with 0 points,\n",
       "  Diagram with 0 points],\n",
       " [Diagram with 999 points,\n",
       "  Diagram with 628 points,\n",
       "  Diagram with 107 points,\n",
       "  Diagram with 0 points,\n",
       "  Diagram with 0 points,\n",
       "  Diagram with 0 points],\n",
       " [Diagram with 1201 points,\n",
       "  Diagram with 647 points,\n",
       "  Diagram with 27 points,\n",
       "  Diagram with 1 points,\n",
       "  Diagram with 0 points,\n",
       "  Diagram with 0 points,\n",
       "  Diagram with 0 points],\n",
       " [Diagram with 776 points,\n",
       "  Diagram with 372 points,\n",
       "  Diagram with 16 points,\n",
       "  Diagram with 0 points,\n",
       "  Diagram with 0 points],\n",
       " [Diagram with 562 points,\n",
       "  Diagram with 189 points,\n",
       "  Diagram with 11 points,\n",
       "  Diagram with 0 points,\n",
       "  Diagram with 0 points,\n",
       "  Diagram with 0 points,\n",
       "  Diagram with 0 points],\n",
       " [Diagram with 231 points,\n",
       "  Diagram with 111 points,\n",
       "  Diagram with 0 points,\n",
       "  Diagram with 0 points,\n",
       "  Diagram with 0 points],\n",
       " [Diagram with 95 points,\n",
       "  Diagram with 31 points,\n",
       "  Diagram with 0 points,\n",
       "  Diagram with 0 points]]"
      ]
     },
     "execution_count": 76,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dgms = client.gather(dgms)\n",
    "dgms"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "plotting not available",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-86-c9bce81ae290>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mig\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mplot\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msubgs\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;32m~/.local/share/virtualenvs/tda-networks--KypeAmE/lib/python3.5/site-packages/igraph/drawing/__init__.py\u001b[0m in \u001b[0;36mplot\u001b[0;34m(obj, target, bbox, *args, **kwds)\u001b[0m\n\u001b[1;32m    444\u001b[0m         \u001b[0mbbox\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mBoundingBox\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mbbox\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    445\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 446\u001b[0;31m     \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mPlot\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtarget\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mbbox\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mbackground\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mkwds\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"background\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"white\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    447\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    448\u001b[0m     \u001b[0;32mif\u001b[0m \u001b[0;34m\"margin\"\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mkwds\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m~/.local/share/virtualenvs/tda-networks--KypeAmE/lib/python3.5/site-packages/igraph/drawing/__init__.py\u001b[0m in \u001b[0;36m__init__\u001b[0;34m(self, target, bbox, palette, background)\u001b[0m\n\u001b[1;32m    115\u001b[0m         \"\"\"\n\u001b[1;32m    116\u001b[0m         \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_filename\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 117\u001b[0;31m         \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_surface_was_created\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtarget\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcairo\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mSurface\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    118\u001b[0m         \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_need_tmpfile\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mFalse\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    119\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m~/.local/share/virtualenvs/tda-networks--KypeAmE/lib/python3.5/site-packages/igraph/drawing/utils.py\u001b[0m in \u001b[0;36m__getattr__\u001b[0;34m(self, _)\u001b[0m\n\u001b[1;32m    394\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    395\u001b[0m     \u001b[0;32mdef\u001b[0m \u001b[0m__getattr__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0m_\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 396\u001b[0;31m         \u001b[0;32mraise\u001b[0m \u001b[0mTypeError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"plotting not available\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    397\u001b[0m     \u001b[0;32mdef\u001b[0m \u001b[0m__call__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0m_\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    398\u001b[0m         \u001b[0;32mraise\u001b[0m \u001b[0mTypeError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"plotting not available\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mTypeError\u001b[0m: plotting not available"
     ]
    }
   ],
   "source": [
    "ig.plot(subgs[0])"
   ]
  },
  {
   "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.5.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
