{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "5b79eca0",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "2022-02-11 16:43:08.366331: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory\n",
      "2022-02-11 16:43:08.366351: I tensorflow/stream_executor/cuda/cudart_stub.cc:29] Ignore above cudart dlerror if you do not have a GPU set up on your machine.\n"
     ]
    }
   ],
   "source": [
    "from library.NNSearch import NNSearch\n",
    "from library.timing import timing\n",
    "from sklearn.neighbors import NearestNeighbors\n",
    "import numpy as np\n",
    "import tensorflow as tf\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "fd8d89ea",
   "metadata": {},
   "outputs": [],
   "source": [
    "n_features = 100\n",
    "numPoints = 2000\n",
    "maxValue = 5000\n",
    "nbhSize = 5"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "234f0cc7",
   "metadata": {},
   "outputs": [],
   "source": [
    "data = np.array([\n",
    "    np.array([float(x) for x in np.random.randint(maxValue, size=n_features)])\n",
    "    for _i in range(numPoints)])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "6388fa61",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2000"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "c5ef8b57",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/kristian/anaconda3/lib/python3.9/site-packages/sklearn/utils/validation.py:70: FutureWarning: Pass n_neighbors=5 as keyword args. From version 1.0 (renaming of 0.25) passing these as positional arguments will result in an error\n",
      "  warnings.warn(f\"Pass {args_msg} as keyword args. From version \"\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "NearestNeighbours: #1 0.9532s\n"
     ]
    }
   ],
   "source": [
    "tNN = timing(\"NearestNeighbours\")\n",
    "tNN.start()\n",
    "nn = NearestNeighbors(nbhSize)\n",
    "nn.fit(data)\n",
    "for x in data:\n",
    "    nbh = nn.kneighbors([x], nbhSize, return_distance=False)\n",
    "tNN.stop()\n",
    "print(tNN)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "84950ba8",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "2022-02-11 16:43:11.312163: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcuda.so.1'; dlerror: libcuda.so.1: cannot open shared object file: No such file or directory\n",
      "2022-02-11 16:43:11.312182: W tensorflow/stream_executor/cuda/cuda_driver.cc:269] failed call to cuInit: UNKNOWN ERROR (303)\n",
      "2022-02-11 16:43:11.312199: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:156] kernel driver does not appear to be running on this host (sbi-klabautermann): /proc/driver/nvidia/version does not exist\n",
      "2022-02-11 16:43:11.312430: I tensorflow/core/platform/cpu_feature_guard.cc:151] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations:  AVX2 FMA\n",
      "To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "NNSearch: #1 10.3314s\n"
     ]
    }
   ],
   "source": [
    "tNNS = timing(\"NNSearch\")\n",
    "tNNS.start()\n",
    "nnb = NNSearch(nbhSize)\n",
    "nnb.fit(data)\n",
    "for x in range(len(data)):\n",
    "    nbh = nnb.neighbourhoodOfItem(x)\n",
    "tNNS.stop()\n",
    "print(tNNS)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "b61b26cb",
   "metadata": {
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "#tNNSH = timing(\"NNSearch\")\n",
    "#tNNSH.start()\n",
    "#nnh = NNSearch(nbhSize)\n",
    "#nnh.fit_heuristic(data)\n",
    "#for x in range(len(data)):\n",
    "#    nbh = nnh.neighbourhoodOfItem(x)\n",
    "#tNNSH.stop()\n",
    "#print(tNNSH)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "686265dc",
   "metadata": {},
   "outputs": [],
   "source": [
    "#for i in range(len(data)):\n",
    "#    nb = set(nnb.neighbourhoodOfItem(i))\n",
    "#    nh = set(nnh.neighbourhoodOfItem(i))\n",
    "#    if nb != nh:\n",
    "#        print(f\"#{i}: {nb} != {nh}\")\n",
    "#        break\n",
    "#print(f\"last: {nb}  {nh}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "ca269d98",
   "metadata": {},
   "outputs": [],
   "source": [
    "def testNNSearchByQueries(nQueries):\n",
    "    timingBf = {}\n",
    "    timingCh = {}\n",
    "    \n",
    "    print(f\"\\n#Queries: {nQueries}\")\n",
    "    tNN = timing(\"NearestNeighbours\")\n",
    "    tNN.start()\n",
    "    nn = NearestNeighbors(n_neighbors=nbhSize)\n",
    "    nn.fit(data)\n",
    "    n = 0\n",
    "    while n < nQueries:\n",
    "        for x in data:\n",
    "            nbh = nn.kneighbors([x], nbhSize, return_distance=False)\n",
    "            n += 1\n",
    "            if n >= nQueries:\n",
    "                break\n",
    "    tNN.stop()\n",
    "    print(tNN)\n",
    "    \n",
    "    tNN_bf = timing(\"NNSearch - brute force\")\n",
    "    tNN_bf.start()\n",
    "    nn = NNSearch(nbhSize, timingBf)\n",
    "    nn.fit_bruteForce_np(data)\n",
    "    n = 0\n",
    "    while n < nQueries:\n",
    "        for x in range(len(data)):\n",
    "            nbh = nn.neighbourhoodOfItem(x)\n",
    "            n += 1\n",
    "            if n >= nQueries:\n",
    "                break\n",
    "    tNN_bf.stop()\n",
    "    print(tNN_bf)\n",
    "    for k in timingBf.keys():\n",
    "        print(timingBf[k])\n",
    "\n",
    "    \n",
    "    tNN_ch = timing(\"NNSearch - chained\")\n",
    "    tNN_ch.start()\n",
    "    nn = NNSearch(nbhSize, timingCh)\n",
    "    nn.fit_chained(data)\n",
    "    n = 0\n",
    "    while n < nQueries:\n",
    "        for x in range(len(data)):\n",
    "            nbh = nn.neighbourhoodOfItem(x)\n",
    "            n += 1\n",
    "            if n >= nQueries:\n",
    "                break\n",
    "    tNN_ch.stop()\n",
    "    print(tNN_ch)\n",
    "    for k in timingCh.keys():\n",
    "        print(timingCh[k])\n",
    "\n",
    "    return (tNN.duration, tNN_bf.duration, tNN_ch.duration)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "1fd643cc",
   "metadata": {},
   "outputs": [],
   "source": [
    "def showResults(results):\n",
    "    xs = [r[0] for r in results]\n",
    "    ys = [r[1][0] for r in results]\n",
    "    zs_bf = [r[1][1] for r in results]\n",
    "    zs_ch = [r[1][2] for r in results]\n",
    "\n",
    "    plt.xscale(\"log\")\n",
    "    #plt.yscale(\"log\")\n",
    "    plt.plot(xs, ys, label=\"NN\")\n",
    "    plt.plot(xs, zs_bf, label=\"NN - bf\")\n",
    "    plt.plot(xs, zs_ch, label=\"NN - ch\")\n",
    "    plt.legend()\n",
    "    plt.show\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "95b332a3",
   "metadata": {
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "def randomPoint():\n",
    "    return np.array([\n",
    "        float(x)\n",
    "        for x in np.random.randint(maxValue, size=n_features)\n",
    "        ])\n",
    "\n",
    "def runTest():\n",
    "    data = np.array([randomPoint() for _i in range(numPoints)])\n",
    "    \n",
    "    q = len(data) / 8\n",
    "    results = []\n",
    "    while q <= 8 * len(data):\n",
    "        results.append((q, testNNSearchByQueries(q)))\n",
    "        q *= 2\n",
    "\n",
    "    showResults(results)  \n",
    "        \n",
    "    return results"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "61482cae",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "#Queries: 250.0\n",
      "NearestNeighbours: #1 0.1009s\n",
      "NNSearch - brute force: #1 11.7175s\n",
      "NN_fit_bfnp_init: #1 0.0027s\n",
      "NN_fit_bfnp_loop: #1 11.7148s\n",
      "NN_fit_bfnp_dist: #2000 4.7026s\n",
      "NN_fit_bfnp_insert: #1999000 5.3951s\n",
      "NN_fit_bfnp_toList: #2000 0.0048s\n",
      "NNSearch - chained: #1 0.8066s\n",
      "NN_fit_chained_init: #1 0.0007s\n",
      "NN_fit_chained_toList: #1 0.8057s\n",
      "#Queries: 500.0\n",
      "NearestNeighbours: #1 0.2005s\n",
      "NNSearch - brute force: #1 11.6808s\n",
      "NN_fit_bfnp_init: #1 0.0025s\n",
      "NN_fit_bfnp_loop: #1 11.6781s\n",
      "NN_fit_bfnp_dist: #2000 4.6813s\n",
      "NN_fit_bfnp_insert: #1999000 5.3829s\n",
      "NN_fit_bfnp_toList: #2000 0.0046s\n",
      "NNSearch - chained: #1 0.8662s\n",
      "NN_fit_chained_init: #1 0.0007s\n",
      "NN_fit_chained_toList: #1 0.8652s\n",
      "#Queries: 1000.0\n",
      "NearestNeighbours: #1 0.4030s\n",
      "NNSearch - brute force: #1 11.7693s\n",
      "NN_fit_bfnp_init: #1 0.0690s\n",
      "NN_fit_bfnp_loop: #1 11.7001s\n",
      "NN_fit_bfnp_dist: #2000 4.7015s\n",
      "NN_fit_bfnp_insert: #1999000 5.3926s\n",
      "NN_fit_bfnp_toList: #2000 0.0047s\n",
      "NNSearch - chained: #1 0.8038s\n",
      "NN_fit_chained_init: #1 0.0005s\n",
      "NN_fit_chained_toList: #1 0.8028s\n",
      "#Queries: 2000.0\n",
      "NearestNeighbours: #1 0.8036s\n",
      "NNSearch - brute force: #1 11.7433s\n",
      "NN_fit_bfnp_init: #1 0.0027s\n",
      "NN_fit_bfnp_loop: #1 11.7403s\n",
      "NN_fit_bfnp_dist: #2000 4.7203s\n",
      "NN_fit_bfnp_insert: #1999000 5.4042s\n",
      "NN_fit_bfnp_toList: #2000 0.0046s\n",
      "NNSearch - chained: #1 0.8056s\n",
      "NN_fit_chained_init: #1 0.0006s\n",
      "NN_fit_chained_toList: #1 0.8044s\n",
      "#Queries: 4000.0\n",
      "NearestNeighbours: #1 1.6057s\n",
      "NNSearch - brute force: #1 11.7360s\n",
      "NN_fit_bfnp_init: #1 0.0027s\n",
      "NN_fit_bfnp_loop: #1 11.7325s\n",
      "NN_fit_bfnp_dist: #2000 4.6920s\n",
      "NN_fit_bfnp_insert: #1999000 5.3934s\n",
      "NN_fit_bfnp_toList: #2000 0.0046s\n",
      "NNSearch - chained: #1 0.8075s\n",
      "NN_fit_chained_init: #1 0.0006s\n",
      "NN_fit_chained_toList: #1 0.8059s\n",
      "#Queries: 8000.0\n",
      "NearestNeighbours: #1 3.1986s\n",
      "NNSearch - brute force: #1 11.6612s\n",
      "NN_fit_bfnp_init: #1 0.0024s\n",
      "NN_fit_bfnp_loop: #1 11.6574s\n",
      "NN_fit_bfnp_dist: #2000 4.6859s\n",
      "NN_fit_bfnp_insert: #1999000 5.3722s\n",
      "NN_fit_bfnp_toList: #2000 0.0045s\n",
      "NNSearch - chained: #1 0.8063s\n",
      "NN_fit_chained_init: #1 0.0006s\n",
      "NN_fit_chained_toList: #1 0.8041s\n",
      "#Queries: 16000.0\n",
      "NearestNeighbours: #1 6.4602s\n",
      "NNSearch - brute force: #1 12.2282s\n",
      "NN_fit_bfnp_init: #1 0.0025s\n",
      "NN_fit_bfnp_loop: #1 12.2229s\n",
      "NN_fit_bfnp_dist: #2000 4.9943s\n",
      "NN_fit_bfnp_insert: #1999000 5.5799s\n",
      "NN_fit_bfnp_toList: #2000 0.0051s\n",
      "NNSearch - chained: #1 0.8166s\n",
      "NN_fit_chained_init: #1 0.0006s\n",
      "NN_fit_chained_toList: #1 0.8131s\n",
      "(250.0, (0.10093569755554199, 11.717548370361328, 0.8066229820251465))\n",
      "(500.0, (0.20050740242004395, 11.680786848068237, 0.866196870803833))\n",
      "(1000.0, (0.40299034118652344, 11.769335508346558, 0.8037700653076172))\n",
      "(2000.0, (0.8035635948181152, 11.743326663970947, 0.8056142330169678))\n",
      "(4000.0, (1.6056647300720215, 11.736043930053711, 0.807450532913208))\n",
      "(8000.0, (3.1986196041107178, 11.661194562911987, 0.806293249130249))\n",
      "(16000.0, (6.460216283798218, 12.228201389312744, 0.8165764808654785))\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 11088 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "results = runTest()\n",
    "for r in results:\n",
    "    print(r)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "ace1968a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "#Queries: 250.0\n",
      "NearestNeighbours: #1 0.1101s\n",
      "NNSearch - brute force: #1 34.5123s\n",
      "NN_fit_bfnp_init: #1 0.0023s\n",
      "NN_fit_bfnp_loop: #1 34.5095s\n",
      "NN_fit_bfnp_dist: #2000 5.5661s\n",
      "NN_fit_bfnp_insert: #1999000 26.7270s\n",
      "NN_fit_bfnp_toList: #2000 0.1024s\n",
      "NNSearch - chained: #1 0.9062s\n",
      "NN_fit_chained_init: #1 0.0003s\n",
      "NN_fit_chained_toList: #1 0.8980s\n",
      "#Queries: 500.0\n",
      "NearestNeighbours: #1 0.2221s\n",
      "NNSearch - brute force: #1 34.1902s\n",
      "NN_fit_bfnp_init: #1 0.0030s\n",
      "NN_fit_bfnp_loop: #1 34.1867s\n",
      "NN_fit_bfnp_dist: #2000 5.5106s\n",
      "NN_fit_bfnp_insert: #1999000 26.4723s\n",
      "NN_fit_bfnp_toList: #2000 0.1029s\n",
      "NNSearch - chained: #1 0.8933s\n",
      "NN_fit_chained_init: #1 0.0006s\n",
      "NN_fit_chained_toList: #1 0.8854s\n",
      "#Queries: 1000.0\n",
      "NearestNeighbours: #1 0.4374s\n",
      "NNSearch - brute force: #1 34.0280s\n",
      "NN_fit_bfnp_init: #1 0.0029s\n",
      "NN_fit_bfnp_loop: #1 34.0245s\n",
      "NN_fit_bfnp_dist: #2000 5.4840s\n",
      "NN_fit_bfnp_insert: #1999000 26.3614s\n",
      "NN_fit_bfnp_toList: #2000 0.1027s\n",
      "NNSearch - chained: #1 0.8961s\n",
      "NN_fit_chained_init: #1 0.0003s\n",
      "NN_fit_chained_toList: #1 0.8879s\n",
      "#Queries: 2000.0\n",
      "NearestNeighbours: #1 0.8844s\n",
      "NNSearch - brute force: #1 34.2027s\n",
      "NN_fit_bfnp_init: #1 0.0729s\n",
      "NN_fit_bfnp_loop: #1 34.1290s\n",
      "NN_fit_bfnp_dist: #2000 5.5232s\n",
      "NN_fit_bfnp_insert: #1999000 26.4227s\n",
      "NN_fit_bfnp_toList: #2000 0.1040s\n",
      "NNSearch - chained: #1 0.8959s\n",
      "NN_fit_chained_init: #1 0.0003s\n",
      "NN_fit_chained_toList: #1 0.8873s\n",
      "#Queries: 4000.0\n",
      "NearestNeighbours: #1 1.7675s\n",
      "NNSearch - brute force: #1 33.9383s\n",
      "NN_fit_bfnp_init: #1 0.0028s\n",
      "NN_fit_bfnp_loop: #1 33.9344s\n",
      "NN_fit_bfnp_dist: #2000 5.4702s\n",
      "NN_fit_bfnp_insert: #1999000 26.3020s\n",
      "NN_fit_bfnp_toList: #2000 0.1028s\n",
      "NNSearch - chained: #1 0.8841s\n",
      "NN_fit_chained_init: #1 0.0004s\n",
      "NN_fit_chained_toList: #1 0.8756s\n",
      "#Queries: 8000.0\n",
      "NearestNeighbours: #1 3.5655s\n",
      "NNSearch - brute force: #1 33.9516s\n",
      "NN_fit_bfnp_init: #1 0.0027s\n",
      "NN_fit_bfnp_loop: #1 33.9470s\n",
      "NN_fit_bfnp_dist: #2000 5.4770s\n",
      "NN_fit_bfnp_insert: #1999000 26.3011s\n",
      "NN_fit_bfnp_toList: #2000 0.1033s\n",
      "NNSearch - chained: #1 0.9640s\n",
      "NN_fit_chained_init: #1 0.0003s\n",
      "NN_fit_chained_toList: #1 0.9548s\n",
      "#Queries: 16000.0\n",
      "NearestNeighbours: #1 7.0631s\n",
      "NNSearch - brute force: #1 33.9494s\n",
      "NN_fit_bfnp_init: #1 0.0027s\n",
      "NN_fit_bfnp_loop: #1 33.9435s\n",
      "NN_fit_bfnp_dist: #2000 5.4798s\n",
      "NN_fit_bfnp_insert: #1999000 26.2945s\n",
      "NN_fit_bfnp_toList: #2000 0.1030s\n",
      "NNSearch - chained: #1 0.8982s\n",
      "NN_fit_chained_init: #1 0.0003s\n",
      "NN_fit_chained_toList: #1 0.8875s\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[(250.0, (0.11011576652526855, 34.51230764389038, 0.9062139987945557)),\n",
       " (500.0, (0.2220914363861084, 34.19019532203674, 0.89328932762146)),\n",
       " (1000.0, (0.4374098777770996, 34.028005838394165, 0.8960974216461182)),\n",
       " (2000.0, (0.8843889236450195, 34.202696323394775, 0.8958609104156494)),\n",
       " (4000.0, (1.7675197124481201, 33.93833684921265, 0.8840756416320801)),\n",
       " (8000.0, (3.5654966831207275, 33.95157527923584, 0.964043140411377)),\n",
       " (16000.0, (7.063101530075073, 33.94935345649719, 0.8981528282165527))]"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 9688 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "n_features = 100\n",
    "numPoints = 2000\n",
    "maxValue = 5000\n",
    "nbhSize = 500\n",
    "runTest()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "f542bd77",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "#Queries: 2000\n",
      "NearestNeighbours: #1 0.7690s\n",
      "NNSearch - brute force: #1 11.6225s\n",
      "NN_fit_bfnp_init: #1 0.0030s\n",
      "NN_fit_bfnp_loop: #1 11.6191s\n",
      "NN_fit_bfnp_dist: #2000 4.8411s\n",
      "NN_fit_bfnp_insert: #1999000 5.1438s\n",
      "NN_fit_bfnp_toList: #2000 0.0048s\n",
      "NNSearch - chained: #1 0.7762s\n",
      "NN_fit_chained_init: #1 0.0004s\n",
      "NN_fit_chained_toList: #1 0.7751s\n",
      "#Queries: 2000\n",
      "NearestNeighbours: #1 0.9258s\n",
      "NNSearch - brute force: #1 12.0495s\n",
      "NN_fit_bfnp_init: #1 0.0032s\n",
      "NN_fit_bfnp_loop: #1 12.0459s\n",
      "NN_fit_bfnp_dist: #2000 4.8804s\n",
      "NN_fit_bfnp_insert: #1999000 5.4840s\n",
      "NN_fit_bfnp_toList: #2000 0.0051s\n",
      "NNSearch - chained: #1 0.8090s\n",
      "NN_fit_chained_init: #1 0.0006s\n",
      "NN_fit_chained_toList: #1 0.8078s\n",
      "#Queries: 2000\n",
      "NearestNeighbours: #1 0.8089s\n",
      "NNSearch - brute force: #1 12.4359s\n",
      "NN_fit_bfnp_init: #1 0.0024s\n",
      "NN_fit_bfnp_loop: #1 12.4330s\n",
      "NN_fit_bfnp_dist: #2000 4.9303s\n",
      "NN_fit_bfnp_insert: #1999000 5.8403s\n",
      "NN_fit_bfnp_toList: #2000 0.0055s\n",
      "NNSearch - chained: #1 0.8682s\n",
      "NN_fit_chained_init: #1 0.0006s\n",
      "NN_fit_chained_toList: #1 0.8668s\n",
      "#Queries: 2000\n",
      "NearestNeighbours: #1 0.8091s\n",
      "NNSearch - brute force: #1 12.8205s\n",
      "NN_fit_bfnp_init: #1 0.0027s\n",
      "NN_fit_bfnp_loop: #1 12.8174s\n",
      "NN_fit_bfnp_dist: #2000 4.8571s\n",
      "NN_fit_bfnp_insert: #1999000 6.3160s\n",
      "NN_fit_bfnp_toList: #2000 0.0056s\n",
      "NNSearch - chained: #1 0.8214s\n",
      "NN_fit_chained_init: #1 0.0003s\n",
      "NN_fit_chained_toList: #1 0.8202s\n",
      "#Queries: 2000\n",
      "NearestNeighbours: #1 0.8118s\n",
      "NNSearch - brute force: #1 13.9575s\n",
      "NN_fit_bfnp_init: #1 0.0024s\n",
      "NN_fit_bfnp_loop: #1 13.9546s\n",
      "NN_fit_bfnp_dist: #2000 4.8472s\n",
      "NN_fit_bfnp_insert: #1999000 7.4357s\n",
      "NN_fit_bfnp_toList: #2000 0.0073s\n",
      "NNSearch - chained: #1 0.8309s\n",
      "NN_fit_chained_init: #1 0.0003s\n",
      "NN_fit_chained_toList: #1 0.8291s\n",
      "#Queries: 2000\n",
      "NearestNeighbours: #1 0.8521s\n",
      "NNSearch - brute force: #1 16.9347s\n",
      "NN_fit_bfnp_init: #1 0.0029s\n",
      "NN_fit_bfnp_loop: #1 16.9314s\n",
      "NN_fit_bfnp_dist: #2000 5.2314s\n",
      "NN_fit_bfnp_insert: #1999000 9.9072s\n",
      "NN_fit_bfnp_toList: #2000 0.0106s\n",
      "NNSearch - chained: #1 0.8430s\n",
      "NN_fit_chained_init: #1 0.0006s\n",
      "NN_fit_chained_toList: #1 0.8406s\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 9244 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "def testNbhSize():\n",
    "    global nbhSize\n",
    "    data = np.array([randomPoint() for _i in range(numPoints)])\n",
    "    q = len(data)\n",
    "    nbhSize = 2\n",
    "    results = []\n",
    "    while nbhSize < 100:\n",
    "        results.append((nbhSize, testNNSearchByQueries(q)))\n",
    "        nbhSize *= 2\n",
    "    showResults(results)\n",
    "    \n",
    "n_features = 100\n",
    "numPoints = 2000\n",
    "maxValue = 5000\n",
    "nbhSize = 500\n",
    "\n",
    "testNbhSize()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "1254b22c",
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "#Queries: 4000\n",
      "NearestNeighbours: #1 1.1085s\n",
      "NNSearch - brute force: #1 9.4616s\n",
      "NN_fit_bfnp_init: #1 0.0033s\n",
      "NN_fit_bfnp_loop: #1 9.4576s\n",
      "NN_fit_bfnp_dist: #2000 2.7834s\n",
      "NN_fit_bfnp_insert: #1999000 5.0853s\n",
      "NN_fit_bfnp_toList: #2000 0.0045s\n",
      "NNSearch - chained: #1 0.5445s\n",
      "NN_fit_chained_init: #1 0.0007s\n",
      "NN_fit_chained_toList: #1 0.5430s\n",
      "#Queries: 4000\n",
      "NearestNeighbours: #1 1.0871s\n",
      "NNSearch - brute force: #1 9.0770s\n",
      "NN_fit_bfnp_init: #1 0.0025s\n",
      "NN_fit_bfnp_loop: #1 9.0738s\n",
      "NN_fit_bfnp_dist: #2000 2.6923s\n",
      "NN_fit_bfnp_insert: #1999000 4.8391s\n",
      "NN_fit_bfnp_toList: #2000 0.0043s\n",
      "NNSearch - chained: #1 0.5439s\n",
      "NN_fit_chained_init: #1 0.0008s\n",
      "NN_fit_chained_toList: #1 0.5423s\n",
      "#Queries: 4000\n",
      "NearestNeighbours: #1 1.1404s\n",
      "NNSearch - brute force: #1 9.3360s\n",
      "NN_fit_bfnp_init: #1 0.0027s\n",
      "NN_fit_bfnp_loop: #1 9.3326s\n",
      "NN_fit_bfnp_dist: #2000 2.8080s\n",
      "NN_fit_bfnp_insert: #1999000 4.9728s\n",
      "NN_fit_bfnp_toList: #2000 0.0044s\n",
      "NNSearch - chained: #1 0.5750s\n",
      "NN_fit_chained_init: #1 0.0012s\n",
      "NN_fit_chained_toList: #1 0.5729s\n",
      "#Queries: 4000\n",
      "NearestNeighbours: #1 1.1007s\n",
      "NNSearch - brute force: #1 9.8054s\n",
      "NN_fit_bfnp_init: #1 0.0027s\n",
      "NN_fit_bfnp_loop: #1 9.8019s\n",
      "NN_fit_bfnp_dist: #2000 3.0390s\n",
      "NN_fit_bfnp_insert: #1999000 5.1741s\n",
      "NN_fit_bfnp_toList: #2000 0.0048s\n",
      "NNSearch - chained: #1 0.5635s\n",
      "NN_fit_chained_init: #1 0.0002s\n",
      "NN_fit_chained_toList: #1 0.5624s\n",
      "#Queries: 4000\n",
      "NearestNeighbours: #1 1.4287s\n",
      "NNSearch - brute force: #1 9.8580s\n",
      "NN_fit_bfnp_init: #1 0.0027s\n",
      "NN_fit_bfnp_loop: #1 9.8546s\n",
      "NN_fit_bfnp_dist: #2000 3.2576s\n",
      "NN_fit_bfnp_insert: #1999000 5.0551s\n",
      "NN_fit_bfnp_toList: #2000 0.0046s\n",
      "NNSearch - chained: #1 0.5933s\n",
      "NN_fit_chained_init: #1 0.0002s\n",
      "NN_fit_chained_toList: #1 0.5922s\n",
      "#Queries: 4000\n",
      "NearestNeighbours: #1 1.3954s\n",
      "NNSearch - brute force: #1 11.3182s\n",
      "NN_fit_bfnp_init: #1 0.0028s\n",
      "NN_fit_bfnp_loop: #1 11.3148s\n",
      "NN_fit_bfnp_dist: #2000 4.2247s\n",
      "NN_fit_bfnp_insert: #1999000 5.4614s\n",
      "NN_fit_bfnp_toList: #2000 0.0051s\n",
      "NNSearch - chained: #1 0.8187s\n",
      "NN_fit_chained_init: #1 0.0004s\n",
      "NN_fit_chained_toList: #1 0.8172s\n",
      "#Queries: 4000\n",
      "NearestNeighbours: #1 1.9051s\n",
      "NNSearch - brute force: #1 12.1622s\n",
      "NN_fit_bfnp_init: #1 0.0032s\n",
      "NN_fit_bfnp_loop: #1 12.1582s\n",
      "NN_fit_bfnp_dist: #2000 4.7477s\n",
      "NN_fit_bfnp_insert: #1999000 5.7415s\n",
      "NN_fit_bfnp_toList: #2000 0.0054s\n",
      "NNSearch - chained: #1 1.0140s\n",
      "NN_fit_chained_init: #1 0.0006s\n",
      "NN_fit_chained_toList: #1 1.0124s\n",
      "#Queries: 4000\n",
      "NearestNeighbours: #1 3.0180s\n",
      "NNSearch - brute force: #1 13.7916s\n",
      "NN_fit_bfnp_init: #1 0.0026s\n",
      "NN_fit_bfnp_loop: #1 13.7882s\n",
      "NN_fit_bfnp_dist: #2000 6.2045s\n",
      "NN_fit_bfnp_insert: #1999000 5.9177s\n",
      "NN_fit_bfnp_toList: #2000 0.0054s\n",
      "NNSearch - chained: #1 1.3896s\n",
      "NN_fit_chained_init: #1 0.0004s\n",
      "NN_fit_chained_toList: #1 1.3882s\n",
      "#Queries: 4000\n",
      "NearestNeighbours: #1 5.3106s\n",
      "NNSearch - brute force: #1 17.8478s\n",
      "NN_fit_bfnp_init: #1 0.0030s\n",
      "NN_fit_bfnp_loop: #1 17.8439s\n",
      "NN_fit_bfnp_dist: #2000 9.7354s\n",
      "NN_fit_bfnp_insert: #1999000 6.2943s\n",
      "NN_fit_bfnp_toList: #2000 0.0058s\n",
      "NNSearch - chained: #1 2.6400s\n",
      "NN_fit_chained_init: #1 0.0007s\n",
      "NN_fit_chained_toList: #1 2.6383s\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 14120 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "def testFeatureCount():\n",
    "    global n_features\n",
    "    global data\n",
    "    q = 2 * len(data)\n",
    "    n_features = 2\n",
    "    results = []\n",
    "    while n_features < 1000:\n",
    "        data = np.array([randomPoint() for _i in range(numPoints)])\n",
    "        results.append((n_features, testNNSearchByQueries(q)))\n",
    "        n_features *= 2\n",
    "    showResults(results)\n",
    "    \n",
    "n_features = 100\n",
    "numPoints = 2000\n",
    "maxValue = 5000\n",
    "nbhSize = 5\n",
    "\n",
    "testFeatureCount()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "fb158f8c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "-- #points: 100\n",
      "#Queries: 40000\n",
      "NearestNeighbours: #1 8.1218s\n",
      "NNSearch - brute force: #1 0.1501s\n",
      "NN_fit_bfnp_init: #1 0.0003s\n",
      "NN_fit_bfnp_loop: #1 0.1446s\n",
      "NN_fit_bfnp_dist: #100 0.1235s\n",
      "NN_fit_bfnp_insert: #4950 0.0162s\n",
      "NN_fit_bfnp_toList: #100 0.0002s\n",
      "NNSearch - chained: #1 0.0267s\n",
      "NN_fit_chained_init: #1 0.0001s\n",
      "NN_fit_chained_toList: #1 0.0210s\n",
      "-- #points: 200\n",
      "#Queries: 40000\n",
      "NearestNeighbours: #1 9.2971s\n",
      "NNSearch - brute force: #1 0.3586s\n",
      "NN_fit_bfnp_init: #1 0.0017s\n",
      "NN_fit_bfnp_loop: #1 0.3515s\n",
      "NN_fit_bfnp_dist: #200 0.2714s\n",
      "NN_fit_bfnp_insert: #19900 0.0616s\n",
      "NN_fit_bfnp_toList: #200 0.0004s\n",
      "NNSearch - chained: #1 0.0531s\n",
      "NN_fit_chained_init: #1 0.0007s\n",
      "NN_fit_chained_toList: #1 0.0467s\n",
      "-- #points: 400\n",
      "#Queries: 40000\n",
      "NearestNeighbours: #1 10.1838s\n",
      "NNSearch - brute force: #1 0.8746s\n",
      "NN_fit_bfnp_init: #1 0.0007s\n",
      "NN_fit_bfnp_loop: #1 0.8681s\n",
      "NN_fit_bfnp_dist: #400 0.5734s\n",
      "NN_fit_bfnp_insert: #79800 0.2253s\n",
      "NN_fit_bfnp_toList: #400 0.0008s\n",
      "NNSearch - chained: #1 0.1097s\n",
      "NN_fit_chained_init: #1 0.0002s\n",
      "NN_fit_chained_toList: #1 0.1035s\n",
      "-- #points: 800\n",
      "#Queries: 40000\n",
      "NearestNeighbours: #1 12.1831s\n",
      "NNSearch - brute force: #1 2.4842s\n",
      "NN_fit_bfnp_init: #1 0.0015s\n",
      "NN_fit_bfnp_loop: #1 2.4768s\n",
      "NN_fit_bfnp_dist: #800 1.3524s\n",
      "NN_fit_bfnp_insert: #319600 0.8589s\n",
      "NN_fit_bfnp_toList: #800 0.0018s\n",
      "NNSearch - chained: #1 0.2493s\n",
      "NN_fit_chained_init: #1 0.0003s\n",
      "NN_fit_chained_toList: #1 0.2422s\n",
      "-- #points: 1600\n",
      "#Queries: 40000\n",
      "NearestNeighbours: #1 15.5947s\n",
      "NNSearch - brute force: #1 7.9417s\n",
      "NN_fit_bfnp_init: #1 0.0024s\n",
      "NN_fit_bfnp_loop: #1 7.9337s\n",
      "NN_fit_bfnp_dist: #1600 3.4632s\n",
      "NN_fit_bfnp_insert: #1279200 3.4460s\n",
      "NN_fit_bfnp_toList: #1600 0.0038s\n",
      "NNSearch - chained: #1 0.6226s\n",
      "NN_fit_chained_init: #1 0.0006s\n",
      "NN_fit_chained_toList: #1 0.6152s\n",
      "-- #points: 3200\n",
      "#Queries: 40000\n",
      "NearestNeighbours: #1 22.3059s\n",
      "NNSearch - brute force: #1 27.4864s\n",
      "NN_fit_bfnp_init: #1 0.0044s\n",
      "NN_fit_bfnp_loop: #1 27.4758s\n",
      "NN_fit_bfnp_dist: #3200 9.0934s\n",
      "NN_fit_bfnp_insert: #5118400 14.2796s\n",
      "NN_fit_bfnp_toList: #3200 0.0082s\n",
      "NNSearch - chained: #1 1.6651s\n",
      "NN_fit_chained_init: #1 0.0003s\n",
      "NN_fit_chained_toList: #1 1.6578s\n",
      "-- #points: 6400\n",
      "#Queries: 40000\n",
      "NearestNeighbours: #1 34.0944s\n",
      "NNSearch - brute force: #1 104.0090s\n",
      "NN_fit_bfnp_init: #1 0.0849s\n",
      "NN_fit_bfnp_loop: #1 103.9171s\n",
      "NN_fit_bfnp_dist: #6400 26.1141s\n",
      "NN_fit_bfnp_insert: #20476800 60.7503s\n",
      "NN_fit_bfnp_toList: #6400 0.0198s\n",
      "NNSearch - chained: #1 5.3554s\n",
      "NN_fit_chained_init: #1 0.0005s\n",
      "NN_fit_chained_toList: #1 5.3477s\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 13504 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "def testPointCount():\n",
    "    global numPoints\n",
    "    global data\n",
    "    q = 40000\n",
    "    numPoints = 100\n",
    "    results = []\n",
    "    while numPoints < 10000:\n",
    "        print(f\"-- #points: {numPoints}\")\n",
    "        data = np.array([randomPoint() for _i in range(numPoints)])\n",
    "        results.append((numPoints, testNNSearchByQueries(q)))\n",
    "        numPoints *= 2\n",
    "    showResults(results)\n",
    "    \n",
    "n_features = 100\n",
    "numPoints = 2000\n",
    "maxValue = 5000\n",
    "nbhSize = 5\n",
    "\n",
    "testPointCount()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2332a58c",
   "metadata": {},
   "outputs": [],
   "source": [
    "a = np.array([[1,2,3],[4,5,6]])\n",
    "b = np.array([[1,4],[2,5],[3,6]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9b1ae45a",
   "metadata": {},
   "outputs": [],
   "source": [
    "t = timing(\"test\")\n",
    "t.start()\n",
    "for d in data:\n",
    "    #np.matmul(data - d, data[0])\n",
    "    pass\n",
    "t.stop()\n",
    "print(t)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b6d70eab",
   "metadata": {},
   "outputs": [],
   "source": [
    "np.transpose(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "05c918c4",
   "metadata": {},
   "outputs": [],
   "source": [
    "t = timing(\"test\")\n",
    "t.start()\n",
    "w = np.array(np.repeat([data[0]], len(data), axis=0))\n",
    "d = tf.keras.layers.Subtract()([w, data])\n",
    "r = tf.keras.layers.Dot(axes=(1,1))([d,d]).numpy()\n",
    "t.stop()\n",
    "print(t)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c25c1615",
   "metadata": {},
   "outputs": [],
   "source": [
    "r.shape"
   ]
  }
 ],
 "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
}
