Added hll space comparison
diff --git a/jupyter/comparison-to-datasketch/space-comparison.ipynb b/jupyter/comparison-to-datasketch/space-comparison.ipynb
new file mode 100644
index 0000000..7ee2994
--- /dev/null
+++ b/jupyter/comparison-to-datasketch/space-comparison.ipynb
@@ -0,0 +1,560 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "id": "472743a8-4868-4329-af35-50ab12b95662",
+   "metadata": {},
+   "source": [
+    "# Space Comparison \n",
+    "\n",
+    "We compare the space usage between the $4, 6, 8$ bit versions of the Apache DataSketches (ASF) HyperLogLog implementation alongside the `datasketch` HyperLogLogPlusPlus implementation.  We show that the `datasketch` version has approximately the same size as the ASF $8$ bit implementation when the latter is in full estimation mode.  However, smaller sketches can be made without compromising on the accuracy if $6$ or $4$ bits per bucket are used which use $75\\%$ and $50\\%$ of the space consumed by either of the $8$ bit variants."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "id": "71570575-d16b-4b9b-a066-f921b58eb179",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import os\n",
+    "from datetime import datetime\n",
+    "import pandas as pd\n",
+    "import numpy as np\n",
+    "from utils import distinct_number_sequence\n",
+    "import datasketches as ds\n",
+    "import datasketch as d\n",
+    "import mmh3\n",
+    "import matplotlib.pyplot as plt\n",
+    "from timeit import default_timer\n",
+    "%matplotlib inline"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "id": "82fac9dc-d5f2-4d19-9f18-8edc96d7c045",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "class SpaceProfile:\n",
+    "    \"\"\"Generates an experiment evaluating the update time for different cardinality inputs\"\"\"\n",
+    "    def __init__(self, sketch_lgk:int, lg_trials:int, max_lgN:int):\n",
+    "        self.sketch_lgk = sketch_lgk\n",
+    "        self.num_trials = 2**lg_trials\n",
+    "        self.max_lgN = max_lgN\n",
+    "        self.max_num_distincts = np.uint64(2 ** self.max_lgN)\n",
+    "        self.directory_name = \"hll_space_profile_\"\n",
+    "        if not os.path.exists(self.directory_name):\n",
+    "            os.mkdir(self.directory_name)\n",
+    "        self.file_extension = \"_\" + datetime.today().strftime('%H%M') + f\"lgK_{self.sketch_lgk}_lgT_{lg_trials}\"\n",
+    "\n",
+    "        # Need to remove repeated items for the program logic in self.run()\n",
+    "        self.plot_points = self._generate_plot_points()\n",
+    "        self.plot_points.extend(self._generate_plot_points())\n",
+    "        self.plot_points = list(set(self.plot_points))\n",
+    "        self.plot_points.sort()\n",
+    "        print(f\"Testing {len(self.plot_points)} points with {self.num_trials} trials for average update times:\")\n",
+    "        print(self.plot_points)\n",
+    "\n",
+    "        # Initialise the data structures for results; one for each method tested 8, 6, datasketch\n",
+    "        # np.ndarrays\n",
+    "        self.DataSketches_results_arr = np.zeros((len(self.plot_points), self.num_trials), dtype=float)\n",
+    "        self.DataSketches_results_arr_6 =  np.zeros_like(self.DataSketches_results_arr)\n",
+    "        self.DataSketches_results_arr_4 =  np.zeros_like(self.DataSketches_results_arr)\n",
+    "        self.datasketch_results_arr = np.zeros_like(self.DataSketches_results_arr)\n",
+    "\n",
+    "        # pd.DataFrames\n",
+    "        self.DataSketches_results_df = pd.DataFrame(index=self.plot_points, columns=None)\n",
+    "        self.DataSketches_results_df_6 = pd.DataFrame(index=self.plot_points, columns=None)\n",
+    "        self.DataSketches_results_df_4 = pd.DataFrame(index=self.plot_points, columns=None)\n",
+    "        self.datasketch_results_df = pd.DataFrame(index=self.plot_points, columns=None)\n",
+    "        \n",
+    "    def _generate_plot_points(self) -> list:\n",
+    "        \"\"\"\n",
+    "        Generates the standard sequence defining the input cardinalites for the experiment\n",
+    "        This is just two points at each power of 2\n",
+    "        \"\"\"\n",
+    "        all_plot_points = []\n",
+    "        for lgk in range(1, self.max_lgN+1):\n",
+    "            points = np.unique(np.logspace(start=lgk, stop=lgk+1, num=4, endpoint=False, base=2, dtype=np.uint64))\n",
+    "            all_plot_points.extend(points)\n",
+    "        all_plot_points.sort()\n",
+    "        return all_plot_points\n",
+    "\n",
+    "    def _is_power_of_two(self, a:np.uint64) -> bool:\n",
+    "        \"\"\"Bitwise operations to check value a is a power of two\"\"\"\n",
+    "        return (a & (a-1) == 0) and a != 0\n",
+    "\n",
+    "    def run(self) -> None:\n",
+    "        \"\"\"Runs the experiment and writes the files every power of two trials.\"\"\"\n",
+    "        seq_start = np.uint64(2345234)\n",
+    "        distinct_number = np.uint64(3462)\n",
+    "        previous_log_trial_index = 0\n",
+    "        ds_all_results = np.zeros((self.num_trials, len(self.plot_points)))\n",
+    "        ds_all_results_6 = np.zeros_like(ds_all_results)\n",
+    "        ds_all_results_4 = np.zeros_like(ds_all_results)\n",
+    "        d_all_results = np.zeros_like(ds_all_results)\n",
+    "\n",
+    "        for trial in range(1, self.num_trials+1):\n",
+    "\n",
+    "            # Initialise the sketches\n",
+    "            hll = ds.hll_sketch(self.sketch_lgk, ds.HLL_8)\n",
+    "            hll6 = ds.hll_sketch(self.sketch_lgk, ds.HLL_6)\n",
+    "            hll4 = ds.hll_sketch(self.sketch_lgk, ds.HLL_4)\n",
+    "            h = d.HyperLogLogPlusPlus(p=self.sketch_lgk, hashfunc=lambda x: mmh3.hash64(x, signed=False)[0])\n",
+    "            plot_point_index = 0  # Return to the start of the plot points list to generate the data\n",
+    "            plot_point_value = self.plot_points[plot_point_index]\n",
+    "            total_updates = 0\n",
+    "            seq_start += distinct_number  # Start a new input sequence\n",
+    "\n",
+    "            # Temporary result data structure\n",
+    "            ds_results = np.zeros((len(self.plot_points),))\n",
+    "            ds_results_6 = np.zeros_like(ds_results)\n",
+    "            ds_results_4 = np.zeros_like(ds_results)\n",
+    "            d_results = np.zeros_like(ds_results)\n",
+    "\n",
+    "\n",
+    "            for new_number in distinct_number_sequence(seq_start):\n",
+    "                d_input = new_number.tobytes()\n",
+    "                \n",
+    "                hll.update(d_input)\n",
+    "                hll6.update(d_input)\n",
+    "                hll4.update(d_input)\n",
+    "                h.update(d_input)\n",
+    "                total_updates += 1\n",
+    "\n",
+    "                if total_updates == plot_point_value:\n",
+    "                    ds_results[plot_point_index]   =  hll.get_compact_serialization_bytes()\n",
+    "                    ds_results_6[plot_point_index] =  hll6.get_compact_serialization_bytes()\n",
+    "                    ds_results_4[plot_point_index] =  hll4.get_compact_serialization_bytes()\n",
+    "                    d_results[plot_point_index]    =  h.bytesize()\n",
+    "                    plot_point_index += 1\n",
+    "\n",
+    "                    if plot_point_index < len(self.plot_points):\n",
+    "                        plot_point_value = self.plot_points[plot_point_index]\n",
+    "                    else:\n",
+    "                        break\n",
+    "\n",
+    "            # After the break statement, control returns here.  Now need to decide whether to write or continue.\n",
+    "            # subtract 1 as we use 1-based indexing for the trial count.\n",
+    "            ds_all_results[trial-1, :]   = ds_results \n",
+    "            ds_all_results_6[trial-1, :] = ds_results_6 \n",
+    "            ds_all_results_4[trial-1, :] = ds_results_4\n",
+    "            d_all_results[trial - 1, :]  = d_results  \n",
+    "            if self._is_power_of_two(trial) and trial > 1:\n",
+    "                # write the array only a logarithmic number of times\n",
+    "                temporary_ds_results = ds_all_results[0:trial, : ]\n",
+    "                temporary_ds_results_6 = ds_all_results_6[0:trial, : ]\n",
+    "                temporary_ds_results_4 = ds_all_results_4[0:trial, : ]\n",
+    "                temporary_d_results = d_all_results[0:trial, :]\n",
+    "                print(f\"#################### PARTIAL RESULTS FOR {trial} TRIALS: DATASKETCHES ####################\")\n",
+    "                previous_log_trial_index = trial\n",
+    "\n",
+    "                # Write 8 bit results\n",
+    "                self.DataSketches_results_df = pd.DataFrame(temporary_ds_results.T, \n",
+    "                                                            index=self.DataSketches_results_df.index, \n",
+    "                                                            columns=np.arange(trial).tolist())\n",
+    "                self.DataSketches_results_df.to_csv(\n",
+    "                    self.directory_name + \"/DataSketches_hll\" + self.file_extension + f\"trials_{trial}_8_bit.csv\",\n",
+    "                    index_label=\"n\")\n",
+    "\n",
+    "                # Write 6 bit results\n",
+    "                self.DataSketches_results_df_6 = pd.DataFrame(temporary_ds_results_6.T, \n",
+    "                                                            index=self.DataSketches_results_df_6.index, \n",
+    "                                                            columns=np.arange(trial).tolist())\n",
+    "                self.DataSketches_results_df_6.to_csv(\n",
+    "                    self.directory_name + \"/DataSketches_hll\" + self.file_extension + f\"trials_{trial}_6_bit.csv\",\n",
+    "                    index_label=\"n\")\n",
+    "\n",
+    "                 # Write 4 bit results\n",
+    "                self.DataSketches_results_df_4 = pd.DataFrame(temporary_ds_results_4.T, \n",
+    "                                                            index=self.DataSketches_results_df_4.index, \n",
+    "                                                            columns=np.arange(trial).tolist())\n",
+    "                self.DataSketches_results_df_4.to_csv(\n",
+    "                    self.directory_name + \"/DataSketches_hll\" + self.file_extension + f\"trials_{trial}_4_bit.csv\",\n",
+    "                    index_label=\"n\")\n",
+    "\n",
+    "                # Write datasketch results\n",
+    "                self.datasketch_results_df = pd.DataFrame(temporary_d_results.T,\n",
+    "                                                            index=self.datasketch_results_df.index,\n",
+    "                                                            columns=np.arange(trial).tolist())\n",
+    "                self.datasketch_results_df.to_csv(\n",
+    "                    self.directory_name + \"/datasketch_hll\" + self.file_extension + f\"trials_{trial}.csv\",\n",
+    "                    index_label=\"n\"\n",
+    "                )\n",
+    "                print(self.DataSketches_results_df)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "01003378-cb60-45d0-9b19-a74b028dd4a1",
+   "metadata": {},
+   "source": [
+    "The experiment updates each of the four sketches with a number of distinct values determined by the input parameters `MAX_LG_N`.  A single pass is taken for each trial and all four methods are updated in that pass.  The number of bytes required to write the sketch to memory is evaluated and written to a results file.\n",
+    "\n",
+    "There is essentially no variation in the sketch sizes over these trials so only a small number of trials are performed.  We set the default experimental parameters below.  \n",
+    "\n",
+    "```SKETCH_LGK = 12, LG_TRIALS = 2, MAX_LG_N = 21``` "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "id": "45e22a9a-4b30-4a2b-9a49-0336e4d27bd8",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "SKETCH_LGK = 12\n",
+    "LG_TRIALS = 3\n",
+    "MAX_LG_N = 21"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "id": "b748aead-1563-485f-adb5-378b1655bf38",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Testing 81 points with 8 trials for average update times:\n",
+      "[2, 3, 4, 5, 6, 8, 9, 11, 13, 16, 19, 22, 26, 32, 38, 45, 53, 64, 76, 90, 107, 128, 152, 181, 215, 256, 304, 362, 430, 512, 608, 724, 861, 1024, 1217, 1448, 1722, 2048, 2435, 2896, 3444, 4096, 4870, 5792, 6888, 8192, 9741, 11585, 13777, 16384, 19483, 23170, 27554, 32768, 38967, 46340, 55108, 65536, 77935, 92681, 110217, 131072, 155871, 185363, 220435, 262144, 311743, 370727, 440871, 524288, 623487, 741455, 881743, 1048576, 1246974, 1482910, 1763487, 2097152, 2493948, 2965820, 3526975]\n"
+     ]
+    }
+   ],
+   "source": [
+    "space_experiment = SpaceProfile(SKETCH_LGK, LG_TRIALS, MAX_LG_N)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "id": "cc7b9b3b-7976-4fb9-adc7-d7691134df93",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "#################### PARTIAL RESULTS FOR 2 TRIALS: DATASKETCHES ####################\n",
+      "              0       1\n",
+      "2          16.0    16.0\n",
+      "3          20.0    20.0\n",
+      "4          24.0    24.0\n",
+      "5          28.0    28.0\n",
+      "6          32.0    32.0\n",
+      "...         ...     ...\n",
+      "1763487  4136.0  4136.0\n",
+      "2097152  4136.0  4136.0\n",
+      "2493948  4136.0  4136.0\n",
+      "2965820  4136.0  4136.0\n",
+      "3526975  4136.0  4136.0\n",
+      "\n",
+      "[81 rows x 2 columns]\n",
+      "#################### PARTIAL RESULTS FOR 4 TRIALS: DATASKETCHES ####################\n",
+      "              0       1       2       3\n",
+      "2          16.0    16.0    16.0    16.0\n",
+      "3          20.0    20.0    20.0    20.0\n",
+      "4          24.0    24.0    24.0    24.0\n",
+      "5          28.0    28.0    28.0    28.0\n",
+      "6          32.0    32.0    32.0    32.0\n",
+      "...         ...     ...     ...     ...\n",
+      "1763487  4136.0  4136.0  4136.0  4136.0\n",
+      "2097152  4136.0  4136.0  4136.0  4136.0\n",
+      "2493948  4136.0  4136.0  4136.0  4136.0\n",
+      "2965820  4136.0  4136.0  4136.0  4136.0\n",
+      "3526975  4136.0  4136.0  4136.0  4136.0\n",
+      "\n",
+      "[81 rows x 4 columns]\n",
+      "#################### PARTIAL RESULTS FOR 8 TRIALS: DATASKETCHES ####################\n",
+      "              0       1       2       3       4       5       6       7\n",
+      "2          16.0    16.0    16.0    16.0    16.0    16.0    16.0    16.0\n",
+      "3          20.0    20.0    20.0    20.0    20.0    20.0    20.0    20.0\n",
+      "4          24.0    24.0    24.0    24.0    24.0    24.0    24.0    24.0\n",
+      "5          28.0    28.0    28.0    28.0    28.0    28.0    28.0    28.0\n",
+      "6          32.0    32.0    32.0    32.0    32.0    32.0    32.0    32.0\n",
+      "...         ...     ...     ...     ...     ...     ...     ...     ...\n",
+      "1763487  4136.0  4136.0  4136.0  4136.0  4136.0  4136.0  4136.0  4136.0\n",
+      "2097152  4136.0  4136.0  4136.0  4136.0  4136.0  4136.0  4136.0  4136.0\n",
+      "2493948  4136.0  4136.0  4136.0  4136.0  4136.0  4136.0  4136.0  4136.0\n",
+      "2965820  4136.0  4136.0  4136.0  4136.0  4136.0  4136.0  4136.0  4136.0\n",
+      "3526975  4136.0  4136.0  4136.0  4136.0  4136.0  4136.0  4136.0  4136.0\n",
+      "\n",
+      "[81 rows x 8 columns]\n",
+      "CPU times: user 2min 9s, sys: 229 ms, total: 2min 9s\n",
+      "Wall time: 2min 9s\n"
+     ]
+    }
+   ],
+   "source": [
+    "%%time\n",
+    "space_experiment.run()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "id": "8afd8986-9641-4cc9-ac4d-5ead4c359367",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "asf8 = pd.read_csv(f\"hll_space_profile_/DataSketches_hll{space_experiment.file_extension}trials_{1<<LG_TRIALS}_8_bit.csv\", index_col=0)\n",
+    "asf6 = pd.read_csv(f\"hll_space_profile_/DataSketches_hll{space_experiment.file_extension}trials_{1<<LG_TRIALS}_6_bit.csv\", index_col=0)\n",
+    "asf4 = pd.read_csv(f\"hll_space_profile_/DataSketches_hll{space_experiment.file_extension}trials_{1<<LG_TRIALS}_4_bit.csv\", index_col=0)\n",
+    "dsk = pd.read_csv(f\"hll_space_profile_/datasketch_hll{space_experiment.file_extension}trials_{1<<LG_TRIALS}.csv\", index_col=0)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "85c00f74-7e5c-4aa5-81ef-6c39d61a49e1",
+   "metadata": {},
+   "source": [
+    "Next, we will plot the median number of bytes required to write the sketch to memory for each method.  There is no variation for the sizes of ASF8 and ASF6; similarly, for ASF4, although there is slight variation in the size of the sketches in estimation mode.  The `datasketch` implementation has no variation."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "id": "702c160f-f5db-4c81-96ba-03935a48c9da",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(      0     1     2     3     4     5     6     7\n",
+       " n                                                \n",
+       " 2  16.0  16.0  16.0  16.0  16.0  16.0  16.0  16.0\n",
+       " 3  20.0  20.0  20.0  20.0  20.0  20.0  20.0  20.0\n",
+       " 4  24.0  24.0  24.0  24.0  24.0  24.0  24.0  24.0\n",
+       " 5  28.0  28.0  28.0  28.0  28.0  28.0  28.0  28.0\n",
+       " 6  32.0  32.0  32.0  32.0  32.0  32.0  32.0  32.0,\n",
+       "               0       1       2       3       4       5       6       7\n",
+       " n                                                                      \n",
+       " 1763487  4136.0  4136.0  4136.0  4136.0  4136.0  4136.0  4136.0  4136.0\n",
+       " 2097152  4136.0  4136.0  4136.0  4136.0  4136.0  4136.0  4136.0  4136.0\n",
+       " 2493948  4136.0  4136.0  4136.0  4136.0  4136.0  4136.0  4136.0  4136.0\n",
+       " 2965820  4136.0  4136.0  4136.0  4136.0  4136.0  4136.0  4136.0  4136.0\n",
+       " 3526975  4136.0  4136.0  4136.0  4136.0  4136.0  4136.0  4136.0  4136.0)"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "asf8.head(), asf8.tail()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "id": "4764f965-4e40-4ff9-a99f-001f8fe7a7a9",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(      0     1     2     3     4     5     6     7\n",
+       " n                                                \n",
+       " 2  16.0  16.0  16.0  16.0  16.0  16.0  16.0  16.0\n",
+       " 3  20.0  20.0  20.0  20.0  20.0  20.0  20.0  20.0\n",
+       " 4  24.0  24.0  24.0  24.0  24.0  24.0  24.0  24.0\n",
+       " 5  28.0  28.0  28.0  28.0  28.0  28.0  28.0  28.0\n",
+       " 6  32.0  32.0  32.0  32.0  32.0  32.0  32.0  32.0,\n",
+       "               0       1       2       3       4       5       6       7\n",
+       " n                                                                      \n",
+       " 1763487  3113.0  3113.0  3113.0  3113.0  3113.0  3113.0  3113.0  3113.0\n",
+       " 2097152  3113.0  3113.0  3113.0  3113.0  3113.0  3113.0  3113.0  3113.0\n",
+       " 2493948  3113.0  3113.0  3113.0  3113.0  3113.0  3113.0  3113.0  3113.0\n",
+       " 2965820  3113.0  3113.0  3113.0  3113.0  3113.0  3113.0  3113.0  3113.0\n",
+       " 3526975  3113.0  3113.0  3113.0  3113.0  3113.0  3113.0  3113.0  3113.0)"
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "asf6.head(), asf6.tail()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "id": "d8513334-4c91-450d-ad97-12418bc8c5d6",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(      0     1     2     3     4     5     6     7\n",
+       " n                                                \n",
+       " 2  16.0  16.0  16.0  16.0  16.0  16.0  16.0  16.0\n",
+       " 3  20.0  20.0  20.0  20.0  20.0  20.0  20.0  20.0\n",
+       " 4  24.0  24.0  24.0  24.0  24.0  24.0  24.0  24.0\n",
+       " 5  28.0  28.0  28.0  28.0  28.0  28.0  28.0  28.0\n",
+       " 6  32.0  32.0  32.0  32.0  32.0  32.0  32.0  32.0,\n",
+       "               0       1       2       3       4       5       6       7\n",
+       " n                                                                      \n",
+       " 1763487  2092.0  2088.0  2096.0  2096.0  2092.0  2100.0  2092.0  2096.0\n",
+       " 2097152  2092.0  2092.0  2104.0  2096.0  2096.0  2100.0  2092.0  2088.0\n",
+       " 2493948  2092.0  2092.0  2104.0  2088.0  2100.0  2104.0  2096.0  2088.0\n",
+       " 2965820  2092.0  2104.0  2088.0  2088.0  2092.0  2100.0  2096.0  2088.0\n",
+       " 3526975  2092.0  2104.0  2088.0  2088.0  2092.0  2100.0  2096.0  2088.0)"
+      ]
+     },
+     "execution_count": 9,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "asf4.head(), asf4.tail()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "id": "a0b4bf36-8fec-4007-8a67-dda92ba49234",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(        0       1       2       3       4       5       6       7\n",
+       " n                                                                \n",
+       " 2  4097.0  4097.0  4097.0  4097.0  4097.0  4097.0  4097.0  4097.0\n",
+       " 3  4097.0  4097.0  4097.0  4097.0  4097.0  4097.0  4097.0  4097.0\n",
+       " 4  4097.0  4097.0  4097.0  4097.0  4097.0  4097.0  4097.0  4097.0\n",
+       " 5  4097.0  4097.0  4097.0  4097.0  4097.0  4097.0  4097.0  4097.0\n",
+       " 6  4097.0  4097.0  4097.0  4097.0  4097.0  4097.0  4097.0  4097.0,\n",
+       "               0       1       2       3       4       5       6       7\n",
+       " n                                                                      \n",
+       " 1763487  4097.0  4097.0  4097.0  4097.0  4097.0  4097.0  4097.0  4097.0\n",
+       " 2097152  4097.0  4097.0  4097.0  4097.0  4097.0  4097.0  4097.0  4097.0\n",
+       " 2493948  4097.0  4097.0  4097.0  4097.0  4097.0  4097.0  4097.0  4097.0\n",
+       " 2965820  4097.0  4097.0  4097.0  4097.0  4097.0  4097.0  4097.0  4097.0\n",
+       " 3526975  4097.0  4097.0  4097.0  4097.0  4097.0  4097.0  4097.0  4097.0)"
+      ]
+     },
+     "execution_count": 10,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "dsk.head(), dsk.tail()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "id": "0bd8f65e-ff85-4857-a79a-87687128adff",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Plotting parameters\n",
+    "method_plot_params = {\n",
+    "    \"asf8\" : {\"color\": \"C0\", \"marker\": '.'},\n",
+    "    \"asf6\" : {\"color\": \"C2\", \"marker\": '+'},\n",
+    "    \"asf4\" : {\"color\": \"C3\", \"marker\": 'd'},\n",
+    "    \"datasketch\" : {\"color\": \"C1\", \"marker\": \"^\"}\n",
+    "}\n",
+    "asf8_color = method_plot_params[\"asf8\"][\"color\"]\n",
+    "asf6_color = method_plot_params[\"asf6\"][\"color\"]\n",
+    "asf4_color = method_plot_params[\"asf4\"][\"color\"]\n",
+    "ds_color = method_plot_params[\"datasketch\"][\"color\"]\n",
+    "q90_ls = \"--\"\n",
+    "\n",
+    "params = {'legend.fontsize': 'x-large',\n",
+    "     'axes.labelsize': 'x-large',\n",
+    "     'axes.titlesize':'x-large',\n",
+    "     'xtick.labelsize':'x-large',\n",
+    "     'ytick.labelsize':'x-large',\n",
+    "      \"lines.linewidth\": 2.5}\n",
+    "plt.rcParams.update(params)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "id": "cb2980aa-c47c-40c1-a69f-ff8271cbcb15",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "Text(0.5, 0, 'Input cardinality $n$')"
+      ]
+     },
+     "execution_count": 12,
+     "metadata": {},
+     "output_type": "execute_result"
+    },
+    {
+     "data": {
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAA+UAAAHHCAYAAADZOPmeAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/SrBM8AAAACXBIWXMAAA9hAAAPYQGoP6dpAACCNUlEQVR4nO3dd3xTdfv/8XeSpovSxSx7D9kb2QiyVFBBURFBcTAERL1/rlspKvDV763cgHor8hVwcauALJE9BAWUpYIgWzZIoQvaNE3O74/S0NC0tKFt2vJ6Ph59QM75nJPrtFfSXP2MYzIMwxAAAAAAAChwZl8HAAAAAADAzYqiHAAAAAAAH6EoBwAAAADARyjKAQAAAADwEYpyAAAAAAB8hKIcAAAAAAAfoSgHAAAAAMBHKMoBAAAAAPARP18HAKDostvtcjgcvg4DAADcAIvFIqvV6uswgJsWRTmAXIuPj9f58+dls9l8HQoAAMgDAQEBKl26tEJDQ30dCnDToSgHkCvx8fE6efKkQkJCVLp0aVmtVplMJl+HBQAAvGAYhux2u+Li4nTy5ElJojAHCpjJMAzD10EAKDoOHz4sq9WqSpUqUYwDAFBMGIahEydOyG63q0aNGr4OB7ipsNAbgByz2+2y2WwKCwujIAcAoBgxmUwKCwuTzWaT3W73dTjATYWiHECOpS/qxmIwAAAUP+m/31nEFShYFOUAco1ecgAAih9+vwO+QVEOAAAAAICPUJQDAAAAAOAjFOUAgGLj6NGjMplMGjp0qNv2oUOHymQy6ejRoz6JC4C79evXy2QyKTo62m17ly5dGEIN4KZDUQ4AN2jixIkymUwymUz6888/s2176tQpjRs3TrfccouCg4MVFBSkKlWqqHPnznrllVd06NAht/bpxWRWX126dHFr73A49MUXX6hjx44qX768goODVadOHT366KPas2dPXl86UKQUptfqtd58801X29WrV9/opQIAihA/XwcAAEWZYRiaOXOmTCaTDMPQxx9/rH/9618e2+7evVudO3fWhQsX1KhRIw0ZMkSRkZE6d+6cfv75Z02aNEnVq1dXzZo1Mx3br18/NW3aNNP2atWquT1+6KGH9PXXX6tSpUq69957VbJkSf3++++aM2eOvvzyS33//fe67bbb8uLSi5TJkyfrxRdfVMWKFX0dCnyksL1WM9qxY4def/11hYSEKDEx0dtLLBY+/fRTXb582ddhAECBoigHgBuwcuVKHT16VEOHDtXy5cs1Z84cTZo0Sf7+/pnaPvPMM7pw4YKio6M1fvz4TPsPHz6slJQUj89z9913ZxqSfa1ffvlFX3/9tRo0aKCff/5ZwcHBrn2zZs3SY489pjfffPOmLMqjoqIUFRXl6zDgQ4XptZpRcnKyBg8erFatWqlmzZr67LPPcnxscVSlShVfhwAABY7h6wBwAz7++GNJ0hNPPKFBgwbp/Pnz+vbbbz22/emnnyRJY8eO9bi/Ro0aqlevntexHD58WJLUrVs3t4JcSuu9k6S///7b6/Onmz17tkwmk2bPnq1Vq1apY8eOCgkJUZkyZfToo48qNjZWkrRz507deeedioiIUEhIiPr27ZvlnO4LFy7opZdeUv369RUUFKSwsDB169ZNK1eu9Ng+ISFBzz77rCpVqqTAwEDVq1dP7777rpxOp8f2Wc0pnz17tvr3768aNWooKChIoaGhat++vT7//HOP50mf75qamqpJkyapdu3aCggIUOXKlfXCCy9kWajB9wrTazWjl156SUeOHNHs2bNlNuftx7Lo6GiZTCatX79ec+fOVYsWLRQcHKwKFSro2Weflc1mkyStXbtWXbp0UWhoqCIiIjR48GDFxMR4POeJEyf09NNPq0aNGgoICFCpUqXUt29f/fLLLx7bnz17VsOGDVO5cuUUFBSkpk2bas6cOVnG7GlOeUpKit577z316dNHVatWVUBAgCIjI9W9e3d9//33Hs9TrVo1VatWTZcuXdI//vEPValSRQEBAapVq5beeustGYaRk28hABQIinIA8NLZs2e1ePFi1alTR+3atXP1js2YMcNj+1KlSkmS9u/fny/xNGjQQFLaB+ykpCS3fUuXLpUkde/ePdNx6fNYc2vx4sW64447VKZMGQ0fPly1a9fW7Nmzdc8992jLli3q0KGDUlNTNWzYMLVv315LlizRnXfemalw/uuvv9SiRQv9z//8j+tcAwcO1N69e9WrVy9XMZXOZrOpW7dumjJlikqXLq2xY8eqc+fOeuONNzRu3LhcXcOIESP0119/qVOnTnrmmWf0wAMP6K+//tLgwYP16quvZnncQw89pOnTp6tjx44aMWKEgoKC9Pbbb+upp57K1fOjYBS212q6tWvXaurUqZo8ebJq166dbdv0RQyzGwaflenTp2vYsGGqW7euRowYoVKlSmnKlCl66qmn9O2336p3796KjIzUk08+qfr16+vzzz/Xww8/nOk8O3bsUNOmTfXBBx+obt26Gj16tO666y798MMP6tChg5YtW+bW/vz582rXrp0++eQT1alTR88884yaNm2q4cOHa8qUKTmO/8KFCxo7dqwSEhJ0++2369lnn1Xfvn21c+dO9enTRzNnzvR4nN1uV8+ePTV//nz17t1bjz/+uJKSkvTiiy/q9ddfz903EQDyEcPXAeSJZLtDMZeKTi9hqRL+CrRabugcs2bNkt1ud33Ab9iwoVq0aKF169bp4MGDqlWrllv7gQMH6p133lHfvn01YsQIde3aVU2bNlVoaOh1n2vhwoUee5mfeeYZhYeHu55/3LhxmjJliurVq6c777xTJUuW1J49e7R8+XI98MADevPNN2/omjNavHix1qxZo86dO0uSnE6nevbsqdWrV6tPnz6aMWOGBg0a5Go/bNgwffLJJ1qyZImr516ShgwZor/++ktz587VAw884NoeGxurLl26aMyYMerbt6/KlSsnSXrnnXf0yy+/6N5779U333zj6l188cUX1aJFi1xdw+7duzPNC05JSVHv3r31P//zPxo+fLjHeeiHDh3Snj17FBkZKSltAbEmTZro008/1eTJk1W+fPlcxVGQnDabHFn0ghZGllKlZA4IuKFzFLbXqiTFxcVp6NCh6tixo8aMGXMjl3ddq1ev1vbt21W/fn1JaX/Yat68uT777DMtWbJEK1euzPQ6Xr58uXbt2uWaH5+amqr7779fiYmJWrdunau9lLYoXqtWrTRs2DAdPXpUAVd+Xi+//LIOHz6sZ555xq0If/rpp3XrrbfmOP6IiAj99ddfqlSpktv2uLg4tW/fXv/v//0/DRo0SEFBQW77T506pSZNmmjVqlWufePHj1edOnU0ZcoUvfzyy7JarTmOAwDyC0U5gDwRcylFX/9y3Ndh5Nj9rSqrYnjQ9RtmIX3RKLPZrEceecS1fejQodq+fbs+/vhjvfXWW27HTJw4UfHx8Zo1a5aio6NdQ0vr1KmjXr16acyYMapRo4bH51u0aJEWLVqUafvQoUPdPui/++67qlu3rsaNG6cPPvjAtb1FixYaMmSISpQokekce/fuze3lS5IefPBBtw/mZrNZgwcP1urVq9WwYUO3glySHnnkEX3yySfatWuXqyj/9ddftWHDBg0YMMCtIJek8PBwTZgwQXfffbfmz5+vkSNHSkorsMxms95++2234b7Vq1fXmDFjNGHChBxfg6eFuvz9/TVq1CitXbtWa9ascfv5pnvrrbdcBbkklShRQoMGDdLrr7+ubdu26c4778xxDAXNEROj2PkLfB1GjoX3v1fmChW8Pr6wvlZHjx6tCxcuuG4Ndj0VK1bU3r17vSoix4wZ4yrIJSkgIEADBw7U+PHjdccdd2R6HT/88MNavXq1fv31V1dR/t133+nQoUN6/vnn3dpLUoUKFfT//t//0zPPPKM1a9aoT58+stvt+uKLL1SyZMlMtz1r2bKlBg0alO0w9owCAgIyFeSSFBYWpscee0zPPfecfvnlF3Xq1ClTm2nTprkV62XLllW/fv306aef6s8//1TDhg1zFAMA5CeGrwOAF9auXatDhw7p9ttvd+tJfeihh+Tv76/Zs2fLbre7HRMQEKAZM2boxIkTmj17tkaMGKHWrVvr4MGDmjp1qho2bOgaZn6tWbNmyTCMTF8Zh7IahqExY8Zo1KhReu2113T8+HElJCRo48aNMplM6t27t95///1M565Xr55X82NbtmyZaVuFK8WTpx7r9O/TiRMnXNs2b94sKa3HK734yfiVPqc8/Q8HCQkJOnjwoCpWrOixoL7ebaeudezYMY0aNUr16tVTcHCwayh///79JUknT570eJyna69cubIk6eLFi7mKAfmrML5W58+fr88++0xvv/12lsX9taxWq+rVq+cx768nL1+rf/31l8fX6s8//yzp6mt13759unz5spo2baqwsLBMz5Hb1+qePXs0dOhQ1/oP6a/V5557TpLn12pYWFimURASr1UAhQ895QDghfS5qNeushwZGam77rpL8+fP16JFizRgwIBMx5YrV05DhgzRkCFDJKXNl3zhhRc0c+ZMPfbYYzpx4oTHFaGvZ86cOZo+fbrGjRunF1980bW9Q4cOWrJkiWrUqKEXX3xRQ4YMUUhISK7Pfy1PH7T9/Pyuuy9jAZS+mNSqVau0atWqLJ8r/TZRcXFxkuQayn6t3AwbP3z4sFq3bq2LFy+qY8eO6tGjh8LCwmSxWHT06FHNmTPHtRDWtTL2eKZLvz6Hw5HjGJD/Cttr9cKFCxo+fLi6deumESNGeHdRuZSXr9Vvvvkm2+fKj9fqli1bdNtttyk1NVXdunVT3759FRoaKrPZrF27dmnRokUeX6ueXqcSr1UAhQ9FOYA8UaqEv+5vVdnXYeRYqRK5L3rT/f3331q4cKGktCHcDz74oMd2M2bM8PhB/1qRkZH66KOPtHLlSh07dky7d+9W8+bNcx1Xes9d165dM+0rX7686tWrp507d+rPP//M9dzr/JJeEEydOjVH82rT2589e9bj/jNnzuT4ud99913FxMRo1qxZmQq2uXPn5nhobVFjKVVK4f3v9XUYOWa5suiaNwrja/XYsWM6f/681qxZk+Vq67fffrskacqUKXrmmWdydf78kv7aW7Rokfr27Zvj9nnxWn3zzTeVlJSkdevWZephnzx5ssfpAgBQlFCUA8gTgVbLDc3RLkrmzJmjlJQUtWjRwjXf8lqLFy/W6tWrdeTIEVWvXv265zSbza753t7eqie9pyir256lb/emFz6/tG3bVpK0cePGHBXlJUuWVK1atXT48GEdOnQo01De9evX5/i5Dx48KEmuoeoZbdiwIcfnKWrMAQE3NEe7KCmMr9VSpUpp2LBhHvf98MMPOnDggHr37q0KFSoUqvnOGV+rOSnK06eE7Nq1S3FxcZl65HP7Wo2MjPQ45L04v1YB3DyYUw4AuZR+i64PPvhAM2fO9Pj11FNPuRaYSjdhwoQs79M9b9487du3TxEREV5/EO/YsaOktB7g9KGj6T788EOdOHFC5cuX1y233OK2b9++fdq3b59Xz3mjWrZsqY4dO2rBggX65JNPPLb5/fffde7cOdfjRx99VE6nUy+88ILb7dWOHDmiadOm5fi50+f4XlscrFixIstbLKFoKYyv1cqVK2cZS7t27SRJzz77rGbOnOl2C0O73a59+/bp0KFDuX7OvNCvXz/VrFlT77//fqZbn6XbvHmzLl++LCltDvygQYOUkJCQaaG3bdu26Ysvvsjxc1erVk0XLlzQb7/95rb9//7v/7RixYrcXQgAFEL0lANALqxfv1779+9Xo0aN1Lp16yzbDRs2TBMnTtSsWbM0YcIE+fn5acqUKYqOjlazZs3UsmVLlSlTRnFxcdqxY4c2b94sPz8/ffjhh67bCeXWyJEj9cUXX+i3335TnTp11LdvX4WHh2vHjh1au3atLBaL3n//fVks7reCS1+V2dse+hv15Zdf6rbbbtOwYcM0bdo0tWnTRuHh4Tpx4oR+++037d69W5s3b1bZsmUlSc8995wWLlyo+fPnq3nz5urZs6diY2P19ddfq1OnTlq8eHGOnnfkyJGaNWuW7rvvPg0YMEAVKlTQ7t27tXz5ct1///366quv8vOykc8K82vVGydPnlT9+vVVtWrVLP9gkJ+sVqsWLFignj176o477lC7du3UtGlTBQcH6/jx4/rll190+PBhnT59WsHBwZKkSZMmac2aNfr3v/+tbdu2qUOHDjp9+rS++uor9enTJ8ev1WeeeUYrVqxQhw4ddP/99yssLEzbtm3Tpk2bNGDAAM2bNy8/Lx0A8h1FOQDkQnrP2+OPP55tu2rVqql79+5atWqVlixZonvuuUdLly7V999/rw0bNmj58uU6e/as/Pz8VKlSJT3++OMaM2aMGjVq5HVsISEh+vHHH/Xuu+9qwYIF+vLLL5WSkqIyZcrovvvu0/PPP59tceIrlSpV0vbt2zV9+nTNnz9fX3zxhRwOh6tXf/To0W7fl4CAAK1evVrR0dH66quvNHXqVFWrVk3//Oc/dc899+T4g37jxo21bt06/fOf/9R3332n1NRUNWnSRAsWLFB4eDhFeRFXmF+rRVXjxo3166+/6t1339XSpUtdtyeMiopSs2bNNGHCBJUuXdrVvnTp0vrxxx/18ssva8mSJdq2bZvq1q2r//znP6pWrVqOX6u9evXSkiVL9Oabb+qrr76SxWJR69attW7dOh0+fJiiHECRZzJ81TUCoMhJTk52zbsMDAz0dTgAACAP8Xse8A3mlAMAAAAA4CMU5QAAAAAA+AhFOQAAAAAAPkJRDgAAAACAj1CUAwAAAADgIxTlAAAAAAD4CEU5AAAAAAA+QlEOAAAAAICPUJQDAAAAAOAjFOUAAAAAAPgIRTkAAAAAAD5CUQ4AAAAAgI9QlAMAAAAA4CMU5QCAYuPo0aMymUwaOnSo2/ahQ4fKZDLp6NGjPokLhVO1atVUrVo1X4fhtdmzZ8tkMmn27Nm+DiVb69evl8lkUnR0tK9D8RnemwBkh6IcAG7QxIkTZTKZZDKZ9Oeff2bb9tSpUxo3bpxuueUWBQcHKygoSFWqVFHnzp31yiuv6NChQ27t0z+wZfXVpUsXj88zb9489ezZU6VLl1ZgYKCqVKmifv36acuWLXl12QCuyO61WFRlVUQCAPKen68DAICizDAMzZw5UyaTSYZh6OOPP9a//vUvj213796tzp0768KFC2rUqJGGDBmiyMhInTt3Tj///LMmTZqk6tWrq2bNmpmO7devn5o2bZpp+7W9fKmpqRoyZIi+/PJL1a5dWwMHDlRYWJjOnDmjzZs3a/v27Wrbtm1eXHqRMnnyZL344ouqWLGir0MBABfemwBIFOUAcENWrlypo0ePaujQoVq+fLnmzJmjSZMmyd/fP1PbZ555RhcuXFB0dLTGjx+faf/hw4eVkpLi8XnuvvvuHPVYjR8/Xl9++aVeeeUVvf766zKb3QdE2e32nF1YMRMVFaWoqChfhwEAbnhvAiAxfB0AbsjHH38sSXriiSc0aNAgnT9/Xt9++63Htj/99JMkaezYsR7316hRQ/Xq1fM6ljNnzuhf//qX2rZtqzfffDNTQS5JVqvV6/OnyziPddWqVerYsaNCQkJUpkwZPfroo4qNjZUk7dy5U3feeaciIiIUEhKivn37Zjlv8sKFC3rppZdUv359BQUFKSwsTN26ddPKlSs9tk9ISNCzzz6rSpUqKTAwUPXq1dO7774rp9PpsX1W8zZnz56t/v37q0aNGgoKClJoaKjat2+vzz//3ON5unTpIpPJpNTUVE2aNEm1a9dWQECAKleurBdeeCHLP6rAdwzD0HvvvacGDRooMDBQFStW1NNPP624uDiP7ePi4vS///u/uu2221SpUiX5+/urTJky6tu3rzZv3uzWNv21IEkbNmxwm1qScf50bvPs8OHDevLJJ1WrVi0FBQUpMjJSjRo10vDhwxUTE3Pda7548aI6deoks9msyZMnu7anpqbqgw8+UNu2bRUaGqrg4GA1a9ZM7733nttrJzo6WtWrV5ckzZkzx+26rp2/vnLlSt11110qW7as67XQr18/rV692mNsu3bt0h133KHw8HAFBwerc+fOrvfGG8V7E+9NQFFFTzkAeOns2bNavHix6tSpo3bt2ik0NFTvvPOOZsyYoYEDB2ZqX6pUKZ04cUL79+9X69at8zyeefPmKSUlRQ888ICSkpL03Xff6eDBgypZsqQ6dOigJk2aeDwuvagwDCNXz7d48WItXbpUd955p4YPH66ffvpJs2fP1tGjRzV58mR169ZNHTt21LBhw/T7779ryZIlOnz4sH777Te3Pxj89ddf6tKli44e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KEjcpxwAcin93uQffPCBZs6c6fHrqaeeci0Gl27ChAlZ3gt33rx52rdvnyIiItSwYUOv4urYsaOaNm2qTZs2ZbpX+scff6y9e/eqVq1ameYc7tu3T/v27fPqOW9Uy5Yt1bFjRy1YsECffPKJxza///67axE7SXr00UfldDr1wgsvuN3798iRI5o2bVqOn7tatWqSMn9YXrFihdvPDUVXei/jxIkTdeHCBdf25ORkvfTSSx6PqVatmg4cOKBTp065thmGoejoaP3xxx8ejylVqpSOHz+e5fmknOfZ9u3bPd5DPb0HNjg42OPzWK1WzZ07Vw8//LDmzp2rgQMHuoZj+/n5afTo0Tp9+rTGjBnjcbTM6dOn3a4vIiJCJpNJx44d8/h8o0ePliQ999xzHuc3ZzXnOTd4b1rvtp33JqD4oqccAHJh/fr12r9/vxo1apTtvcaHDRumiRMnatasWZowYYL8/Pw0ZcoURUdHq1mzZmrZsqXKlCmjuLg47dixQ5s3b5afn58+/PBDBQQEeBWbyWTSnDlz1LlzZ/Xv31933XWX6tSpoz179uj7779XiRIlNGfOnEyLW6X3CHrbQ3+jvvzyS912220aNmyYpk2bpjZt2ig8PFwnTpzQb7/9pt27d2vz5s0qW7aspLQiYOHChZo/f76aN2+unj17KjY2Vl9//bU6deqkxYsX5+h5R44cqVmzZum+++7TgAEDVKFCBe3evVvLly/X/fffr6+++io/LxsFoH379ho9erSmT5+uhg0basCAAa77lEdERCgqKvPonnHjxmn48OFq1qyZ+vfvL6vVqh9//FF//PGH7rrrLi1ZsiTTMd26ddN///tf3XXXXWrevLmsVqs6deqkTp065TrPPvvsM3300Ufq0KGDatasqYiICB06dEhLlixRQECAnnnmmSyv12KxaM6cOQoMDNTMmTN17733at68eQoICNCrr76qX3/9VR9++KGWLFmi2267TRUrVtS5c+d04MAB/fjjj5o4caJuueUWSVJISIjatGmjjRs3atCgQapTp44sFov69u2rxo0bq0ePHvrnP/+pN998U/Xr13fdp/zs2bPatGmT2rZtm+lOD7nFexPvTcDNgqIcAHIhvZf88ccfz7ZdtWrV1L17d61atUpLlizRPffco6VLl+r777/Xhg0btHz5cp09e1Z+fn6qVKmSHn/8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585l2+bIkSMqXbp0rs/dvXt3HTx4UJs2bdLOnTsVGxurEiVKqE6dOho8eLDGjBmjyMhIb8IGABSgFIdTGe/vkbEot5qtslpYxAYAAMCrorxVq1ZaunSpEhISVLJkyUz7T58+rWXLlunOO+/M9bkbNmyo9957z5uwAACFiNsib5JSlez6P0PXAQAA0ng1p3zs2LGKiYlRnz59tHfvXrd9e/fu1X333afk5GSNGTMmT4IEABQ91xblDuNqT3mwlaHrAAAAkpc95T179tT48eM1YcIENWzY0HUPttKlS+vixYsyDENvvfWW2rVrl6fBAgCKjoyLvElSqmGTTGn/p6ccAAAgjVc95ZI0fvx4rVmzRn379lVERIQsFotMJpP69Omj1atX6x//+EdexgkAKGIyDV83rg5fZ5E3AACANF71lKfr2rWrunbtmlexAACKkYxFuWEYsjuTFWBJ+1swPeUAAABpvOop//TTT/Xbb79l2+b333/Xp59+6lVQAICiz5ahKHcYKTKZru5jTjkAAEAar4ryoUOHauHChdm2Wbx4sR599FFvTg8AKAYyFuV2I1kW89WqnOHrAAAAabyeU349DodDpozdIgCAm0rG4etO2ZShJmf4OgAAwBX5VpTv379fERER+XV6AEAh57b6utnm9odahq8DAACkyfFCb4899pjb44ULF+ro0aOZ2jkcDh07dkwbN27UHXfcccMBAgCKJrfV180pbvvoKQcAAEiT46J89uzZrv+bTCbt2rVLu3bt8tjWZDKpTZs2mjJlyo3GBwAootxWXzddLcr9zH6ymq2+CAkAAKDQyXFRfuTIEUlpt7WpUaOGnnnmGY0dOzZTO4vFooiICJUoUSLvogQAFDkpDsfVByab679BfkGsOQIAAHBFjovyqlWruv4/fvx4de3a1W0bAAAZuS30lqEoZ+V1AACAq3JclGd01113qXnz5nkdCwCgGLl29fV0zCcHAAC4yqvV11u2bKk2bdrok08+0eXLl/M6JgBAMZDxPuUOI0NPOSuvAwAAuHhVlN9xxx3asWOHnnjiCVWoUEGjR4/W77//ntexAQCKsPSi3DAMOegpBwAA8MironzJkiU6cuSIXn31VYWGhur9999X06ZN1b59e3366aey2WzXPwkAoNgyDEP2K/cpdyhFJtPVXnPmlAMAAFzlVVEuSZUqVVJ0dLSOHj2qRYsWqU+fPvr555/16KOPqkKFCho3bpz27t2bl7ECAIqIFIdThpH2f7szWRbz1dXW6SkHAAC4yuui3HUCs1l33XWXq/f8tddek7+/v6ZNm6aGDRuqS5cumjdvXl7ECgAoIjIu8pZq2NyKcuaUAwAAXHXDRXlGf/zxh3777TfFxMTIMAyVKlVKGzdu1MCBA9WiRQsdPXo0L58OAFBIuRflyfKjpxwAAMCjGy7Kz507p//5n/9RzZo11bt3by1cuFBdunTRggULdObMGR08eFBPPfWUdu3apZEjR+ZFzACAQi7FcbUotxvJspiv/rqhpxwAAOAqr+5TLklr1qzRRx99pEWLFslutysiIkLPPPOMRowYoVq1arnaVa9eXR988IFsNpu+/vrrPAkaAFC4XdtTnj583Wwyy9/s76uwAAAACh2vivLatWvr8OHDMgxDLVu21MiRI/XAAw8oMDAw22MuXbrkdaAAgKLDdu2cclNaUR7sFyyTyZTVYQAAADcdr4rykydPaujQoRo5cqRatGiRo2MGDRqkW2+91ZunAwAUMRl7yjOuvs7QdQAAAHdeFeWnTp1SeHh4ro6pXLmyKleu7M3TAQCKGFsWw9dZ5A0AAMCdVwu95bYgBwDcXNzmlMum9MXXg/3oKQcAAMjohlZf/+KLL9StWzdFRkbKz89PkZGR6t69u7744ou8ig8AUASlr75uGIYM2VzzyIOs9JQDAABk5NXwdbvdrgEDBmjp0qUyDEMWi0VlypTR+fPntXbtWq1bt05ff/215s2bJ6vVmtcxAwAKufSecofsMpmv9prTUw4AAODOq57yyZMna8mSJWrTpo3WrVun5ORknT59WsnJyVq7dq1at26tpUuX6q233srreAEARUB6UZ5q2ORnvrraOnPKAQAA3HlVlH/66aeqVauW1q9fr86dO8tisUiSLBaLunTpovXr16tGjRqaPXt2XsYKACgiUhwOSVKqM8m1yJvE6usAAADX8qooP3HihPr16yd/f3+P+wMCAtSvXz+dPHnyhoIDABRNNntaT7ndsLkV5fSUAwAAuPOqKK9QoYLsdnu2bex2uypUqOBVUACAoi19obdUI1kWU4aecuaUAwAAuPGqKH/ooYc0b948xcfHe9wfGxurefPmadCgQTcUHACgaLo6p/zqPcrNJrMCLAG+DAsAAKDQ8aoof+2119SyZUu1bt1aX375pU6cOCG73a4TJ07oiy++UNu2bdW6dWu9+uqreR0vAKAIsKWmD1+/WpQH+QW5bo0GAACANDm6JZrZbPb4QcowDA0ePNjj9gMHDigoKEipqak3HiUAoMgwDEP2K8PX7c5kBWUoygEAAOAuR0V5p06d6N0AAORIisMpw0j7f2qGhd5YeR0AACCzHBXl69evz+cwAADFRfp8ciltTrmfOW2mFD3lAAAAmXk1pxwAgKykF+WGYbjNKWfldQAAgMxy1FOeHbvdrn379ik2NlZhYWGqX7++rFZrXsQGACiC0m+H5lSqnIbDbaE3AAAAuPO6pzw+Pl7Dhw9XeHi4mjZtqi5duqhZs2YKDw/X8OHDFRsbm4dhAgCKCpv96u3QJDGnHAAAIBte9ZTHx8erffv22rNnj0qWLKmOHTsqKipKp0+f1q5duzRjxgxt2rRJP/30k0JDQ/M6ZgBAIZaSYeV1SbKYGL4OAACQFa96yidPnqw9e/ZoxIgR+uuvv7R+/XrNnTtX69ev119//aVRo0bpjz/+0OTJk/M6XgBAIZc+pzzVsEkSw9cBAACy4VVRvmDBArVt21bvv/++wsPD3faFhYVp+vTpuvXWWzV//vy8iBEAUITYrhTldoavAwAAXJdXRflff/2lLl26ZNumc+fOOn78uDenBwAUYVd7ypNlMklmk2QymRRoCfRxZAAAAIWPV0V5iRIldO7cuWzb/P333woOplcEAG42rjnlV26HZjKZFOwXLNOVueUAAAC4yquivFWrVvrmm2904MABj/sPHTqkr7/+Wq1atbqh4AAARU/GOeV+zCcHAADIllerr//jH/9Qjx491KpVK40ePVpdu3ZVVFSUzpw5o/Xr12v69OlKTEzU888/n9fxAgAKOVdR7kySxY+iHAAAIDteFeXdunXTBx98oLFjx2rSpEmaNGmSa59hGLJarXrvvffUvXv3PAsUAFA02FIdkiS7YVOAmduhAQAAZMerolySnnrqKfXu3VufffaZdu7cqbi4OIWFhalZs2Z6+OGHVbVq1byMEwBQRGRc6C04ffi6lZ5yAAAAT7wuyiWpSpUqeuWVV/IqFgBAMZDicMpppMphpMpi8pdETzkAAEBWvFroDQCArKSkOjPdo5w55QAAAJ7lqKf8hx9+8PoJOnXq5PWxAICix5bqVKphk3S1KKenHAAAwLMcFeVdunTx+v6yDofDq+MAAEWPYRhpPeXOJEkZesqZUw4AAOBRjory1157zeuiHABw80hxXF3kTZL8zGmzpOgpBwAA8CxHRXl0dHQ+hwEAKA7SV163Zxi+bpJJgX6BvgwLAACg0Cp0C73FxMRo5syZuueee1SrVi0FBQUpLCxMHTp00P/93//J6XT6OkQAQBZsqe495RZzWkFuNhW6XzcAAACFwg3dEi0/fPPNNxoxYoSioqLUtWtXValSRWfPntWCBQv0+OOP6/vvv9c333zDcHoAKISu9pRfLcoZug4UH4ZhSA6HDIcj7V+nU0pNTdtuGJLTmbbNkGQ4rzw2JKXtkySZzWmf48xmyWSSTGaZzKa0/1/Z5tPPea443OMymTLEmP64GMj4s5NhpD12OjM/Tm+Xm3O6ciJDDjid7vtzKrtcufIzyRDA9XPRbJHJ6ieT39UvWa1p/zfn3x+S3b6fGb8XTqecKSkyJyXLER8vs8WS85NmzFmTrn4/rv3+ZPyZZPy5X/s4Nz+XnMri9e72XlCMXle5laOi/LbbbpPJZNKcOXNUqVIl3XbbbTk6uclk0po1a3IVUJ06dbR48WLdcccdMmd4QUyaNEmtW7fW/PnztWDBAvXv3z9X5wUA5L8UDz3lwdarRbmRmqrL27bJfuaMT+LLSw6HQyV//VXxqamy5ObDEwoXQ1c+qF75AO803B8bulJM5vxDqsPhUPgffyj2woWinRuGIcPhlOFIlRxOGU6H5GDE4o1wOB0qdeCAYo4elcVchHOjuLOYZbJaZfKzymQ2pRXzV94HPL5POPOmiHU4HYo4cECxZ8+QHzkQeEt9lezWzddh5IkcFeXr16+XyWTS5cuXXY9zwpu/dGRV8JcvX17Dhw/XK6+8ovXr11OUA0Ah5FrozXllTrnJ5HaP8qRdu3T5l20+iS2vOZwO+V+4IPuJE3Ly4QkZOJwOWZKS5IiPl8gNoOhxOGU4bDJk83UkuEnkqCi/dh63r+Z1W61WSZKfX6EbdQ8A0PWHr9uOHPFJXAAAAIVVkaluU1NT9emnn0qSevXq5eNoAACe2FKdchoOOQy7pLSiPP0e5UZKilLPnXO1tYSFylwy1Cdx5gWzI1X2mBhZK1aUxVJkfp3CA5P56nxMmZQ2n9SUPsfRdOVxzkf/OVJTlXz5sgLr15eliHckmCyWtLm3FrNk8bvyr+Xqdj9L2jzQLOawus3DNpklXTPP2HB6fpwfc1pzIG1erZQ+7/jq0GQPc5S9iDE1NVWXDUPBbdoUrk4ms1mS6ZrXQsbHptzP9fcwLz/TY+VmVK3n+c/XzhvPar55plx0OmSkpsqwp8pItaetjWC3Z9h2ZbvTSHsfMGX9PuG6plx9bzK8t5jMktkkh9OpBH9/hXTqJD+rNcff72y/H4Zx9bUlXf9nkg9rOrheV0Z6PJ5eV7lfZ8BSqlSexulLXr0brFmzRt1yMH5//PjxmjBhgjdPkcmLL76o3bt3q0+fPurZs2eW7Ww2m2y2q0NN4uPjJUl2u93tXyAduYGskBu5l2RLkc1xSYbhTPulbjjlL3/Z7XbZT56UIzXV1Ta4TRv516jhw2hvjN1uV7zVqqDbb3eN5AKktNy4lJQk/w4dyI1sXPux/6ZY3sluV9LZs/Jr3JjcuAGmLP7vzXkKU94ZdrtSDh+WuXp1WciPHCnMn9FyE5vJMHL/Z77w8HBt3LhRjRo1yrLNpEmT9Oqrr8rhcOT29JlMmzZNY8eOVb169fTjjz8qMjIyy7bR0dEe/xDw5ZdfKjiYFYABID/tjTXpz8R4nbX+IotJql7SUFP/piplKaWgw4cVfOiQq+2Fzp1l+Pv7MFoAAID8cfnyZT300EOKi4tTaGj2IwO9KsorVqwos9mszZs3q1KlSpn2T5kyRc8995zat2+vjRs35vb0bt577z2NHj1at9xyi9asWaPy5ctn295TT3nlypV1+vRpbd26VbfTo4Fr2O12rVq1itxAJuRG7q3ee06bj+/T4aRNCrBa1LRSmAbUHqDSQaUVv3ix7CdOSJIs4REKf+hBH0d7Y8gPZIXcQFbIDWSH/Che4uPjVbp06RwV5V4NX1+2bJk6d+6s3r17a9OmTQoLC3Pt+89//qPnnntOrVq10vfff+/N6V3+/e9/a9y4cWrYsKHWrFmjsmXLXveYgIAABQQEZNqenthWq5Ukh0fkBrJCbuScQyY5ZJfJZJbVYpbFYlFoUKj8LBYZf5933eIlsHKlYvM9JT+QFXIDWSE3kB3yo3jIzc/QfP0mmTVp0kTz58/X/v371a9fP6WkpEiSZs6cqaefflpNmjTRihUrFBIS4s3pJUlvvfWWxo0bp6ZNm2rdunU5KsgBAL6VkupUqpEkKW2RN5PSbomW+vd5GRnmVlkrVPBViAAAAIWKV0W5JHXr1k3/93//p40bN2rw4MH69NNPNXz4cNWrV0+rV69WeHi410G98cYbevHFF9WiRQutWbNGpUuX9vpcAICCk5LqlN24co9ys0kBfgEym8yynzrp1s4aFeWL8AAAAAqdG7oXw8MPP6wTJ07o5Zdf1rx581SzZk2tWbNGpW5gefo5c+botddek8ViUceOHTVt2rRMbapVq6ahQ4feQOQAgPyQ4nAqNf0e5aar9yhPPX3a1cZcooTM15lbBQAAcLPIUVF+7NixLPc99NBD+vnnn7Vx40bNmjVLKSkpbu2rVKmSq4COHDkiSXI4HPr3v//tsU3nzp0pygGgEEobvn6lKDenDV03DEP2DEW5tUKFPL8HKgAAQFGVo6K8WrVq1/0AZRiGOnXq5LbNZDIpNcM9aXMiOjpa0dHRuToGAFA42FKdsl8pyv3MZgVbg+WIjZXzcpKrjbUCQ9cBAADS5agof+SRR+jVAABkyzCMtJ5y59U55UF+QbKfOuXWjvnkAAAAV+WoKJ89e3Y+hwEAKOpsqU45DYdSjbQ7cljMaXPKM84nNwUEyHID644AAAAUN16vvg4AQEYZF3mTPPeUW6PKy2TmVw8AAEA6PhkBAPJE2iJvNtdji9mkoBTJERfv2sbQdQAAAHc5KsqffvppnT171usn+fbbbzV37lyvjwcAFH4pGRZ5k67cp/x8glsba4UKBR0WAABAoZajovzLL79UjRo1NGLECG3dujVHJ46Li9NHH32k5s2ba8CAAYqJibmhQAEAhVvG26FJaUW537mLrscmP4v8ypb1RWgAAACFVo4Wejt48KBee+01zZgxQzNmzFDlypXVvn17tWzZUlFRUYqIiFBycrJiYmK0b98+bdmyRb/88otsNpvq16+vpUuXqnfv3vl9LQAAH0pxOGV3ZijKTSaZz8bIeeWxX9myMvnl6NcOAADATSNHn44iIyP13nvv6YUXXtCHH36o2bNna+7cuZo7d26mW6UZhiGLxaJu3bpp5MiRuvPOO2VmUR8AKPaunVMeIj85L1ztKWfoOgAAQGa56rKoXLmyJk6cqIkTJ2rPnj3atGmTjh07ppiYGAUFBals2bJq3LixOnbsqNDQ0PyKGQBQCNmumVNeKj5VMq7+4ZZF3gAAADLzehxhgwYN1KBBg7yMBQBQhNlSHa455WaTFBprkxSYttNkkh9FOQAAQCaMKwcA5ImMq69bzCaVuHDZtc+vdCmZAwJ8FRoAAEChRVEOAMgTKalOpTrT5pT7GYYCMhTlDF0HAADwjKIcAJAnklPtroXewhKT5Z/hVwyLvAEAAHhGUQ4AyBOXUpJc/w+LuyQ/s9X12C+KohwAAMATinIAQJ5ITLk6XD0s9rKsV4pyS1ioLCElfBUWAABAoUZRDgDIE5dTrxTlTkMlYy/Jz5x2gw+GrgMAAGSNohwAkCcu29OK8hKXk+XvcLp6yrkVGgAAQNbypCi/ePGijh8/nhenAgAUUZdS0+aUh168JJPJ5CrK6SkHAADImtdFeWJiop577jmVL19epUuXVvXq1V37tm7dqj59+mjHjh15EiQAoHBzOg0lXekpD4u7LD+zRWaTWebgIFnCw30bHAAAQCHmVVEeFxenW2+9VVOmTFGFChVUv359GYbh2t+oUSNt3LhRc+fOzbNAAQCFV4rDqVQjWTIMhcZeutpLHhUlk8nk4+gAAAAKL6+K8okTJ2rPnj2aPXu2duzYofvuu89tf3BwsDp37qw1a9bkSZAAgMItxeGU3bApMNmuAJtd/hbmkwMAAOSEV0X5ggUL1LNnTz3yyCNZtqlatapOnjzpdWAAgKIjJTWtpzw09pIkuYpya4WKvgwLAACg0POqKD9x4oQaN26cbZuQkBDFxcV5FRQAoGhJL8rDMhTlJqtVfmVK+zgyAACAws2rorxkyZI6d+5ctm2OHDmi0qX5MAYAN4Nke6pSjRRXT3mAxV9+5cvJZObOmwAAANnx6tNSq1attHTpUiUkJHjcf/r0aS1btkwdOnS4oeAAAEVDQspl+dnsCr5skyQF+Fm5FRoAAEAOeFWUjx07VjExMerTp4/27t3rtm/v3r267777lJycrDFjxuRJkACAwi3BdsnVSy6l9ZRTlAMAAFyfnzcH9ezZU+PHj9eECRPUsGFDWa1pC/qULl1aFy9elGEYeuutt9SuXbs8DRYAUDglpFxSaFyGotwaIGu5cj6MCAAAoGjwerLf+PHjtWbNGvXt21cRERGyWCwymUzq06ePVq9erX/84x95GScAoBCLt11SWOxlSZJJUmBUlExX/mALAACArHnVU56ua9eu6tq1a17FAgAooi4nJSgkIUmSZDKZVKJSVR9HBAAAUDSwLC4A4IY5zpySyTAkSRazRYEVK/s4IgAAgKLBq6J8zZo1euyxx3Tq1CmP+0+dOqXHHntM69evv5HYAABFxd9nXf/1M/vJGhXlw2AAAACKDq+Gr0+fPl379u1ThSxW1q1QoYI2b96suLg4denS5UbiAwAUcrFxF+X88w/XY0domMxBQT6MCAAAoOjwqqd8x44d111ZvUOHDtq2bZtXQQEAio7vvvhQunx15fWwOg18GA0AAEDR4lVRfu7cuSx7ydOVK1dO586d8yooAEDRsO2XTbq0e8fVDaFh6tF/sO8CAgAAKGK8KsrDwsJ0/PjxbNscP35cJUqU8CooAEDhl3gpUTvmzXLb1mLAoyoRHOKjiAAAAIoer4ry1q1ba+HChTpz5ozH/adOndLChQvVunXrGwoOAFB4LZ07Q0qIdz0OadhCLVq292FEAAAARY9XRfno0aOVkJCgjh07avHixbLZbJIkm82mRYsWqVOnTkpMTNSYMWPyNFgAQOHw22+/KH7nlqsbgkN05+ARvgsIAACgiPJq9fUePXro1Vdf1RtvvKF77rlHJpNJERERunjxogzDkGEYevXVV9WrV6+8jhcA4GNJSZe19auZ0pX7kktSg36DFFoyzIdRAQAAFE1e9ZRL0oQJE7R8+XL16dNHkZGRiouLU2RkpO644w6tWLFCEyZMyMs4AQCFxLJvZsm4eMH1OKhuQ7Xv2N2HEQEAABRdXvWUp+vRo4d69OiRV7EAAAq5fX/uVszWH65uCAzSHQ+P8l1AAAAARZzXPeUAgJuL3W7Xpi8/lAyna1vtPvcpslRpH0YFAABQtFGUAwBy5PsFn8r591nXY//qtdWpax8fRgQAAFD0eV2Unz59WqNGjVKtWrUUFBQki8WS6cvP74ZGxwMACokjRw7ozKZVVzf4+6vXI0/LYrH4LigAAIBiwKuq+eTJk2rdurXOnj2rBg0ayGazqWrVqgoICNDhw4eVmpqqpk2bKiyMlXgBoKhzOBxa+/n7ksPh2latez+VL1fBh1EBAAAUD171lL/++us6c+aMli9frl9//VWS9Oijj2rfvn06fPiwevbsqaSkJC1YsCBPgwUAFLwVS7+S4/RJ12O/ilXVrXd/H0YEAABQfHhVlK9YsUK9evVS9+6Zb4FTqVIlffPNN0pKStL48eNvOEAAgO+cPHVMJ9YuvbrBz0/dB49i2DoAAEAe8aooP3PmjBo0aOB6bLFYlJSU5HocEhKi22+/XYsWLbrxCAEAPuFwOLRy9nTJbndti+rcS1WqVPdhVAAAAMWLV0V5aGioUlJSXI8jIiJ08uRJtzZhYWH6+++/byw6AIDPLPxyhuwnjroem8tFqVffh3wXEAAAQDHkVVFetWpVHT9+3PW4SZMmWrt2rS5fvixJcjqdWrlypSpVqpQ3UQIACtSWn9YpZsu6qxv8/NR18ChZrVbfBQUAAFAMeVWUd+vWTevWrZP9ypDGIUOG6NSpU2rXrp3+8Y9/qH379tqzZ48GDhyYp8ECAPLf8RN/6bdvPpEMw7Wt1l0PqGaNuj6MCgAAoHjy6pZow4YNU0REhM6fP6+oqCg9/PDD2r59u6ZPn67ffvtNkvTAAw/olVdeydNgAQD5KynpslZ8/L+SLdm1rWSTVrrt9n4+jAoAAKD48qoor127tl544QW3bVOmTNHLL7+sw4cPq1q1aipXrlyeBAgAKDjfzpom599nXY/NZaN079CxPowIAACgePOqKM9KmTJlVKZMmbw8JQCggKxevkCJu7df3RAYqN5PPq+AgADfBQUAAFDM3XBRfvz4ce3cuVNxcXEKCwtTs2bNVLly5byIDQBQQPb9uVuHl31zdYPJpKYDn1TFClV8FxQAAMBNwOui/MCBAxo5cqTWrl2bad9tt92m999/X3Xq1Lmh4AAA+S827qJ+mPVvKTXVta1M+25q3aaj74ICAAC4SXhVlB88eFDt2rVTTEyMatasqQ4dOqh8+fI6c+aMNm3apDVr1qhDhw766aefVKtWrVyff968edqwYYN27dqlX3/9VQkJCRo0aJA+//xzb8IFAGTB4XBo4Yz/leLjXNusVWuq78DHfRgVAADAzcOrovyll15STEyMpk6dqlGjRslsvnpnNafTqenTp2vcuHF6+eWX9fXXX+f6/G+++aZ+/fVXhYSEqFKlStq3b583YQIAruO7ebOVcuTA1Q0lQ3X3k/+QxWLxXVAAAAA3Ea/uU75mzRr16dNHo0ePdivIJclsNmvs2LHq1auXVq9e7VVQU6ZM0f79+xUfH6///Oc/Xp0DAJC97dt+1JkfVlzdYLGo45Axiogo5bugAAAAbjJeFeUpKSlq2rRptm2aNWsmu93uzenVtWtX1a5dWyaTyavjAQDZO3P2lLZ/+ZFkGK5tVXv1V/1bmvgwKgAAgJuPV0V5kyZNdPDgwWzbHDx4UI0bN/YqKABA/rl0OVFL//M/UnKSa1twg2bqecd9PowKAADg5uTVnPKXX35Z99xzj77//nv17t070/7vvvtO3377rRYuXHij8eWazWaTzWZzPY6Pj5ckV6+9t733KL7IDWSlOOaGzWbTV9Nfl+PsKdc2U+myuuvhUcXqOgtCccwP5A1yA1khN5Ad8qN4yc3P0auiPCYmRr1799add96pbt26qVOnTipXrpzOnj2rDRs2aO3atbrrrrt0/vx5ffrpp27HPvLII948ZY5NnjxZEyZMyLR93bp1Cg4O1qpVq/L1+VF0kRvISnHJDafDqQM/r5D/meOubQ6rv0rXaaX169f7LrAirrjkB/IeuYGskBvIDvlRPFy+fDnHbU2GkWFCYQ6ZzWaZTCZd79CMc8INw5DJZJLD4cjVc61fv15du3bN8S3RPPWUV65cWadPn9bWrVt1++23y2q15ioGFG92u12rVq0iN5BJccoNh8OhBbOnKeHXn69utFrV+rFxatigme8CK8KKU34gb5EbyAq5geyQH8VLfHy8Spcurbi4OIWGhmbb1que8lmzZnkVWEEICAhQQEBApu3piW21WklyeERuICvFITeWfvOJEn/75eofS81mNR00Us2atvZtYMVAccgP5A9yA1khN5Ad8qN4yM3P0KuifMiQId4cBgDwge8Xz9XfmzLcotJkUr3+Q9S6TUffBQUAAABJXq6+DgAoGtavWarjK75121alV3916trHRxEBAAAgI696yj1ZvHix1q5dK8Mw1KlTJ/Xv3z+vTg0A8MLPW9Zr/7efud2LvGzHHup110AfRgUAAICMclyUL1myRP/7v/+rN954Q507d3bb9+ijj+rTTz91Lfz23nvv6e6779b8+fO9CmrhwoWu26mdOXNGkrR582YNHTpUklS6dGn961//8urcAHAz+O23X7Rr7gzJ6XRtC21+q+66/zEfRgUAAIBr5bgoX7x4sXbs2KE2bdq4bV+6dKnmzJmjEiVKaNy4cSpZsqRmzJihhQsXau7cuXrwwQdzHdSuXbs0Z84ct22HDx/W4cOHJUlVq1alKAeALBw8uE9bZk2TMtwfM6huI9336FhZLBYfRgYAAIBr5XhO+c8//6yOHTsqMDDQbfsnn3wik8mkWbNm6fXXX9c//vEPbdy4UYGB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AABX7NixQwkJCZm2p98arFmzZq5tERERkqTjx49nan/w4MFMverpQ7YdDkeu42rbtq0k6fvvv79u24MHD0qSa3h3Rhs2bMj1c6fPgfZ07KZNm7y6npzK62vJKKc/j5EjR0qSPvroI82YMUOS9NRTT+X4edKnPLRs2dLjPsMwPBbsAICbB0U5AABXxMXF6fXXX3fbtm3bNn3xxRcKCwvTPffc49per149hYaGatGiRTp37pxre1JSksaMGZPp3BERETKZTDp27Fiu4xoxYoT8/Pz0xhtv6I8//si0/8SJE67/p98bPf0PCelWrFihmTNn5vq503uoJ06cqAsXLri2Jycn66WXXsr1+XIjr68lo5z+PLp166Y6depozpw5+vrrr1W3bt1s719+rR07dsjf31+NGzfOtG/79u2SlGnxNwDAzYXh6wAAXNGpUyfNnDlTW7duVfv27V33KXc6nfroo49c9+2WJKvVqrFjx+qNN95Qs2bNdM899yg1NVWrVq1ShQoVVKFCBbdzh4SEqE2bNtq4caMGDRqkOnXquO457qlgy+iWW27RBx98oOHDh6tZs2bq16+fateurZiYGP3yyy8KDQ3VunXrJKX17M6aNUv33XefBgwYoAoVKmj37t1avny57r//fn311Ve5+p60b99eo0eP1vTp09WwYUMNGDDAdZ/yiIiIHN2n21t5fS0Z5fTnYTKZNHz4cD377LOS0uaZ55TNZtMff/yhxo0be7yXe3pRTk85ANzc6CkHAOCK6tWr66efflJERIQ+/PBDff3112revLmWLVumgQMHZmo/YcIETZ48WYGBgZoxY4aWLVum/v37a8WKFbJarZnaf/bZZ7rjjju0fPlyTZgwQa+++qprzvH1PPHEE9q0aZPuvPNOrV+/Xv/7v/+rxYsXq0yZMho1apSrXePGjbVu3Tq1a9dO3333nf7zn/8oPj5eCxYs0PDhw736vkydOlXTp09XWFiYPvroI82dO1c9e/bU6tWrPRabeSU/riWjnP48hg4dKrPZrMDAQA0ZMiTH59+9e7dSU1M9Dl2X0orykJAQ1alTx+trAAAUfSbDMAxfBwEAgC8dPXpU1atX15AhQzR79mxfh4NCZv369eratasefvhhffbZZ74OBwBQzNBTDgAAkI23335bkvT000/7OBIAQHHEnHIAAIBr/P7771q6dKm2b9+u77//XnfeeafatGnj67AAAMUQRTkAAMA1tm/frpdfflmhoaG677779MEHH/g6JABAMcWccgAAAAAAfIQ55QAAAAAA+AhFOQAAAAAAPkJRDgAAAACAj1CUAwAAAADgIxTlAAAAAAD4CEU5AAAAAAA+QlEOAAAAAICPUJQDAAAAAOAjFOUAAAAAAPgIRTkAAAAAAD5CUQ4AAAAAgI/8fzTRYeZtx1mYAAAAAElFTkSuQmCC",
+      "text/plain": [
+       "<Figure size 1200x400 with 1 Axes>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fig, ax = plt.subplots(figsize=(12,4))\n",
+    "\n",
+    "methods = [\"ASF8\", \"ASF6\", \"ASF4\", \"datasketch\"]\n",
+    "\n",
+    "for i, (method, colour, df) in enumerate(zip(methods, [asf8_color, asf6_color, asf4_color, ds_color], [asf8, asf6, asf4, dsk])):\n",
+    "    xn = df.index \n",
+    "    median = df.median(axis=1)\n",
+    "    ax.plot(xn, median / 1024,\n",
+    "           color=colour, label=method+\": median\", alpha=0.5)\n",
+    "\n",
+    "ax.set_xscale('log', base=10)\n",
+    "ax.legend(loc='upper center', bbox_to_anchor=(0.5, 1.25),\n",
+    "          ncol=2, fancybox=True)\n",
+    "ax.grid()\n",
+    "ax.set_ylabel(\"Space (kilobytes)\")\n",
+    "ax.set_xlabel(r\"Input cardinality $n$\")\n",
+    "# ax.set_ylim(0.6E-6, 1.6E-6)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "46851818-f89e-4f02-9968-beb0b3594909",
+   "metadata": {},
+   "source": [
+    "Each of the ASF methods go through some resizing and growth stages until a maximum size is reached.  At this point the sketches grow no further.  As expected, the $4$ bit version is half the size of the $8$ bit version and the $6$ bit version is $3/4$ the size of the $8$ bit version.  Once the $8$ bit ASF HLL enters its final stage, it is the same size as the datasketch HLL, but can be much smaller prior to this stage."
+   ]
+  }
+ ],
+ "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.11.4"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}