]> git.armaanb.net Git - python_dp.git/blob - gaussian_mechanism.ipynb
Initial commit
[python_dp.git] / gaussian_mechanism.ipynb
1 {
2  "cells": [
3   {
4    "cell_type": "markdown",
5    "id": "112c2ca0",
6    "metadata": {},
7    "source": [
8     "# Gaussian mechanism PLRV\n",
9     "\n",
10     "By [Armaan Bhojwani](https://armaanb.net) under [Praneeth Vepakomma](https://praneeth.mit.edu/)\n",
11     "\n",
12     "### Preface\n",
13     "This notebook features the following differentially private operations utilizing [Google's Differential Privacy Accounting library](https://github.com/google/differential-privacy/tree/main/python).\n",
14     "\n",
15     "- Gaussian mechanism\n",
16     "    - Privacy loss random variable\n",
17     "    - Privacy loss distribution\n",
18     "    - Observations 1, 2, 3 from [Google Privacy Loss Distributions paper](https://github.com/google/differential-privacy/blob/main/common_docs/Privacy_Loss_Distributions.pdf)\n",
19     "\n",
20     "### Dependencies\n",
21     "- dp_accounting\n",
22     "- matplotlib\n",
23     "- scipy\n",
24     "- tqdm\n",
25     "\n",
26     "This notebook makes extensive use of Google's `dp_accounting` library. To install, obtain the [sources here](https://github.com/google/differential-privacy/tree/main/python) or from the included git submodule (the submodule is in the `External/` directory, and the sources are in the `External/python/dp_accounting` subdirectory), and install using setuptools (`python3 setup.py install`).\n",
27     "\n",
28     "### References\n",
29     "- https://programming-dp.com/ch6.html\n",
30     "- https://desfontain.es/privacy/almost-differential-privacy.html\n",
31     "- https://desfontain.es/privacy/gaussian-noise.html\n",
32     "- https://github.com/google/differential-privacy/tree/main/python\n",
33     "- https://github.com/google/differential-privacy/blob/main/common_docs/Privacy_Loss_Distributions.pdf\n",
34     "\n",
35     "    \n",
36     "### Status\n",
37     "- Complete"
38    ]
39   },
40   {
41    "cell_type": "markdown",
42    "id": "f9940fdd",
43    "metadata": {},
44    "source": [
45     "## Setup\n",
46     "\n",
47     "`epsilon` and `delta` are the standard DP parameters. `sensitivity` is the sensitivity of the particular function that you want to test. See [Programming Differential Privacy Chapter 5](https://programming-dp.com/ch5.html#calculating-sensitivity)\n",
48     "\n",
49     "### Parameters"
50    ]
51   },
52   {
53    "cell_type": "code",
54    "execution_count": 1,
55    "id": "e4f4beed",
56    "metadata": {},
57    "outputs": [],
58    "source": [
59     "epsilon = 3     # Privacy level\n",
60     "delta = 10e-7   # Probability of failure. Should be much less than (length of dataset)^-1\n",
61     "sensitivity = 2 # Sensitivity of function"
62    ]
63   },
64   {
65    "cell_type": "markdown",
66    "id": "ffa5bfc2",
67    "metadata": {},
68    "source": [
69     "### Imports"
70    ]
71   },
72   {
73    "cell_type": "code",
74    "execution_count": 2,
75    "id": "a6129fcd",
76    "metadata": {},
77    "outputs": [],
78    "source": [
79     "from dp_accounting.pld import privacy_loss_distribution as pld\n",
80     "from dp_accounting.pld import privacy_loss_mechanism as plm\n",
81     "\n",
82     "import matplotlib.pyplot as plt\n",
83     "import numpy as np\n",
84     "from tqdm.notebook import tqdm\n",
85     "\n",
86     "from math import e\n",
87     "import math"
88    ]
89   },
90   {
91    "cell_type": "markdown",
92    "id": "8b192e1a",
93    "metadata": {},
94    "source": [
95     "## Privacy loss analysis\n",
96     "### Fitting sigma\n",
97     "\n",
98     "The `dp_accounting` library expects you to provide the sensitivity of the function and the standard deviation of the gaussian mechanism to use. This doesn't help us much as we would like to work the other way around, providing the sensitivity of the mechanism, and our privacy tolerances (epsilon and delta) and let the algorithm choose the best standard deviation to use. This function finds the optimal standard deviation to use in the gaussian function while satisfying the given privacy parameters.\n",
99     "\n",
100     "A potential replacement for this function is the `calibrate_dp_mechanism` function from the dp_accounting library."
101    ]
102   },
103   {
104    "cell_type": "code",
105    "execution_count": 3,
106    "id": "5ef86f2b",
107    "metadata": {},
108    "outputs": [],
109    "source": [
110     "def fit_sigma_from_params(delta, epsilon, sensitivity, verbose=False):\n",
111     "    \"\"\" Find the ideal sigma value given privacy parameters.\n",
112     "    \n",
113     "    This function iteratively increases the standard deviation of a gaussian\n",
114     "    PLD until it finds a value that creates a PLD that meets the given privacy\n",
115     "    parameters. It takes a first pass refining until it validates epsilon, \n",
116     "    then it takes a second pass for delta.\n",
117     "    \n",
118     "    A potential replacement for this function is the calibrate_dp_mechanism\n",
119     "    function from the dp_accounting library.\n",
120     "    \n",
121     "    Inputs:\n",
122     "        delta: delta value to use\n",
123     "        epsilon: epsilon value to use\n",
124     "        sensitivity: sensitivity of mechanism\n",
125     "        \n",
126     "    Output:\n",
127     "        Optimal standard deviation of the gaussian mechanism\n",
128     "    \"\"\"\n",
129     "\n",
130     "    def find_epsilon(sigma, delta, sensitivity):\n",
131     "        gauss_pld = pld.from_gaussian_mechanism(\n",
132     "            sigma, sensitivity=sensitivity, value_discretization_interval=0.01)\n",
133     "        epsilon = gauss_pld.get_epsilon_for_delta(delta)\n",
134     "        return epsilon\n",
135     "\n",
136     "    def find_delta(sigma, epsilon, sensitivity):\n",
137     "        gauss_pld = pld.from_gaussian_mechanism(\n",
138     "            sigma, sensitivity=sensitivity, value_discretization_interval=0.01)\n",
139     "        epsilon = gauss_pld.get_delta_for_epsilon(epsilon)\n",
140     "        return epsilon\n",
141     "\n",
142     "    # While loop fitting epsilon\n",
143     "    sigma = 1\n",
144     "    test_epsilon = 0\n",
145     "    with tqdm() as t:\n",
146     "        while not math.isclose(test_epsilon, epsilon):\n",
147     "            test_epsilon = find_epsilon(sigma, delta, sensitivity)\n",
148     "            epsilon_range = test_epsilon - epsilon\n",
149     "            sigma += (epsilon_range / 4)\n",
150     "\n",
151     "            t.update()\n",
152     "\n",
153     "    if verbose: print(f\"(Epsilon layer) Fit to sigma of: {sigma}\")\n",
154     "\n",
155     "    # Do-while loop fitting delta\n",
156     "    with tqdm() as t:\n",
157     "        cond = True\n",
158     "        while cond:\n",
159     "            test_delta = find_delta(sigma, epsilon, sensitivity)\n",
160     "            sigma += 10e-8\n",
161     "            cond = test_delta >= delta\n",
162     "\n",
163     "            t.update()\n",
164     "\n",
165     "    if verbose: print(f\"(Delta layer) Fit to sigma of: {sigma}\")\n",
166     "\n",
167     "    return sigma\n",
168     "\n",
169     "\n",
170     "# sigma = fit_sigma_from_params(delta, epsilon, sensitivity, verbose=True)"
171    ]
172   },
173   {
174    "cell_type": "markdown",
175    "id": "4b0a9fd2",
176    "metadata": {},
177    "source": [
178     "### Privacy loss distribution functions"
179    ]
180   },
181   {
182    "cell_type": "code",
183    "execution_count": 4,
184    "id": "4f66b640",
185    "metadata": {},
186    "outputs": [
187     {
188      "data": {
189       "application/vnd.jupyter.widget-view+json": {
190        "model_id": "a5e4e242ec154f93a107d482b8c192ad",
191        "version_major": 2,
192        "version_minor": 0
193       },
194       "text/plain": [
195        "0it [00:00, ?it/s]"
196       ]
197      },
198      "metadata": {},
199      "output_type": "display_data"
200     },
201     {
202      "name": "stdout",
203      "output_type": "stream",
204      "text": [
205       "(Epsilon layer) Fit to sigma of: 3.087722833683524\n"
206      ]
207     },
208     {
209      "data": {
210       "application/vnd.jupyter.widget-view+json": {
211        "model_id": "8d1989247d75415aa2b8d42aefc1a547",
212        "version_major": 2,
213        "version_minor": 0
214       },
215       "text/plain": [
216        "0it [00:00, ?it/s]"
217       ]
218      },
219      "metadata": {},
220      "output_type": "display_data"
221     },
222     {
223      "name": "stdout",
224      "output_type": "stream",
225      "text": [
226       "(Delta layer) Fit to sigma of: 3.0877230336835235\n"
227      ]
228     },
229     {
230      "data": {
231       "image/png": "iVBORw0KGgoAAAANSUhEUgAAAj0AAAGzCAYAAADEw6Y0AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAABopUlEQVR4nO3deVhUZf8/8PcMywyyurEpKhmmqamJ8OASmRSWlbRompWS2/NLS7PlyUptsSi18rEsH1u0xdJosXIrUstSxN1Sy7TQFANUZFB2Zu7fH/d3BkZAGTycM8v7dV3nOscz98x85sDtfLi3oxNCCBARERG5Ob3WARARERGpgUkPEREReQQmPUREROQRmPQQERGRR2DSQ0RERB6BSQ8RERF5BCY9RERE5BGY9BAREZFHYNJDREREHoFJD9Elmjt3Li677DJ4eXmhZ8+eWofTKDqdDs8884zdue3bt6Nv377w9/eHTqfDnj178Mwzz0Cn0yn63tdeey2uvfZaRV/T2XXo0AFjxozROgzNXHvttejWrZsm790Uv8PkOpj0kKaWLl0KnU5n24xGIzp16oTJkycjLy/PVu6HH36ATqfDZ599dsHXq/la3t7eaNGiBXr37o0pU6bgwIEDisf/3Xff4fHHH0e/fv2wZMkSvPjii4q/hxYqKysxbNgwFBQU4LXXXsOHH36I9u3bax0WLBYLPvjgA1x//fVo1aoVfHx8EBoaihtuuAGLFy9GeXm51iE6tZr17eeff671uBACUVFR0Ol0uPnmmzWIkKhpeWsdABEAPPfcc4iOjkZZWRl+/vlnvPXWW1izZg327duHZs2aOfRa119/Pe677z4IIWAymbB37168//77ePPNN/Hyyy9j2rRpisW9YcMG6PV6vPvuu/D19VXsddVWWloKb+/q/w7+/PNPHD16FG+//TbGjRtnO//000/jiSee0CJElJaW4rbbbsO3336Lvn374tFHH0VYWBgKCgrw448/4oEHHkBWVhbeffddTeJzxMGDB6HXa/c3p9FoxMcff4z+/fvbnf/xxx9x/PhxGAwGjSJrelr+DpP2mPSQU7jxxhsRGxsLABg3bhxatmyJV199FV999RVGjhzp0Gt16tQJ99xzj925l156CbfccgseeeQRdO7cGTfddJMicefn58PPz8+lEx5AfgnWlJ+fDwAICQmxO+/t7W2XHKnp4Ycfxrfffov58+djypQpdo898sgjOHToEDIyMjSJzVFaJxU33XQT0tPTsWDBAruf58cff4zevXvj1KlTGkbXtLT8HSbtsXuLnNJ1110HAMjOzlbk9Vq2bInly5fD29sbL7zwwkXLV1VV4fnnn0fHjh1hMBjQoUMHPPnkk3bdJzqdDkuWLEFxcbGty2Dp0qX1vuahQ4dwxx13IDw8HEajEW3btsWIESNgMpnsXnPy5MlYtmwZrrjiChiNRvTu3RubNm2q9Xo5OTm4//77ERYWBoPBgK5du+K9996rVa6srAzPPPMMOnXqBKPRiIiICNx+++34888/7d7XOqZnzJgxSExMBAAMGzYMOp3ONuamvvEQH330EXr37g0/Pz+0aNECI0aMwLFjx2qVW7x4MTp27Ag/Pz/ExcXhp59+qvd61XTs2DG88847GDx4cK2ExyomJgYPPPCA3bl58+ahb9++aNmyJfz8/NC7d+9aXaRHjhyp92d3/lins2fPYurUqejQoQMMBgNCQ0Nx/fXXY9euXbYyDfk5nz+mp6CgAI8++ii6d++OgIAABAUF4cYbb8TevXvt4rF283766ad44YUX0LZtWxiNRgwaNAiHDx++2GW0GTlyJE6fPm2XJFZUVOCzzz7D3XffXedzLBYL5s+fj65du8JoNCIsLAwTJ07EmTNnapVdu3YtEhMTERgYiKCgIPTp0wcff/xxrXIHDhzAwIED0axZM7Rp0wZz5syxe7yiogIzZ85E7969ERwcDH9/fwwYMAAbN260K2f9Gc6bN8/2O2YwGNCnTx9s377drmxdv8MZGRno378/QkJCEBAQgCuuuAJPPvmk7fGa1/3ZZ59FmzZtEBgYiDvvvBMmkwnl5eWYOnUqQkNDERAQgNTUVHa1Oimmu+SUrF/ILVu2VOw127Vrh8TERGzcuBFFRUUICgqqt+y4cePw/vvv484778QjjzyCrKwspKWl4bfffsOXX34JAPjwww+xePFibNu2De+88w4AoG/fvnW+XkVFBZKTk1FeXo4HH3wQ4eHhyMnJwapVq1BYWIjg4GBb2R9//BErVqzAQw89BIPBgDfffBODBw/Gtm3bbIM/8/Ly8K9//cuWJLVu3Rpr167F2LFjUVRUhKlTpwIAzGYzbr75Zqxfvx4jRozAlClTcPbsWWRkZGDfvn3o2LFjrVgnTpyINm3a4MUXX8RDDz2EPn36ICwsrN5r9cILL2DGjBkYPnw4xo0bh5MnT+L111/HNddcg927d9tai959911MnDgRffv2xdSpU/HXX3/h1ltvRYsWLRAVFVX/Dw7yS9RsNtdqwbuY//73v7j11lsxatQoVFRUYPny5Rg2bBhWrVqFIUOGOPRaAPDvf/8bn332GSZPnowrr7wSp0+fxs8//4zffvsNV199tUM/55r++usvrFy5EsOGDUN0dDTy8vLwv//9D4mJiThw4AAiIyPtyr/00kvQ6/V49NFHYTKZMGfOHIwaNQpZWVkN+hwdOnRAQkICPvnkE9x4440A5DU2mUwYMWIEFixYUOs5EydOxNKlS5GamoqHHnoI2dnZeOONN7B7925s3rwZPj4+AOS4ofvvvx9du3bF9OnTERISgt27d2PdunV2CdWZM2cwePBg3H777Rg+fDg+++wz/Oc//0H37t1tMRUVFeGdd97ByJEjMX78eJw9exbvvvsukpOTsW3btloTBz7++GOcPXsWEydOhE6nw5w5c3D77bfjr7/+ssV3vv379+Pmm2/GVVddheeeew4GgwGHDx/G5s2ba5VNS0uDn58fnnjiCRw+fBivv/46fHx8oNfrcebMGTzzzDPYunUrli5diujoaMycObNBPw9SkSDS0JIlSwQA8f3334uTJ0+KY8eOieXLl4uWLVsKPz8/cfz4cSGEEBs3bhQARHp6+gVfD4CYNGlSvY9PmTJFABB79+6tt8yePXsEADFu3Di7848++qgAIDZs2GA7N3r0aOHv73/Rz7l79+4Gxw9A7Nixw3bu6NGjwmg0ittuu812buzYsSIiIkKcOnXK7vkjRowQwcHBoqSkRAghxHvvvScAiFdffbXWe1ksFrv3nTVrlu3f9V3vWbNmiZr/bRw5ckR4eXmJF154wa7cr7/+Kry9vW3nKyoqRGhoqOjZs6coLy+3lVu8eLEAIBITEy94XR5++GEBQOzZs8fufHl5uTh58qRtO/96WK+DVUVFhejWrZu47rrrbOeys7MFALFkyZJa73v+dQkODr7g71dDf87t27cXo0ePtv27rKxMmM1muzLZ2dnCYDCI5557znbO+nPp0qWL3XX873//KwCIX3/99YLva61v27dvF2+88YYIDAy0XaNhw4aJgQMH2uIbMmSI7Xk//fSTACCWLVtm93rr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XpPaeE1q4zWpjdekNne6JhzITERERB6BLT1ERETkEZj0EBERkUdg0kNEREQegUkPEREReQQmPUREROQRmPS4uNWrVyM+Ph5+fn5o3rw5UlJStA7JKZSXl6Nnz57Q6XTYs2eP1uFo5siRIxg7diyio6Ph5+eHjh07YtasWaioqNA6NFUtXLgQHTp0gNFoRHx8PLZt26Z1SJpKS0tDnz59EBgYiNDQUKSkpODgwYNah+VUXnrpJeh0OkydOlXrUDSVk5ODe+65By1btoSfnx+6d++OHTt2aB1WozHpcWGff/457r33XqSmpmLv3r3YvHkz7r77bq3DcgqPP/44InnnQvz++++wWCz43//+h/379+O1117DokWL8OSTT2odmmpWrFiBadOmYdasWdi1axd69OiB5ORk5Ofnax2aZn788UdMmjQJW7duRUZGBiorK3HDDTeguObtzj3Y9u3b8b///Q9XXXWV1qFo6syZM+jXrx98fHywdu1aHDhwAK+88gqaN2+udWiNJ8glVVZWijZt2oh33nlH61Cczpo1a0Tnzp3F/v37BQCxe/durUNyKnPmzBHR0dFah6GauLg4MWnSJNu/zWaziIyMFGlpaRpG5Vzy8/MFAPHjjz9qHYrmzp49K2JiYkRGRoZITEwUU6ZM0TokzfznP/8R/fv31zoMRbGlx0Xt2rULOTk50Ov16NWrFyIiInDjjTdi3759Woemqby8PIwfPx4ffvghmjVrpnU4TslkMqFFixZah6GKiooK7Ny5E0lJSbZzer0eSUlJyMzM1DAy52IymQDAY34vLmTSpEkYMmSI3e+Mp/r6668RGxuLYcOGITQ0FL169cLbb7+tdViXhEmPi/rrr78AAM888wyefvpprFq1Cs2bN8e1116LgoICjaPThhACY8aMwb///W/ExsZqHY5TOnz4MF5//XVMnDhR61BUcerUKZjNZoSFhdmdDwsLQ25urkZROReLxYKpU6eiX79+6Natm9bhaGr58uXYtWsX0tLStA7FKfz111946623EBMTg2+//Rb/7//9Pzz00EN4//33tQ6t0Zj0OJknnngCOp3ugpt1nAYAPPXUU7jjjjvQu3dvLFmyBDqdDunp6Rp/CmU19Jq8/vrrOHv2LKZPn651yE2uodekppycHAwePBjDhg3D+PHjNYqcnM2kSZOwb98+LF++XOtQNHXs2DFMmTIFy5Ytg9Fo1Docp2CxWHD11VfjxRdfRK9evTBhwgSMHz8eixYt0jq0RvPWOgCy98gjj2DMmDEXLHPZZZfhn3/+AQBceeWVtvMGgwGXXXYZ/v7776YMUXUNvSYbNmxAZmZmrZvixcbGYtSoUS7918n5GnpNrE6cOIGBAweib9++WLx4cRNH5zxatWoFLy8v5OXl2Z3Py8tDeHi4RlE5j8mTJ2PVqlXYtGkT2rZtq3U4mtq5cyfy8/Nx9dVX286ZzWZs2rQJb7zxBsrLy+Hl5aVhhOqLiIiw+44BgC5duuDzzz/XKKJLx6THybRu3RqtW7e+aLnevXvDYDDg4MGD6N+/PwCgsrISR44cQfv27Zs6TFU19JosWLAAs2fPtv37xIkTSE5OxooVKxAfH9+UIaquodcEkC08AwcOtLUG6vWe08Dr6+uL3r17Y/369bblHCwWC9avX4/JkydrG5yGhBB48MEH8eWXX+KHH35AdHS01iFpbtCgQfj111/tzqWmpqJz5874z3/+43EJDwD069ev1lIGf/zxh0t/xzDpcVFBQUH497//jVmzZiEqKgrt27fH3LlzAQDDhg3TODpttGvXzu7fAQEBAICOHTt67F+xOTk5uPbaa9G+fXvMmzcPJ0+etD3mKS0d06ZNw+jRoxEbG4u4uDjMnz8fxcXFSE1N1To0zUyaNAkff/wxvvrqKwQGBtrGNwUHB8PPz0/j6LQRGBhYa0yTv78/WrZs6bFjnR5++GH07dsXL774IoYPH45t27Zh8eLFLt1azKTHhc2dOxfe3t649957UVpaivj4eGzYsMG111AgRWVkZODw4cM4fPhwrcRPCKFRVOq66667cPLkScycORO5ubno2bMn1q1bV2twsyd56623AADXXnut3fklS5ZctNuUPEefPn3w5ZdfYvr06XjuuecQHR2N+fPnY9SoUVqH1mg64Sn/8xEREZFH85zOfSIiIvJoTHqIiIjIIzDpISIiIo/ApIeIiIg8ApMeIiIi8ghMeoiIiMgjMOkhIiIij8Ckh4iIiDwCkx4iIiLyCEx6iIiIyCMw6SEiIiKP8P8B7mM6lssJv04AAAAASUVORK5CYII=",
232       "text/plain": [
233        "<Figure size 640x480 with 1 Axes>"
234       ]
235      },
236      "metadata": {},
237      "output_type": "display_data"
238     }
239    ],
240    "source": [
241     "def make_gauss_pld(sigma, sensitivity):\n",
242     "    \"\"\" Makes a guassian PLD from standard deviation\n",
243     "    \n",
244     "    Inputs:\n",
245     "        sigma: standard deviation of gaussian mechanism\n",
246     "        sensitivity: sensitivity of mechanism\n",
247     "        \n",
248     "    Output:\n",
249     "        dp_accounting.pld.PrivacyLossDistribution object\n",
250     "    \"\"\"\n",
251     "\n",
252     "    return pld.from_gaussian_mechanism(sigma,\n",
253     "                                       sensitivity=sensitivity,\n",
254     "                                       value_discretization_interval=0.001)\n",
255     "\n",
256     "\n",
257     "def make_gauss_pld_from_params(delta,\n",
258     "                               epsilon,\n",
259     "                               sensitivity,\n",
260     "                               verbose=False,\n",
261     "                               *args):\n",
262     "    \"\"\" Makes a guassian PLD from privacy parameters\n",
263     "    \n",
264     "    Inputs:\n",
265     "        delta: delta value to use\n",
266     "        epsilon: epsilon to use\n",
267     "        sensitivity: sensitivity of mechanism\n",
268     "        \n",
269     "    Output:\n",
270     "        dp_accounting.pld.PrivacyLossDistribution object\n",
271     "    \"\"\"\n",
272     "\n",
273     "    sigma = fit_sigma_from_params(delta, epsilon, sensitivity, verbose=verbose)\n",
274     "    return make_gauss_pld(sigma, sensitivity, *args)\n",
275     "\n",
276     "\n",
277     "def analyze_gauss_pld(gauss_pld, color='blue', verbose=False):\n",
278     "    \"\"\" Create a PMF from a PLD object\n",
279     "    \n",
280     "    Inputs:\n",
281     "        gauss_pld: dp_accounting.pld.PrivacyLossDistribution object\n",
282     "        color: color to use in plots\n",
283     "        verbose: print detail and charts\n",
284     "        \n",
285     "    Output:\n",
286     "        Returns (x, y) PMF of PLD\n",
287     "        If verbose, shows a matplotlib chart of the data\n",
288     "    \"\"\"\n",
289     "    gauss_pmf = gauss_pld._pmf_add.to_dense_pmf()\n",
290     "\n",
291     "    y = gauss_pmf._probs\n",
292     "    y = (y - y.min()) / (y - y.min()).sum()  # Normalize\n",
293     "\n",
294     "    x = [gauss_pmf._discretization * gauss_pmf._lower_loss]\n",
295     "    [x.append(gauss_pmf._discretization + x[i - 1]) for i in range(1, len(y))]\n",
296     "\n",
297     "    if verbose:\n",
298     "        plt.title(f\"PLD of specified Gaussian Mechanism\")\n",
299     "        plt.plot(x, y, c=color)\n",
300     "        plt.axvline(epsilon, c=color, linestyle='dotted')\n",
301     "        plt.axvline(-epsilon, c=color, linestyle='dotted')\n",
302     "        plt.show()\n",
303     "\n",
304     "    return (x, y)\n",
305     "\n",
306     "\n",
307     "gauss_pld = make_gauss_pld_from_params(delta,\n",
308     "                                       epsilon,\n",
309     "                                       sensitivity,\n",
310     "                                       verbose=True)\n",
311     "x, y = analyze_gauss_pld(gauss_pld, verbose=True)"
312    ]
313   },
314   {
315    "cell_type": "markdown",
316    "id": "58b8e9b9",
317    "metadata": {},
318    "source": [
319     "### Sampling from the PLD"
320    ]
321   },
322   {
323    "cell_type": "code",
324    "execution_count": 5,
325    "id": "8863591f",
326    "metadata": {},
327    "outputs": [
328     {
329      "data": {
330       "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjkAAAGzCAYAAADNKAZOAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAAA+hklEQVR4nO3de1hVdf7+/xvQDXjYGzUBSVTKUjHTPOHubJG7ooOjNmpmpGZpaCmTBxoHtKnRrMZDeMiaEa8pP6mVHSQxw9RviYcwS02ZMgvLNmLK3koFCuv3x/xY4x7RwNOG5fNxXeu63Ov9Wmu91rq64r7ee621AwzDMAQAAGAxgf5uAAAA4Hwg5AAAAEsi5AAAAEsi5AAAAEsi5AAAAEsi5AAAAEsi5AAAAEsi5AAAAEsi5AAAAEsi5AC4YAICAjR58uQLesyCggL169dPTZo0UUBAgGbOnHlBjw/Afwg5QC2zfft29evXTy1btlRISIguvfRS3XbbbXrppZf83VqNNHbsWK1atUopKSn617/+pdtvv93fLZ3Sd999p4CAAHMJCgpSixYt9Ic//EHbtm3zqQ0ICNCoUaNOu7+bb77Z3FdgYKDsdrvatGmjwYMHa/Xq1efxTICaoY6/GwBQdRs2bFDPnj3VokULDR8+XJGRkdq3b582btyoWbNmafTo0f5uscZZs2aN7r33Xj355JP+bqXKBg4cqDvvvFNlZWXatWuX5s2bp5UrV2rjxo3q1KlTtfbVvHlzTZ06VZJUXFysb775Rm+//bZee+01/fGPf9Rrr72munXrnoezAPyPkAPUIs8++6wcDoe2bNmisLAwn7EDBw74p6ka7sCBAyddq8oUFxerfv3657+hKujcubMeeOAB8/N1112ne+65R/PmzdPLL79crX05HA6ffUnStGnT9Pjjj2vu3Llq1aqVnnvuuXPSN1DT8HUVUIvs2bNH7du3r/SPdnh4uM/nhQsX6pZbblF4eLiCg4MVGxurefPmnbRdq1atdNddd2nt2rXq2rWrQkND1aFDB61du1aS9Pbbb6tDhw4KCQlRly5d9Pnnn/ts/9BDD6lBgwb69ttv5XK5VL9+fUVFRenpp5+WYRi/e04//vijhg4dqoiICAUHB6t9+/b65z//eVLdSy+9pPbt26tevXpq1KiRunbtqsWLF59yvxkZGQoICJBhGJozZ475tc2JY+vWrdNjjz2m8PBwNW/e3Nx27ty5at++vYKDgxUVFaWkpCQVFRX57P/mm2/WVVddpS+//FI33XST6tWrp9atW+vNN9+UJK1bt05xcXEKDQ1VmzZt9NFHH/3utTiVW265RZK0d+/eM97HiYKCgjR79mzFxsYqPT1dHo/nnOwXqGkIOUAt0rJlS+Xm5mrHjh2/Wztv3jy1bNlSTz31lF588UVFR0frscce05w5c06q/eabb3T//ffr7rvv1tSpU3X48GHdfffdev311zV27Fg98MADmjJlivbs2aM//vGPKi8v99m+rKxMt99+uyIiIjR9+nR16dJFaWlpSktLO22PBQUF6tGjhz766CONGjVKs2bNUuvWrTVs2DCfG4RfeeUVPf7444qNjdXMmTM1ZcoUderUSZs2bTrlvm+88Ub961//kiTddttt+te//mV+rvDYY4/pq6++UmpqqiZOnChJmjx5spKSkhQVFaUXX3xRffv21csvv6xevXrp2LFjPtsfPnxYd911l+Li4jR9+nQFBwdrwIABWrJkiQYMGKA777xT06ZNU3Fxsfr166cjR46c9nqcyp49eyRJTZo0OaPtKxMUFKSBAwfql19+0SeffHLO9gvUKAaAWuPDDz80goKCjKCgIMPpdBrjx483Vq1aZZSWlp5U+8svv5y0zuVyGZdddpnPupYtWxqSjA0bNpjrVq1aZUgyQkNDje+//95c//LLLxuSjI8//thcl5iYaEgyRo8eba4rLy83EhISDJvNZhQWFprrJRlpaWnm52HDhhnNmjUzDh486NPTgAEDDIfDYZ7Dvffea7Rv3/53rk7lJBlJSUk+6xYuXGhIMq6//nrj+PHj5voDBw4YNpvN6NWrl1FWVmauT09PNyQZ//znP811N910kyHJWLx4sblu9+7dhiQjMDDQ2Lhxo7m+4nouXLjwtL3u3bvXkGRMmTLFKCwsNNxut7F27VrjmmuuMSQZb7311mnP63/ddNNNp71uy5cvNyQZs2bNOu1+gNqKmRygFrntttuUk5Oje+65R1988YWmT58ul8ulSy+9VO+9955PbWhoqPlvj8ejgwcP6qabbtK333570tcTsbGxcjqd5ue4uDhJ//mapEWLFiet//bbb0/q7cQnfSqe/CktLT3l1zSGYeitt97S3XffLcMwdPDgQXNxuVzyeDzaunWrJCksLEw//PCDtmzZUqXrVFXDhw9XUFCQ+fmjjz5SaWmpxowZo8DAQJ86u92uzMxMn+0bNGigAQMGmJ/btGmjsLAwtWvXzrxW0umvW2XS0tLUtGlTRUZG6uabb9aePXv03HPPqU+fPmd0nqfSoEEDSTrjGSagpuPGY6CW6datm95++22Vlpbqiy++0PLlyzVjxgz169dP27ZtU2xsrCTp008/VVpamnJycvTLL7/47MPj8cjhcJifTwwyksyx6OjoStcfPnzYZ31gYKAuu+wyn3VXXnmlpP88Fl2ZwsJCFRUVacGCBVqwYEGlNRU3U0+YMEEfffSRunfvrtatW6tXr166//77dd1111W6XVXFxMT4fP7+++8l/SesnMhms+myyy4zxys0b97cvM+ngsPhqPJ1O5VHHnlE9913nwIDAxUWFmbeH3SuHT16VJLUsGHDc75voCYg5AC1lM1mU7du3dStWzddeeWVGjJkiJYtW6a0tDTt2bNHt956q9q2bau///3vio6Ols1m0wcffKAZM2acdE/NibMZVVlvVOGG4t9T0cMDDzygxMTESmuuvvpqSVK7du2Ul5enFStWKCsrS2+99Zbmzp2r1NRUTZky5Yx7OHG260ycr+t2xRVXKD4+/oz7qqqKe7tat2593o8F+AMhB7CArl27SpJ++uknSdL777+vkpISvffeez6zNB9//PF5OX55ebm+/fZbc/ZGkv79739L+s/TW5Vp2rSpGjZsqLKysir9Qa9fv7769++v/v37q7S0VH369NGzzz6rlJQUhYSEnJPzaNmypSQpLy/PZ2aqtLRUe/fuvSDB40IpKyvT4sWLVa9ePV1//fX+bgc4L7gnB6hFPv7440pnAz744ANJ//2apWIm4cRaj8ejhQsXnrfe0tPTzX8bhqH09HTVrVtXt956a6X1QUFB6tu3r956661KnxYrLCw0//3zzz/7jNlsNsXGxsowjJOeeDob8fHxstlsmj17ts+1+8c//iGPx6OEhIRzdix/Kisr0+OPP65du3bp8ccfl91u93dLwHnBTA5Qi4wePVq//PKL/vCHP6ht27YqLS3Vhg0btGTJErVq1UpDhgyRJPXq1Us2m0133323Hn30UR09elSvvPKKwsPDzdmecykkJERZWVlKTExUXFycVq5cqczMTD311FNq2rTpKbebNm2aPv74Y8XFxWn48OGKjY3VoUOHtHXrVn300Uc6dOiQeT6RkZG67rrrFBERoV27dik9PV0JCQnn9H6Spk2bKiUlRVOmTNHtt9+ue+65R3l5eZo7d666det20kv1/O2zzz7TM888c9L6m2++2Zyd8Xg8eu211yRJv/zyi/nG4z179mjAgAH661//ekF7Bi4kQg5Qi7zwwgtatmyZPvjgAy1YsEClpaVq0aKFHnvsMU2aNMl8SWCbNm305ptvatKkSXryyScVGRmpkSNHqmnTpho6dOg57ysoKEhZWVkaOXKkxo0bp4YNGyotLU2pqamn3S4iIkKbN2/W008/rbfffltz585VkyZN1L59e5+38D766KN6/fXX9fe//11Hjx5V8+bN9fjjj2vSpEnn/FwmT56spk2bKj09XWPHjlXjxo31yCOP6G9/+1uN+/mDTZs2VfquoL/+9a9myPnhhx80ePBgSf95mqpZs2ZyOp2aN2+ebrvttgvaL3ChBRjn4g5CABethx56SG+++ab5pA4A1BTckwMAACyJkAMAACyJkAMAACyJe3IAAIAlMZMDAAAsiZADAAAs6aJ+T055ebn279+vhg0bnvQjewAAoGYyDENHjhxRVFSUAgNPPV9zUYec/fv3n/RrwQAAoHbYt2+fmjdvfsrxizrkVLwOft++ffx2CwAAtYTX61V0dPTv/qzLRR1yKr6istvthBwAAGqZ37vVpFo3HpeVlekvf/mLYmJiFBoaqssvv1x//etffX6t1zAMpaamqlmzZgoNDVV8fLy+/vprn/0cOnRIgwYNkt1uV1hYmIYNG3bSK+G//PJL3XDDDQoJCVF0dLSmT59+Uj/Lli1T27ZtFRISog4dOpi/xAwAAFCtkPPcc89p3rx5Sk9P165du/Tcc89p+vTpeumll8ya6dOna/bs2Zo/f742bdqk+vXry+Vy6bfffjNrBg0apJ07d2r16tVasWKF1q9fr0ceecQc93q96tWrl1q2bKnc3Fw9//zzmjx5shYsWGDWbNiwQQMHDtSwYcP0+eefq3fv3urdu7d27NhxNtcDAABYhVENCQkJxtChQ33W9enTxxg0aJBhGIZRXl5uREZGGs8//7w5XlRUZAQHBxv/93//ZxiGYXz11VeGJGPLli1mzcqVK42AgADjxx9/NAzDMObOnWs0atTIKCkpMWsmTJhgtGnTxvz8xz/+0UhISPDpJS4uznj00UerfD4ej8eQZHg8nipvAwAA/Kuqf7+rNZNz7bXXKjs7W//+978lSV988YU++eQT3XHHHZKkvXv3yu12Kz4+3tzG4XAoLi5OOTk5kqScnByFhYWpa9euZk18fLwCAwO1adMms+bGG2+UzWYza1wul/Ly8nT48GGz5sTjVNRUHKcyJSUl8nq9PgsAALCmat14PHHiRHm9XrVt21ZBQUEqKyvTs88+q0GDBkmS3G63JCkiIsJnu4iICHPM7XYrPDzct4k6ddS4cWOfmpiYmJP2UTHWqFEjud3u0x6nMlOnTtWUKVOqc8oAAKCWqtZMztKlS/X6669r8eLF2rp1qxYtWqQXXnhBixYtOl/9nVMpKSnyeDzmsm/fPn+3BAAAzpNqzeSMGzdOEydO1IABAyRJHTp00Pfff6+pU6cqMTFRkZGRkqSCggI1a9bM3K6goECdOnWSJEVGRurAgQM++z1+/LgOHTpkbh8ZGamCggKfmorPv1dTMV6Z4OBgBQcHV+eUAQBALVWtmZxffvnlpNcnBwUFqby8XJIUExOjyMhIZWdnm+Ner1ebNm2S0+mUJDmdThUVFSk3N9esWbNmjcrLyxUXF2fWrF+/XseOHTNrVq9erTZt2qhRo0ZmzYnHqaipOA4AALjIVedu5sTEROPSSy81VqxYYezdu9d4++23jUsuucQYP368WTNt2jQjLCzMePfdd40vv/zSuPfee42YmBjj119/NWtuv/1245prrjE2bdpkfPLJJ8YVV1xhDBw40BwvKioyIiIijMGDBxs7duww3njjDaNevXrGyy+/bNZ8+umnRp06dYwXXnjB2LVrl5GWlmbUrVvX2L59e5XPh6erAACofar697taIcfr9RpPPPGE0aJFCyMkJMS47LLLjD//+c8+j3qXl5cbf/nLX4yIiAgjODjYuPXWW428vDyf/fz888/GwIEDjQYNGhh2u90YMmSIceTIEZ+aL774wrj++uuN4OBg49JLLzWmTZt2Uj9Lly41rrzySsNmsxnt27c3MjMzq3M6hBwAAGqhqv79DjCME15XfJHxer1yOBzyeDz8rAMAALVEVf9+V+ueHAAAgNqCkAMAACyJkAMAACypWu/JAYCaotXEzN+t+W5awgXoBEBNxUwOAACwJEIOAACwJEIOAACwJEIOAACwJEIOAACwJEIO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sbGx2rJli7p27SpJysrK0p133qkffvhBUVFRmjdvnv785z/L7XbLZrOZx37nnXe0e/duSVL//v1VXFysFStWmMfv0aOHOnXqpPnz51fpfLxerxwOhzwej+x2e1UvA4BTaDUx098t+M130xL83QJw0ajq3+9qzeS899576tq1q+677z6Fh4frmmuu0SuvvGKO7927V263W/Hx8eY6h8OhuLg45eTkSJJycnIUFhZmBhxJio+PV2BgoDZt2mTW3HjjjWbAkSSXy6W8vDwdPnzYrDnxOBU1FcepTElJibxer88CAACsqVoh59tvv9W8efN0xRVXaNWqVRo5cqQef/xxLVq0SJLkdrslSRERET7bRUREmGNut1vh4eE+43Xq1FHjxo19airbx4nHOFVNxXhlpk6dKofDYS7R0dHVOX0AAFCLVCvklJeXq3Pnzvrb3/6ma665Ro888oiGDx9e5a+H/C0lJUUej8dc9u3b5++WAADAeVKtkNOsWTPFxsb6rGvXrp3y8/MlSZGRkZKkgoICn5qCggJzLDIyUgcOHPAZP378uA4dOuRTU9k+TjzGqWoqxisTHBwsu93uswAAAGuqVsi57rrrlJeX57Pu3//+t1q2bClJiomJUWRkpLKzs81xr9erTZs2yel0SpKcTqeKioqUm5tr1qxZs0bl5eWKi4sza9avX69jx46ZNatXr1abNm3MJ7mcTqfPcSpqKo4DAAAubtUKOWPHjtXGjRv1t7/9Td98840WL16sBQsWKCkpSZIUEBCgMWPG6JlnntF7772n7du368EHH1RUVJR69+4t6T8zP7fffruGDx+uzZs369NPP9WoUaM0YMAARUVFSZLuv/9+2Ww2DRs2TDt37tSSJUs0a9YsJScnm7088cQTysrK0osvvqjdu3dr8uTJ+uyzzzRq1KhzdGkAAEBtVq1HyCVpxYoVSklJ0ddff62YmBglJydr+PDh5rhhGEpLS9OCBQtUVFSk66+/XnPnztWVV15p1hw6dEijRo3S+++/r8DAQPXt21ezZ89WgwYNzJovv/xSSUlJ2rJliy655BKNHj1aEyZM8Oll2bJlmjRpkr777jtdccUVmj59uu68884qnwuPkANVdzE/Hl4VPEIOXDhV/ftd7ZBjJYQcoOoIOadHyAEunPPynhwAAIDagpADAAAsiZADAAAsiZADAAAsiZAD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",
331       "text/plain": [
332        "<Figure size 640x480 with 1 Axes>"
333       ]
334      },
335      "metadata": {},
336      "output_type": "display_data"
337     }
338    ],
339    "source": [
340     "def sample_from_pmf(data, num_samples=1000000, num_bins=50, verbose=False):\n",
341     "    \"\"\" Draw samples from a PMF\n",
342     "    \n",
343     "    Inputs:\n",
344     "        data: PMF in the form of (x, y)\n",
345     "        num_samples: number of samples to draw\n",
346     "        num_bins: number of bins to draw in histogram\n",
347     "        verbose: print details and plots\n",
348     "        \n",
349     "    Output:\n",
350     "        array of samples\n",
351     "        If verbose, matplotlib histogram\n",
352     "    \"\"\"\n",
353     "    rng = np.random.default_rng()\n",
354     "    choices = rng.choice(data[0], num_samples, p=data[1])\n",
355     "\n",
356     "    if verbose:\n",
357     "        plt.title(\"Samples from PLD\")\n",
358     "        plt.hist(choices, bins=num_bins)\n",
359     "        plt.show()\n",
360     "\n",
361     "    return choices\n",
362     "\n",
363     "\n",
364     "_ = sample_from_pmf((x, y), verbose=True)"
365    ]
366   },
367   {
368    "cell_type": "markdown",
369    "id": "8f23c674",
370    "metadata": {},
371    "source": [
372     "### Google paper observations\n",
373     "Empirical testing of the observations in [this paper](https://github.com/google/differential-privacy/blob/main/common_docs/Privacy_Loss_Distributions.pdf)\n",
374     "\n",
375     "#### Observation 1\n",
376     "Epsilon-hockey stick divergence is less than or equal to delta"
377    ]
378   },
379   {
380    "cell_type": "code",
381    "execution_count": 6,
382    "id": "28b65fc1",
383    "metadata": {},
384    "outputs": [
385     {
386      "name": "stdout",
387      "output_type": "stream",
388      "text": [
389       "Epsilon-Hockey Stick Div: 9.999984507048863e-07\n",
390       "Delta:                    1e-06\n",
391       "Observation 1 true?:      True\n"
392      ]
393     }
394    ],
395    "source": [
396     "EHSD = gauss_pld.get_delta_for_epsilon(epsilon)\n",
397     "\n",
398     "print(f\"Epsilon-Hockey Stick Div: {EHSD}\")\n",
399     "print(f\"Delta:                    {delta}\")\n",
400     "print(f\"Observation 1 true?:      {EHSD <= delta}\")"
401    ]
402   },
403   {
404    "cell_type": "markdown",
405    "id": "945a5af4",
406    "metadata": {},
407    "source": [
408     "#### Observation 2\n",
409     "Epsilon-hockey stick divergence is equal to the given equation"
410    ]
411   },
412   {
413    "cell_type": "code",
414    "execution_count": 7,
415    "id": "eef91f41",
416    "metadata": {},
417    "outputs": [
418     {
419      "data": {
420       "application/vnd.jupyter.widget-view+json": {
421        "model_id": "23b0ec7170a341f2bc9fe43f40f140d1",
422        "version_major": 2,
423        "version_minor": 0
424       },
425       "text/plain": [
426        "  0%|          | 0/1000000 [00:00<?, ?it/s]"
427       ]
428      },
429      "metadata": {},
430      "output_type": "display_data"
431     },
432     {
433      "name": "stdout",
434      "output_type": "stream",
435      "text": [
436       "Obs. 2 result:                 1.055938431879598e-06\n",
437       "Epsilon-Hockey Stick Div:      9.999984507048863e-07\n",
438       "Obs. 2 true? (result == EHSD): True\n"
439      ]
440     }
441    ],
442    "source": [
443     "num_samples = 1000000\n",
444     "\n",
445     "\n",
446     "def observation2(x, y, num_samples=1000000):\n",
447     "    obs = []\n",
448     "    rng = np.random.default_rng()\n",
449     "    samples = rng.choice(x, num_samples, p=y)\n",
450     "    for y in tqdm(samples):\n",
451     "        # eq is the equation given in the paper\n",
452     "        eq = 1 - (e**(epsilon - y))\n",
453     "        obs.append(eq if eq > 0 else 0)\n",
454     "\n",
455     "    return np.mean(obs)  # Expected value\n",
456     "\n",
457     "\n",
458     "obs2 = observation2(x, y, num_samples)\n",
459     "cond = math.isclose(obs2, EHSD, abs_tol=10e-7)\n",
460     "\n",
461     "print(f\"Obs. 2 result:                 {obs2}\")\n",
462     "print(f\"Epsilon-Hockey Stick Div:      {EHSD}\")\n",
463     "print(f\"Obs. 2 true? (result == EHSD): {cond}\")"
464    ]
465   },
466   {
467    "cell_type": "markdown",
468    "id": "8e2155be",
469    "metadata": {},
470    "source": [
471     "#### Observation 3\n",
472     "Composing mechanisms results in the convolution of their respective PLRVs. In this case, for ease, we self compose the mechanism.\n",
473     "\n",
474     "By observation 3, the two histograms should be roughly equal."
475    ]
476   },
477   {
478    "cell_type": "code",
479    "execution_count": 8,
480    "id": "339a2b2d",
481    "metadata": {},
482    "outputs": [
483     {
484      "data": {
485       "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjkAAAGzCAYAAADNKAZOAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAABSoklEQVR4nO3deVxU9f4/8NcAzrAOiMp2RcEVcIFEwUlzSXJUNEksKG/hflXwipgLN7+4pA9NSzFxaxMrSVyuehMFCQWviakY7uAShoUDlMIoKSic3x/+ONcRVPaB4+v5eMxDz+e855zPOYzOm892ZIIgCCAiIiKSGAN9V4CIiIioPjDJISIiIklikkNERESSxCSHiIiIJIlJDhEREUkSkxwiIiKSJCY5REREJElMcoiIiEiSmOQQERGRJDHJIWoEkpOTIZPJkJycXKfHHTt2LJycnOr0mNT4yGQyLFy4sEqxTk5OGDt2bL3Wh6ixYJJDTdq1a9fwj3/8A+3atYOxsTGUSiX69OmDNWvW4N69e/quXoPIycnBwoULkZ6eru+qNLjc3Fy8//77cHFxgampKczMzODp6YklS5agoKBA39XTm2PHjmHhwoWN6h5ER0dDJpOJL2NjY3Tq1AkhISHIzc0V48oT/p07dz7zeI8fy8jICNbW1vD09MSMGTNw8eLF+r4caiKM9F0BopqKi4vDm2++CYVCgffeew9du3ZFSUkJjh49itmzZ+PChQv47LPP9F3NepeTk4NFixbByckJHh4eOvs+//xzlJWV6adi9ezkyZMYNmwY7t69i7///e/w9PQEAJw6dQrLly/HkSNHcPDgQT3XsmHcu3cPRkb/++/82LFjWLRoEcaOHQsrKyud2MzMTBgY6O/328WLF8PZ2Rn379/H0aNHsWHDBuzfvx/nz5+HqalptY712muv4b333oMgCCgsLMSZM2ewZcsWrF+/Hh999BHCwsLq6SqoqWCSQ01SVlYWAgMD0bZtWxw6dAj29vbivuDgYFy9ehVxcXF6rGHj0KxZM31XoV4UFBTgjTfegKGhIX7++We4uLjo7F+6dCk+//xzPdWu4RkbG1c5VqFQ1GNNnm/o0KHo2bMnAGDixIlo0aIFVq1ahb179+Ltt9+u1rE6deqEv//97zply5cvx4gRIzBr1iy4uLhg2LBhdVZ3anrYXUVN0ooVK3D37l18+eWXOglOuQ4dOmDGjBni9sOHD/Hhhx+iffv2UCgUcHJywr/+9S8UFxfrvM/JyQnDhw/H0aNH4eXlBWNjY7Rr1w5ff/21GHPq1CnIZDJs2bKlwnkTEhIgk8mwb98+seznn3/G0KFDoVQqYW5ujkGDBuH48ePPvcanjZ0YMGAABgwYAOBR036vXr0AAOPGjROb76OjowFUPianqKgIs2bNgqOjIxQKBTp37oyPP/4YgiDoxMlkMoSEhGDPnj3o2rUrFAoFunTpgvj4+GfWOzc3F0ZGRli0aFGFfZmZmZDJZIiKigIAPHjwAIsWLULHjh1hbGyMFi1aoG/fvkhMTHzmOTZt2oTff/8dq1atqpDgAICtrS3mz5+vU7Z+/Xp06dIFCoUCDg4OCA4OrtCdM2DAAHTt2hVnz55F//79YWpqig4dOohdJykpKfD29oaJiQk6d+6MH374Qef9CxcuhEwmQ0ZGBt566y0olUq0aNECM2bMwP3793Viq/qZPHXqFNRqNVq2bAkTExM4Oztj/PjxOjGPj8lZuHAhZs+eDQBwdnYWPxPXr18HUPnn6pdffsGbb74Ja2trmJqaonfv3hV+SSjvRtq+fTuWLl2K1q1bw9jYGIMGDcLVq1cr/Ayq6tVXXwXw6BeXutCiRQts27YNRkZGWLp0qc6+tWvXokuXLjA1NUXz5s3Rs2dPxMTE1Ml5qXFikkNN0vfff4927drh5ZdfrlL8xIkTERERgR49emD16tXo378/li1bhsDAwAqxV69exejRo/Haa6/hk08+QfPmzTF27FhcuHABANCzZ0+0a9cO27dvr/De2NhYNG/eHGq1GgBw4cIFvPLKKzhz5gzmzJmD//u//0NWVhYGDBiAn376qRZ34BFXV1csXrwYADB58mR88803+Oabb9CvX79K4wVBwOuvv47Vq1djyJAhWLVqFTp37ozZs2dX2rR/9OhRTJs2DYGBgVixYgXu378Pf39//Pnnn0+tk62tLfr37//U+2NoaIg333wTwKMv5EWLFmHgwIGIiorCBx98gDZt2uD06dPPvO7//Oc/MDExwejRo58ZV27hwoUIDg6Gg4MDPvnkE/j7+2PTpk0YPHgwHjx4oBN7+/ZtDB8+HN7e3lixYgUUCgUCAwMRGxuLwMBADBs2DMuXL0dRURFGjx6NO3fuVDjfW2+9hfv372PZsmUYNmwYPv30U0yePFknpiqfyby8PAwePBjXr1/HvHnzsHbtWowZM+aZSfKoUaPEFpHVq1eLn4lWrVpVGp+bm4uXX34ZCQkJmDZtGpYuXYr79+/j9ddfx+7duyvEL1++HLt378b777+P8PBwHD9+HGPGjHn6zX+Oa9euAXiUnNSVNm3aoH///jh+/Di0Wi2AR123//znP+Hm5obIyEgsWrQIHh4edfLvkBoxgaiJKSwsFAAII0eOrFJ8enq6AECYOHGiTvn7778vABAOHToklrVt21YAIBw5ckQsy8vLExQKhTBr1iyxLDw8XGjWrJlw69Ytsay4uFiwsrISxo8fL5b5+fkJcrlcuHbtmliWk5MjWFhYCP369RPLDh8+LAAQDh8+rFOXoKCgCtfTv39/oX///uL2yZMnBQDC5s2bK8QGBQUJbdu2Fbf37NkjABCWLFmiEzd69GhBJpMJV69eFcsACHK5XKfszJkzAgBh7dq1Fc71uE2bNgkAhHPnzumUu7m5Ca+++qq47e7uLvj6+j7zWJVp3ry54O7uXqXYvLw8QS6XC4MHDxZKS0vF8qioKAGA8NVXX4ll/fv3FwAIMTExYllGRoYAQDAwMBCOHz8ulickJFS47wsWLBAACK+//rpOHaZNmyYAEM6cOSMIQtU/k7t37xYACCdPnnzmNQIQFixYIG6vXLlSACBkZWVViH3ycxUaGioAEP773/+KZXfu3BGcnZ0FJycn8Z6Vf0ZdXV2F4uJiMXbNmjWV/qyftHnzZgGA8MMPPwj5+fnCjRs3hG3btgktWrQQTExMhN9++03nPDt27HjuNQcHBz91/4wZM3Tu+ciRI4UuXbo885gkPWzJoSan/DczCwuLKsXv378fACq0VMyaNQsAKjTLu7m54ZVXXhG3W7Vqhc6dO+OXX34RywICAvDgwQP8+9//FssOHjyIgoICBAQEAABKS0tx8OBB+Pn5oV27dmKcvb093nnnHRw9elS8loayf/9+GBoa4p///KdO+axZsyAIAg4cOKBT7uPjg/bt24vb3bt3h1Kp1LkXlRk1ahSMjIwQGxsrlp0/fx4XL14U7w8AWFlZ4cKFC7hy5Uq1rkOr1Vb55//DDz+gpKQEoaGhOgNuJ02aBKVSWeHnb25urtOa0rlzZ1hZWcHV1RXe3t5iefnfK7sXwcHBOtvTp08H8L/PYlU/k+WDhvft21ehxamu7N+/H15eXujbt69YZm5ujsmTJ+P69esVZiqNGzcOcrlc3C7/t/K8z0Q5Hx8ftGrVCo6OjggMDIS5uTl2796Nv/3tb3VwNf9jbm4OAGJLm5WVFX777TecPHmyTs9DjRuTHGpylEolAFTaTVCZX3/9FQYGBujQoYNOuZ2dHaysrPDrr7/qlLdp06bCMZo3b47bt2+L2+7u7nBxcdH5Eo+NjUXLli3FMQb5+fn466+/0Llz5wrHc3V1RVlZGW7cuFGla6grv/76KxwcHCokCK6uruL+x1XlXlSmZcuWGDRokE6XVWxsLIyMjDBq1CixbPHixSgoKECnTp3QrVs3zJ49G2fPnn3udSiVymr9/AFU+DnI5XK0a9euwjW3bt0aMplMp8zS0hKOjo4VygBUei86duyos92+fXsYGBiI42Kq+pns378//P39sWjRIrRs2RIjR47E5s2bK4zbqY1ff/31qZ/R8v2Pe/Iz0bx5cwCV34fKrFu3DomJiTh8+DAuXryIX375RezerUt3794F8L9fhubOnQtzc3N4eXmhY8eOCA4Oxo8//ljn56XGhUkONTlKpRIODg44f/58td735BfX0xgaGlZaLjwxMDcgIACHDx/GH3/8geLiYvznP/+Bv7+/zlTe2nhafUtLS+vk+FVR1XtRmcDAQFy+fFlcv2f79u0YNGgQWrZsKcb069cP165dw1dffYWuXbviiy++QI8ePfDFF18889guLi64fPkySkpKqn4xVfS0a67NvXjaz/J5n8ny9WJSU1MREhKC33//HePHj4enp6f4Jd7QanMfAMDLyws+Pj4YMGAAXF1d6206+/nz52FoaAhnZ2cAj5K2zMxMbNu2DX379sWuXbvQt29fLFiwoF7OT40DkxxqkoYPH45r164hNTX1ubFt27ZFWVlZhS6R3NxcFBQUoG3btjWqQ0BAAB4+fIhdu3bhwIED0Gq1Ot0crVq1gqmpKTIzMyu8NyMjAwYGBhVaBx7XvHnzShdze/I366omb8Cje5GTk1OhFSQjI0PcX1f8/Pwgl8sRGxuL9PR0XL58udKB3tbW1hg3bhy+++473LhxA927d3/u6r0jRozAvXv3sGvXrufWo/yanvw5lJSUICsrq06vudyTn7WrV6+irKxMnOlW3c9k7969sXTpUpw6dQpbt27FhQsXsG3btqee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",
486       "text/plain": [
487        "<Figure size 640x480 with 1 Axes>"
488       ]
489      },
490      "metadata": {},
491      "output_type": "display_data"
492     }
493    ],
494    "source": [
495     "# Convolution (Definition 2)\n",
496     "x1 = sample_from_pmf((x, y)) + sample_from_pmf((x, y))\n",
497     "\n",
498     "# Composition\n",
499     "mech2 = gauss_pld.compose(gauss_pld)\n",
500     "x2 = sample_from_pmf(analyze_gauss_pld(mech2))\n",
501     "\n",
502     "# They're the same! (Observation 3)\n",
503     "plt.hist(x1, bins=100, label=\"Convolution\")\n",
504     "plt.hist(x2, bins=100, alpha=0.5, label=\"Composition\")\n",
505     "plt.title(\"Convolution vs Composition PLDs\")\n",
506     "plt.legend()\n",
507     "plt.show()"
508    ]
509   }
510  ],
511  "metadata": {
512   "kernelspec": {
513    "display_name": "Python 3 (ipykernel)",
514    "language": "python",
515    "name": "python3"
516   },
517   "language_info": {
518    "codemirror_mode": {
519     "name": "ipython",
520     "version": 3
521    },
522    "file_extension": ".py",
523    "mimetype": "text/x-python",
524    "name": "python",
525    "nbconvert_exporter": "python",
526    "pygments_lexer": "ipython3",
527    "version": "3.9.7"
528   }
529  },
530  "nbformat": 4,
531  "nbformat_minor": 5
532 }