{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "293692f4",
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "import pickle\n",
    "import csv\n",
    "\n",
    "import sys\n",
    "sys.path += ['utils/']  \n",
    "\n",
    "from EDRep import *\n",
    "\n",
    "import warnings\n",
    "warnings.filterwarnings(\"ignore\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "b66c4124",
   "metadata": {},
   "outputs": [],
   "source": [
    "def Normal(μ, σ2, t):\n",
    "    \n",
    "    return 1/np.sqrt(2*np.pi*σ2)*np.exp(-(t - μ)**2/(2*σ2))\n",
    "\n",
    "\n",
    "def RFM(X, D, indeces):\n",
    "\n",
    "    n, dim = X.shape\n",
    "\n",
    "    # create the random projection\n",
    "    W = np.random.normal(0, 1, (D, dim))\n",
    "    M = np.zeros((n, 2*D))\n",
    "\n",
    "    J = X@W.T\n",
    "    norms = np.sqrt(X**2@np.ones(dim))\n",
    "    Λ = diags(np.exp(norms**2/2))\n",
    "\n",
    "    # obtain the high dimensional vectors\n",
    "    M[:,:D] = Λ@np.sin(J)\n",
    "    M[:,D:] = Λ@np.cos(J)\n",
    "    M *= np.sqrt(1/D)\n",
    "\n",
    "    Z = M[indeces]@np.sum(M, axis = 0)\n",
    "\n",
    "    return Z\n",
    "\n",
    "\n",
    "def Performers(X, D, indeces):\n",
    "\n",
    "    n, dim = X.shape\n",
    "    W = np.random.normal(0, 1, size = (D, dim))\n",
    "    M = np.zeros((n, 2*D))\n",
    "\n",
    "    J = X@W.T\n",
    "    norms = np.sqrt(X**2@np.ones(dim))\n",
    "    Λ = diags(np.exp(-norms**2/2)/np.sqrt(2))\n",
    "\n",
    "    M[:,:D] = Λ@np.exp(J)\n",
    "    M[:,D:] = Λ@np.exp(-J)\n",
    "    M *= np.sqrt(1/D)\n",
    "\n",
    "    Z = M[indeces]@np.sum(M, axis = 0)\n",
    "\n",
    "    return Z\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "fff6f927",
   "metadata": {},
   "outputs": [],
   "source": [
    "# file name\n",
    "f = 30\n",
    "\n",
    "# k-values\n",
    "kv = [1, 5, 15]\n",
    "\n",
    "# number of sampled indeces\n",
    "Nindeces = 1000\n",
    "\n",
    "# projection size for kernel methods\n",
    "D = 1000\n",
    "\n",
    "# read and pre-process the embedding\n",
    "X = pd.read_csv('Dataset/' + str(f) + '.txt', skiprows = 1, on_bad_lines='skip', sep = ' ', header = None, quoting=csv.QUOTE_NONE,\n",
    "                encoding='latin-1')\n",
    "X.set_index(0, inplace = True)\n",
    "X = X.dropna(axis = 1)\n",
    "X = X.values\n",
    "n, dim = np.shape(X)\n",
    "norms = np.sqrt(X**2@np.ones(dim))\n",
    "X = X/np.mean(norms)\n",
    "\n",
    "\n",
    "# select the random indeces\n",
    "indeces = np.random.choice(np.arange(n), Nindeces, replace = False)\n",
    "\n",
    "Z = computeZ(X, indeces)\n",
    "res = [computeZest(X, indeces, k = int(k)) for k in kv]\n",
    "ZPerformers = Performers(X, D, indeces)\n",
    "ZRFM = RFM(X, D, indeces)\n",
    "\n",
    "\n",
    "# compute the normalized version\n",
    "Y = normalize(X, norm = 'l2', axis = 1)\n",
    "Zn = computeZ(Y, indeces)\n",
    "resn = [computeZest(Y, indeces, k = int(k)) for k in kv]\n",
    "ZPerformersn = Performers(Y, D, indeces)\n",
    "ZRFMn = RFM(Y, D, indeces)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "520f59fe",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 18472 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "α = np.random.randint(n)\n",
    "plt.hist(X[α]@X.T, bins = 30, edgecolor = 'white', color = 'chartreuse', \n",
    "                density = True, label = 'Empirical', cumulative = True)\n",
    "\n",
    "m = np.mean(X[α]@X.T) \n",
    "s = np.sqrt(np.var(X[α]@X.T))\n",
    "\n",
    "t = np.linspace(1.03*np.min(X[α]@X.T), np.max(X[α]@X.T))\n",
    "k = 1\n",
    "π, μ, σ2 = res[k].π, res[k].μ, res[k].Ω\n",
    "\n",
    "y = np.sum(np.diag(π/n)@np.array([Normal(X[α]@μ[b].T, X[α]@σ2[b]@X[α], t) for b in range(len(μ))]), axis = 0)\n",
    "plt.plot(t, np.cumsum(y)*(max(t)-min(t))/len(t), color = 'k', linewidth = 3, linestyle = '-.', label = 'mvGaussian')\n",
    "plt.show();"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "5a1fe8d7",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 39180 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "eps = []\n",
    "\n",
    "for i in range(len(res)):\n",
    "    eps.append(np.log10(np.abs(Z - res[i].Zest)/Z))\n",
    "\n",
    "eps.append(np.log10(np.abs(Z - ZPerformers)/Z))\n",
    "eps.append(np.log10(np.abs(Z - ZRFM)/Z))\n",
    "    \n",
    "    \n",
    "tv = np.linspace(np.min(np.concatenate(eps)), np.max(np.concatenate(eps)))\n",
    "\n",
    "for i in range(len(eps)):\n",
    "    plt.plot(tv, [np.mean(eps[i] < t) for t in tv])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "232ca258",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "EDRep",
   "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
}
