{ "cells": [ { "cell_type": "markdown", "metadata": { "toc": "true" }, "source": [ "# Table of Contents\n", "

1  Bernoulli and binomial distribution
1.1  Requirements
1.2  A naive generator
1.3  The generator included in numpy.random
1.4  An efficient generator using the inverse transform method
1.4.1  Explicit computation of the probabilities
1.4.2  First function using the inversion method
1.4.3  Simplified code of the inversion method
1.4.4  In Cython
1.5  Numerical experiments to check time cost of the different versions
1.6  Checking that sampling from Bin(n,p)\" role=\"presentation\" style=\"position: relative;\">𝐵𝑖𝑛(𝑛,𝑝)Bin(n,p) requires a time Ω(n)\" role=\"presentation\" style=\"position: relative;\">Ω(𝑛)Ω(n).
1.7  Conclusion
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Bernoulli and binomial distribution\n", "- References: [Bernoulli distribution on Wikipedia](https://en.wikipedia.org/wiki/Bernoulli_distribution) and [Binomial distribution on Wikipedia](https://en.wikipedia.org/wiki/Binomial_distribution#Generating_binomial_random_variates).\n", "\n", "The Bernoulli distribution of mean $p\\in[0,1]$ is defined as the distribution on $\\{0,1\\}$ such that $\\mathbb{P}(X=1) = p$ and $\\mathbb{P}(X=0) = 1-p$.\n", "\n", "If $X$ follows a Binomial distribution of mean $p\\in[0,1]$ and $n$ samples, $X$ is defined as the sum of $n$ independent and identically distributed (iid) samples from a Bernoulli distribution of mean $p$, that is $X\\in\\{0,\\dots,n\\}$ ($X\\in\\mathbb{N}$) and $\\forall k\\in\\{0,\\dots,n\\}, \\mathbb{P}(X=k) = {n \\choose k} p^k (1-p)^{n-k}$." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Requirements\n", "Let's import the modules required for this notebook." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import matplotlib.pyplot as plt" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "%load_ext cython" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Lilian Besson (Naereen) 2019-02-28T14:09:13+01:00\n", "\n", "CPython 3.6.7\n", "IPython 7.2.0\n", "\n", "numpy 1.15.4\n", "matplotlib 3.0.2\n", "cython 0.29.2\n" ] } ], "source": [ "%load_ext watermark\n", "%watermark -a \"Lilian Besson (Naereen)\" -i -v -p numpy,matplotlib,cython" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## A naive generator\n", "Using the pseudo-random generator of (`float`) random numbers in $[0,1]$ from the `random` or `numpy.random` module, we can easily generate a sample from a Bernoulli distribution." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "import random\n", "\n", "def uniform_01() -> float:\n", " return random.random()" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[0.02240955612218365,\n", " 0.7770015834088284,\n", " 0.8358045673716832,\n", " 0.4095374878779069,\n", " 0.987872833694527]" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[ uniform_01() for _ in range(5) ]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It's very quick now:" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "def bernoulli(p: float) -> int:\n", " return 1 if uniform_01() <= p else 0" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[0, 0, 0, 0, 0]" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[ bernoulli(0) for _ in range(5) ]" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1, 0, 0, 0, 0]" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[ bernoulli(0.12345) for _ in range(5) ]" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1, 1, 1, 1, 1]" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[ bernoulli(1) for _ in range(5) ]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "So we can naively generate samples from a Binomial distribution by summing iid samples generated using this `bernoulli` function." ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [], "source": [ "def naive_binomial(n: int, p: float) -> int:\n", " result = 0\n", " for k in range(n): # sum of n iid samples from Bernoulli(p)\n", " result += bernoulli(p)\n", " return result" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For example :" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "[0, 1, 2, 0, 1]" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[ naive_binomial(10, 0.1) for _ in range(5) ]" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[8, 4, 6, 5, 8]" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[ naive_binomial(10, 0.5) for _ in range(5) ]" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[10, 9, 8, 10, 10]" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[ naive_binomial(10, 0.9) for _ in range(5) ]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can quickly illustrate the generated distribution, to check it has the correct \"shape\":" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "
" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/plain": [ "(array([254., 0., 378., 0., 248., 0., 92., 0., 24., 4.]),\n", " array([0. , 0.5, 1. , 1.5, 2. , 2.5, 3. , 3.5, 4. , 4.5, 5. ]),\n", " )" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/plain": [ "Text(0.5, 1.0, '1000 samples from a Binomial distribution with n = 10 and p = 0.12345.')" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAcUAAAEICAYAAAAut+/uAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvOIA7rQAAHQtJREFUeJzt3Xv8ZXVd7/HXm+GiAgbKRDCDjilp4knwTEhJRpKKeAHLCDJEo0ZP0NG0Y3gp4SAdtJN4rCTHICAvyPHykIBMDiJEBjTYCAwXm3SIGQZm5D6KGPA5f6zvTzbb353f77f37zev5+OxH7+97p+19trrvdZ3rdmTqkKSJME2gy5AkqRhYShKktQYipIkNYaiJEmNoShJUmMoSpLUGIpTkOSsJO+f4Xk+McnfJbk3yf+dyXkPQpI1SQ4a5uUmqSTPmuS4Jyb5RHv/tCRbkix6HKX2zvuvkvxRe39QkvUzMd82v19IcvNMzW+ml59kWfsctp3LuuarJOuS/PKg69gaTBiKSY5PsirJg0nOGmX4wUluSvK9JJcmeXrPsB2SnJnkviS3J3n7ZKfdirwO2B14alX92qCLGU/PgWxLe92R5KNJthsZp6r2qaqvznVtc7HcqvqPqtqpqh4eb7wkb0xyxSTm95aqOnkmausP+qr6x6p69kzMezr6lz8fDupJtk/y2VZr9Z9kpfOBJHe21weSZEDlzrmpHK+TnJzkuiQPJTmxb9grk1yR5J6WC3+dZOee4R9McmvLjVuSvHuMZbyhfU6/3dPvxCT/2XOM2pLkJ6eynpO5UrwNeD9w5ihF7QZ8Hvgj4CnAKuAzPaOcCOwNPB34JeCdSQ6Z5LRbi6cD36yqh0YbOKRn0rtU1U7AfwF+DjhuwPXMOzN1takZdwXwm8DtowxbARwOPB/4GeDVwJvnrrTBmcbxei3wTuDCUYb9GF2m7An8NLAE+NOe4WcAz6mqJwM/D7w+ya/01bMr8G5gzSjz/0w7eR15fWsSq/ioqprUq63EWX39VgBf6+neEXigrRB0gfqynuEnA+dOZtpRlv+HwAbgfuBm4ODWf3/gn4F7gI3AXwDb90xXwO8C/9amPRl4JvA14D7gvJHxgYOA9W1jfwdYB7y+Z15nAe/v6X4VsLot+2vAz0xUb986nQT8APhPYAtwLPBG4J+A04A723bfBngvcAuwCTgH+LE2j2VtHd8E3ArcDbwF+Fng2lbbX4zzuY67/frGHVnWtj39Pgis7OleB/xye39i277ntO2wBljeM+5PA19ty14DvKZvW38U+Pu2bf4J+Angw20dbwL2G2O5k9knnjXGOj4DuKzVe3Gb9hOjrX/7rL7Vxv028Pq2Tt8HHm5139OzPqcDFwHfBX6Znv2Jife9rwK/3dP9RuCK9v7yVtd32zJ/fWR+U9jWf0l3ALsfuAp45hjb52zgHe39krbc41r3M4G76PbXHy4f+FvgEbrv9xa6g+XItjwG+I+2zu8ZZz+ddI0z8WqfxUF9/b4GrOjpPha4cozpdwUuADbT7a8XAEv7Ps+T6fbr+4EvA7v1DD+a7vt+J/AeevbvMbbNX9Htr/fT7b9Pn+HtMaXjdc94nwBOnGCcXwGuG2PYEuA64J19/f+K7rje/704kfZ9ne7r8d5T3Af4xkhHVX0X+Hdgn5bke/QOb+/3mWja/oUkeTZwPPCzVbUz8HK6nQS6g8/vA7vRXbUcTLexer0c+K/AAXRfyJV0Z4N7Ac8DjuoZ9yfavJbQfWFXtuX317Qf3dXzm4GnAh8Dzm9NxuPV+0NV9T7gT3j0zOaMNuiFdAfb3YFT6A6Ab6S72v5JYCe6g3WvF9Jdlf86XXC8h+7Auw9wRJJf7F9+M5ntN6oke7Z1u3Kc0V4DnAvsApw/Undrcv07uoPBjwO/B3yyb1sfQXcysBvwIF3Qfb11fxb40EyvE/Ap4Jo27cl0+8CPSLIj8BHgFe0z/nlgdVXdSHdS8s/tM92lZ7LfoPs8d6a7Iuk3qX2vX1W9uL19flvmY87gJ7mtj6Q7SduV7iz/lDEWdxld4AH8It1++uKe7n+sqkf66juaLvhe3er7YM/gA4Fn031Gf5zkp8dZ1cnWSGuaG+t1wjjLGM9jjlk89njWbxvgb+hagp5GFyD939nfoDuZ/XFge+APWu3PpTuBOpruauqpwNIJans93f66G92J+ifHGnGa22bSx+tpeDF9V3xJTkiyhe7kZEe67+XIsP2B5XTBOJpXJ7kr3XMG/22qxTzeUNwJuLev3710X/qderr7h000bb+HgR2A5ybZrqrWVdW/A1TVNVV1ZVU9VFXr6MKpPwA+WFX3VdUa4Hrgy1X1raq6l+5KZL++8f+oqh6sqsvozkyPGKWmFcDHquqqqnq4qs6mO3AfMF69k3RbVf15W6cH6Hb4D7WatwDvAo7sa1o9uaq+X1Vfprti+HRVbaqqDcA/jrKOwKS3X7/vJLmH7kr4u3QBNZYrquqi6u7D/S1d0xN022kn4NSq+kFVfYXubLr3BOULrb7vA18Avl9V57R5fWaG14kkT6O7wh75/C+nC5OxPAI8L8kTq2pj27/G88Wq+qeqeqSt02gms+9N1WS39dXVNeN/Eth3jHldBhyYZBu6g9kHgRe1Yb/Yhk/FSVX1QFV9g+6g+/xxxp1sjVTVLuO8Tp1ijSP6j1n3AjuNdl+xqu6sqs9V1feq6n66AO/fB/+mqr7ZvuPn9azP64ALquryqnqQrsnyEcZ3Yc/47wF+Lsleo404zW0zleP1pCV5Kd0J4B/31Xhqm/cL6I4b97bxF9G1IB3ff/LVnEfXKrIY+B26E62jRhlvTI83FLcAT+7r92S6S/gtPd39wyaa9jGqai3wNrpL401Jzm1XKST5qSQXtBu299Fdee3WN4s7et4/MEr3Tj3dd7ezoBG30J2t9Xs68I7esyy6K889x6t3km7t696z1dFb07Z0V5IjprKOPzTJ7ddvt3YF9CS65p9/GGfc3nsz3wOe0MJ8T+DWvh37FrqrpEGsE62m0T7/H9HG+XW6q8KNSS5M8pwJ5t//ufab7L43VZPZ1v2f06jbtp3cfZfuAP4LdOF6W7vqnE4oTmq50xh3NvQfs54MbKmqH/lfFZI8KcnH2oMi99E1ce/Sdy95rPXZk559pe0Td05QW+/4W+iasWdi3xkx6eP1ZCU5gO4K8HVV9c3+4dX5V7rv+kmt9+8C11bVqK1TVXVDVd3WLlS+BvwfupOMSXu8obiGnjO71qT0TGBNVd1Ndz+n98zv+Tx6mTzmtKMtqKo+VVUH0oVRAR9og06nu7+0d3U3Zt8NPJ4nwnZttYx4Gt290X63Aqf0nWU9qao+PUG9k9H/Jbutzae3pod4bEhM17S3XzvDPQs4oN2In4rbgL3aFceIp9FdfT5e012njYz++Y+qqv6hql5Kd5vgJuDjI4PGmmSC5Y+3732X7iRkxE9MMK9eM72tL6M70GzfWiIuozvb35Wu6W40c/rf8fQ9fdj/GvVpxkl4zDGLxx7P+r2Drln4hW0fHGlinux++MOrvCRPomtCHU/v+DvRPQwz2nFruttmSsfribTbT+cDv1VVl0ww+rZtWdA1s7+2nfDeTnfb4s+S9DdNjyimmAeT+ScZ2yZ5ArAIWJRk5Ewfuiat5yX51TbOH9Ol+E1t+DnAe5Ps2s6if4fuIDqZaXtreHaSlyTZge4hhgd4tDlhZ7oHZra0ZUy5DXkUJ6V7PPsX6B6mGe3fD34ceEuSF6azY7pHjXeeoN7p+DTw+0me0Xb4kfuQoz6xOkXT3n5t/Y6mO+Od6Ey231V0Z8fvTLJdusffX013//HxmtY6VdUtdE/VjXz+B7aafkSS3ZMc1g4OD9KdSY98xncAS5NsP43ax9r3VgO/0q5AnkX3kEevO+juN49mprf1ZXT3zC9v3V9t3VfU2P9cZbz6Zlw99unD/tefjDVdumcCntA6t2/Hu5GD6jnA25MsaS0/7+DR41m/nem+9/ckeQrwvimU/1ngVUkObPvQ/2TiY/WhPeOfTPcA0KgtE9PcNpM+XkN3H7uNtw2wbduOi9qw5wFfAn6vqv6ub7ptkry5ZUbS3T88DhgJzjfSNY/u216r6K4i39OmP6xv2v8OfHGCbfcYk7lSfC/dh3sC3cMpD7R+VNVm4Ffp2svvpnvY48iead9HdzP2Frov0p9W1ZcmOW2vHYBT6Z5Qu53uxvS72rA/oLthfT9dUD3ef9Zxe6vnNrr7Fm8Z7YOvqlV0If8Xbfy1dB/YRPVOx5l07eqX0z3l+H26hyVmwnS23z3pboLfQfcgy2tGa0IaT1X9gO7A/Aq67fRR4A1jfcmm6PHsE79Bty/eRbf/njPGeNsAb6fbT+6iazocCd+v0J1B357kO1NY9nj73ml0TyrfQfcEaP+DFCcCZ6dryn/MfchZ2NaX0R30R0LxCrqr2MvHnAL+F90J8j1J/mCay50LN9Md45bQ3RZ4gEdbaT5Gd4/5OrpnEy5s/UbzYeCJdNv7SroQmJR2b/o4uqbFjXT7xEQ/7PApuv31LrqHCn9zssubZE3jHq/T/RBF74MvH6fbdkfRBdYDdCfQ0J1MLAbO6LlC7b3ifC1dbtxP9/Tqn7cXVXVPVd0+8qL7TtxX3fMhtJrWtmnPAT5Q3fMeI3VuaSecY8oUj2ULWjuD/kRVTfSklyQNhXQ/qrK+qt476FoWAn/mTZKkxlCUJKmx+VSSpMYrRUmSmmH8selZtdtuu9WyZcsGXYYkzRvXXHPNd6pq8aDrmAtbXSguW7aMVatWDboMSZo3koz6y04Lkc2nkiQ1hqIkSY2hKElSYyhKktQYipIkNYaiJEmNoShJUmMoSpLUGIqSJDVb3S/aaGqWnXDhQJa77tRXDmS5krZuXilKktQYipIkNYaiJEmNoShJUmMoSpLUGIqSJDWGoiRJjaEoSVJjKEqS1BiKkiQ1hqIkSc3QhGKSJyS5Osk3kqxJclLrf1aSbydZ3V77tv5J8pEka5Ncm+QFg10DSdJ8N0w/CP4g8JKq2pJkO+CKJH/fhv2Pqvps3/ivAPZurxcCp7e/kiRNy9BcKVZnS+vcrr1qnEkOA85p010J7JJkj9muU5K0cA1NKAIkWZRkNbAJuLiqrmqDTmlNpKcl2aH1WwLc2jP5+tZvtPmuSLIqyarNmzfPWv2SpPltqEKxqh6uqn2BpcD+SZ4HvAt4DvCzwFOAP5zGfFdW1fKqWr548eIZrVmStHAMVSiOqKp7gEuBQ6pqY2sifRD4G2D/NtoGYK+eyZa2fpIkTcvQhGKSxUl2ae+fCLwUuGnkPmGSAIcD17dJzgfe0J5CPQC4t6o2DqB0SdICMUxPn+4BnJ1kEV1Yn1dVFyT5SpLFQIDVwFva+BcBhwJrge8BbxpAzZKkBWRoQrGqrgX2G6X/S8YYv4DjZrsuSdLWY2iaTyVJGjRDUZKkxlCUJKkxFCVJagxFSZIaQ1GSpMZQlCSpMRQlSWoMRUmSGkNRkqTGUJQkqTEUJUlqDEVJkhpDUZKkxlCUJKkxFCVJagxFSZIaQ1GSpGaoQjHJE5JcneQbSdYkOan1f0aSq5KsTfKZJNu3/ju07rVt+LJB1i9Jmt+GKhSBB4GXVNXzgX2BQ5IcAHwAOK2qngXcDRzbxj8WuLv1P62NJ0nStAxVKFZnS+vcrr0KeAnw2db/bODw9v6w1k0bfnCSzFG5kqQFZqhCESDJoiSrgU3AxcC/A/dU1UNtlPXAkvZ+CXArQBt+L/DUUea5IsmqJKs2b94826sgSZqnhi4Uq+rhqtoXWArsDzxnBua5sqqWV9XyxYsXP+4aJUkL09CF4oiquge4FPg5YJck27ZBS4EN7f0GYC+ANvzHgDvnuFRJ0gIxVKGYZHGSXdr7JwIvBW6kC8fXtdGOAb7Y3p/fumnDv1JVNXcVS5IWkm0nHmVO7QGcnWQRXWCfV1UXJLkBODfJ+4F/Bc5o458B/G2StcBdwJGDKFqStDAMVShW1bXAfqP0/xbd/cX+/t8Hfm0OSpMkbQWGqvlUkqRBMhQlSWoMRUmSGkNRkqTGUJQkqTEUJUlqDEVJkhpDUZKkxlCUJKkxFCVJagxFSZIaQ1GSpMZQlCSpMRQlSWoMRUmSGkNRkqTGUJQkqTEUJUlqDEVJkpqhCcUkeyW5NMkNSdYkeWvrf2KSDUlWt9ehPdO8K8naJDcnefngqpckLQTbDrqAHg8B76iqryfZGbgmycVt2GlV9b97R07yXOBIYB9gT+D/Jfmpqnp4tgpcdsKFszXrca079ZUDWa4kbW2G5kqxqjZW1dfb+/uBG4El40xyGHBuVT1YVd8G1gL7z36lkqSFamhCsVeSZcB+wFWt1/FJrk1yZpJdW78lwK09k61njBBNsiLJqiSrNm/ePEtVS5Lmu2FqPgUgyU7A54C3VdV9SU4HTgaq/f0z4LemMs+qWgmsBFi+fHnNbMVaaGwml7ZeQ3WlmGQ7ukD8ZFV9HqCq7qiqh6vqEeDjPNpEugHYq2fypa2fJEnTMjShmCTAGcCNVfWhnv579Iz2WuD69v584MgkOyR5BrA3cPVc1StJWniGqfn0RcDRwHVJVrd+7waOSrIvXfPpOuDNAFW1Jsl5wA10T64eN5tPnkqSFr6hCcWqugLIKIMuGmeaU4BTZq0oSdJWZWiaTyVJGjRDUZKkxlCUJKkxFCVJagxFSZIaQ1GSpMZQlCSpMRQlSWoMRUmSGkNRkqTGUJQkqTEUJUlqDEVJkhpDUZKkxlCUJKkxFCVJagxFSZIaQ1GSpGZoQjHJXkkuTXJDkjVJ3tr6PyXJxUn+rf3dtfVPko8kWZvk2iQvGOwaSJLmu6EJReAh4B1V9VzgAOC4JM8FTgAuqaq9gUtaN8ArgL3bawVw+tyXLElaSIYmFKtqY1V9vb2/H7gRWAIcBpzdRjsbOLy9Pww4pzpXArsk2WOOy5YkLSBDE4q9kiwD9gOuAnavqo1t0O3A7u39EuDWnsnWt36jzW9FklVJVm3evHlWapYkzX9DF4pJdgI+B7ytqu7rHVZVBdRU51lVK6tqeVUtX7x48QxVKklaaIYqFJNsRxeIn6yqz7fed4w0i7a/m1r/DcBePZMvbf0kSZqWoQnFJAHOAG6sqg/1DDofOKa9Pwb4Yk//N7SnUA8A7u1pZpUkacq2HXQBPV4EHA1cl2R16/du4FTgvCTHArcAR7RhFwGHAmuB7wFvmttyJUkLzdCEYlVdAWSMwQePMn4Bx81qUZKkrcrQNJ9KkjRohqIkSY2hKElSYyhKktQYipIkNYaiJEmNoShJUmMoSpLUGIqSJDWGoiRJjaEoSVJjKEqS1BiKkiQ1hqIkSY2hKElSYyhKktQYipIkNYaiJEnNUIVikjOTbEpyfU+/E5NsSLK6vQ7tGfauJGuT3Jzk5YOpWpK0UAxVKAJnAYeM0v+0qtq3vS4CSPJc4EhgnzbNR5MsmrNKJUkLzlCFYlVdDtw1ydEPA86tqger6tvAWmD/WStOkrTgDVUojuP4JNe25tVdW78lwK0946xv/SRJmpb5EIqnA88E9gU2An821RkkWZFkVZJVmzdvnun6JEkLxNCHYlXdUVUPV9UjwMd5tIl0A7BXz6hLW7/R5rGyqpZX1fLFixfPbsGSpHlr6EMxyR49na8FRp5MPR84MskOSZ4B7A1cPdf1SZIWjm0HXUCvJJ8GDgJ2S7IeeB9wUJJ9gQLWAW8GqKo1Sc4DbgAeAo6rqocHUbckaWEYqlCsqqNG6X3GOOOfApwyexVJkrYmQ998KknSXDEUJUlqDEVJkhpDUZKkxlCUJKkxFCVJagxFSZIaQ1GSpMZQlCSpMRQlSWoMRUmSGkNRkqTGUJQkqTEUJUlqDEVJkhpDUZKkxlCUJKkxFCVJagxFSZKaoQrFJGcm2ZTk+p5+T0lycZJ/a393bf2T5CNJ1ia5NskLBle5JGkhGKpQBM4CDunrdwJwSVXtDVzSugFeAezdXiuA0+eoRknSAjVUoVhVlwN39fU+DDi7vT8bOLyn/znVuRLYJckec1OpJGkhGqpQHMPuVbWxvb8d2L29XwLc2jPe+tbvRyRZkWRVklWbN2+evUolSfPafAjFH6qqAmoa062squVVtXzx4sWzUJkkaSGYD6F4x0izaPu7qfXfAOzVM97S1k+SpGmZD6F4PnBMe38M8MWe/m9oT6EeANzb08wqSdKUbTvoAnol+TRwELBbkvXA+4BTgfOSHAvcAhzRRr8IOBRYC3wPeNOcFywtAMtOuHBgy1536isHtmxpNEMVilV11BiDDh5l3AKOm92KJElbk/nQfCpJ0pwwFCVJagxFSZIaQ1GSpMZQlCSpMRQlSWoMRUmSGkNRkqTGUJQkqTEUJUlqDEVJkhpDUZKkxlCUJKkxFCVJagxFSZIaQ1GSpMZQlCSpMRQlSWq2HXQBk5VkHXA/8DDwUFUtT/IU4DPAMmAdcERV3T2oGiVJ89t8u1L8parat6qWt+4TgEuqam/gktYtSdK0zLdQ7HcYcHZ7fzZw+ABrkSTNc/MpFAv4cpJrkqxo/Xavqo3t/e3A7qNNmGRFklVJVm3evHkuapUkzUPz5p4icGBVbUjy48DFSW7qHVhVlaRGm7CqVgIrAZYvXz7qOJIkzZsrxara0P5uAr4A7A/ckWQPgPZ30+AqlCTNd/MiFJPsmGTnkffAy4DrgfOBY9poxwBfHEyFkqSFYL40n+4OfCEJdDV/qqq+lORfgPOSHAvcAhwxwBolSfPcvAjFqvoW8PxR+t8JHDz3FUmSFqJ50XwqSdJcMBQlSWoMRUmSGkNRkqTGUJQkqTEUJUlqDEVJkhpDUZKkxlCUJKmZF79oI0kzadkJFw5s2etOfeXAlq2JeaUoSVJjKEqS1BiKkiQ1hqIkSY2hKElSYyhKktQYipIkNYaiJEmNoShJUjPvQzHJIUluTrI2yQmDrkeSNH/N6595S7II+EvgpcB64F+SnF9VNwy2Mkka3aB+Ys6fl5uc+X6luD+wtqq+VVU/AM4FDhtwTZKkeSpVNegapi3J64BDquq3W/fRwAur6vi+8VYAK1rns4Gbp7nI3YDvTHPa+cp1Xvi2tvUF13mqnl5Vi2eymGE1r5tPJ6uqVgIrH+98kqyqquUzUNK84TovfFvb+oLrrLHN9+bTDcBePd1LWz9JkqZsvofivwB7J3lGku2BI4HzB1yTJGmemtfNp1X1UJLjgX8AFgFnVtWaWVzk426CnYdc54Vva1tfcJ01hnn9oI0kSTNpvjefSpI0YwxFSZIaQ3EStsafkktyZpJNSa4fdC1zIcleSS5NckOSNUneOuiaZluSJyS5Osk32jqfNOia5kqSRUn+NckFg65lLiRZl+S6JKuTrBp0PcPMe4oTaD8l9016fkoOOGqh/5RckhcDW4Bzqup5g65ntiXZA9ijqr6eZGfgGuDwhfw5JwmwY1VtSbIdcAXw1qq6csClzbokbweWA0+uqlcNup7ZlmQdsLyqtrYfLJgyrxQntlX+lFxVXQ7cNeg65kpVbayqr7f39wM3AksGW9Xsqs6W1rldey34s+QkS4FXAn896Fo0fAzFiS0Bbu3pXs8CP1hu7ZIsA/YDrhpsJbOvNSOuBjYBF1fVgl9n4MPAO4FHBl3IHCrgy0muaT97qTEYilKPJDsBnwPeVlX3Dbqe2VZVD1fVvnS/BrV/kgXdVJ7kVcCmqrpm0LXMsQOr6gXAK4Dj2u0RjcJQnJg/JbeVaPfVPgd8sqo+P+h65lJV3QNcChwy6Fpm2YuA17R7bOcCL0nyicGWNPuqakP7uwn4At1tIY3CUJyYPyW3FWgPnZwB3FhVHxp0PXMhyeIku7T3T6R7mOymwVY1u6rqXVW1tKqW0X2Xv1JVvzngsmZVkh3bw2Mk2RF4GbBVPFU+HYbiBKrqIWDkp+RuBM6b5Z+SGwpJPg38M/DsJOuTHDvommbZi4Cj6a4cVrfXoYMuapbtAVya5Fq6k7+Lq2qr+CcKW5ndgSuSfAO4Griwqr404JqGlv8kQ5KkxitFSZIaQ1GSpMZQlCSpMRQlSWoMRUmSGkNRkqTGUJQkqfn/Cax7R7zpdrUAAAAASUVORK5CYII=\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "m = 1000\n", "n = 10\n", "p = 0.12345\n", "X = [ naive_binomial(n, p) for _ in range(m) ]\n", "plt.figure()\n", "plt.hist(X)\n", "plt.title(f\"{m} samples from a Binomial distribution with n = {n} and p = {p}.\")\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "
" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/plain": [ "(array([ 1., 10., 41., 98., 215., 236., 219., 116., 51., 13.]),\n", " array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.]),\n", " )" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/plain": [ "Text(0.5, 1.0, '1000 samples from a Binomial distribution with n = 10 and p = 0.5.')" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "m = 1000\n", "n = 10\n", "p = 0.5\n", "X = [ naive_binomial(n, p) for _ in range(m) ]\n", "plt.figure()\n", "plt.hist(X)\n", "plt.title(f\"{m} samples from a Binomial distribution with n = {n} and p = {p}.\")\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "
" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/plain": [ "(array([ 1., 0., 0., 5., 0., 0., 101., 0., 0., 893.]),\n", " array([ 7. , 7.3, 7.6, 7.9, 8.2, 8.5, 8.8, 9.1, 9.4, 9.7, 10. ]),\n", " )" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/plain": [ "Text(0.5, 1.0, '1000 samples from a Binomial distribution with n = 10 and p = 0.98765.')" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "m = 1000\n", "n = 10\n", "p = 0.98765\n", "X = [ naive_binomial(n, p) for _ in range(m) ]\n", "plt.figure()\n", "plt.hist(X)\n", "plt.title(f\"{m} samples from a Binomial distribution with n = {n} and p = {p}.\")\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## The generator included in `numpy.random`" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [], "source": [ "def numpy_binomial(n: int, p: float) -> int:\n", " return np.random.binomial(n, p)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's try this out:" ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "[1, 1, 0, 1, 1]" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[ numpy_binomial(10, 0.1) for _ in range(5) ]" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[4, 6, 7, 6, 5]" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[ numpy_binomial(10, 0.5) for _ in range(5) ]" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[9, 9, 10, 8, 9]" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[ numpy_binomial(10, 0.9) for _ in range(5) ]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's plot this out also." ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "
" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/plain": [ "(array([288., 343., 0., 245., 0., 96., 22., 0., 5., 1.]),\n", " array([0. , 0.6, 1.2, 1.8, 2.4, 3. , 3.6, 4.2, 4.8, 5.4, 6. ]),\n", " )" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/plain": [ "Text(0.5, 1.0, '1000 samples from a Binomial distribution with n = 10 and p = 0.12345.')" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAcUAAAEICAYAAAAut+/uAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvOIA7rQAAHb5JREFUeJzt3Xu4HHWd5/H3hwQQCRowRwxJIAxmUHCHwGYAR1QGvHBRg46DoCK6ONEdcHXEdQJegEVmg7OC4zii0SCJcjGL8oDAqCwiGB1gAkYgXDRimCTkJhBIuDmE7/7x+x6oNH3O6dPn0pd8Xs/Tz+m6dX2ruro+Vb+q062IwMzMzGCbVhdgZmbWLhyKZmZmyaFoZmaWHIpmZmbJoWhmZpYcimZmZsmhOAiSLpL0hWF+zR0k/VDSo5L+73C+ditIWirp0Haer6SQ9MoGxz1T0nfz+e6SNkkaM4RSq6/9dUmfy+eHSlo5HK+br/d6SfcN1+sN9/wlTc33Yexo1tWpJC2X9KZW17E1GDAUJZ0iabGkpyVdVGf44ZLulfSEpBsk7VEZtr2kCyU9JmmNpE82Ou1W5N3ArsDLIuKvW11Mfyo7sk35WCvpa5K27R0nIvaNiJ+Ndm2jMd+I+I+IGBcRm/sbT9IHJS1q4PU+GhFnD0dttUEfET+PiL2H47WbUTv/TtipS9pO0uVZa9QeZKk4V9JD+ThXklpU7qgbzP5a0tmS7pT0jKQza4YdLWmRpA2ZC9+StFNl+BclrcjceEDS6X3M4wP5Pn240u9MSf9Z2UdtkvQng1nORs4UHwS+AFxYp6gJwA+AzwG7AIuB71VGOROYBuwB/CXwaUlHNDjt1mIP4DcR8Uy9gW16JD0+IsYB/wV4LXByi+vpOMN1tmnDbhHwfmBNnWGzgGOA/YA/A94OfGT0SmudJvbXy4BPA9fUGfZSSqbsBrwamAT8Y2X4POBVEfES4C+A90l6V009OwOnA0vrvP738uC193F/A4v4vIho6JELcVFNv1nALyvdOwJP5gJBCdS3VIafDVzWyLR15v/3wCpgI3AfcHj2PxD4N2ADsBr4KrBdZboA/hb4bU57NrAX8EvgMWBh7/jAocDKXNl/AJYD76u81kXAFyrdbwOW5Lx/CfzZQPXWLNNZwB+B/wQ2AScBHwR+AZwPPJTrfRvgs8ADwDpgAfDSfI2puYwfAlYAjwAfBf4cuCNr+2o/72u/669m3N55ja30+yIwt9K9HHhTPj8z1++CXA9LgRmVcV8N/CznvRR4R826/hrwr7lufgG8AvhyLuO9wP59zLeRbeKVfSzjnsCNWe91Oe136y1/vlf357i/B96Xy/QUsDnr3lBZnguAa4HHgTdR2Z4YeNv7GfDhSvcHgUX5/Kas6/Gc53t6X28Q6/pfKDuwjcAtwF59rJ/5wKn5fFLO9+Ts3gt4mLK9Pjd/4DvAs5TP9ybKzrJ3XZ4I/Ecu82f62U4brnE4HvleHFrT75fArEr3ScDNfUy/M3A1sJ6yvV4NTK55P8+mbNcbgZ8AEyrDT6B83h8CPkNl++5j3Xydsr1upGy/ewzz+hjU/roy3neBMwcY513AnX0MmwTcCXy6pv/XKfv12s/FmeTntdnHUK8p7gv8urcjIh4Hfgfsm0k+sTo8n+870LS1M5G0N3AK8OcRsRPwVspGAmXn83fABMpZy+GUlVX1VuC/AgdTPpBzKUeDU4DXAMdXxn1FvtYkygd2bs6/tqb9KWfPHwFeBnwDuCqbjPur9zkRcQbwDzx/ZDMvBx1E2dnuCpxD2QF+kHK2/SfAOMrOuuogyln5eyjB8RnKjndf4FhJb6ydf2pk/dUlabdctpv7Ge0dwGXAeOCq3rqzyfWHlJ3By4GPARfXrOtjKQcDE4CnKUF3e3ZfDpw33MsEXALcltOeTdkGXkDSjsBXgCPzPf4LYElE3EM5KPm3fE/HVyZ7L+X93IlyRlKroW2vVkS8IZ/ul/Pc4gi+wXV9HOUgbWfKUf45fczuRkrgAbyRsp2+odL984h4tqa+EyjB9/as74uVwYcAe1Peo89LenU/i9pojWTTXF+P2f3Moz9b7LPYcn9Waxvg25SWoN0pAVL7mX0v5WD25cB2wKey9n0oB1AnUM6mXgZMHqC291G21wmUA/WL+xqxyXXT8P66CW+g5oxP0mxJmygHJztSPpe9ww4EZlCCsZ63S3pY5T6D/z7YYoYaiuOAR2v6PUr50I+rdNcOG2jaWpuB7YF9JG0bEcsj4ncAEXFbRNwcEc9ExHJKONUGwBcj4rGIWArcBfwkIu6PiEcpZyL714z/uYh4OiJupByZHlunplnANyLilojYHBHzKTvug/urt0EPRsQ/5zI9Sdngz8uaNwGnAcfVNK2eHRFPRcRPKGcMl0bEuohYBfy8zjICDa+/Wn+QtIFyJvw4JaD6sigiro1yHe47lKYnKOtpHDAnIv4YET+lHE1XD1CuyPqeAq4AnoqIBfla3xvmZULS7pQz7N73/yZKmPTlWeA1knaIiNW5ffXnyoj4RUQ8m8tUTyPb3mA1uq5vjdKMfzEwvY/XuhE4RNI2lJ3ZF4HX5bA35vDBOCsinoyIX1N2uvv1M26jNRIR4/t5zBlkjb1q91mPAuPqXVeMiIci4vsR8UREbKQEeO02+O2I+E1+xhdWlufdwNURcVNEPE1psnyW/l1TGf8zwGslTak3YpPrZjD764ZJejPlAPDzNTXOydc+gLLfeDTHH0NpQTql9uArLaS0ivQAf0M50Dq+znh9GmoobgJeUtPvJZRT+E2V7tphA027hYhYBnyCcmq8TtJleZaCpD+VdHVesH2McuY1oeYl1laeP1mne1yl+5E8Cur1AOVordYewKnVoyzKmedu/dXboBU13btlHdWaxlLOJHsNZhmf0+D6qzUhz4BeTGn++XE/41avzTwBvCjDfDdgRc2G/QDlLKkVy0TWVO/9f4Ec5z2Us8LVkq6R9KoBXr/2fa3V6LY3WI2s69r3qe66zYO7xyk78NdTwvXBPOtsJhQbmm8T446E2n3WS4BNEfGCX1WQ9GJJ38gbRR6jNHGPr7mW3Nfy7EZlW8lt4qEBaquOv4nSjD0c206vhvfXjZJ0MOUM8N0R8Zva4VH8ivJZPyt7/y1wR0TUbZ2KiLsj4sE8Ufkl8E+Ug4yGDTUUl1I5sssmpb2ApRHxCOV6TvXIbz+eP03uc9p6M4qISyLiEEoYBXBuDrqAcn1pWpQLs6cDQ7kjbOespdfulGujtVYA59QcZb04Ii4doN5G1H7IHszXqdb0DFuGRLOaXn95hHsRcHBeiB+MB4EpecbRa3fK2edQNbtMq6n//tcVET+OiDdTLhPcC3yzd1Bfkwww//62vccpByG9XjHAa1UN97q+kbKj2S5bIm6kHO3vTGm6q2dUf46n5u7D2kfduxkbsMU+iy33Z7VOpTQLH5TbYG8Tc6Pb4XNneZJeTGlC7U91/HGUm2Hq7beaXTeD2l8PJC8/XQX8t4i4foDRx+a8oDSzvzMPeNdQLlt8SVJt03SvYJB50Mi/ZIyV9CJgDDBGUu+RPpQmrddI+qsc5/OUFL83hy8APitp5zyK/hvKTrSRaas17C3pMEnbU25ieJLnmxN2otwwsynnMeg25DrOUrk9+/WUm2nq/f/gN4GPSjpIxY4qtxrvNEC9zbgU+DtJe+YG33sdsu4dq4PU9PrL5TuBcsQ70JFsrVsoR8eflrStyu3vb6dcfxyqppYpIh6g3FXX+/4fkjW9gKRdJc3MncPTlCPp3vd4LTBZ0nZN1N7XtrcEeFeegbyScpNH1VrK9eZ6hntd30i5Zn5Tdv8suxdF3/+u0l99wy62vPuw9vEPfU2nck/Ai7Jzu9zf9e5UFwCflDQpW35O5fn9Wa2dKJ/7DZJ2Ac4YRPmXA2+TdEhuQ/+LgffVR1XGP5tyA1Ddlokm103D+2so17FzvG2Asbkex+Sw1wA/Aj4WET+smW4bSR/JzJDK9cOTgd7g/CCleXR6PhZTziI/k9PPrJn2fwBXDrDuttDImeJnKW/ubMrNKU9mPyJiPfBXlPbyRyg3exxXmfYMysXYBygfpH+MiB81OG3V9sAcyh1qaygXpk/LYZ+iXLDeSAmqof5bx5qs50HKdYuP1nvjI2IxJeS/muMvo7xhA9XbjAsp7eo3Ue5yfIpys8RwaGb9bVC5CL6WciPLO+o1IfUnIv5I2TEfSVlPXwM+0NeHbJCGsk28l7ItPkzZfhf0Md42wCcp28nDlKbD3vD9KeUIeo2kPwxi3v1te+dT7lReS7kDtPZGijOB+SpN+VtchxyBdX0jZaffG4qLKGexN/U5BfxvygHyBkmfanK+o+E+yj5uEuWywJM830rzDco15jsp9yZck/3q+TKwA2V930wJgYbktemTKU2LqynbxEBf7HAJZXt9mHJT4fsbnV+DNfW7v1b5IorqjS/fpKy74ymB9STlABrKwUQPMK9yhlo943wnJTc2Uu5e/ed8EBEbImJN74PymXgsyv0hZE3LctoFwLlR7vforXNTHnD2SYPcl3W1PIL+bkQMdKeXmVlbUPlSlZUR8dlW19IN/DVvZmZmyaFoZmaW3HxqZmaWfKZoZmaW2vHLpkfUhAkTYurUqa0uw8ysY9x2221/iIieVtcxGra6UJw6dSqLFy9udRlmZh1DUt1vdupGbj41MzNLbROK+Y0Ht0r6tcq3m5+V/S+S9HtJS/IxPftL0lckLZN0h6QDWrsEZmbW6dqp+fRp4LCI2KTyUzeLJP1rDvufEVH7SwxHUn4qaRrl2xUuyL9mZmZNaZszxfxG9N5f1tg2H/39v8hMYEFOdzPlG+gnjnSdZmbWvdomFKH8VpakJZRfl78uIm7JQedkE+n5+SXUUL6bsPqFtyvZ8qdwqq87S9JiSYvXr18/YvWbmVlna6tQzN/Amk75lekD89vUTwNeRfnx112Av2/idedGxIyImNHTs1XcVWxmZk1oq1DsFREbgBuAI6L8onnkL0p/GzgwR1tF5TfEKEE6HL/FZ2ZmW6m2CUVJPZLG5/MdgDcD9/ZeJ8zfNDuG8pMtUH6g8gN5F+rBwKMRsboFpZuZWZdop7tPJ1J+D24MJawXRsTVkn4qqYfy68lLgI/m+NcCR1F+O+sJ4EMtqNnMzLpI24RiRNwB7F+n/2F9jB+UH+LselNnX9OyeS+fc3TL5m1mNtrapvnUzMys1RyKZmZmyaFoZmaWHIpmZmbJoWhmZpYcimZmZsmhaGZmlhyKZmZmyaFoZmaWHIpmZmbJoWhmZpYcimZmZsmhaGZmlhyKZmZmyaFoZmaWHIpmZmbJoWhmZpYcimZmZsmhaGZmlhyKZmZmyaFoZmaWHIpmZmaprUJR0osk3Srp15KWSjor++8p6RZJyyR9T9J22X/77F6Ww6e2sn4zM+tsbRWKwNPAYRGxHzAdOELSwcC5wPkR8UrgEeCkHP8k4JHsf36OZ2Zm1pS2CsUoNmXntvkI4DDg8uw/Hzgmn8/MbnL44ZI0SuWamVmXaatQBJA0RtISYB1wHfA7YENEPJOjrAQm5fNJwAqAHP4o8LI6rzlL0mJJi9evXz/Si2BmZh2q7UIxIjZHxHRgMnAg8KpheM25ETEjImb09PQMuUYzM+tObReKvSJiA3AD8FpgvKSxOWgysCqfrwKmAOTwlwIPjXKpZmbWJdoqFCX1SBqfz3cA3gzcQwnHd+doJwJX5vOrspsc/tOIiNGr2MzMusnYgUcZVROB+ZLGUAJ7YURcLelu4DJJXwB+BczL8ecB35G0DHgYOK4VRZuZWXdoq1CMiDuA/ev0v59yfbG2/1PAX49CaWZmthVoq+ZTMzOzVmqrM8V2N3X2Na0uwczMRpDPFM3MzJJD0czMLDkUzczMkkPRzMwsORTNzMySQ9HMzCw5FM3MzJJD0czMLDkUzczMkkPRzMwsORTNzMySQ9HMzCw5FM3MzJJD0czMLDkUzczMkkPRzMwsORTNzMySQ9HMzCw5FM3MzFLbhKKkKZJukHS3pKWSPp79z5S0StKSfBxVmeY0Scsk3Sfpra2r3szMusHYVhdQ8QxwakTcLmkn4DZJ1+Ww8yPi/1RHlrQPcBywL7Ab8P8k/WlEbB7Vqs3MrGu0zZliRKyOiNvz+UbgHmBSP5PMBC6LiKcj4vfAMuDAka/UzMy6VduEYpWkqcD+wC3Z6xRJd0i6UNLO2W8SsKIy2Ur6CFFJsyQtlrR4/fr1I1S1mZl1urYLRUnjgO8Dn4iIx4ALgL2A6cBq4EuDfc2ImBsRMyJiRk9Pz7DWa2Zm3aOtQlHStpRAvDgifgAQEWsjYnNEPAt8k+ebSFcBUyqTT85+ZmZmTWmbG20kCZgH3BMR51X6T4yI1dn5TuCufH4VcImk8yg32kwDbh3Fkm0ETZ19TcvmvXzO0S2bt5m1VtuEIvA64ATgTklLst/pwPGSpgMBLAc+AhARSyUtBO6m3Ll6su88NTOzoWibUIyIRYDqDLq2n2nOAc4ZsaLMzGyr0lbXFM3MzFrJoWhmZpYcimZmZsmhaGZmlhyKZmZmyaFoZmaWHIpmZmbJoWhmZpYcimZmZsmhaGZmlhyKZmZmyaFoZmaWHIpmZmbJoWhmZpYcimZmZsmhaGZmlhyKZmZmyaFoZmaWHIpmZmbJoWhmZpYcimZmZqltQlHSFEk3SLpb0lJJH8/+u0i6TtJv8+/O2V+SviJpmaQ7JB3Q2iUwM7NO1zahCDwDnBoR+wAHAydL2geYDVwfEdOA67Mb4EhgWj5mAReMfslmZtZN2iYUI2J1RNyezzcC9wCTgJnA/BxtPnBMPp8JLIjiZmC8pImjXLaZmXWRtgnFKklTgf2BW4BdI2J1DloD7JrPJwErKpOtzH71Xm+WpMWSFq9fv35EajYzs87XdqEoaRzwfeATEfFYdVhEBBCDfc2ImBsRMyJiRk9PzzBVamZm3aatQlHStpRAvDgifpC91/Y2i+bfddl/FTClMvnk7GdmZtaUtglFSQLmAfdExHmVQVcBJ+bzE4ErK/0/kHehHgw8WmlmNTMzG7SxrS6g4nXACcCdkpZkv9OBOcBCSScBDwDH5rBrgaOAZcATwIdGt1wzM+s2bROKEbEIUB+DD68zfgAnj2hRZma2VWmb5lMzM7NWcyiamZklh6KZmVlyKJqZmSWHopmZWXIompmZJYeimZlZciiamZklh6KZmVlyKJqZmSWHopmZWXIompmZJYeimZlZciiamZklh6KZmVlyKJqZmSWHopmZWXIompmZJYeimZlZciiamZklh6KZmVlqq1CUdKGkdZLuqvQ7U9IqSUvycVRl2GmSlkm6T9JbW1O1mZl1i7YKReAi4Ig6/c+PiOn5uBZA0j7AccC+Oc3XJI0ZtUrNzKzrtFUoRsRNwMMNjj4TuCwino6I3wPLgANHrDgzM+t6bRWK/ThF0h3ZvLpz9psErKiMszL7vYCkWZIWS1q8fv36ka7VzMw6VCeE4gXAXsB0YDXwpcG+QETMjYgZETGjp6dnuOszM7Mu0fahGBFrI2JzRDwLfJPnm0hXAVMqo07OfmZmZk1p+1CUNLHS+U6g987Uq4DjJG0vaU9gGnDraNdnZmbdY2yrC6iSdClwKDBB0krgDOBQSdOBAJYDHwGIiKWSFgJ3A88AJ0fE5lbUbWZm3aGtQjEijq/Te14/458DnDNyFZmZ2dak7ZtPzczMRotD0czMLDkUzczMkkPRzMwsORTNzMySQ9HMzCw5FM3MzJJD0czMLDkUzczMkkPRzMwsORTNzMySQ9HMzCw5FM3MzJJD0czMLDkUzczMkkPRzMwsORTNzMySQ9HMzCw5FM3MzJJD0czMLDkUzczMUluFoqQLJa2TdFel3y6SrpP02/y7c/aXpK9IWibpDkkHtK5yMzPrBm0VisBFwBE1/WYD10fENOD67AY4EpiWj1nABaNUo5mZdam2CsWIuAl4uKb3TGB+Pp8PHFPpvyCKm4HxkiaOTqVmZtaN2ioU+7BrRKzO52uAXfP5JGBFZbyV2e8FJM2StFjS4vXr149cpWZm1tE6IRSfExEBRBPTzY2IGRExo6enZwQqMzOzbtAJobi2t1k0/67L/quAKZXxJmc/MzOzpoxtdQENuAo4EZiTf6+s9D9F0mXAQcCjlWZWs44zdfY1LZnv8jlHt2S+Zu2orUJR0qXAocAESSuBMyhhuFDSScADwLE5+rXAUcAy4AngQ6NesJmZdZW2CsWIOL6PQYfXGTeAk0e2IjMz25p0wjVFMzOzUeFQNDMzSw5FMzOz5FA0MzNLDkUzM7PkUDQzM0sORTMzs+RQNDMzSw5FMzOz5FA0MzNLDkUzM7PkUDQzM0sORTMzs+RQNDMzSw5FMzOz5FA0MzNLDkUzM7PkUDQzM0sORTMzs+RQNDMzSw5FMzOzNLbVBTRK0nJgI7AZeCYiZkjaBfgeMBVYDhwbEY+0qkYzM+tsnXam+JcRMT0iZmT3bOD6iJgGXJ/dZmZmTem0UKw1E5ifz+cDx7SwFjMz63CdFIoB/ETSbZJmZb9dI2J1Pl8D7Nqa0szMrBt0zDVF4JCIWCXp5cB1ku6tDoyIkBT1JswQnQWw++67j3ylZmbWkTrmTDEiVuXfdcAVwIHAWkkTAfLvuj6mnRsRMyJiRk9Pz2iVbGZmHaYjQlHSjpJ26n0OvAW4C7gKODFHOxG4sjUVmplZN+iU5tNdgSskQan5koj4kaR/BxZKOgl4ADi2hTWamVmH64hQjIj7gf3q9H8IOHz0KzIzs27UEc2nZmZmo8GhaGZmlhyKZmZmyaFoZmaWHIpmZmbJoWhmZpYcimZmZsmhaGZmlhyKZmZmyaFoZmaWHIpmZmbJoWhmZpY64gvBzWzkTJ19TcvmvXzO0S2bt1k9PlM0MzNLDkUzM7PkUDQzM0sORTMzs+RQNDMzSw5FMzOz5FA0MzNLDkUzM7PkUDQzM0sd/402ko4A/gkYA3wrIua0uCQza3P+Fh/rS0efKUoaA/wLcCSwD3C8pH1aW5WZmXWqTj9TPBBYFhH3A0i6DJgJ3N3SqszM+tCqs1SfoTZGEdHqGpom6d3AERHx4ew+ATgoIk6pGW8WMCs79wbua3KWE4A/NDltO+mW5QAvS7vqlmXpluWAoS3LHhHRM5zFtKtOP1NsSETMBeYO9XUkLY6IGcNQUkt1y3KAl6VddcuydMtyQHcty0jq6GuKwCpgSqV7cvYzMzMbtE4PxX8HpknaU9J2wHHAVS2uyczMOlRHN59GxDOSTgF+TPmXjAsjYukIznLITbBtoluWA7ws7apblqVblgO6a1lGTEffaGNmZjacOr351MzMbNg4FM3MzJJDsQGSjpB0n6Rlkma3up5mSbpQ0jpJd7W6lqGSNEXSDZLulrRU0sdbXVOzJL1I0q2Sfp3LclaraxoKSWMk/UrS1a2uZSgkLZd0p6Qlkha3up6hkDRe0uWS7pV0j6TXtrqmduVrigPIr5L7DfBmYCXljtfjI6LjvjVH0huATcCCiHhNq+sZCkkTgYkRcbuknYDbgGM69H0RsGNEbJK0LbAI+HhE3Nzi0poi6ZPADOAlEfG2VtfTLEnLgRkR0fH/vC9pPvDziPhW3qn/4ojY0Oq62pHPFAf23FfJRcQfgd6vkus4EXET8HCr6xgOEbE6Im7P5xuBe4BJra2qOVFsys5t89GRR6uSJgNHA99qdS1WSHop8AZgHkBE/NGB2DeH4sAmASsq3Svp0J1vt5I0FdgfuKW1lTQvmxyXAOuA6yKiU5fly8CngWdbXcgwCOAnkm7Lr4rsVHsC64FvZ7P2tyTt2Oqi2pVD0TqapHHA94FPRMRjra6nWRGxOSKmU76V6UBJHde8LeltwLqIuK3VtQyTQyLiAMqv8Jyclx860VjgAOCCiNgfeBzo2HsjRppDcWD+Krk2ldffvg9cHBE/aHU9wyGbtW4Ajmh1LU14HfCOvBZ3GXCYpO+2tqTmRcSq/LsOuIJyKaUTrQRWVlofLqeEpNXhUByYv0quDeXNKfOAeyLivFbXMxSSeiSNz+c7UG7qure1VQ1eRJwWEZMjYirlc/LTiHh/i8tqiqQd8wYusqnxLUBH3rUdEWuAFZL2zl6H45/X61NHf83baGjBV8mNGEmXAocCEyStBM6IiHmtrapprwNOAO7Ma3EAp0fEtS2sqVkTgfl5p/M2wMKI6Oh/Z+gCuwJXlGMvxgKXRMSPWlvSkHwMuDgP7O8HPtTietqW/yXDzMwsufnUzMwsORTNzMySQ9HMzCw5FM3MzJJD0czMLDkUzczMkkPRzMws/X9htrRCNJHIwgAAAABJRU5ErkJggg==\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "m = 1000\n", "n = 10\n", "p = 0.12345\n", "X = [ numpy_binomial(n, p) for _ in range(m) ]\n", "plt.figure()\n", "plt.hist(X)\n", "plt.title(f\"{m} samples from a Binomial distribution with n = {n} and p = {p}.\")\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "
" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/plain": [ "(array([ 2., 10., 46., 106., 218., 230., 211., 114., 51., 12.]),\n", " array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.]),\n", " )" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/plain": [ "Text(0.5, 1.0, '1000 samples from a Binomial distribution with n = 10 and p = 0.5.')" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "m = 1000\n", "n = 10\n", "p = 0.5\n", "X = [ naive_binomial(n, p) for _ in range(m) ]\n", "plt.figure()\n", "plt.hist(X)\n", "plt.title(f\"{m} samples from a Binomial distribution with n = {n} and p = {p}.\")\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "
" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/plain": [ "(array([ 7., 0., 0., 0., 0., 105., 0., 0., 0., 888.]),\n", " array([ 8. , 8.2, 8.4, 8.6, 8.8, 9. , 9.2, 9.4, 9.6, 9.8, 10. ]),\n", " )" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/plain": [ "Text(0.5, 1.0, '1000 samples from a Binomial distribution with n = 10 and p = 0.98765.')" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "m = 1000\n", "n = 10\n", "p = 0.98765\n", "X = [ naive_binomial(n, p) for _ in range(m) ]\n", "plt.figure()\n", "plt.hist(X)\n", "plt.title(f\"{m} samples from a Binomial distribution with n = {n} and p = {p}.\")\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## An efficient generator using the inverse transform method\n", "\n", "1. We start by computing the binomial coefficients and then the probability $\\mathbb{P}(X=k)$ for $k\\in\\{0,\\dots,n\\}$, if $X\\sim Bin(n, p)$, and,\n", "2. Then use this to write a generator of Binomial-distributed random values.\n", "3. This function is then simplified to inline all computations.\n", "4. We propose a fast and simple Cython implementation, to be as efficient as possible, and hopefully comparably efficient when compared against the implementation in Numpy." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Explicit computation of the probabilities" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [], "source": [ "def binomial_coefficient(n: int, k: int) -> int:\n", " \"\"\"From https://en.wikipedia.org/wiki/Binomial_coefficient#Binomial_coefficient_in_programming_languages\"\"\"\n", " if k < 0 or k > n:\n", " return 0\n", " if k == 0 or k == n:\n", " return 1\n", " k = min(k, n - k) # take advantage of symmetry\n", " c = 1\n", " for i in range(k):\n", " c = (c * (n - i)) / (i + 1)\n", " return c" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [], "source": [ "def proba_binomial(n: int, p: float, k: int) -> float:\n", " \"\"\"Compute {n \\choose k} p^k (1-p)^(n-k)\"\"\"\n", " q = 1.0 - p\n", " return binomial_coefficient(n, k) * p**k * q**(n-k)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### First function using the inversion method" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This first function is a generic implementation of the discrete inverse transform method.\n", "For more details, see [the Wikipedia page](https://en.wikipedia.org/wiki/Inverse_transform_sampling).\n", "\n", "> Inverse transformation sampling takes uniform samples of a number $u$ between $0$ and $1$, interpreted as a probability, and then returns the largest number $x$ from the domain of the distribution $\\mathbb{P}(X)$ such that $\\mathbb{P}(-\\infty int:\n", " probas = [ compute_proba(x) for x in range(xmin, xmax + 1) ]\n", " result = xmin\n", " current_proba = 0\n", " one_uniform_sample = uniform_01()\n", " while current_proba <= one_uniform_sample:\n", " current_proba += probas[result]\n", " result += 1\n", " return result - 1" ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [], "source": [ "def first_inversion_binomial(n: int, p: float) -> int:\n", " def compute_proba(x):\n", " return proba_binomial(n, p, x)\n", " xmax = n\n", " xmin = 0\n", " return inversion_method(compute_proba, xmax, xmin=xmin)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's try out." ] }, { "cell_type": "code", "execution_count": 51, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "[1, 0, 0, 1, 1]" ] }, "execution_count": 51, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[ first_inversion_binomial(10, 0.1) for _ in range(5) ]" ] }, { "cell_type": "code", "execution_count": 52, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[5, 3, 4, 4, 5]" ] }, "execution_count": 52, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[ first_inversion_binomial(10, 0.5) for _ in range(5) ]" ] }, { "cell_type": "code", "execution_count": 53, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "[10, 9, 9, 8, 8]" ] }, "execution_count": 53, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[ first_inversion_binomial(10, 0.9) for _ in range(5) ]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It seems to work as wanted!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Simplified code of the inversion method\n", "\n", "The previous function as a few weaknesses: it stores the $n+1$ values of $\\mathbb{P}(X=k)$ before hand, it computes all of them even if the `for` loop of the inversion method stops in average before the end (in average, it takes $np$ steps, which can be much smaller than $n$ for small $p$).\n", "Furthermore, the computations of both the binomial coefficients and the values $p^k (1-p)^{n-k}$ is using powers and not iterative multiplications, leading to more rounding errors.\n", "\n", "We can solve all these issues by inlining all the computations." ] }, { "cell_type": "code", "execution_count": 104, "metadata": {}, "outputs": [], "source": [ "def inversion_binomial(n: int, p: float) -> int:\n", " if p <= 1e-10:\n", " return 0\n", " if p >= 1 - 1e-10:\n", " return n\n", " if p > 0.5: # speed up by computing for q and then substracting\n", " return n - inversion_binomial(n, 1.0 - p)\n", " result = 0\n", " q = 1.0 - p\n", " current_proba = q**n\n", " cum_proba = current_proba\n", " one_uniform_sample = uniform_01()\n", " while cum_proba <= one_uniform_sample:\n", " current_proba *= (p * (n - result)) / (q * (result + 1))\n", " cum_proba += current_proba\n", " result += 1\n", " return result" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's try out." ] }, { "cell_type": "code", "execution_count": 64, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "[1, 2, 1, 2, 3]" ] }, "execution_count": 64, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[ inversion_binomial(10, 0.1) for _ in range(5) ]" ] }, { "cell_type": "code", "execution_count": 82, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[4, 6, 5, 4, 4]" ] }, "execution_count": 82, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[ inversion_binomial(10, 0.5) for _ in range(5) ]" ] }, { "cell_type": "code", "execution_count": 67, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "[10, 10, 7, 10, 10]" ] }, "execution_count": 67, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[ inversion_binomial(10, 0.9) for _ in range(5) ]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It seems to work as wanted!\n", "\n", "And now the storage is indeed $O(1)$, and the computation time is $O(x)$ if the return value is $x$, so the mean computation time is $O(np)$.\n", "\n", "Note that if $p=1/2$, then $O(np) = O(n/2) = O(n)$, and thus this improved method using the inversion method is (asymptotically) as costly as the naive method (the first method which consists of summing $n$ iid samples from a Bernoulli of mean $p$)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's plot this out also." ] }, { "cell_type": "code", "execution_count": 68, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "
" ] }, "execution_count": 68, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/plain": [ "(array([261., 367., 0., 248., 0., 96., 27., 0., 0., 1.]),\n", " array([0. , 0.6, 1.2, 1.8, 2.4, 3. , 3.6, 4.2, 4.8, 5.4, 6. ]),\n", " )" ] }, "execution_count": 68, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/plain": [ "Text(0.5, 1.0, '1000 samples from a Binomial distribution with n = 10 and p = 0.12345.')" ] }, "execution_count": 68, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAcUAAAEICAYAAAAut+/uAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvOIA7rQAAHZxJREFUeJzt3Xu4XXV95/H3h4SbBA2YYwxJIFRTFJgSmAhYUSl44aIGrUVQES02Og2OVhwbUAsM0kE7imOtaDRIoghmUB4iUJVBBKMFGjAC4aIRQ5OQm0Ag4WYJ3/nj9z2w2Oxzzj77XPYln9fz7Ofsdf+utddZn7V+a519FBGYmZkZbNfqAszMzNqFQ9HMzCw5FM3MzJJD0czMLDkUzczMkkPRzMwsORQHQdJFkj47zPPcWdIPJT0s6f8O57xbQdJySYe383IlhaSXNzjuWZK+k+/3lLRF0pghlFqd99ckfSbfHy5p9XDMN+f3Wkn3DNf8hnv5kqbl5zB2NOvqVJJWSnpDq+vYFgwYipJOlbRU0pOSLqoz/EhJd0t6TNJ1kvaqDNtR0oWSHpG0TtLHG512G/JOYCLw4oj4q1YX05/KgWxLvtZL+qqk7XvHiYj9IuJno13baCw3Iv4jIsZFxNb+xpP0fklLGpjfhyPinOGorTboI+LnEbHPcMy7GbXL74SDuqQdJF2WtUbtSZaKz0l6IF+fk6QWlTvqBnO8lnSOpNslPSXprJphx0paImlT5sI3Je1aGf55SasyN+6TdEYfy3hffk4frPQ7S9J/Vo5RWyT9yWDWs5ErxfuBzwIX1ilqAvAD4DPA7sBS4HuVUc4CpgN7AX8BfFLSUQ1Ou63YC/hNRDxVb2CbnkmPj4hxwH8BXg3MaXE9HWe4rjZt2C0B3gusqzNsNnAccADwZ8BbgQ+NXmmt08TxegXwSeCqOsNeRMmUPYBXApOBf6oMnw+8IiJeCPw58B5J76ipZzfgDGB5nfl/L09ee1/3NrCKz4qIhl65EhfV9JsN/LLSvQvweK4QlEB9U2X4OcCljUxbZ/l/D6wBNgP3AEdm/4OBfwM2AWuBrwA7VKYL4G+B3+a05wAvA34JPAIs6h0fOBxYnRv7D8BK4D2VeV0EfLbS/RZgWS77l8CfDVRvzTqdDfwR+E9gC3AK8H7gF8D5wAO53bcDPg3cB2wAFgIvynlMy3X8ALAKeAj4MPAq4Las7Sv9fK79br+acXuXNbbS7/PAvEr3SuAN+f6s3L4LczssB2ZWxn0l8LNc9nLgbTXb+qvAv+a2+QXwUuBLuY53Awf2sdxG9omX97GOewPXZ73X5LTfqbf++Vndm+P+HnhPrtMTwNase1NlfS4ArgYeBd5AZX9i4H3vZ8AHK93vB5bk+xuyrkdzme/qnd8gtvW/UA5gm4GbgJf1sX0WAKfl+8m53DnZ/TLgQcr++szygW8DT1N+v7dQDpa92/Jk4D9ynT/Vz37acI3D8crP4vCafr8EZle6TwFu7GP63YArgY2U/fVKYErN53kOZb/eDPwEmFAZfhLl9/0B4FNU9u8+ts3XKPvrZsr+u9cwb49BHa8r430HOGuAcd4B3N7HsMnA7cAna/p/jXJcr/29OIv8fW32NdR7ivsBv+7tiIhHgd8B+2WST6oOz/f7DTRt7UIk7QOcCrwqInYF3kzZSaAcfP4OmEC5ajmSsrGq3gz8V+BQyi/kPMrZ4FRgf+DEyrgvzXlNpvzCzsvl19Z0IOXq+UPAi4GvA4uzybi/ep8REWcC/8izZzbzc9AhlIPtROBcygHw/ZSr7T8BxlEO1lWHUK7K30UJjk9RDrz7AcdLen3t8lMj268uSXvkut3Yz2hvAy4FxgOLe+vOJtcfUg4GLwE+Alxcs62Pp5wMTACepATdrdl9GfDF4V4n4LvALTntOZR94Hkk7QJ8GTg6P+M/B5ZFxF2Uk5J/y890fGWyd1M+z10pVyS1Gtr3akXE6/LtAbnM55zBN7itT6CcpO1GOcs/t4/FXU8JPIDXU/bT11W6fx4RT9fUdxIl+N6a9X2+MvgwYB/KZ/QPkl7Zz6o2WiPZNNfXa24/y+jPc45ZPPd4Vms74FuUlqA9KQFS+zv7bsrJ7EuAHYBPZO37Uk6gTqJcTb0YmDJAbe+h7K8TKCfqF/c1YpPbpuHjdRNeR80Vn6S5krZQTk52ofxe9g47GJhJCcZ63irpQZXnDP7bYIsZaiiOAx6u6fcw5Zd+XKW7dthA09baCuwI7Ctp+4hYGRG/A4iIWyLixoh4KiJWUsKpNgA+HxGPRMRy4A7gJxFxb0Q8TLkSObBm/M9ExJMRcT3lzPT4OjXNBr4eETdFxNaIWEA5cB/aX70Nuj8i/jnX6XHKDv/FrHkLcDpwQk3T6jkR8URE/IRyxXBJRGyIiDXAz+usI9Dw9qv1B0mbKFfCj1ICqi9LIuLqKPfhvk1peoKyncYB50XEHyPip5Sz6eoJyuVZ3xPA5cATEbEw5/W9YV4nJO1JucLu/fxvoIRJX54G9pe0c0Sszf2rP1dExC8i4ulcp3oa2fcGq9FtfXOUZvyLgRl9zOt64DBJ21EOZp8HXpPDXp/DB+PsiHg8In5NOege0M+4jdZIRIzv53XeIGvsVXvMehgYV+++YkQ8EBHfj4jHImIzJcBr98FvRcRv8nd8UWV93glcGRE3RMSTlCbLp+nfVZXxPwW8WtLUeiM2uW0Gc7xumKQ3Uk4A/6GmxvNy3gdRjhsP5/hjKC1Ip9aefKVFlFaRHuBvKCdaJ9YZr09DDcUtwAtr+r2Qcgm/pdJdO2ygaZ8jIlYAH6NcGm+QdGlepSDpTyVdmTdsH6FceU2omcX6yvvH63SPq3Q/lGdBve6jnK3V2gs4rXqWRbny3KO/ehu0qqZ7j6yjWtNYypVkr8Gs4zMa3H61JuQV0AsozT8/7mfc6r2Zx4CdMsz3AFbV7Nj3Ua6SWrFOZE31Pv/nyXHeRbkqXCvpKkmvGGD+tZ9rrUb3vcFqZFvXfk51t22e3D1KOYC/lhKu9+dVZzOh2NBymxh3JNQes14IbImI5/1XBUkvkPT1fFDkEUoT9/iae8l9rc8eVPaV3CceGKC26vhbKM3Yw7Hv9Gr4eN0oSYdSrgDfGRG/qR0exa8ov+tnZ++/BW6LiLqtUxFxZ0TcnxcqvwT+D+Uko2FDDcXlVM7ssknpZcDyiHiIcj+neuZ3AM9eJvc5bb0FRcR3I+IwShgF8LkcdAHl/tL0KDdmzwCG8kTYbllLrz0p90ZrrQLOrTnLekFEXDJAvY2o/SW7P+dTrekpnhsSzWp6++UZ7kXAoXkjfjDuB6bmFUevPSlXn0PV7Dqtpf7nX1dE/Dgi3ki5TXA38I3eQX1NMsDy+9v3HqWchPR66QDzqhrubX095UCzQ7ZEXE8529+N0nRXz6j+O56apw9rX3WfZmzAc45ZPPd4Vus0SrPwIbkP9jYxN7ofPnOVJ+kFlCbU/lTHH0d5GKbecavZbTOo4/VA8vbTYuCvI+LaAUYfm8uC0sz+9jzhXUe5bfEFSbVN072CQeZBI3+SMVbSTsAYYIyk3jN9KE1a+0v6yxznHygpfncOXwh8WtJueRb9N5SDaCPTVmvYR9IRknakPMTwOM82J+xKeWBmSy5j0G3IdZyt8nj2aykP09T7+8FvAB+WdIiKXVQeNd51gHqbcQnwd5L2zh2+9z5k3SdWB6np7ZfrdxLljHegM9laN1HOjj8paXuVx9/fSrn/OFRNrVNE3Ed5qq738z8sa3oeSRMlzcqDw5OUM+nez3g9MEXSDk3U3te+twx4R16BvJzykEfVesr95nqGe1tfT7lnfkN2/yy7l0Tff67SX33DLp779GHt6x/7mk7lmYCdsnOHPN71HlQXAh+XNDlbfk7j2eNZrV0pv/ebJO0OnDmI8i8D3iLpsNyH/icDH6uPqYx/DuUBoLotE01um4aP11DuY+d42wFjczuOyWH7Az8CPhIRP6yZbjtJH8rMkMr9wzlAb3C+n9I8OiNfSylXkZ/K6WfVTPvfgSsG2HbP0ciV4qcpH+5cysMpj2c/ImIj8JeU9vKHKA97nFCZ9kzKzdj7KL9I/xQRP2pw2qodgfMoT6ito9yYPj2HfYJyw3ozJaiG+mcd67Ke+yn3LT5c74OPiKWUkP9Kjr+C8oENVG8zLqS0q99AecrxCcrDEsOhme23SeUm+HrKgyxvq9eE1J+I+CPlwHw0ZTt9FXhfX79kgzSUfeLdlH3xQcr+u7CP8bYDPk7ZTx6kNB32hu9PKWfQ6yT9YRDL7m/fO5/ypPJ6yhOgtQ9SnAUsUGnKf859yBHY1tdTDvq9obiEchV7Q59TwP+inCBvkvSJJpc7Gu6hHOMmU24LPM6zrTRfp9xjvp3ybMJV2a+eLwE7U7b3jZQQaEjem55DaVpcS9knBvpih+9S9tcHKQ8VvrfR5TVYU7/Ha5Uvoqg++PINyrY7kRJYj1NOoKGcTPQA8ytXqNUrzrdTcmMz5enVf84XEbEpItb1vii/E49EeT6ErGlFTrsQ+FyU5z1669ySJ5x90iCPZV0tz6C/ExEDPellZtYWVL5UZXVEfLrVtXQDf82bmZlZciiamZklN5+amZklXymamZmldvyy6RE1YcKEmDZtWqvLMDPrGLfccssfIqKn1XWMhm0uFKdNm8bSpUtbXYaZWceQVPebnbqRm0/NzMySQ9HMzCw5FM3MzJJD0czMLDkUzczMkkPRzMwsORTNzMySQ9HMzCw5FM3MzNI29402nWja3KtatuyV5x3bsmWbmY02XymamZklh6KZmVlyKJqZmSWHopmZWXIompmZpbYJRUk7SbpZ0q8lLZd0dva/SNLvJS3L14zsL0lflrRC0m2SDmrtGpiZWadrpz/JeBI4IiK2SNoeWCLpX3PY/4iIy2rGPxqYnq9DgAvyp5mZWVPa5koxii3ZuX2+op9JZgELc7obgfGSJo10nWZm1r3aJhQBJI2RtAzYAFwTETfloHOzifR8STtmv8nAqsrkq7NfvfnOlrRU0tKNGzeOWP1mZtbZ2ioUI2JrRMwApgAHS9ofOB14BfAqYHfg75uY77yImBkRM3t6eoa1ZjMz6x5tFYq9ImITcB1wVESszSbSJ4FvAQfnaGuAqZXJpmQ/MzOzprRNKErqkTQ+3+8MvBG4u/c+oSQBxwF35CSLgfflU6iHAg9HxNoWlG5mZl2inZ4+nQQskDSGEtaLIuJKST+V1AMIWAZ8OMe/GjgGWAE8BnygBTWbmVkXaZtQjIjbgAPr9D+ij/EDmDPSdZmZ2bajbZpPzczMWs2haGZmlhyKZmZmyaFoZmaWHIpmZmbJoWhmZpYcimZmZsmhaGZmlhyKZmZmyaFoZmaWHIpmZmbJoWhmZpYcimZmZsmhaGZmlhyKZmZmyaFoZmaWHIpmZmbJoWhmZpYcimZmZqmtQlHSTpJulvRrScslnZ3995Z0k6QVkr4naYfsv2N2r8jh01pZv5mZdba2CkXgSeCIiDgAmAEcJelQ4HPA+RHxcuAh4JQc/xTgoex/fo5nZmbWlLYKxSi2ZOf2+QrgCOCy7L8AOC7fz8pucviRkjRK5ZqZWZdpq1AEkDRG0jJgA3AN8DtgU0Q8laOsBibn+8nAKoAc/jDw4tGt2MzMukXbhWJEbI2IGcAU4GDgFUOdp6TZkpZKWrpx48Yh12hmZt2p7UKxV0RsAq4DXg2MlzQ2B00B1uT7NcBUgBz+IuCBOvOaFxEzI2JmT0/PiNduZmadqa1CUVKPpPH5fmfgjcBdlHB8Z452MnBFvl+c3eTwn0ZEjF7FZmbWTcYOPMqomgQskDSGEtiLIuJKSXcCl0r6LPArYH6OPx/4tqQVwIPACa0o2szMukNbhWJE3AYcWKf/vZT7i7X9nwD+ahRKMzOzbUBbNZ+amZm1kkPRzMwsORTNzMySQ9HMzCw5FM3MzJJD0czMLDkUzczMkkPRzMwsORTNzMySQ9HMzCw5FM3MzJJD0czMLDkUzczMkkPRzMwsORTNzMySQ9HMzCw5FM3MzNLYVhfQSabNvarVJZiZ2QjylaKZmVlyKJqZmaW2CUVJUyVdJ+lOScslfTT7nyVpjaRl+TqmMs3pklZIukfSm1tXvZmZdYN2uqf4FHBaRNwqaVfgFknX5LDzI+J/V0eWtC9wArAfsAfw/yT9aURsHdWqzcysa7TNlWJErI2IW/P9ZuAuYHI/k8wCLo2IJyPi98AK4OCRr9TMzLpV24RilaRpwIHATdnrVEm3SbpQ0m7ZbzKwqjLZavoIUUmzJS2VtHTjxo0jVLWZmXW6dmo+BUDSOOD7wMci4hFJFwDnAJE/vwD89WDmGRHzgHkAM2fOjOGt2EZCK//8ZeV5x7Zs2WbWWm11pShpe0ogXhwRPwCIiPURsTUinga+wbNNpGuAqZXJp2Q/MzOzprRNKEoSMB+4KyK+WOk/qTLa24E78v1i4ARJO0raG5gO3Dxa9ZqZWfdpp+bT1wAnAbdLWpb9zgBOlDSD0ny6EvgQQEQsl7QIuJPy5OocP3lqZmZD0TahGBFLANUZdHU/05wLnDtiRZmZ2TalbZpPzczMWs2haGZmlhyKZmZmyaFoZmaWHIpmZmbJoWhmZpYcimZmZsmhaGZmlhyKZmZmyaFoZmaWHIpmZmbJoWhmZpYcimZmZsmhaGZmlhyKZmZmyaFoZmaWHIpmZmbJoWhmZpYcimZmZqltQlHSVEnXSbpT0nJJH83+u0u6RtJv8+du2V+SvixphaTbJB3U2jUwM7NO1zahCDwFnBYR+wKHAnMk7QvMBa6NiOnAtdkNcDQwPV+zgQtGv2QzM+smbROKEbE2Im7N95uBu4DJwCxgQY62ADgu388CFkZxIzBe0qRRLtvMzLpI24RilaRpwIHATcDEiFibg9YBE/P9ZGBVZbLV2a/e/GZLWipp6caNG0ekZjMz63xtF4qSxgHfBz4WEY9Uh0VEADHYeUbEvIiYGREze3p6hqlSMzPrNm0VipK2pwTixRHxg+y9vrdZNH9uyP5rgKmVyadkPzMzs6a0TShKEjAfuCsivlgZtBg4Od+fDFxR6f++fAr1UODhSjOrmZnZoI1tdQEVrwFOAm6XtCz7nQGcByySdApwH3B8DrsaOAZYATwGfGB0yzUzs27TNqEYEUsA9TH4yDrjBzBnRIsyM7NtSts0n5qZmbWaQ9HMzCw5FM3MzJJD0czMLDkUzczMkkPRzMwsORTNzMySQ9HMzCw5FM3MzJJD0czMLDkUzczMkkPRzMwsORTNzMySQ9HMzCw5FM3MzJJD0czMLDkUzczMkkPRzMwsORTNzMxSW4WipAslbZB0R6XfWZLWSFqWr2Mqw06XtELSPZLe3JqqzcysW7RVKAIXAUfV6X9+RMzI19UAkvYFTgD2y2m+KmnMqFVqZmZdp61CMSJuAB5scPRZwKUR8WRE/B5YARw8YsWZmVnXa6tQ7Mepkm7L5tXdst9kYFVlnNXZ73kkzZa0VNLSjRs3jnStZmbWoTohFC8AXgbMANYCXxjsDCJiXkTMjIiZPT09w12fmZl1ibYPxYhYHxFbI+Jp4Bs820S6BphaGXVK9jMzM2tK24eipEmVzrcDvU+mLgZOkLSjpL2B6cDNo12fmZl1j7GtLqBK0iXA4cAESauBM4HDJc0AAlgJfAggIpZLWgTcCTwFzImIra2o28zMukNbhWJEnFin9/x+xj8XOHfkKjIzs21J2zefmpmZjRaHopmZWXIompmZJYeimZlZciiamZklh6KZmVlyKJqZmSWHopmZWXIompmZJYeimZlZciiamZklh6KZmVlyKJqZmSWHopmZWXIompmZJYeimZlZciiamZklh6KZmVlyKJqZmaW2CkVJF0raIOmOSr/dJV0j6bf5c7fsL0lflrRC0m2SDmpd5WZm1g3aKhSBi4CjavrNBa6NiOnAtdkNcDQwPV+zgQtGqUYzM+tSbRWKEXED8GBN71nAgny/ADiu0n9hFDcC4yVNGp1KzcysG7VVKPZhYkSszffrgIn5fjKwqjLe6uz3PJJmS1oqaenGjRtHrlIzM+tonRCKz4iIAKKJ6eZFxMyImNnT0zMClZmZWTfohFBc39ssmj83ZP81wNTKeFOyn5mZWVPGtrqABiwGTgbOy59XVPqfKulS4BDg4Uozq1nHmTb3qpYsd+V5x7ZkuWbtqK1CUdIlwOHABEmrgTMpYbhI0inAfcDxOfrVwDHACuAx4AOjXrCZmXWVtgrFiDixj0FH1hk3gDkjW5GZmW1LOuGeopmZ2ahwKJqZmSWHopmZWXIompmZJYeimZlZciiamZklh6KZmVlyKJqZmSWHopmZWXIompmZJYeimZlZciiamZklh6KZmVlyKJqZmSWHopmZWXIompmZJYeimZlZciiamZklh6KZmVka2+oCGiVpJbAZ2Ao8FREzJe0OfA+YBqwEjo+Ih1pVo5mZdbZOu1L8i4iYEREzs3sucG1ETAeuzW4zM7OmdFoo1poFLMj3C4DjWliLmZl1uE4KxQB+IukWSbOz38SIWJvv1wETW1OamZl1g465pwgcFhFrJL0EuEbS3dWBERGSot6EGaKzAfbcc8+Rr9TMzDpSx1wpRsSa/LkBuBw4GFgvaRJA/tzQx7TzImJmRMzs6ekZrZLNzKzDdEQoStpF0q6974E3AXcAi4GTc7STgStaU6GZmXWDTmk+nQhcLglKzd+NiB9J+ndgkaRTgPuA41tYo5mZdbiOCMWIuBc4oE7/B4AjR78iMzPrRh3RfGpmZjYaHIpmZmbJoWhmZpYcimZmZsmhaGZmlhyKZmZmyaFoZmaWHIpmZmapI/5438xGzrS5V7Vs2SvPO7Zlyzarx1eKZmZmyaFoZmaWHIpmZmbJoWhmZpYcimZmZsmhaGZmlhyKZmZmyaFoZmaWHIpmZmbJoWhmZpYcimZmZqnjQ1HSUZLukbRC0txW12NmZp2ro0NR0hjgX4CjgX2BEyXt29qqzMysU3X6f8k4GFgREfcCSLoUmAXc2dKqzMz60Kr/SuL/SNIYRUSra2iapHcCR0XEB7P7JOCQiDi1ZrzZwOzs3Ae4p8lFTgD+0OS07aRb1gO8Lu2qW9alW9YDhrYue0VEz3AW0646/UqxIRExD5g31PlIWhoRM4ehpJbqlvUAr0u76pZ16Zb1gO5al5HU0fcUgTXA1Er3lOxnZmY2aJ0eiv8OTJe0t6QdgBOAxS2uyczMOlRHN59GxFOSTgV+DIwBLoyI5SO4yCE3wbaJblkP8Lq0q25Zl25ZD+iudRkxHf2gjZmZ2XDq9OZTMzOzYeNQNDMzSw7FBnTLV8lJulDSBkl3tLqWoZI0VdJ1ku6UtFzSR1tdU7Mk7STpZkm/znU5u9U1DYWkMZJ+JenKVtcyFJJWSrpd0jJJS1tdz1BIGi/pMkl3S7pL0qtbXVO78j3FAeRXyf0GeCOwmvLE64kR0XHfmiPpdcAWYGFE7N/qeoZC0iRgUkTcKmlX4BbguA79XATsEhFbJG0PLAE+GhE3tri0pkj6ODATeGFEvKXV9TRL0kpgZkR0/B/vS1oA/DwivplP6r8gIja1uq525CvFgT3zVXIR8Ueg96vkOk5E3AA82Oo6hkNErI2IW/P9ZuAuYHJrq2pOFFuyc/t8deTZqqQpwLHAN1tdixWSXgS8DpgPEBF/dCD2zaE4sMnAqkr3ajr04NutJE0DDgRuam0lzcsmx2XABuCaiOjUdfkS8Eng6VYXMgwC+ImkW/KrIjvV3sBG4FvZrP1NSbu0uqh25VC0jiZpHPB94GMR8Uir62lWRGyNiBmUb2U6WFLHNW9LeguwISJuaXUtw+SwiDiI8l945uTth040FjgIuCAiDgQeBTr22YiR5lAcmL9Krk3l/bfvAxdHxA9aXc9wyGat64CjWl1LE14DvC3vxV0KHCHpO60tqXkRsSZ/bgAup9xK6USrgdWV1ofLKCFpdTgUB+avkmtD+XDKfOCuiPhiq+sZCkk9ksbn+50pD3Xd3dqqBi8iTo+IKRExjfJ78tOIeG+Ly2qKpF3yAS6yqfFNQEc+tR0R64BVkvbJXkfif6/Xp47+mrfR0IKvkhsxki4BDgcmSFoNnBkR81tbVdNeA5wE3J734gDOiIirW1hTsyYBC/JJ5+2ARRHR0X/O0AUmApeXcy/GAt+NiB+1tqQh+QhwcZ7Y3wt8oMX1tC3/SYaZmVly86mZmVlyKJqZmSWHopmZWXIompmZJYeimZlZciiamZklh6KZmVn6/5Ttptisvu2RAAAAAElFTkSuQmCC\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "m = 1000\n", "n = 10\n", "p = 0.12345\n", "X = [ inversion_binomial(n, p) for _ in range(m) ]\n", "plt.figure()\n", "plt.hist(X)\n", "plt.title(f\"{m} samples from a Binomial distribution with n = {n} and p = {p}.\")\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": 87, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "
" ] }, "execution_count": 87, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/plain": [ "(array([ 1., 10., 52., 115., 208., 239., 205., 110., 49., 11.]),\n", " array([0. , 0.9, 1.8, 2.7, 3.6, 4.5, 5.4, 6.3, 7.2, 8.1, 9. ]),\n", " )" ] }, "execution_count": 87, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/plain": [ "Text(0.5, 1.0, '1000 samples from a Binomial distribution with n = 10 and p = 0.5.')" ] }, "execution_count": 87, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "m = 1000\n", "n = 10\n", "p = 0.5\n", "X = [ inversion_binomial(n, p) for _ in range(m) ]\n", "plt.figure()\n", "plt.hist(X)\n", "plt.title(f\"{m} samples from a Binomial distribution with n = {n} and p = {p}.\")\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": 88, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "
" ] }, "execution_count": 88, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/plain": [ "(array([ 7., 0., 0., 0., 0., 113., 0., 0., 0., 880.]),\n", " array([ 8. , 8.2, 8.4, 8.6, 8.8, 9. , 9.2, 9.4, 9.6, 9.8, 10. ]),\n", " )" ] }, "execution_count": 88, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/plain": [ "Text(0.5, 1.0, '1000 samples from a Binomial distribution with n = 10 and p = 0.98765.')" ] }, "execution_count": 88, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "m = 1000\n", "n = 10\n", "p = 0.98765\n", "X = [ inversion_binomial(n, p) for _ in range(m) ]\n", "plt.figure()\n", "plt.hist(X)\n", "plt.title(f\"{m} samples from a Binomial distribution with n = {n} and p = {p}.\")\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### In Cython" ] }, { "cell_type": "code", "execution_count": 89, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The cython extension is already loaded. To reload it, use:\n", " %reload_ext cython\n" ] } ], "source": [ "%load_ext cython" ] }, { "cell_type": "code", "execution_count": 112, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", " \n", " Cython: _cython_magic_beb04c003b39b7afc4e8a1cfd3d3afad.pyx\n", " \n", "\n", "\n", "

Generated by Cython 0.29.2

\n", "

\n", " Yellow lines hint at Python interaction.
\n", " Click on a line that starts with a \"+\" to see the C code that Cython generated for it.\n", "

\n", "
 01: 
\n", "
+02: import random
\n", "
  __pyx_t_1 = __Pyx_Import(__pyx_n_s_random, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2, __pyx_L1_error)\n",
       "  __Pyx_GOTREF(__pyx_t_1);\n",
       "  if (PyDict_SetItem(__pyx_d, __pyx_n_s_random, __pyx_t_1) < 0) __PYX_ERR(0, 2, __pyx_L1_error)\n",
       "  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;\n",
       "
 03: 
\n", "
+04: def cython_inversion_binomial(int n, double p) -> int:
\n", "
/* Python wrapper */\n",
       "static PyObject *__pyx_pw_46_cython_magic_beb04c003b39b7afc4e8a1cfd3d3afad_1cython_inversion_binomial(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/\n",
       "static PyMethodDef __pyx_mdef_46_cython_magic_beb04c003b39b7afc4e8a1cfd3d3afad_1cython_inversion_binomial = {\"cython_inversion_binomial\", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_46_cython_magic_beb04c003b39b7afc4e8a1cfd3d3afad_1cython_inversion_binomial, METH_VARARGS|METH_KEYWORDS, 0};\n",
       "static PyObject *__pyx_pw_46_cython_magic_beb04c003b39b7afc4e8a1cfd3d3afad_1cython_inversion_binomial(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {\n",
       "  int __pyx_v_n;\n",
       "  double __pyx_v_p;\n",
       "  PyObject *__pyx_r = 0;\n",
       "  __Pyx_RefNannyDeclarations\n",
       "  __Pyx_RefNannySetupContext(\"cython_inversion_binomial (wrapper)\", 0);\n",
       "  {\n",
       "    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_n,&__pyx_n_s_p,0};\n",
       "    PyObject* values[2] = {0,0};\n",
       "    if (unlikely(__pyx_kwds)) {\n",
       "      Py_ssize_t kw_args;\n",
       "      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);\n",
       "      switch (pos_args) {\n",
       "        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);\n",
       "        CYTHON_FALLTHROUGH;\n",
       "        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);\n",
       "        CYTHON_FALLTHROUGH;\n",
       "        case  0: break;\n",
       "        default: goto __pyx_L5_argtuple_error;\n",
       "      }\n",
       "      kw_args = PyDict_Size(__pyx_kwds);\n",
       "      switch (pos_args) {\n",
       "        case  0:\n",
       "        if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_n)) != 0)) kw_args--;\n",
       "        else goto __pyx_L5_argtuple_error;\n",
       "        CYTHON_FALLTHROUGH;\n",
       "        case  1:\n",
       "        if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_p)) != 0)) kw_args--;\n",
       "        else {\n",
       "          __Pyx_RaiseArgtupleInvalid(\"cython_inversion_binomial\", 1, 2, 2, 1); __PYX_ERR(0, 4, __pyx_L3_error)\n",
       "        }\n",
       "      }\n",
       "      if (unlikely(kw_args > 0)) {\n",
       "        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, \"cython_inversion_binomial\") < 0)) __PYX_ERR(0, 4, __pyx_L3_error)\n",
       "      }\n",
       "    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {\n",
       "      goto __pyx_L5_argtuple_error;\n",
       "    } else {\n",
       "      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);\n",
       "      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);\n",
       "    }\n",
       "    __pyx_v_n = __Pyx_PyInt_As_int(values[0]); if (unlikely((__pyx_v_n == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 4, __pyx_L3_error)\n",
       "    __pyx_v_p = __pyx_PyFloat_AsDouble(values[1]); if (unlikely((__pyx_v_p == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 4, __pyx_L3_error)\n",
       "  }\n",
       "  goto __pyx_L4_argument_unpacking_done;\n",
       "  __pyx_L5_argtuple_error:;\n",
       "  __Pyx_RaiseArgtupleInvalid(\"cython_inversion_binomial\", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4, __pyx_L3_error)\n",
       "  __pyx_L3_error:;\n",
       "  __Pyx_AddTraceback(\"_cython_magic_beb04c003b39b7afc4e8a1cfd3d3afad.cython_inversion_binomial\", __pyx_clineno, __pyx_lineno, __pyx_filename);\n",
       "  __Pyx_RefNannyFinishContext();\n",
       "  return NULL;\n",
       "  __pyx_L4_argument_unpacking_done:;\n",
       "  __pyx_r = __pyx_pf_46_cython_magic_beb04c003b39b7afc4e8a1cfd3d3afad_cython_inversion_binomial(__pyx_self, __pyx_v_n, __pyx_v_p);\n",
       "\n",
       "  /* function exit code */\n",
       "  __Pyx_RefNannyFinishContext();\n",
       "  return __pyx_r;\n",
       "}\n",
       "\n",
       "static PyObject *__pyx_pf_46_cython_magic_beb04c003b39b7afc4e8a1cfd3d3afad_cython_inversion_binomial(CYTHON_UNUSED PyObject *__pyx_self, int __pyx_v_n, double __pyx_v_p) {\n",
       "  int __pyx_v_result;\n",
       "  double __pyx_v_q;\n",
       "  double __pyx_v_current_proba;\n",
       "  double __pyx_v_cum_proba;\n",
       "  double __pyx_v_one_uniform_sample;\n",
       "  PyObject *__pyx_r = NULL;\n",
       "  __Pyx_RefNannyDeclarations\n",
       "  __Pyx_RefNannySetupContext(\"cython_inversion_binomial\", 0);\n",
       "/* … */\n",
       "  /* function exit code */\n",
       "  __pyx_L1_error:;\n",
       "  __Pyx_XDECREF(__pyx_t_2);\n",
       "  __Pyx_XDECREF(__pyx_t_3);\n",
       "  __Pyx_XDECREF(__pyx_t_4);\n",
       "  __Pyx_XDECREF(__pyx_t_5);\n",
       "  __Pyx_XDECREF(__pyx_t_6);\n",
       "  __Pyx_XDECREF(__pyx_t_7);\n",
       "  __Pyx_XDECREF(__pyx_t_9);\n",
       "  __Pyx_AddTraceback(\"_cython_magic_beb04c003b39b7afc4e8a1cfd3d3afad.cython_inversion_binomial\", __pyx_clineno, __pyx_lineno, __pyx_filename);\n",
       "  __pyx_r = NULL;\n",
       "  __pyx_L0:;\n",
       "  __Pyx_XGIVEREF(__pyx_r);\n",
       "  __Pyx_RefNannyFinishContext();\n",
       "  return __pyx_r;\n",
       "}\n",
       "/* … */\n",
       "  __pyx_tuple_ = PyTuple_Pack(7, __pyx_n_s_n, __pyx_n_s_p, __pyx_n_s_result, __pyx_n_s_q, __pyx_n_s_current_proba, __pyx_n_s_cum_proba, __pyx_n_s_one_uniform_sample); if (unlikely(!__pyx_tuple_)) __PYX_ERR(0, 4, __pyx_L1_error)\n",
       "  __Pyx_GOTREF(__pyx_tuple_);\n",
       "  __Pyx_GIVEREF(__pyx_tuple_);\n",
       "/* … */\n",
       "  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_46_cython_magic_beb04c003b39b7afc4e8a1cfd3d3afad_1cython_inversion_binomial, NULL, __pyx_n_s_cython_magic_beb04c003b39b7afc4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4, __pyx_L1_error)\n",
       "  __Pyx_GOTREF(__pyx_t_1);\n",
       "  if (PyDict_SetItem(__pyx_d, __pyx_n_s_cython_inversion_binomial, __pyx_t_1) < 0) __PYX_ERR(0, 4, __pyx_L1_error)\n",
       "  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;\n",
       "
+05:     if p <= 1e-9:
\n", "
  __pyx_t_1 = ((__pyx_v_p <= 1e-9) != 0);\n",
       "  if (__pyx_t_1) {\n",
       "/* … */\n",
       "  }\n",
       "
+06:         return 0
\n", "
    __Pyx_XDECREF(__pyx_r);\n",
       "    __Pyx_INCREF(__pyx_int_0);\n",
       "    __pyx_r = __pyx_int_0;\n",
       "    goto __pyx_L0;\n",
       "
+07:     if p >= 1 - 1e-9:
\n", "
  __pyx_t_1 = ((__pyx_v_p >= (1.0 - 1e-9)) != 0);\n",
       "  if (__pyx_t_1) {\n",
       "/* … */\n",
       "  }\n",
       "
+08:         return n
\n", "
    __Pyx_XDECREF(__pyx_r);\n",
       "    __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_n); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 8, __pyx_L1_error)\n",
       "    __Pyx_GOTREF(__pyx_t_2);\n",
       "    __pyx_r = __pyx_t_2;\n",
       "    __pyx_t_2 = 0;\n",
       "    goto __pyx_L0;\n",
       "
+09:     if p > 0.5:  # speed up by computing for q and then substracting
\n", "
  __pyx_t_1 = ((__pyx_v_p > 0.5) != 0);\n",
       "  if (__pyx_t_1) {\n",
       "/* … */\n",
       "  }\n",
       "
+10:         return n - cython_inversion_binomial(n, 1.0 - p)
\n", "
    __Pyx_XDECREF(__pyx_r);\n",
       "    __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_n); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 10, __pyx_L1_error)\n",
       "    __Pyx_GOTREF(__pyx_t_2);\n",
       "    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_cython_inversion_binomial); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 10, __pyx_L1_error)\n",
       "    __Pyx_GOTREF(__pyx_t_4);\n",
       "    __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_n); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 10, __pyx_L1_error)\n",
       "    __Pyx_GOTREF(__pyx_t_5);\n",
       "    __pyx_t_6 = PyFloat_FromDouble((1.0 - __pyx_v_p)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 10, __pyx_L1_error)\n",
       "    __Pyx_GOTREF(__pyx_t_6);\n",
       "    __pyx_t_7 = NULL;\n",
       "    __pyx_t_8 = 0;\n",
       "    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) {\n",
       "      __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_4);\n",
       "      if (likely(__pyx_t_7)) {\n",
       "        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);\n",
       "        __Pyx_INCREF(__pyx_t_7);\n",
       "        __Pyx_INCREF(function);\n",
       "        __Pyx_DECREF_SET(__pyx_t_4, function);\n",
       "        __pyx_t_8 = 1;\n",
       "      }\n",
       "    }\n",
       "    #if CYTHON_FAST_PYCALL\n",
       "    if (PyFunction_Check(__pyx_t_4)) {\n",
       "      PyObject *__pyx_temp[3] = {__pyx_t_7, __pyx_t_5, __pyx_t_6};\n",
       "      __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-__pyx_t_8, 2+__pyx_t_8); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 10, __pyx_L1_error)\n",
       "      __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;\n",
       "      __Pyx_GOTREF(__pyx_t_3);\n",
       "      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;\n",
       "      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;\n",
       "    } else\n",
       "    #endif\n",
       "    #if CYTHON_FAST_PYCCALL\n",
       "    if (__Pyx_PyFastCFunction_Check(__pyx_t_4)) {\n",
       "      PyObject *__pyx_temp[3] = {__pyx_t_7, __pyx_t_5, __pyx_t_6};\n",
       "      __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-__pyx_t_8, 2+__pyx_t_8); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 10, __pyx_L1_error)\n",
       "      __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;\n",
       "      __Pyx_GOTREF(__pyx_t_3);\n",
       "      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;\n",
       "      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;\n",
       "    } else\n",
       "    #endif\n",
       "    {\n",
       "      __pyx_t_9 = PyTuple_New(2+__pyx_t_8); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 10, __pyx_L1_error)\n",
       "      __Pyx_GOTREF(__pyx_t_9);\n",
       "      if (__pyx_t_7) {\n",
       "        __Pyx_GIVEREF(__pyx_t_7); PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_7); __pyx_t_7 = NULL;\n",
       "      }\n",
       "      __Pyx_GIVEREF(__pyx_t_5);\n",
       "      PyTuple_SET_ITEM(__pyx_t_9, 0+__pyx_t_8, __pyx_t_5);\n",
       "      __Pyx_GIVEREF(__pyx_t_6);\n",
       "      PyTuple_SET_ITEM(__pyx_t_9, 1+__pyx_t_8, __pyx_t_6);\n",
       "      __pyx_t_5 = 0;\n",
       "      __pyx_t_6 = 0;\n",
       "      __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_9, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 10, __pyx_L1_error)\n",
       "      __Pyx_GOTREF(__pyx_t_3);\n",
       "      __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;\n",
       "    }\n",
       "    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n",
       "    __pyx_t_4 = PyNumber_Subtract(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 10, __pyx_L1_error)\n",
       "    __Pyx_GOTREF(__pyx_t_4);\n",
       "    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;\n",
       "    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;\n",
       "    __pyx_r = __pyx_t_4;\n",
       "    __pyx_t_4 = 0;\n",
       "    goto __pyx_L0;\n",
       "
+11:     cdef int result = 0
\n", "
  __pyx_v_result = 0;\n",
       "
+12:     cdef double q = 1.0 - p
\n", "
  __pyx_v_q = (1.0 - __pyx_v_p);\n",
       "
+13:     cdef double current_proba = q**n
\n", "
  __pyx_v_current_proba = pow(__pyx_v_q, ((double)__pyx_v_n));\n",
       "
+14:     cdef double cum_proba = current_proba
\n", "
  __pyx_v_cum_proba = __pyx_v_current_proba;\n",
       "
+15:     cdef double one_uniform_sample = random.random()
\n", "
  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_random); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 15, __pyx_L1_error)\n",
       "  __Pyx_GOTREF(__pyx_t_3);\n",
       "  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_random); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 15, __pyx_L1_error)\n",
       "  __Pyx_GOTREF(__pyx_t_2);\n",
       "  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;\n",
       "  __pyx_t_3 = NULL;\n",
       "  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {\n",
       "    __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);\n",
       "    if (likely(__pyx_t_3)) {\n",
       "      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);\n",
       "      __Pyx_INCREF(__pyx_t_3);\n",
       "      __Pyx_INCREF(function);\n",
       "      __Pyx_DECREF_SET(__pyx_t_2, function);\n",
       "    }\n",
       "  }\n",
       "  __pyx_t_4 = (__pyx_t_3) ? __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3) : __Pyx_PyObject_CallNoArg(__pyx_t_2);\n",
       "  __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;\n",
       "  if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 15, __pyx_L1_error)\n",
       "  __Pyx_GOTREF(__pyx_t_4);\n",
       "  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;\n",
       "  __pyx_t_10 = __pyx_PyFloat_AsDouble(__pyx_t_4); if (unlikely((__pyx_t_10 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 15, __pyx_L1_error)\n",
       "  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n",
       "  __pyx_v_one_uniform_sample = __pyx_t_10;\n",
       "
+16:     while cum_proba < one_uniform_sample:
\n", "
  while (1) {\n",
       "    __pyx_t_1 = ((__pyx_v_cum_proba < __pyx_v_one_uniform_sample) != 0);\n",
       "    if (!__pyx_t_1) break;\n",
       "
+17:         current_proba *= (p * (n - result)) / (q * (result + 1))
\n", "
    __pyx_t_10 = (__pyx_v_p * (__pyx_v_n - __pyx_v_result));\n",
       "    __pyx_t_11 = (__pyx_v_q * (__pyx_v_result + 1));\n",
       "    if (unlikely(__pyx_t_11 == 0)) {\n",
       "      PyErr_SetString(PyExc_ZeroDivisionError, \"float division\");\n",
       "      __PYX_ERR(0, 17, __pyx_L1_error)\n",
       "    }\n",
       "    __pyx_v_current_proba = (__pyx_v_current_proba * (__pyx_t_10 / __pyx_t_11));\n",
       "
+18:         cum_proba += current_proba
\n", "
    __pyx_v_cum_proba = (__pyx_v_cum_proba + __pyx_v_current_proba);\n",
       "
+19:         result += 1
\n", "
    __pyx_v_result = (__pyx_v_result + 1);\n",
       "  }\n",
       "
+20:     return result
\n", "
  __Pyx_XDECREF(__pyx_r);\n",
       "  __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_result); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 20, __pyx_L1_error)\n",
       "  __Pyx_GOTREF(__pyx_t_4);\n",
       "  __pyx_r = __pyx_t_4;\n",
       "  __pyx_t_4 = 0;\n",
       "  goto __pyx_L0;\n",
       "
" ], "text/plain": [ "" ] }, "execution_count": 112, "metadata": {}, "output_type": "execute_result" } ], "source": [ "%%cython --annotate\n", "\n", "import random\n", "\n", "def cython_inversion_binomial(int n, double p) -> int:\n", " if p <= 1e-9:\n", " return 0\n", " if p >= 1 - 1e-9:\n", " return n\n", " if p > 0.5: # speed up by computing for q and then substracting\n", " return n - cython_inversion_binomial(n, 1.0 - p)\n", " cdef int result = 0\n", " cdef double q = 1.0 - p\n", " cdef double current_proba = q**n\n", " cdef double cum_proba = current_proba\n", " cdef double one_uniform_sample = random.random()\n", " while cum_proba < one_uniform_sample:\n", " current_proba *= (p * (n - result)) / (q * (result + 1))\n", " cum_proba += current_proba\n", " result += 1\n", " return result" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's try out." ] }, { "cell_type": "code", "execution_count": 113, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "[1, 1, 1, 1, 0]" ] }, "execution_count": 113, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[ cython_inversion_binomial(10, 0.1) for _ in range(5) ]" ] }, { "cell_type": "code", "execution_count": 114, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[7, 9, 4, 4, 5]" ] }, "execution_count": 114, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[ cython_inversion_binomial(10, 0.5) for _ in range(5) ]" ] }, { "cell_type": "code", "execution_count": 115, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "[9, 7, 10, 9, 4]" ] }, "execution_count": 115, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[ cython_inversion_binomial(10, 0.9) for _ in range(5) ]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It seems to work as wanted!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's plot this out also." ] }, { "cell_type": "code", "execution_count": 116, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "
" ] }, "execution_count": 116, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/plain": [ "(array([279., 0., 371., 0., 227., 0., 97., 0., 20., 6.]),\n", " array([0. , 0.5, 1. , 1.5, 2. , 2.5, 3. , 3.5, 4. , 4.5, 5. ]),\n", " )" ] }, "execution_count": 116, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/plain": [ "Text(0.5, 1.0, '1000 samples from a Binomial distribution with n = 10 and p = 0.12345.')" ] }, "execution_count": 116, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "m = 1000\n", "n = 10\n", "p = 0.12345\n", "X = [ cython_inversion_binomial(n, p) for _ in range(m) ]\n", "plt.figure()\n", "plt.hist(X)\n", "plt.title(f\"{m} samples from a Binomial distribution with n = {n} and p = {p}.\")\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": 117, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "
" ] }, "execution_count": 117, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/plain": [ "(array([ 2., 6., 37., 105., 205., 234., 244., 126., 33., 8.]),\n", " array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.]),\n", " )" ] }, "execution_count": 117, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/plain": [ "Text(0.5, 1.0, '1000 samples from a Binomial distribution with n = 10 and p = 0.5.')" ] }, "execution_count": 117, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "m = 1000\n", "n = 10\n", "p = 0.5\n", "X = [ cython_inversion_binomial(n, p) for _ in range(m) ]\n", "plt.figure()\n", "plt.hist(X)\n", "plt.title(f\"{m} samples from a Binomial distribution with n = {n} and p = {p}.\")\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": 118, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "
" ] }, "execution_count": 118, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/plain": [ "(array([ 7., 0., 0., 0., 0., 99., 0., 0., 0., 894.]),\n", " array([ 8. , 8.2, 8.4, 8.6, 8.8, 9. , 9.2, 9.4, 9.6, 9.8, 10. ]),\n", " )" ] }, "execution_count": 118, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/plain": [ "Text(0.5, 1.0, '1000 samples from a Binomial distribution with n = 10 and p = 0.98765.')" ] }, "execution_count": 118, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "inversion_binomialm = 1000\n", "n = 10\n", "p = 0.98765\n", "X = [ cython_inversion_binomial(n, p) for _ in range(m) ]\n", "plt.figure()\n", "plt.hist(X)\n", "plt.title(f\"{m} samples from a Binomial distribution with n = {n} and p = {p}.\")\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Numerical experiments to check time cost of the different versions" ] }, { "cell_type": "code", "execution_count": 119, "metadata": {}, "outputs": [], "source": [ "n = 100" ] }, { "cell_type": "code", "execution_count": 120, "metadata": {}, "outputs": [ { "data": { "text/plain": [ " int>" ] }, "execution_count": 120, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/plain": [ " int>" ] }, "execution_count": 120, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/plain": [ " int>" ] }, "execution_count": 120, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/plain": [ "" ] }, "execution_count": 120, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/plain": [ " int>" ] }, "execution_count": 120, "metadata": {}, "output_type": "execute_result" } ], "source": [ "naive_binomial\n", "first_inversion_binomial\n", "inversion_binomial\n", "cython_inversion_binomial\n", "numpy_binomial" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can use the `%timeit` magic to check the (mean) computation time of all the previously mentioned functions:" ] }, { "cell_type": "code", "execution_count": 106, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "21.8 µs ± 832 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)\n", "320 µs ± 9.6 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)\n", "2.45 µs ± 154 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)\n", "201 ns ± 31 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)\n", "2.4 µs ± 307 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)\n" ] } ], "source": [ "%timeit naive_binomial(n, 0.123456)\n", "%timeit first_inversion_binomial(n, 0.123456)\n", "%timeit inversion_binomial(n, 0.123456)\n", "%timeit cython_inversion_binomial(n, 0.123456)\n", "%timeit numpy_binomial(n, 0.123456)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Apparently, our `cython` method is faster than the function from `numpy`!\n", "\n", "We also check that our first naive implementation of the inversion method was suboptimal, as announced, because of its pre computation of all the values of $\\mathbb{P}(X=k)$.\n", "However, we check that the naive method, using the sum of $n$ binomial samples, is as comparably efficient to the pure-Python inversion-based method (for this small $n=100$)." ] }, { "cell_type": "code", "execution_count": 121, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "21.6 µs ± 1.38 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)\n", "311 µs ± 16.8 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)\n", "7.86 µs ± 168 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)\n", "309 ns ± 5.56 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)\n", "2.08 µs ± 319 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)\n" ] } ], "source": [ "%timeit naive_binomial(n, 0.5)\n", "%timeit first_inversion_binomial(n, 0.5)\n", "%timeit inversion_binomial(n, 0.5)\n", "%timeit cython_inversion_binomial(n, 0.5)\n", "%timeit numpy_binomial(n, 0.5)" ] }, { "cell_type": "code", "execution_count": 108, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "21 µs ± 629 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)\n", "298 µs ± 6.24 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)\n", "777 ns ± 22.1 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)\n", "208 ns ± 7.2 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)\n", "1.52 µs ± 56 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)\n" ] } ], "source": [ "%timeit naive_binomial(n, 0.987654)\n", "%timeit first_inversion_binomial(n, 0.987654)\n", "%timeit inversion_binomial(n, 0.987654)\n", "%timeit cython_inversion_binomial(n, 0.987654)\n", "%timeit numpy_binomial(n, 0.987654)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It's quite awesome to see that our inversion-based method is more efficient that the numpy function, both in the pure-Python and the Cython versions!\n", "But it's weird, as the numpy function is... based on the inversion method, and itself written in C!\n", "\n", "> See the source code, [numpy/distributions.c line 426](https://github.com/numpy/numpy/blob/7c41164f5340dc998ea1c04d2061f7d246894955/numpy/random/mtrand/distributions.c#L426) (on the 28th February 2019, commit 7c41164).\n", "\n", "But the trick is that the implementation in numpy uses the inversion method (running in $\\Omega(np)$) if $pn < 30$, and a method denoted \"BTPE\" otherwise.\n", "I need to work on this method! The BTPE algorithm is much more complicated, and it is described in the following paper:\n", "\n", "> Kachitvichyanukul, V.; Schmeiser, B. W. (1988). \"Binomial random variate generation\". Communications of the ACM. 31 (2): 216–222. [doi:10.1145/42372.42381](https://doi.org/10.1145%2F42372.42381).\n", "\n", "> See the source code, [numpy/distributions.c line 263](https://github.com/numpy/numpy/blob/7c41164f5340dc998ea1c04d2061f7d246894955/numpy/random/mtrand/distributions.c#L263) (on the 28th February 2019, commit 7c41164)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Checking that sampling from $Bin(n,p)$ requires a time $\\Omega(n)$." ] }, { "cell_type": "code", "execution_count": 123, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "22.3 µs ± 1.26 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)\n", "4.83 µs ± 570 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)\n", "412 ns ± 70.9 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)\n", "1.95 µs ± 173 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)\n" ] } ], "source": [ "n = 100\n", "%timeit naive_binomial(n, random.random())\n", "%timeit inversion_binomial(n, random.random())\n", "%timeit cython_inversion_binomial(n, random.random())\n", "%timeit numpy_binomial(n, random.random())" ] }, { "cell_type": "code", "execution_count": 124, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "228 µs ± 3.58 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)\n", "44 µs ± 2.41 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)\n", "859 ns ± 21.2 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)\n", "1.83 µs ± 201 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)\n" ] } ], "source": [ "n = 1000\n", "%timeit naive_binomial(n, random.random())\n", "%timeit inversion_binomial(n, random.random())\n", "%timeit cython_inversion_binomial(n, random.random())\n", "%timeit numpy_binomial(n, random.random())" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2.62 ms ± 238 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n" ] } ], "source": [ "n = 10000\n", "%timeit naive_binomial(n, random.random())\n", "%timeit inversion_binomial(n, random.random())\n", "%timeit cython_inversion_binomial(n, random.random())\n", "%timeit numpy_binomial(n, random.random())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As we can see, our inversion method (no matter the implementation) runs in $O(n)$ (for $p$ in average $1/2$ in the trials above).\n", "But numpy's implementation is using the BTPE method, which runs in $O(1)$." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Conclusion\n", "\n", "- So I was write, for the inversion method the computation time is in average $O(np)$ so it is $\\Omega(n)$ and cannot be $O(1)$.\n", "- But there has been many algorithms proposed in the literature which achieves a $O(1)$ running time, and the state-of-the-art algorithm is the BTPE method by V. Kachitvichyanukul & B. W. Schmeiser (from 1988). It is implemented in numpy, for the cases when $np > 30$ (that is, as soon as $n>60$ for $p=1/2$).\n", "- So the authors of [[Perturbed-History Exploration in Stochastic Multi-Armed Bandits, by Branislav Kveton, Csaba Szepesvari, Mohammad Ghavamzadeh, Craig Boutilier, 26 Feb 2019, arXiv:1902.10089]](https://arxiv.org/abs/1902.10089) were correct, it can indeed cost $O(1)$ time to generate the sum of $t$ samples from $Bern(1/2)$ (that is, a sample from $Bin(t, 1/2)$)." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "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.6.7" }, "toc": { "colors": { "hover_highlight": "#DAA520", "running_highlight": "#FF0000", "selected_highlight": "#FFD700" }, "moveMenuLeft": true, "nav_menu": { "height": "258.286px", "width": "252px" }, "navigate_menu": true, "number_sections": true, "sideBar": false, "threshold": 4, "toc_cell": true, "toc_position": { "height": "223.705px", "left": "925.384px", "right": "20px", "top": "78px", "width": "166.759px" }, "toc_section_display": "block", "toc_window_display": true } }, "nbformat": 4, "nbformat_minor": 2 }