{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "ad19f8f3",
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "from time import time\n",
    "import os\n",
    "\n",
    "import sys\n",
    "sys.path += ['utils/']  \n",
    "\n",
    "from EDRep import *\n",
    "from dcsbm import *\n",
    "from node_embedding import *\n",
    "\n",
    "import warnings\n",
    "warnings.filterwarnings(\"ignore\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a2e78dd5",
   "metadata": {},
   "source": [
    "## Test against spectral clustering"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "6512871c",
   "metadata": {},
   "outputs": [],
   "source": [
    "def RunSimulation(N, n_clusters, c, c_out_v, γ, dim):\n",
    "    \n",
    "    dfNMI = pd.DataFrame(columns = ['α', 'EDRep', 'DW', 'SC'])\n",
    "    dft = pd.DataFrame(columns = ['α', 'EDRep', 'DW', 'SC'])\n",
    "    \n",
    "    θ = np.random.uniform(3,12, 10000000)**γ\n",
    "    θ = θ/np.mean(θ)\n",
    "    sq = np.mean(θ**2)\n",
    "\n",
    "    # label vector\n",
    "    π = np.ones(n_clusters)/n_clusters\n",
    "    label = np.concatenate([[j for i in range(int(π[j]*N))] for j in range(n_clusters)])\n",
    "\n",
    "    θ = np.random.uniform(3, 12, N)**γ\n",
    "    θ = θ/np.mean(θ)\n",
    "    \n",
    "    for i, c_out in enumerate(c_out_v):\n",
    "        \n",
    "        n = N\n",
    "        α = (c - c_out)*np.sqrt(sq/c)\n",
    "\n",
    "        # create the C matrix\n",
    "        C = matrix_C(c_out, c, 0., π)\n",
    "\n",
    "        # generate the adjacency matrix\n",
    "        A, ℓ = adj(C,c, label, θ, True)\n",
    "        \n",
    "        tv = []\n",
    "        NMIv = []\n",
    "\n",
    "        # Node embedding with degree correction\n",
    "        t0 = time()\n",
    "        res = NodeEmbedding(A, dim, n_epochs = 50, walk_length = 3, k = 1, verbose = False, η = 1., sym = True)\n",
    "        NMIv.append(computeScore(res.X, ℓ))\n",
    "        tv.append(time()-t0)\n",
    "        \n",
    "        # Node2Vec\n",
    "        t0 = time()\n",
    "        Y = Node2VecNS(A, dim, verbose = False)\n",
    "        tv.append(time() - t0)\n",
    "        NMIv.append(computeScore(Y, ℓ))\n",
    "\n",
    "        # Spectral clustering\n",
    "        t0 = time()\n",
    "        X = community_detection(A , n_clusters = n_clusters, verbose = False)\n",
    "        tv.append(time()-t0)\n",
    "        NMIv.append(computeScore(X, ℓ))\n",
    "        \n",
    "\n",
    "        print(\"[%-25s] %d%%\" % ('='*(int((i+1)/len(c_out_v)*25)-1) + '>', (i+1)/(len(c_out_v))*100), end = '\\r')\n",
    "\n",
    "        row = {'α': α, 'EDRep': NMIv[0], 'DW': NMIv[1], 'SC': NMIv[2]}\n",
    "        dfNMI = dfNMI.append(row, ignore_index = True)\n",
    "        \n",
    "        row = {'α': α, 'EDRep': tv[0], 'DW': tv[1], 'SC': tv[2]}\n",
    "        dft = dft.append(row, ignore_index = True)\n",
    "        \n",
    "   \n",
    "    # save the result\n",
    "    try:\n",
    "        nn = (np.max([int(x.split('_')[1]) for x in os.listdir('saved_files/CD/NMI')]))\n",
    "        dfNMI.to_csv('saved_files/CD/NMI/v_' + str(nn+1) + '_.csv', index = False)\n",
    "\n",
    "    except:\n",
    "        dfNMI.to_csv('saved_files/CD/NMI/v_' + str(1) + '_.csv', index = False)\n",
    "        \n",
    "        \n",
    "    try:\n",
    "        nn = (np.max([int(x.split('_')[1]) for x in os.listdir('saved_files/CD/t')]))\n",
    "        dft.to_csv('saved_files/CD/t/v_' + str(nn+1) + '_.csv', index = False)\n",
    "\n",
    "    except:\n",
    "        dft.to_csv('saved_files/CD/t/v_' + str(1) + '_.csv', index = False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "23c7000e",
   "metadata": {},
   "outputs": [],
   "source": [
    "# n_iterations = 10\n",
    "# N = 30000\n",
    "# n_clusters = 4\n",
    "# c = 10\n",
    "# c_out_v = np.linspace(1, 9.5, 15)\n",
    "# γ = 6\n",
    "# dim = 32\n",
    "\n",
    "# for nn in range(n_iterations):\n",
    "#     print('\\n' + str(nn+1) + '/' + str(n_iterations) + '\\n')\n",
    "#     RunSimulation(N, n_clusters, c, c_out_v, γ, dim)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "a610c436",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 93300 characters]\n",
      "text/plain": [
       "<Figure size 1080x360 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "dfNMI_list = []\n",
    "dft_list = []\n",
    "\n",
    "for filename_NMI, filename_t in zip(os.listdir('saved_files/CD/NMI'), os.listdir('saved_files/CD/t')):\n",
    "    dfNMI_list.append(pd.read_csv('saved_files/CD/NMI/' + filename_NMI))\n",
    "    dft_list.append(pd.read_csv('saved_files/CD/t/' + filename_t))\n",
    "    \n",
    "dfNMI = pd.concat(dfNMI_list)\n",
    "dfNMI.α = dfNMI.α.map(lambda x: np.round(x, 1))\n",
    "dfNMI_m = dfNMI.groupby('α').mean().reset_index()\n",
    "dfNMI_stdv = dfNMI.groupby('α').std().reset_index()\n",
    "\n",
    "dft = pd.concat(dft_list)\n",
    "dft.α = dft.α.map(lambda x: np.round(x, 1))\n",
    "dft_m = dft.groupby('α').mean().reset_index()\n",
    "dft_stdv = dft.groupby('α').std().reset_index()\n",
    "\n",
    "colors = ['purple', 'dodgerblue', 'darkorange']\n",
    "markers = ['o', 'D', 'd', '*']\n",
    "ms = 14\n",
    "lw = 3\n",
    "names = list(dfNMI.columns[1:])\n",
    "labels = ['EDRep', 'negative sampling', 'SC']\n",
    "\n",
    "fig, ax = plt.subplots(1,2, figsize = (15, 5))\n",
    "\n",
    "for i, (name, label) in enumerate(zip(names, labels)):\n",
    "\n",
    "    ax[0].plot(dfNMI_m.α, dfNMI_m[name], color = colors[i], marker = markers[i], linewidth = lw,\n",
    "                       markersize = ms, fillstyle = 'none', label = label)\n",
    "    \n",
    "    ax[0].fill_between(dfNMI_m.α, dfNMI_m[name] - dfNMI_stdv[name]/2, dfNMI_m[name] + dfNMI_stdv[name]/2,\n",
    "                      color = colors[i], alpha = 0.3)\n",
    "\n",
    "\n",
    "    ax[1].plot(dft_m.α, dft_m[name], color = colors[i], marker = markers[i],  linewidth = lw,\n",
    "                       markersize = ms, fillstyle = 'none')\n",
    "    \n",
    "    ax[1].fill_between(dft_m.α, (dft_m[name] - dft_stdv[name]), (dft_m[name] + dft_stdv[name]),\n",
    "                  color = colors[i], alpha = 0.3)\n",
    "\n",
    "\n",
    "ax[0].axvline(1, linewidth = 1.5, linestyle = '-.', color = 'k')\n",
    "ax[0].set_xlabel(r'$\\alpha$', fontsize = 24)\n",
    "ax[0].set_ylabel('NMI', fontsize = 24)\n",
    "ax[0].tick_params(axis='both', which='major', labelsize = 18)\n",
    "ax[0].legend(fontsize = 18)\n",
    "\n",
    "ax[1].axvline(1, linewidth = 1.5, linestyle = '-.', color = 'k')\n",
    "ax[1].set_xlabel(r'$\\alpha$', fontsize = 24)\n",
    "ax[1].yaxis.tick_right()\n",
    "ax[1].yaxis.set_label_position(\"right\")\n",
    "ax[1].set_ylabel(r'$t~({\\rm sec})$', fontsize = 24, rotation = -90, labelpad = 30)\n",
    "ax[1].tick_params(axis='both', which='major', labelsize = 18)\n",
    "\n",
    "fig.tight_layout()\n",
    "plt.savefig('../../paper/v2/arXiv/Figures/ov.pdf')\n",
    "\n",
    "plt.show();"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "214f71c7",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "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.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
