{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "8e89918fe72e413eb9c76f9ed3819116", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Dropdown(description='Case', options=('Needle drop', 'Error function', 'Test np.random.random()'), value='Need…" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "a3c2db121ec545c491854e3f5534a058", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Output()" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import main\n", "main.run()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The program consists of three primary modules. The module ran_test.py (Test np.random.random() in the dropdown menu) alows the user to visualy verify that np.random.random() generates uniformly distributed pseudo-random numbers on the interval $[0,1)$. To achieve satisfactory runtime 20000 random numbers are generated when the program is started, the only function of the slider is to select how many of those numbers that are used to generate the displayed plots. To generate a new set of random numbers for the test module the program must be restarted. Further, np.where() and np.searchsorted() were used to reduce runtime from $\\approx 10$s when plotting 20000 numbers to $\\approx 0.3$s, this allowed for using a continuously updating slider, to show the development of the graphs as the number of random numbers increases.\n", "\n", "The module needle_drop.py simulates the ''needle drop experiment'' to approximate the value of $\\pi$. Note: The number of points displayed in the plot to the right increases linearly from 100 when $N=10^3$ to 1000 when $N=10^5$ to give a picture of the number of points without making the graph unreadable by displaying too many points. The value is aquired by solving the integral\n", "\\begin{equation}\n", " I = \\frac{1}{2}\\int_0^{\\pi} sin(\\theta)d\\theta\n", "\\end{equation}\n", "numerically. Three methods can be used to solve the integral numerically: Random mean value, random counting and evenly distributed mean value. The first method generates $N$ random values on the intervall $[0,\\pi)$ (yes, we use $\\pi$ to find $\\pi$, I sent a mail to Thomas about another way to do it), evaluates the function in these points and calulates the mean value of the function, $\\pi$ is then given by the inverse of the mean, or:\n", "\\begin{equation}\n", " \\pi \\approx \\frac{N}{\\sum_i^N f(\\theta_i)}\n", "\\end{equation}\n", "the second method generates $N$ $(x,y)$ points on $[0,\\pi] \\times [0,0.5]$, and checks which proportion of the points is below the function curve. $\\pi$ is then given by:\n", "\\begin{equation}\n", " \\pi = \\frac{2N}{N^*}\n", "\\end{equation}\n", "where $N^*$ is the number of points below the curve. This method has significantly longer runtime than the first because twice as many random numbers are generated and it requires $N$ logic-checks (these are likely negiligable compared to the time required to generate numbers). The last method is equivilent to the first, but uses uniformly distributed numbers. The displayed runtimes are recorded for the chosen max N value, runtime for the program is obviously significantly higher, as it must calculate the approximated value of $\\pi$ for all $N$ (with a given stepsize) to generate the displayed plots. \n", "\n", "The module mc_erf.py (Error function in the dropdown menu) uses Monte Carlo integration to approximate the value of \n", "\\begin{equation}\n", " erf(x) = \\frac{2}{\\sqrt{\\pi}}\\int_0^x e^{u^2}du\n", "\\end{equation}\n", "by generating $N$ random points in $[0,x] \\times [0,\\frac{2}{\\sqrt{\\pi}}]$ and finding the fraction of the points that lie beneath the curve\n", "\\begin{equation}\n", " f(x) = \\frac{2}{\\sqrt{\\pi}} e^{x^2}\n", "\\end{equation}\n", "$erf(x)$ is then given by\n", "\\begin{equation}\n", " erf(x) \\approx \\frac{2x}{\\sqrt{\\pi}} \\cdot \\frac{N^*}{N}\n", "\\end{equation}\n", "where $N^*$ is the number of points beneath the curve." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "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.7.1" } }, "nbformat": 4, "nbformat_minor": 2 }