{ "cells": [ { "cell_type": "markdown", "id": "d58b6979", "metadata": {}, "source": [ "# Measurement Error Propagation" ] }, { "cell_type": "markdown", "id": "67f82a55", "metadata": {}, "source": [ "Here, we are interested in estimating the error of our result, provided we know the error of input variables. In experiments, measurements are always known only up to finite precision. It is important to quantify the resulting uncertainty before we can reliably interpret the results of the measurement." ] }, { "cell_type": "markdown", "id": "550d41ee", "metadata": {}, "source": [ "Suppose that we want to calculate error estimation of function $f(x,y)$, where both $x$ and $y$ are known with finite precision. We either have a large number of measurements of $x$ and $y$, or, we might know the probability distribution of measurements and their averages. For now, let's assume \n", "\n", "For now, let's assume that we have measured $x$ and $y$ and have a large number $n$ of measurements with values $[x_0,x_1,...,x_{n-1}]$ and $[y_0,y_1,...,y_{n-1}]$. \n", "Using statistics, we can define\n", "\n", "$$ = \\frac{1}{n}\\sum_{i=0}^{n-1} x_i$$\n", "$$ = \\frac{1}{n}\\sum_{i=0}^{n-1} y_i$$\n", "$$\\sigma_x^2 = \\frac{1}{n-1}\\sum_{i=0}^{n-1} (x_i-)^2$$\n", "$$\\sigma_y^2 = \\frac{1}{n-1}\\sum_{i=0}^{n-1} (y_i-)^2$$" ] }, { "cell_type": "markdown", "id": "6c4d35b6", "metadata": {}, "source": [ "In many experimental measurements we can assume that errors on measurement of $x$ and $y$ are uncorrelated. On the other hand, there are cases of non-negligible correlation between the measurements of different variables. In the latter case, the covariance should also be nonzero:\n", "\n", "$$cov(x,y)=\\frac{1}{n-1}\\sum_{i=0}^{n-1} (x_i-)(y_i-)$$\n", "\n", "$cov(x,y)$ quantifies the degree of correlation between variables $x$ and $y$.\n", "\n", "Using the inputs $$, $$, $\\sigma_x^2$, $\\sigma_y^2$, and $cov(x,y)$, we want to estimate the error of function $f$, which we denote by $\\sigma_f$. \n", "If we have $n$ measurements of $x$ and $y$, we could calculate it by\n", "\n", "$$\\sigma^2_f=\\frac{1}{n-1}\\sum_{i=0}^{n-1}(f_i-)^2$$\n" ] }, { "cell_type": "markdown", "id": "ed32e3b2", "metadata": {}, "source": [ "Below we will derive general expression for $\\sigma_f$ knowing function $f(x,y)$ and the input variables and their errors.\n", "\n", "We will work under the assumption that erros are small and can be trated in a linear approximation. If only the variable $x$ has finite error, which is small, we could estiate \n", "\n", "$$f(x_i)-f()\\approx (x_i-) \\frac{\\partial f()}{\\partial x}$$\n", "which is correct up to linear order. \n", "It then folows\n", "$$\\sigma^2_f = \\frac{1}{n-1}\\sum_{i=0}^{n-1} (f(x_i)-f())^2= \\frac{1}{n-1}\\sum_{i=0}^{n-1} \n", "(x_i-)^2 \\left(\\frac{\\partial f()}{\\partial x}\\right)^2\n", "= \\left(\\frac{\\partial f()}{\\partial x}\\right)^2 \\sigma^2_x $$\n", "\n", "For shorter notation, we will denote the derivative\n", "$$\\frac{\\partial f()}{\\partial x}\\equiv \\frac{\\partial f}{\\partial x}. $$ Note that we always evaluate derivative at the average value of $x$.\n", "\n", "For single variable with uncertainty, we thus simply have\n", "\n", "$$\\sigma_f = \\left|\\frac{\\partial f}{\\partial x}\\right|\\sigma_x$$" ] }, { "cell_type": "markdown", "id": "9730e6c1", "metadata": {}, "source": [ "If the error of $y$ and $cov$ are also finite, we need to add more terms. We start by estimating\n", "\n", "$$f(x_i,y_i)-f(,)\\approx (x_i-) \\frac{\\partial f}{\\partial x} + (y_i-)\\frac{\\partial f}{\\partial y} + O(\\Delta_x^2,\\Delta_y^2,\\Delta_x\\Delta_y).$$\n", "\n", "Up to linear order in all variables, we have\n", "$$\n", "\\sigma_f^2=\\frac{1}{n-1}\\sum_{i=0}^{n-1} \\left[(x_i-) \\frac{\\partial f}{\\partial x} + (y_i-)\\frac{\\partial f}{\\partial y} \\right]^2\n", "$$\n", "which gives\n", "$$\n", "\\sigma_f^2=\\sigma^2_x \\left(\\frac{\\partial f}{\\partial x}\\right)^2 + \\sigma^2_y \\left(\\frac{\\partial f}{\\partial y}\\right)^2+2cov(x,y)\\frac{\\partial f}{\\partial x}\\frac{\\partial f}{\\partial y}\n", "$$\n", "\n", "We can also write this equation in matrix form\n", "$$\n", "\\sigma_f^2 = \n", "\\begin{bmatrix}\\frac{\\partial f}{\\partial x},&\\frac{\\partial f}{\\partial y}\n", "\\end{bmatrix}\n", "\\begin{bmatrix}\n", "\\sigma^2_x & cov(x,y)\\\\\n", "cov(x,y) & \\sigma^2_y\n", "\\end{bmatrix}\n", "\\begin{bmatrix}\\frac{\\partial f}{\\partial x}\\\\\n", " \\frac{\\partial f}{\\partial y}\n", "\\end{bmatrix}\n", "$$\n", "\n", "Now it is easy to generalize this equation to any number of variables\n", "$$\n", "\\sigma_f^2 = \n", "\\begin{bmatrix}\\frac{\\partial f}{\\partial x_1},&\\frac{\\partial f}{\\partial x_2},&\n", "\\frac{\\partial f}{\\partial x_3},...\n", "\\end{bmatrix}\n", "\\begin{bmatrix}\n", "\\sigma^2_{x_1} & cov(x_1,x_2) & cov(x_1,x_3) & ...\\\\\n", "cov(x_2,x_1) & \\sigma^2_{x_2} & cov(x_2,x_3) & ...\\\\\n", "cov(x_3,x_1) & cov(x_3,x_2) & \\sigma^2_{x_3} & ...\\\\\n", "...\n", "\\end{bmatrix}\n", "\\begin{bmatrix}\\frac{\\partial f}{\\partial x_1}\\\\\n", " \\frac{\\partial f}{\\partial x_2}\\\\\n", " \\frac{\\partial f}{\\partial x_3}\\\\\n", " ...\n", "\\end{bmatrix}\n", "$$" ] }, { "cell_type": "markdown", "id": "1b15c531", "metadata": {}, "source": [ "The following demonstrates covariance with a set of measurements of variables $x$ and $y$: We display 400 random measurements (black dots) which have the same means (white squares) but different covariance structures. The marginal distributions of the $x$ and $y$ variables are shown as ‘bell curves’ on the top and right axis of each plot.\n", "\n", "\n" ] }, { "cell_type": "markdown", "id": "87a4c546", "metadata": {}, "source": [ "Often we do not have many measurements, but we know the probability distribution of measurement $P(x)$, and we need to compute the variance from the distribution. The formulas are straighforard generalization of discrete formulas\n", "\n", "$$\\sigma_x^2 = \\int dx P(x) (x-)^2$$\n", "where probability is normalized\n", "$$ \\int dx P(x)=1 $$ and average is given by\n", "$$ = \\int dx P(x) x$$\n", "\n", "We can check that with discrete probability distribution defined by\n", "$$P(x) = \\frac{1}{n}\\sum_{i=0}^{n-1} \\delta(x-x_i)$$\n", "we recover the discrete formulas, except that $n-1$ is replaced by $n$ in estimation of variance. For continuum distributions it is assumed that $n$ is very large, hence the two formulas are equivalent." ] }, { "cell_type": "markdown", "id": "086dab73", "metadata": {}, "source": [ "As an example we consider uniform distribution between $[-a,a]$. The probability is than \n", "$$P(x) = \\frac{1}{2a} \\theta(-a=0$ and \n", "$$\\sigma^2_x = \\frac{1}{2a}\\int_{-a}^a x^2 dx=\\frac{a^2}{3} $$\n", "and hence $\\sigma_x = \\frac{a}{\\sqrt{3}}$.\n", "\n", "As the second example we consider triangular distribution between $[-a,a]$. The probability is \n", "\n", "$$P(x) = \\frac{1}{a}\\left(1-\\left|\\frac{x}{a}\\right|\\right) \\theta(-a=0$ and \n", "$$\\sigma^2_x = \\frac{1}{a}\\int_{-a}^a \\left(1-\\left|\\frac{x}{a}\\right|\\right)x^2 dx=\\frac{a^2}{6} $$ hence $\\sigma_x = \\frac{a}{\\sqrt{6}}$" ] }, { "cell_type": "code", "execution_count": 46, "id": "c1a9fc6e", "metadata": {}, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import numpy as np\n", "import matplotlib.pyplot as plt\n", "\n", "N=200\n", "x=np.linspace(-2,2,N)\n", "yuniform=np.hstack( (np.zeros(int(N/4)),0.5*np.ones(int(N/2)),np.zeros(int(N/4)) ))\n", "ytriang= [0 if abs(t)>1 else 1.-abs(t) for t in x]\n", "plt.plot(x,yuniform, label='P(uniform)')\n", "plt.plot(x,ytriang, label='P(triangular)')\n", "plt.legend(loc='best');" ] }, { "cell_type": "markdown", "id": "ad7746a2", "metadata": {}, "source": [ "As a simplest example, assume that we want to calculate person's body mass index (BMI), which is the ratio of \n", "$$\\textrm{BMI} = \\frac{\\textrm{body_mass}(kg)}{[\\textrm{body_height}(m)]^2}.$$\n", "It is often used as an (imperfect) indicator of obesity or malnutrition.\n", "\n", "Suppose that the scale tells you that your weigh is 84 kg, but has precision to the nearest kilogram. The tape measure says you are between 181 and 182 cm tall, most likely 181.5cm. \n", "\n", "We can safely assume that measurements of height and weight are uncorrelated, i.e., error in measuring weight is not affected by the way we measure height: $cov(m,l)=0$.\n", "\n", "We can say that probability for mass $m$ is uniformly distributed between 83.5 kg and 84.5 kg. The probability for height has most likely triangular probability distribution between 1.81 m and 1.82 m.\n", "\n", "\n", "The uniform distribution between $83.5$ and $84.5$ has variance $\\sigma_m = 0.5/\\sqrt{3}=0.2887$ kg.\n", "The triangular distribution between 1.81 and 1.82 cm has variance $\\sigma_h=0.005/\\sqrt{6}=0.00204$\n", "\n", "$$ BMI = \\frac{m}{h^2} $$\n", "$$ \\frac{\\partial BMI}{\\partial m} = \\frac{1}{h^2} $$\n", "$$ \\frac{\\partial BMI}{\\partial h} = -\\frac{2m}{h^3}$$\n", "$$\\sigma_{BMI} = \\sqrt{\\frac{1}{h^4}\\sigma^2_m + \\frac{4 m^2}{h^6}\\sigma^2_h}$$" ] }, { "cell_type": "markdown", "id": "35cf75db", "metadata": {}, "source": [ "Below we compute BMI and its error using just derived formulas:" ] }, { "cell_type": "code", "execution_count": 44, "id": "6a57bb6e", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[25.49916900029597, 0.10473188414630029]" ] }, "execution_count": 44, "metadata": {}, "output_type": "execute_result" } ], "source": [ "mi = 84; sm = 0.5/sqrt(3); # average mass and its variance\n", "hi = 1.815; sh=0.005/sqrt(6); # average height and its variance\n", "\n", "# BMI and its variance\n", "[mi/hi**2 , sqrt(sm**2/hi**4+sh**2*4*mi**2/hi**6)]" ] }, { "cell_type": "markdown", "id": "8f9160cb", "metadata": {}, "source": [ "Python provides package `uncertainties`, which has capabilities to automatically differentiate any function, and propagate error. \n", "\n", "Here we demonstrate it on the example of BMI:" ] }, { "cell_type": "code", "execution_count": 45, "id": "47437a20", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "25.49916900029597+/-0.10473188414630027" ] }, "execution_count": 45, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from uncertainties import ufloat\n", "from uncertainties.umath import * # functions like sin(), etc.\n", "\n", "m = ufloat(84,0.5/sqrt(3))\n", "l = ufloat(1.815,0.005/sqrt(6))\n", "\n", "m/l**2" ] }, { "cell_type": "markdown", "id": "6c7174e3", "metadata": {}, "source": [ "Clearly our derivation agrees with the package, and we are on the right track." ] }, { "cell_type": "markdown", "id": "27765aba", "metadata": {}, "source": [ "### Stochastic solution\n", "\n", "If we do not have the analytical form of the function, it is sometimes hard to differentiate it. The solution with Monte Carlo is more robust and straightforward. The idea is to throw many points with the correct distribution and analyze the resulting distribution of points. Essentially, we go from continuous functions to a discrete representation by a random sample of Monte Carlo points.\n" ] }, { "cell_type": "code", "execution_count": 61, "id": "36f27ab9", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "25.499446219636475 ± 0.1046575342925108\n" ] }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjMAAAGdCAYAAADnrPLBAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAuD0lEQVR4nO3df3RUdX7/8ddsfoxIkyshJJNoyKKLlBrK8sOFIAoIBLIGilJBsSkoDdsF8cTAcY2uBTwuUazitny1lLKggEK7FbXKiQQFLCf81igoi6iosCaEpckMQZwE+Hz/sNw6JCgJM8l8wvNxzj0nc+9n7nzu5wzOy/f93Hs9xhgjAAAAS/2orTsAAABwMQgzAADAaoQZAABgNcIMAACwGmEGAABYjTADAACsRpgBAABWI8wAAACrxbZ1ByLlzJkz+uqrr5SQkCCPx9PW3QEAABfAGKPjx48rPT1dP/rRhdVc2m2Y+eqrr5SRkdHW3QAAAC1w6NAhXXXVVRfUtt2GmYSEBEnfDkZiYmIb9wYAAFyIQCCgjIwM93f8QrTbMHP21FJiYiJhBgAAyzRniggTgAEAgNWaFWZKSkp0/fXXKyEhQSkpKRo3bpz2798f0sYYo7lz5yo9PV0dOnTQ0KFD9eGHH4a0CQaDmjlzppKTk9WxY0eNHTtWhw8fDmlTU1Oj/Px8OY4jx3GUn5+v2tralh0lAABot5oVZjZv3qwZM2Zo27ZtKisr06lTp5STk6MTJ064bRYsWKCnn35aixYt0s6dO+Xz+TRy5EgdP37cbVNYWKi1a9dq9erV2rJli+rq6pSXl6fTp0+7bSZNmqSKigqVlpaqtLRUFRUVys/PD8MhAwCAdsVchOrqaiPJbN682RhjzJkzZ4zP5zOPP/642+abb74xjuOYf/mXfzHGGFNbW2vi4uLM6tWr3TZ//OMfzY9+9CNTWlpqjDHmo48+MpLMtm3b3DZbt241kswf/vCHC+qb3+83kozf77+YQwQAAK2oJb/fFzVnxu/3S5KSkpIkSQcPHlRVVZVycnLcNl6vV0OGDFF5ebkkaffu3WpoaAhpk56erqysLLfN1q1b5TiOBgwY4LYZOHCgHMdx2wAAAEgXcTWTMUZFRUUaPHiwsrKyJElVVVWSpNTU1JC2qamp+uKLL9w28fHx6tSpU6M2Z99fVVWllJSURp+ZkpLitjlXMBhUMBh0XwcCgRYeGQAAsEmLKzP33nuvPvjgA7300kuNtp17OZUx5gcvsTq3TVPtv28/JSUl7mRhx3G4YR4AAJeIFoWZmTNn6rXXXtPGjRtD7s7n8/kkqVH1pLq62q3W+Hw+1dfXq6am5nvbHDlypNHnHj16tFHV56zi4mL5/X53OXToUEsODQAAWKZZYcYYo3vvvVcvv/yy3n77bXXr1i1ke7du3eTz+VRWVuauq6+v1+bNmzVo0CBJUr9+/RQXFxfSprKyUnv37nXbZGdny+/3a8eOHW6b7du3y+/3u23O5fV63RvkcaM8AAAuHc2aMzNjxgy9+OKLevXVV5WQkOBWYBzHUYcOHeTxeFRYWKj58+ere/fu6t69u+bPn6/LL79ckyZNcttOnTpVs2bNUufOnZWUlKTZs2erV69eGjFihCSpZ8+eGj16tAoKCrR48WJJ0rRp05SXl6cePXqE8/gBAIDlmhVmnnvuOUnS0KFDQ9YvW7ZMU6ZMkSQ98MADOnnypKZPn66amhoNGDBA69evD3nGwsKFCxUbG6sJEybo5MmTGj58uJYvX66YmBi3zapVq3Tfffe5Vz2NHTtWixYtaskxAgCAdsxjjDFt3YlICAQCchxHfr+fU04AAFiiJb/fPJsJAABYjTADAACs1uKb5gHAhVhY9nHI6/tHXttGPQHQXlGZAQAAVqMyAyBszq3CRCMqRUD7Q2UGAABYjTADAACsRpgBAABWY84MgFbV1Lwa5q0AuBiEGQAtZsOEXwDtH2EGQNShegOgOZgzAwAArEaYAQAAViPMAAAAqzFnBoCVmFcD4CwqMwAAwGqEGQAAYDXCDAAAsBphBgAAWI0JwADaXLTdSfjc/jCxGIhuhBkA7QYhBLg0EWYAWCHaqjcAogdhBkC71dYBiEoR0DoIMwCaxA8xAFsQZgC0eQUj2l3I3YYvZAy5azEQGVyaDQAArEZlBsAljaoUYD8qMwAAwGqEGQAAYDVOMwHtHJNOAbR3hBkAaAHm2gDRg9NMAADAalRmgEtQS6oKVCIARCsqMwAAwGqEGQAAYLVmh5l33nlHY8aMUXp6ujwej1555ZWQ7R6Pp8nlySefdNsMHTq00fY77rgjZD81NTXKz8+X4zhyHEf5+fmqra1t0UECAID2q9lh5sSJE+rdu7cWLVrU5PbKysqQ5Xe/+508Ho/Gjx8f0q6goCCk3eLFi0O2T5o0SRUVFSotLVVpaakqKiqUn5/f3O4CAIB2rtkTgHNzc5Wbm3ve7T6fL+T1q6++qmHDhunqq68OWX/55Zc3anvWvn37VFpaqm3btmnAgAGSpCVLlig7O1v79+9Xjx49mtttAIhKPJ0cuHgRnTNz5MgRvfHGG5o6dWqjbatWrVJycrKuu+46zZ49W8ePH3e3bd26VY7juEFGkgYOHCjHcVReXt7kZwWDQQUCgZAFAAC0fxG9NPv5559XQkKCbrvttpD1d911l7p16yafz6e9e/equLhY77//vsrKyiRJVVVVSklJabS/lJQUVVVVNflZJSUlmjdvXvgPAgAARLWIhpnf/e53uuuuu3TZZZeFrC8oKHD/zsrKUvfu3dW/f3+9++676tu3r6RvJxKfyxjT5HpJKi4uVlFRkfs6EAgoIyMjHIcBAACiWMTCzH//939r//79WrNmzQ+27du3r+Li4nTgwAH17dtXPp9PR44cadTu6NGjSk1NbXIfXq9XXq/3ovsN2ITnLgFABOfMLF26VP369VPv3r1/sO2HH36ohoYGpaWlSZKys7Pl9/u1Y8cOt8327dvl9/s1aNCgSHUZAABYqNmVmbq6On3yySfu64MHD6qiokJJSUnq2rWrpG9P8fzHf/yHnnrqqUbv//TTT7Vq1Sr9/Oc/V3Jysj766CPNmjVLffr00Q033CBJ6tmzp0aPHq2CggL3ku1p06YpLy+PK5kAAECIZldmdu3apT59+qhPnz6SpKKiIvXp00f/8A//4LZZvXq1jDG68847G70/Pj5eb731lkaNGqUePXrovvvuU05OjjZs2KCYmBi33apVq9SrVy/l5OQoJydHf/mXf6kVK1a05BgBAEA75jHGmLbuRCQEAgE5jiO/36/ExMS27g4QERcyZ4YHRNqlqTlP3IsGl5KW/H7zbCYAAGA1wgwAALAaYQYAAFgtojfNAwA0D3OcgOajMgMAAKxGmAEAAFYjzAAAAKsxZwawyIXMp2DOBYBLDZUZAABgNcIMAACwGmEGAABYjTADAACsRpgBAABWI8wAAACrEWYAAIDVCDMAAMBq3DQPACzT1I0R7x95bRv0BIgOVGYAAIDVqMwAQDtE9QaXEiozAADAaoQZAABgNcIMAACwGmEGAABYjTADAACsRpgBAABW49JsIEo1dWktAKAxKjMAAMBqhBkAAGA1TjMBUYLTSgDQMlRmAACA1QgzAADAapxmAoB2gNOUuJRRmQEAAFajMgO0Af4vGgDCp9mVmXfeeUdjxoxRenq6PB6PXnnllZDtU6ZMkcfjCVkGDhwY0iYYDGrmzJlKTk5Wx44dNXbsWB0+fDikTU1NjfLz8+U4jhzHUX5+vmpra5t9gAAAoH1rdpg5ceKEevfurUWLFp23zejRo1VZWeku69atC9leWFiotWvXavXq1dqyZYvq6uqUl5en06dPu20mTZqkiooKlZaWqrS0VBUVFcrPz29udwEAQDvX7NNMubm5ys3N/d42Xq9XPp+vyW1+v19Lly7VihUrNGLECEnSypUrlZGRoQ0bNmjUqFHat2+fSktLtW3bNg0YMECStGTJEmVnZ2v//v3q0aNHc7sNAADaqYjMmdm0aZNSUlJ0xRVXaMiQIfrNb36jlJQUSdLu3bvV0NCgnJwct316erqysrJUXl6uUaNGaevWrXIcxw0ykjRw4EA5jqPy8vImw0wwGFQwGHRfBwKBSBwaAFjr3Lla94+8to16AoRX2K9mys3N1apVq/T222/rqaee0s6dO3XzzTe7QaOqqkrx8fHq1KlTyPtSU1NVVVXltjkbfr4rJSXFbXOukpISd36N4zjKyMgI85EBAIBoFPbKzMSJE92/s7Ky1L9/f2VmZuqNN97Qbbfddt73GWPk8Xjc19/9+3xtvqu4uFhFRUXu60AgQKABAOASEPH7zKSlpSkzM1MHDhyQJPl8PtXX16umpiakXXV1tVJTU902R44cabSvo0ePum3O5fV6lZiYGLIAAID2L+L3mTl27JgOHTqktLQ0SVK/fv0UFxensrIyTZgwQZJUWVmpvXv3asGCBZKk7Oxs+f1+7dixQz/72c8kSdu3b5ff79egQYMi3WUg7LivDABETrPDTF1dnT755BP39cGDB1VRUaGkpCQlJSVp7ty5Gj9+vNLS0vT555/roYceUnJysm699VZJkuM4mjp1qmbNmqXOnTsrKSlJs2fPVq9evdyrm3r27KnRo0eroKBAixcvliRNmzZNeXl5XMkEAABCNDvM7Nq1S8OGDXNfn52nMnnyZD333HPas2ePXnjhBdXW1iotLU3Dhg3TmjVrlJCQ4L5n4cKFio2N1YQJE3Ty5EkNHz5cy5cvV0xMjNtm1apVuu+++9yrnsaOHfu997YBAACXJo8xxrR1JyIhEAjIcRz5/X7mz6DNcZoJtuBybbS1lvx+86BJAABgNcIMAACwGmEGAABYjTADAACsFvH7zACXGib7AkDrojIDAACsRpgBAABWI8wAAACrEWYAAIDVCDMAAMBqhBkAAGA1wgwAALAaYQYAAFiNMAMAAKxGmAEAAFYjzAAAAKsRZgAAgNUIMwAAwGo8NRu4SDwlG+3Jud/n+0de20Y9AS4clRkAAGA1wgwAALAaYQYAAFiNMAMAAKxGmAEAAFYjzAAAAKsRZgAAgNW4zwzQDNxTBgCiD5UZAABgNcIMAACwGmEGAABYjTkzAIDzamqeGM9rQrShMgMAAKxGmAEAAFbjNBMAoFnOPfXEaSe0tWZXZt555x2NGTNG6enp8ng8euWVV9xtDQ0N+tWvfqVevXqpY8eOSk9P19/+7d/qq6++CtnH0KFD5fF4QpY77rgjpE1NTY3y8/PlOI4cx1F+fr5qa2tbdJAAAKD9anZl5sSJE+rdu7fuvvtujR8/PmTb119/rXfffVePPPKIevfurZqaGhUWFmrs2LHatWtXSNuCggI9+uij7usOHTqEbJ80aZIOHz6s0tJSSdK0adOUn5+v//qv/2pulwEAEcQkYbS1ZoeZ3Nxc5ebmNrnNcRyVlZWFrPvnf/5n/exnP9OXX36prl27uusvv/xy+Xy+Jvezb98+lZaWatu2bRowYIAkacmSJcrOztb+/fvVo0eP5nYbAAC0UxGfM+P3++XxeHTFFVeErF+1apVWrlyp1NRU5ebmas6cOUpISJAkbd26VY7juEFGkgYOHCjHcVReXt5kmAkGgwoGg+7rQCAQmQPCJYXHFwBA9ItomPnmm2/04IMPatKkSUpMTHTX33XXXerWrZt8Pp/27t2r4uJivf/++25Vp6qqSikpKY32l5KSoqqqqiY/q6SkRPPmzYvMgQAAgKgVsTDT0NCgO+64Q2fOnNGzzz4bsq2goMD9OysrS927d1f//v317rvvqm/fvpIkj8fTaJ/GmCbXS1JxcbGKiorc14FAQBkZGeE4FAAAEMUiEmYaGho0YcIEHTx4UG+//XZIVaYpffv2VVxcnA4cOKC+ffvK5/PpyJEjjdodPXpUqampTe7D6/XK6/WGpf8AAMAeYb9p3tkgc+DAAW3YsEGdO3f+wfd8+OGHamhoUFpamiQpOztbfr9fO3bscNts375dfr9fgwYNCneXAQCAxZpdmamrq9Mnn3zivj548KAqKiqUlJSk9PR0/fVf/7Xeffddvf766zp9+rQ7xyUpKUnx8fH69NNPtWrVKv385z9XcnKyPvroI82aNUt9+vTRDTfcIEnq2bOnRo8erYKCAi1evFjSt5dm5+XlcSUTAAAI0ewws2vXLg0bNsx9fXaeyuTJkzV37ly99tprkqSf/vSnIe/buHGjhg4dqvj4eL311lv67W9/q7q6OmVkZOiWW27RnDlzFBMT47ZftWqV7rvvPuXk5EiSxo4dq0WLFjX7AAEAQPvmMcaYtu5EJAQCATmOI7/f/4NzdoDz4dJsoGW4aR5aqiW/3zxoEgAAWI0wAwAArEaYAQAAViPMAAAAq0X82UyALZjsCwB2ojIDAACsRpgBAABWI8wAAACrEWYAAIDVCDMAAMBqhBkAAGA1wgwAALAaYQYAAFiNm+YBACKuqZtS8mRthAthBgAQdtxRG62J00wAAMBqVGZwSeL/GgGg/aAyAwAArEaYAQAAViPMAAAAqxFmAACA1QgzAADAaoQZAABgNcIMAACwGmEGAABYjTADAACsRpgBAABWI8wAAACrEWYAAIDVCDMAAMBqhBkAAGA1wgwAALBabFt3AGgNC8s+busuAAAihMoMAACwWrPDzDvvvKMxY8YoPT1dHo9Hr7zySsh2Y4zmzp2r9PR0dejQQUOHDtWHH34Y0iYYDGrmzJlKTk5Wx44dNXbsWB0+fDikTU1NjfLz8+U4jhzHUX5+vmpra5t9gAAAoH1rdpg5ceKEevfurUWLFjW5fcGCBXr66ae1aNEi7dy5Uz6fTyNHjtTx48fdNoWFhVq7dq1Wr16tLVu2qK6uTnl5eTp9+rTbZtKkSaqoqFBpaalKS0tVUVGh/Pz8FhwiAABozzzGGNPiN3s8Wrt2rcaNGyfp26pMenq6CgsL9atf/UrSt1WY1NRUPfHEE/rFL34hv9+vLl26aMWKFZo4caIk6auvvlJGRobWrVunUaNGad++ffqLv/gLbdu2TQMGDJAkbdu2TdnZ2frDH/6gHj16/GDfAoGAHMeR3+9XYmJiSw8R7QRzZoDoc//Ia9u6C4hCLfn9DuucmYMHD6qqqko5OTnuOq/XqyFDhqi8vFyStHv3bjU0NIS0SU9PV1ZWlttm69atchzHDTKSNHDgQDmO47Y5VzAYVCAQCFkAAED7F9armaqqqiRJqampIetTU1P1xRdfuG3i4+PVqVOnRm3Ovr+qqkopKSmN9p+SkuK2OVdJSYnmzZt30ccAAGgd51ZMqdSgpSJyNZPH4wl5bYxptO5c57Zpqv337ae4uFh+v99dDh061IKeAwAA24Q1zPh8PklqVD2prq52qzU+n0/19fWqqan53jZHjhxptP+jR482qvqc5fV6lZiYGLIAAID2L6xhplu3bvL5fCorK3PX1dfXa/PmzRo0aJAkqV+/foqLiwtpU1lZqb1797ptsrOz5ff7tWPHDrfN9u3b5ff73TYAAABSC+bM1NXV6ZNPPnFfHzx4UBUVFUpKSlLXrl1VWFio+fPnq3v37urevbvmz5+vyy+/XJMmTZIkOY6jqVOnatasWercubOSkpI0e/Zs9erVSyNGjJAk9ezZU6NHj1ZBQYEWL14sSZo2bZry8vIu6EomAABw6Wh2mNm1a5eGDRvmvi4qKpIkTZ48WcuXL9cDDzygkydPavr06aqpqdGAAQO0fv16JSQkuO9ZuHChYmNjNWHCBJ08eVLDhw/X8uXLFRMT47ZZtWqV7rvvPveqp7Fjx5733jYAAODSdVH3mYlm3GcG38V9ZoDox9VMkKLgPjMAAACtjTADAACsRpgBAABWI8wAAACrEWYAAIDVCDMAAMBqhBkAAGA1wgwAALAaYQYAAFiNMAMAAKzW7GczAdGGRxUAwKWNygwAALAaYQYAAFiNMAMAAKxGmAEAAFYjzAAAAKsRZgAAgNUIMwAAwGrcZwYAEBUu5J5R94+8thV6AttQmQEAAFYjzAAAAKsRZgAAgNUIMwAAwGqEGQAAYDXCDAAAsBphBgAAWI37zMAqF3IfCgDApYXKDAAAsBphBgAAWI0wAwAArEaYAQAAViPMAAAAqxFmAACA1QgzAADAamEPMz/+8Y/l8XgaLTNmzJAkTZkypdG2gQMHhuwjGAxq5syZSk5OVseOHTV27FgdPnw43F0FAADtQNjDzM6dO1VZWekuZWVlkqTbb7/dbTN69OiQNuvWrQvZR2FhodauXavVq1dry5YtqqurU15enk6fPh3u7gIAAMuF/Q7AXbp0CXn9+OOP65prrtGQIUPcdV6vVz6fr8n3+/1+LV26VCtWrNCIESMkSStXrlRGRoY2bNigUaNGhbvLAADAYhGdM1NfX6+VK1fqnnvukcfjcddv2rRJKSkpuvbaa1VQUKDq6mp32+7du9XQ0KCcnBx3XXp6urKyslReXn7ezwoGgwoEAiELAABo/yL6bKZXXnlFtbW1mjJlirsuNzdXt99+uzIzM3Xw4EE98sgjuvnmm7V79255vV5VVVUpPj5enTp1CtlXamqqqqqqzvtZJSUlmjdvXqQOBW2EZzEBAH5IRMPM0qVLlZubq/T0dHfdxIkT3b+zsrLUv39/ZWZm6o033tBtt9123n0ZY0KqO+cqLi5WUVGR+zoQCCgjI+MijwAAAES7iIWZL774Qhs2bNDLL7/8ve3S0tKUmZmpAwcOSJJ8Pp/q6+tVU1MTUp2prq7WoEGDzrsfr9crr9cbns4DAABrRCzMLFu2TCkpKbrlllu+t92xY8d06NAhpaWlSZL69eunuLg4lZWVacKECZKkyspK7d27VwsWLIhUdwEAFmjq1PP9I69tg54gmkQkzJw5c0bLli3T5MmTFRv7fx9RV1enuXPnavz48UpLS9Pnn3+uhx56SMnJybr11lslSY7jaOrUqZo1a5Y6d+6spKQkzZ49W7169XKvbgIAADgrImFmw4YN+vLLL3XPPfeErI+JidGePXv0wgsvqLa2VmlpaRo2bJjWrFmjhIQEt93ChQsVGxurCRMm6OTJkxo+fLiWL1+umJiYSHQXAABYzGOMMW3diUgIBAJyHEd+v1+JiYlt3R20EFczAfghnGZqX1ry+82zmQAAgNUIMwAAwGqEGQAAYDXCDAAAsBphBgAAWI0wAwAArEaYAQAAViPMAAAAqxFmAACA1SL2oEkAAFrDuXcK547Alx7CDKIGjy4AALQEp5kAAIDVCDMAAMBqhBkAAGA1wgwAALAaYQYAAFiNq5nQZrh6CQAQDlRmAACA1QgzAADAapxmAgC0e02d1uZOwe0HYQYA0K4wH+/Sw2kmAABgNcIMAACwGmEGAABYjTADAACsRpgBAABWI8wAAACrEWYAAIDVCDMAAMBqhBkAAGA1wgwAALAaYQYAAFiNMAMAAKxGmAEAAFYLe5iZO3euPB5PyOLz+dztxhjNnTtX6enp6tChg4YOHaoPP/wwZB/BYFAzZ85UcnKyOnbsqLFjx+rw4cPh7ipa0cKyjxstAACEQ0QqM9ddd50qKyvdZc+ePe62BQsW6Omnn9aiRYu0c+dO+Xw+jRw5UsePH3fbFBYWau3atVq9erW2bNmiuro65eXl6fTp05HoLgAAsFhsRHYaGxtSjTnLGKNnnnlGDz/8sG677TZJ0vPPP6/U1FS9+OKL+sUvfiG/36+lS5dqxYoVGjFihCRp5cqVysjI0IYNGzRq1KhIdBkAcIk5t0J8/8hr26gnuFgRqcwcOHBA6enp6tatm+644w599tlnkqSDBw+qqqpKOTk5bluv16shQ4aovLxckrR79241NDSEtElPT1dWVpbbpinBYFCBQCBkAQAA7V/Yw8yAAQP0wgsv6M0339SSJUtUVVWlQYMG6dixY6qqqpIkpaamhrwnNTXV3VZVVaX4+Hh16tTpvG2aUlJSIsdx3CUjIyPMRwYAAKJR2MNMbm6uxo8fr169emnEiBF64403JH17Ouksj8cT8h5jTKN15/qhNsXFxfL7/e5y6NChizgKAABgi4jMmfmujh07qlevXjpw4IDGjRsn6dvqS1pamtumurrardb4fD7V19erpqYmpDpTXV2tQYMGnfdzvF6vvF5vZA4CzcbVSgCA1hLx+8wEg0Ht27dPaWlp6tatm3w+n8rKytzt9fX12rx5sxtU+vXrp7i4uJA2lZWV2rt37/eGGQAAcGkKe2Vm9uzZGjNmjLp27arq6mo99thjCgQCmjx5sjwejwoLCzV//nx1795d3bt31/z583X55Zdr0qRJkiTHcTR16lTNmjVLnTt3VlJSkmbPnu2etgIAAPiusIeZw4cP684779Sf/vQndenSRQMHDtS2bduUmZkpSXrggQd08uRJTZ8+XTU1NRowYIDWr1+vhIQEdx8LFy5UbGysJkyYoJMnT2r48OFavny5YmJiwt1dAABgOY8xxrR1JyIhEAjIcRz5/X4lJia2dXcuOcyZAWAb7jMTHVry+82zmQAAgNUIMwAAwGqEGQAAYDXCDAAAsFrEb5oHAIANmrpwgUnBdqAyAwAArEaYAQAAViPMAAAAqxFmAACA1QgzAADAalzNhIvGowsAAG2JygwAALAalRk0G5UYAEA0oTIDAACsRpgBAABW4zQTAADncSGn1XnkQdujMgMAAKxGmAEAAFYjzAAAAKsRZgAAgNUIMwAAwGqEGQAAYDXCDAAAsBphBgAAWI0wAwAArMYdgAEAuAjn3iWYOwK3PiozAADAalRm8L0u5LkkAAC0JSozAADAaoQZAABgNU4zAQAQRk2dnmdScGRRmQEAAFYjzAAAAKsRZgAAgNXCHmZKSkp0/fXXKyEhQSkpKRo3bpz2798f0mbKlCnyeDwhy8CBA0PaBINBzZw5U8nJyerYsaPGjh2rw4cPh7u7OMfCso9DFgAAol3Yw8zmzZs1Y8YMbdu2TWVlZTp16pRycnJ04sSJkHajR49WZWWlu6xbty5ke2FhodauXavVq1dry5YtqqurU15enk6fPh3uLgMAAIuF/Wqm0tLSkNfLli1TSkqKdu/erZtuusld7/V65fP5mtyH3+/X0qVLtWLFCo0YMUKStHLlSmVkZGjDhg0aNWpUuLsNAAAsFfE5M36/X5KUlJQUsn7Tpk1KSUnRtddeq4KCAlVXV7vbdu/erYaGBuXk5Ljr0tPTlZWVpfLy8iY/JxgMKhAIhCwAAKD9i+h9ZowxKioq0uDBg5WVleWuz83N1e23367MzEwdPHhQjzzyiG6++Wbt3r1bXq9XVVVVio+PV6dOnUL2l5qaqqqqqiY/q6SkRPPmzYvk4QAA0CI8jDKyIhpm7r33Xn3wwQfasmVLyPqJEye6f2dlZal///7KzMzUG2+8odtuu+28+zPGyOPxNLmtuLhYRUVF7utAIKCMjIyLPAIAABDtInaaaebMmXrttde0ceNGXXXVVd/bNi0tTZmZmTpw4IAkyefzqb6+XjU1NSHtqqurlZqa2uQ+vF6vEhMTQxYAAND+hb0yY4zRzJkztXbtWm3atEndunX7wfccO3ZMhw4dUlpamiSpX79+iouLU1lZmSZMmCBJqqys1N69e7VgwYJwd/mSxaXXAID2IOxhZsaMGXrxxRf16quvKiEhwZ3j4jiOOnTooLq6Os2dO1fjx49XWlqaPv/8cz300ENKTk7Wrbfe6radOnWqZs2apc6dOyspKUmzZ89Wr1693KubAAAApAiEmeeee06SNHTo0JD1y5Yt05QpUxQTE6M9e/bohRdeUG1trdLS0jRs2DCtWbNGCQkJbvuFCxcqNjZWEyZM0MmTJzV8+HAtX75cMTEx4e7yJYNKDACgPfIYY0xbdyISAoGAHMeR3+9n/sz/IswAQHTgaqbza8nvN89mAgAAViPMAAAAqxFmAACA1SJ60zy0HebHAED0auq/0cyjaTkqMwAAwGqEGQAAYDXCDAAAsBphBgAAWI0wAwAArEaYAQAAViPMAAAAq3GfGQAAosC5957hvjMXjjDTTnCTPADApYrTTAAAwGqEGQAAYDXCDAAAsBpzZgAAiEIXMheSScLfIsxYiMm+AAD8H04zAQAAq1GZsQCVGAAAzo/KDAAAsBqVGQAALNVU5f5SnBRMZQYAAFiNMAMAAKxGmAEAAFYjzAAAAKsRZgAAgNW4minKcE8ZAACah8oMAACwGpUZAADakXMr/JfCfWeozAAAAKtRmWljzJEBAODiUJkBAABWozIDAEA7diFnAGyfVxP1YebZZ5/Vk08+qcrKSl133XV65plndOONN7Z1t1qEU0oAAIRfVIeZNWvWqLCwUM8++6xuuOEGLV68WLm5ufroo4/UtWvXtu7eDyK8AABsYPvTtz3GGNPWnTifAQMGqG/fvnruuefcdT179tS4ceNUUlLyve8NBAJyHEd+v1+JiYmR7mqTCDMAgPaitcJNS36/o7YyU19fr927d+vBBx8MWZ+Tk6Py8vJG7YPBoILBoPva7/dL+nZQWsP/e/uTVvkcAADaQmv9np79nObUWqI2zPzpT3/S6dOnlZqaGrI+NTVVVVVVjdqXlJRo3rx5jdZnZGRErI8AAFwqHmrlzzt+/Lgcx7mgtlEbZs7yeDwhr40xjdZJUnFxsYqKitzXZ86c0f/8z/+oc+fOTbY/VyAQUEZGhg4dOtRmp6Vsxdi1DOPWcoxdyzBuLcO4tVxLxs4Yo+PHjys9Pf2CPydqw0xycrJiYmIaVWGqq6sbVWskyev1yuv1hqy74oormv25iYmJfFlbiLFrGcat5Ri7lmHcWoZxa7nmjt2FVmTOitqb5sXHx6tfv34qKysLWV9WVqZBgwa1Ua8AAEC0idrKjCQVFRUpPz9f/fv3V3Z2tv71X/9VX375pf7+7/++rbsGAACiRFSHmYkTJ+rYsWN69NFHVVlZqaysLK1bt06ZmZlh/yyv16s5c+Y0OlWFH8bYtQzj1nKMXcswbi3DuLVca41dVN9nBgAA4IdE7ZwZAACAC0GYAQAAViPMAAAAqxFmAACA1dplmCkpKdH111+vhIQEpaSkaNy4cdq/f39ImylTpsjj8YQsAwcO/N79LlmyRDfeeKM6deqkTp06acSIEdqxY0ckD6VVRWrcXn75ZfXv319XXHGFOnbsqJ/+9KdasWJFJA+l1UVq7L5r9erV8ng8GjduXJh733YiNW7Lly9v9B6Px6NvvvkmkofTaiL5fautrdWMGTOUlpamyy67TD179tS6desidSitLlJjN3To0Ca/c7fcckskD6fVRPI798wzz6hHjx7q0KGDMjIydP/99zf732q7DDObN2/WjBkztG3bNpWVlenUqVPKycnRiRMnQtqNHj1alZWV7vJD/2A3bdqkO++8Uxs3btTWrVvVtWtX5eTk6I9//GMkD6fVRGrckpKS9PDDD2vr1q364IMPdPfdd+vuu+/Wm2++GcnDaVWRGruzvvjiC82ePVs33nhjJLrfZiI5bomJiSHvqays1GWXXRapQ2lVkRq3+vp6jRw5Up9//rl+//vfa//+/VqyZImuvPLKSB5Oq4rU2L388ssh7ffu3auYmBjdfvvtkTycVhOpcVu1apUefPBBzZkzR/v27dPSpUu1Zs0aFRcXN6+D5hJQXV1tJJnNmze76yZPnmz+6q/+6qL2e+rUKZOQkGCef/75i+xhdIrUuBljTJ8+fcyvf/3ri95PtArn2J06dcrccMMN5t/+7d/CNv7RKlzjtmzZMuM4Tng7F8XCNW7PPfecufrqq019fX2Yexi9IvXfuYULF5qEhARTV1d3kT2MTuEatxkzZpibb745ZF1RUZEZPHhws/bTLisz5/L7/ZK+rRB816ZNm5SSkqJrr71WBQUFqq6ubtZ+v/76azU0NDTab3sRiXEzxuitt97S/v37ddNNN4W1v9EknGP36KOPqkuXLpo6dWpE+hpNwjludXV1yszM1FVXXaW8vDy99957EelzNAjXuL322mvKzs7WjBkzlJqaqqysLM2fP1+nT5+OWN/bWqR+H5YuXao77rhDHTt2DFtfo0m4xm3w4MHavXu3O2Xjs88+07p165p/eq5Z0cdCZ86cMWPGjGmU8lavXm1ef/11s2fPHvPaa6+Z3r17m+uuu8588803F7zv6dOnm2uuucacPHky3N1uc+Eet9raWtOxY0cTGxtrvF6vWbp0aSS736bCOXZbtmwxV155pTl69KgxJnyVsWgUznHbunWrWbFihamoqDDvvPOOGT9+vOnQoYP5+OOPI30YrS6c49ajRw/j9XrNPffcY3bt2mVeeuklk5SUZObNmxfpw2gTkfp92L59u5Fktm/fHolut7lwj9s//dM/mbi4OBMbG2skmV/+8pfN7lO7DzPTp083mZmZ5tChQ9/b7quvvjJxcXHmP//zPy9ov0888YTp1KmTef/998PRzagT7nE7ffq0OXDggHnvvffMP/7jPxrHcczGjRvD2OPoEa6xCwQC5sc//rFZt26du649h5lI/Vs15tvvX+/evc3MmTMvtptRJ5zj1r17d5ORkWFOnTrlrnvqqaeMz+cLW3+jSaS+c9OmTTNZWVnh6GJUCue4bdy40aSmppolS5aYDz74wLz88ssmIyPDPProo83qU7sOM/fee6+56qqrzGeffXZB7X/yk5+Yxx9//AfbPfnkk8ZxHLNz586L7WJUitS4fdfUqVNNTk5OS7oX1cI5du+9956RZGJiYtzF4/EYj8djYmJizCeffBLOrrep1vjO/d3f/Z0ZPXp0S7oXtcI9bjfddJMZPnx4yLp169YZSSYYDF5UX6NNpL5zJ06cMImJieaZZ5652C5GpXCP2+DBg83s2bND1q1YscJ06NDBnD59+oL7FdUPmmwpY4xmzpyptWvXatOmTerWrdsPvufYsWM6dOiQ0tLSvrfdk08+qccee0xvvvmm+vfvH64uR4VIjltTnxUMBlva1agTibH78z//c+3Zsydk3a9//WsdP35cv/3tb5WRkRGWvrel1vrOGWNUUVGhXr16XUx3o0akxu2GG27Qiy++qDNnzuhHP/p2SuXHH3+stLQ0xcfHh63/bSnS37l///d/VzAY1N/8zd+Eo7tRI1Lj9vXXX7vftbNiYmJkvi22NKuD7c4vf/lL4ziO2bRpk6msrHSXr7/+2hhjzPHjx82sWbNMeXm5OXjwoNm4caPJzs42V155pQkEAu5+8vPzzYMPPui+fuKJJ0x8fLz5/e9/H7Lf48ePt/oxRkKkxm3+/Plm/fr15tNPPzX79u0zTz31lImNjTVLlixp9WOMlEiN3bna22mmSI3b3LlzTWlpqfn000/Ne++9Z+6++24TGxvbbuYwRGrcvvzyS/Nnf/Zn5t577zX79+83r7/+uklJSTGPPfZYqx9jpET63+rgwYPNxIkTW+14Wkukxm3OnDkmISHBvPTSS+azzz4z69evN9dcc42ZMGFCs/rXLsOMpCaXZcuWGWOM+frrr01OTo7p0qWLiYuLM127djWTJ082X375Zch+hgwZYiZPnuy+zszMbHK/c+bMab2Di6BIjdvDDz9sfvKTn5jLLrvMdOrUyWRnZ5vVq1e34pFFXqTG7lztLcxEatwKCwtN165dTXx8vOnSpYvJyckx5eXlrXhkkRXJ71t5ebkZMGCA8Xq95uqrrza/+c1vQubQ2C6SY7d//34jyaxfv76Vjqb1RGrcGhoazNy5c80111xjLrvsMpORkWGmT59uampqmtU/z/92EgAAwEqXxH1mAABA+0WYAQAAViPMAAAAqxFmAACA1QgzAADAaoQZAABgNcIMAACwGmEGAABYjTADAACsRpgBAABWI8wAAACrEWYAAIDV/j/tyc5r2/sxUQAAAABJRU5ErkJggg==", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import numpy as np\n", "from numpy.random import *\n", "\n", "# N is the number of runs in our stochastic simulation\n", "N = 100_000\n", "\n", "def BMI():\n", " return uniform(83.5, 84.5) / triangular(1.81, 1.815, 1.82)**2\n", "\n", "sim = np.zeros(N)\n", "for i in range(N):\n", " sim[i] = BMI()\n", "print(\"{} ± {}\".format(sim.mean(), sim.std()))\n", "plt.hist(sim, alpha=0.5, bins=100);" ] }, { "cell_type": "markdown", "id": "d98e9595", "metadata": {}, "source": [ "### More information on using *uncertainties* package" ] }, { "cell_type": "code", "execution_count": 69, "id": "8069aa01", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'floor', 'fmod', 'gamma', 'hypot', 'isinf', 'isnan', 'lgamma', 'log', 'log10', 'log1p', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc', 'modf', 'ldexp', 'factorial', 'fsum', 'frexp']\n" ] } ], "source": [ "import uncertainties as u\n", "from uncertainties import ufloat\n", "from uncertainties.umath import * # functions like sin(), etc.\n", "\n", "print(uncertainties.umath.__all__) # many, but not all functions are defined in umath" ] }, { "cell_type": "markdown", "id": "f9016b67", "metadata": {}, "source": [ "Suppose we need to use a special function `erf`, which is not available in `umath` part. Can we still compute uncertainty with the package?\n", "\n", "The package provide function (a decorator) that wraps any numerically given function, and produces function that can work with uncertainties through `ufloat`. The wrapper is `u.wrap`.\n", "\n", "The limitation is that such function needs to return float given input float (should not return a list). No need to specify any derivatives, which seems are computed internally numerically.\n" ] }, { "cell_type": "code", "execution_count": 77, "id": "7cb8f9f5", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.8427007929497148+/-0.20755374990403652" ] }, "execution_count": 77, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from scipy.special import erf\n", "\n", "u.wrap(erf)(ufloat(1,0.5))" ] }, { "cell_type": "markdown", "id": "5bd988aa", "metadata": {}, "source": [ "How do we know if the package got the correct unswer? \n", "Can we check if package works correctly?" ] }, { "cell_type": "code", "execution_count": 86, "id": "d3633a10", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.20755374940228943" ] }, "execution_count": 86, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x0=1.0\n", "dx=1e-4\n", "df=(erf(x0+dx)-erf(x0-dx))/(2*dx)\n", "df*0.5 # sigma_f = df/dx * sig_x" ] }, { "cell_type": "markdown", "id": "137506ea", "metadata": {}, "source": [ "Indeed the package works correctly for this simple case." ] }, { "cell_type": "code", "execution_count": 87, "id": "963f82e2", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.4769362762044693+/-0.02781462064012885" ] }, "execution_count": 87, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from scipy.optimize import fsolve\n", "\n", "def f(x,a):\n", " return a*erf(x)-1\n", "\n", "def g(x0,a):\n", " sol, = fsolve(f, x0, args=(a,))\n", " return sol\n", "\n", "u.wrap(g)(1.0, ufloat(2,0.1))" ] }, { "cell_type": "markdown", "id": "ed405a3d", "metadata": {}, "source": [ "## Projectile motion with uncertainty" ] }, { "cell_type": "markdown", "id": "04897713", "metadata": {}, "source": [ "Next we want to understand how hard it is to hit a target with projectile taking into account a realistic air resistance and its uncertainty due to weather and density of athmospehere.\n", "\n", "\n", "A spherical projectile of mass $m$ launched with some initial velocity moves under the influence of two forces: gravity $\\vec{F}_g=-mg \\vec{e}_z$, and air resistance (drag), $\\vec{F}_D=- \\frac{1}{2} c \\rho A v \\vec{v}$, acting in the opposite direction to the projectile's velocity and proportional to the square of that velocity. Here, $c$ is the drag coefficient, $\\rho$ the air density, and $A$ the projectile's cross-sectional area.\n", "\n", "The relevant equations of motion are therefore:\n", "\n", "$$m\\ddot{\\vec{r}} = \\vec{F} = -mg \\vec{e}_z - \\frac{1}{2} c \\rho A v \\vec{v}$$\n", "\n", "The horizontal axis is choosen as $x$ and vertical as $z$, hence in component work we have\n", "$$ m \\begin{bmatrix}\\ddot{x}\\\\ \\ddot{z}\\end{bmatrix} = \n", "-mg\\begin{bmatrix}0\\\\ 1\\end{bmatrix}\n", "-\\frac{1}{2} c \\rho A \\sqrt{\\dot{x}^2+\\dot{z}^2} \\begin{bmatrix}\\dot{x}\\\\ \\dot{z}\\end{bmatrix}$$\n", "\n", "Next we choose $$ k=\\frac{c \\rho A}{2 m}$$ and a set of new variables \n", "\n", "$$\\begin{bmatrix}u_1\\\\ u_2\\\\ u_3\\\\ u_4 \\end{bmatrix}= \\begin{bmatrix}x\\\\ z\\\\ \\dot{x}\\\\ \\dot{z} \\end{bmatrix}$$\n", "with which we can decomposed these Eq. into the following four first-order ODEs:\n", "$$\\begin{bmatrix}\\dot{u}_1=\\dot{x}\\\\ \\dot{u}_2=\\dot{z}\\\\ \\dot{u}_3=\\ddot{x}\\\\ \\dot{u}_4=\\ddot{z} \\end{bmatrix}= \\begin{bmatrix} \\dot{x}\\\\ \\dot{z}\\\\ -k\\, \\dot{x} \\sqrt{\\dot{x}^2+\\dot{z}^2}\\\\ -g-k\\, \\dot{z} \\sqrt{\\dot{x}^2+\\dot{z}^2} \\end{bmatrix}$$\n", "\n" ] }, { "cell_type": "markdown", "id": "fa0bf464", "metadata": {}, "source": [ "We have only one parameter of the theory $k$ (in addition to $g$ which we will treat as a constant withouth error). \n", "\n", "This constant has units of 1/m if we meassure distance in m. Indeed $c$ has no units, density of air $\\rho$ has units of km/m$^3$ and crossection m$^2$ and mass kg." ] }, { "cell_type": "markdown", "id": "160c1f40", "metadata": {}, "source": [ "In the absence of air resistance, we can solve the equations to get \n", "$$ z= v_0 \\sin\\theta t - \\frac{1}{2} g t^2 $$\n", "$$ x = v_0 \\cos\\theta t$$\n", "and distance traveled when the projectile hits the ground is \n", "$$D=\\frac{v_0^2}{g}\\sin(2\\theta)$$\n", "\n", "We thus want to aim at $45^\\circ$ to get maximum distance, in which case projectile should go to $D=\\frac{v_0^2}{g}$. Let's assume that we can choose initial speed of 1000 m/s and $g=9.82$, which would result in $D\\approx 102 km$" ] }, { "cell_type": "markdown", "id": "03088f8d", "metadata": {}, "source": [ "Next we set up integration of these equations when $k$ is choosen to be a small constant ($10^{-4}$). We will adrees its good estimation and its error below." ] }, { "cell_type": "code", "execution_count": 323, "id": "196ae2d4", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 323, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAj8AAAGdCAYAAAD9kBJPAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAABHqUlEQVR4nO3deVhUV7ou8LdAKJGGCloyVEQpbRO1MQ6QRtQENR2I0ajH3EQbDx09CdEYNR60o9jn3GgGMR3b7hujRo2aOXrPJaYd0EDiiKAiTuAcRUApRBQLgwgI6/6htduiirnm/f6ep7rjrkWx96YsXtf61loKIYQAERERkUy42fsEiIiIiGyJ4YeIiIhkheGHiIiIZIXhh4iIiGSF4YeIiIhkheGHiIiIZIXhh4iIiGSF4YeIiIhkpZ29T8BR1NXVoaioCD4+PlAoFPY+HSIiImoGIQRu374NjUYDN7fm9ekw/DxQVFSE4OBge58GERERtUJhYSG6dOnSrLYMPw/4+PgAuH/zfH197Xw2RERE1Bzl5eUIDg6Wfo83B8PPA4ahLl9fX4YfIiIiJ9OSkhUWPBMREZGsMPwQERGRrDD8EBERkaww/BAREZGsMPwQERGRrDD8EBERkaww/BAREZGsMPwQERGRrDD8EBERkaww/BAREZGscHsLIiI70ukrkVdaAW9Pd1RU10Kr9kaQysvep0Xk0hh+iIgspH6Qqf//WrU3AEhttp3UYV16HurEv15DASD+KS1GPRFk9jUae22GJqLmUQghRNPNXF95eTlUKhX0ej03NiWiBhkCTnOCjC01FJoYisjVteb3N8PPAww/RGTOw705Dwccw/7Rjv4BqgDwx98HY/Bv1Qjr5scgRC6nNb+/OexFRPRA/WGrnKt6fLjjrNneHEcPPQYCwLeHC/Ht4UIAwOsP9Q6xV4jkij0/D7Dnh0he6g9frU/Ps+uwlT3UHypjGCJnxGGvNmD4IZIHnb7SKOgoYLteHMWD/3n4U9cNwGtPazGqbxC2nyzGZ+mX7Fo3xCEycjYMP23A8EPkesz17ny2P88iYaepIHOnug4dPN2M/j9E3QEAcLn0jtGxh0OGTl9p9Hxz/t9aoen1p7SYMlTLEEQOjeGnDRh+iFyHNXt3DAFnyhAtgMaDjC2ZC03bTxZj7f5Lbbp2Do2Ro2P4aQOGHyLnZujlybmqx5KUsxYJO+4KBd5+7nE80eURhwg4raHTVyL7chkyL93Ad4cL2tw7ZAhD7BEiR8Hw0wYMP0TOqX4vT0s9PHxVf9jK2YJOUx7uHWrrUJkCwPyRvTA1qodFz5GopRh+2oDhh8h5WKKXRwEgvt7wlauFnabUD0OtGSKLjQjGhPBgDomR3TD8tAHDD5Hja20vj7nenSlDOGxT38NDZN8eKmhxEGJvENkDw08bMPwQOSapl+fKLSTtONeirzVXnCy33p3W0ukrsSH9cquGxmIjgjFzRE/eZ7IJhp82YPghciyGXp7P0vPQkk8pNwUw77leeKLLIww6FvDw0NimrCv49nBBs76OhdFkKww/bcDwQ2R/lurl4S9b61m972KL6qw4FEbWxvDTBgw/RPbxcPFyQ/toNYS9PPbRmiExDoWRtTD8tAHDD5FttWWKOnt5HINhSOzAL9exYvfFJnuDOBRG1sDw0wYMP0S2symrAPOTc1o0m4i9PI7N0BvUnOnyHAojS2L4aQOGHyLr0+krcTjvJmZvPN7s4MNeHuei01di+c+/NKswmkNhZAkMP23A8ENkHYaanqP5t/C31HPNCj0PbyvBXh7n1NzCaA6FUVsx/LQBww+R5bSmiJnDWq6HQ2FkCww/bcDwQ2QZm7IKkPh9TrOLmDms5fpaMhSW+HwvTH2aAYiarzW/v9tZ+ZyISCZ0+kocuXwT87/PadaihG4AlscOwMBufgw9Li5I5YXF4/uim7pDk0NhS1LOYpC2I/oF+9ns/Eh+3Kz9Da5evYp///d/R6dOndChQwf0798f2dnZ0vNCCCxcuBAajQZeXl4YNmwYTp06ZfQaVVVVmDlzJtRqNby9vTFmzBhcuXLFqE1ZWRni4uKgUqmgUqkQFxeHW7duWfvyiGRNp69ExsVSrN53EUOW7MLM7443K/i4KxRIerEvRj2hYfCRkalP90BG4gi8/lT3+/utmSEAjF2RgdV7L9ry1EhmrDrsVVZWhgEDBmD48OF444034O/vj4sXLyIkJAQ9etzv1vzwww/xwQcf4PPPP8djjz2G999/H/v27cO5c+fg4+MDAHjjjTewdetWfP755+jUqRPmzJmDmzdvIjs7G+7u7gCAkSNH4sqVK1izZg0A4PXXX0dISAi2bt3arHPlsBdRy7R0eItFzPSw5gyFcTYYNYfD1fzMnz8fBw4cwP79+80+L4SARqPB7NmzMW/ePAD3e3kCAgLw4YcfYurUqdDr9ejcuTO++uorTJgwAQBQVFSE4OBgpKSkICYmBmfOnEGfPn1w8OBBREREAAAOHjyIyMhInD17Fo8//niT58rwQ9R8JwrLMG5lRpO9PAw81JSmZoWxEJqa0prf31Yd9tqyZQvCw8Px0ksvwd/fHwMGDMDatWul5/Py8lBcXIzo6GjpmFKpRFRUFDIyMgAA2dnZqKmpMWqj0WgQGhoqtcnMzIRKpZKCDwAMGjQIKpVKalNfVVUVysvLjR5E1DDDENfK3b9g7IrGg48bgBWxA5A+fzimRvVAZI9ODD5k1tSne+CHNwc3+LwAkLTjLBZsPgmdvtJ2J0Yuzarh59KlS1i1ahV69uyJH3/8EdOmTcOsWbPw5ZdfAgCKi4sBAAEBAUZfFxAQID1XXFwMT09P+Pn5NdrG39/f5Pv7+/tLbepLSkqS6oNUKhWCg4PbdrFELmxTVgGGLNmF2LWH8NcfG99wlPU81FL9gv2QOLJXo22+PVSIIUt2YVNW83aVJ2qMVWd71dXVITw8HIsXLwYADBgwAKdOncKqVavwpz/9SWqnUBiXvgkhTI7VV7+NufaNvU5iYiISEhKkP5eXlzMAEdUjzeBqYisKrtFDbTU1qgegQKNDYHUCSEzOwdOPdeZ7jNrEqj0/QUFB6NOnj9Gx3r17o6DgfnIPDAwEAJPemZKSEqk3KDAwENXV1SgrK2u0zbVr10y+//Xr1016lQyUSiV8fX2NHkT0L5uyCjDYMIOrkXZuADZPH8zhLWozw2yw2N93bbBNHYAPtp3hEBi1iVXDz5AhQ3DunHEX+fnz59GtWzcAgFarRWBgINLS0qTnq6ursXfvXgwefH8MOCwsDB4eHkZtdDodcnNzpTaRkZHQ6/U4fPiw1ObQoUPQ6/VSGyJqHp2+El8fvIx5yU2v12MY4uKaLGQphjWBEp/v1eB0+G05OgxO2sXp8NRqVp3tlZWVhcGDB2PRokV4+eWXcfjwYcTHx2PNmjWYNGkSgPtT3ZOSkrBhwwb07NkTixcvxp49e0ymum/btg2ff/45OnbsiLlz5+LGjRsmU92LioqwevVqAPenunfr1o1T3YmawbAdxbGCW1j6Y+P7b3EGF9mKTl+JD7adwbYcXYNtuCI0OdxUdwDYtm0bEhMTceHCBWi1WiQkJCA+Pl56XgiBRYsWYfXq1SgrK0NERARWrFiB0NBQqc3du3fx5z//Gd9++y0qKyvxzDPPYOXKlUY1Ojdv3sSsWbOwZcsWAMCYMWPwySef4JFHHmnWeTL8kFw1d70ershM9qDTV2LIkl0Nvj8VAH54czB7H2XMIcOPs2D4ITkx9PR4e7o3e72exeNDMeHJhmsxiKxlU1YBEpNzUNdIm0SuBSRb3NuLiJrUkpWZ2dtDjmDCk13x9GOdG10ROmnHWUABDoFRs1h9by8icgw6fSW2nrja7ODD9XrIkTSnEHpJylmcKCxr4Fmif+Gw1wMc9iJX1lRvj5vi/hoqLGYmZ3CisAxjV5hfvR/gEJjccNiLiIwYFilsLPi4KxT4fnok7lTXMfCQUzCsCJ2046zZ5zkERk1h+CFyUc2p7TEUMnOmDDmbplaEXpJyFoO0HfneJrM47PUAh73IVRh6e2ZtPN7gLC4WMpOr4BAYcdiLSOZa0tsz6gmN7U6MyEo4BEatwfBD5OQeXrNn/vcNb0nB3h5yVRwCo5bisNcDHPYiZ9TcNXu4SCHJAYfA5InDXkQy0ZxZXAB7e0heOARGzcXwQ+RkWrJmD2t7SG6aMwQ2ph8X7pQ7hh8iJ6LTV3LNHqImTH26BwZpO5odAhMAPth2Bn8Z3Zt/P2SM21sQOQmdvhJfZFxuNPgY1uyJ7NGJH+wka4YhMHO25egwZMkubMoyv08YuT72/BA5gW8P5eMvm3PNduOzrofIvKlRPZB/swLfHio0ea5OAInJOXj6sc78eyND7PkhclA6fSUyLpZi64mrWNBA8OHmo0SNmzmiJ9wa2Am1DsCG9Mu2PB1yEOz5IXJAzZnC/t+jeuP5J4IYeogaEaTyQtL4vkhMzkGdmefX7r+EKUND+PdIZtjzQ+RAdPpKbD1xFfObsUozgw9R80x4sisOJI7A6L5BJs8ZCqB1+krbnxjZDcMPkYPYlFWAIUt2YeZ35vfkMnTdGwqbGXyImi9I5YW/jO4NcyNgLICWHw57ETkATmEnsr4glRfin9Jizf48k+dYAC0v7PkhsiOdvhIZv5Ri+c8XOIWdyAamDNWyAJrY80NkL02u1AxOYSeyNBZAE8CeHyKbMkxfP1FYhvnJpsHn4boeTmEnsg4WQBN3dX+Au7qTtTVn+vonfxyATr9Rsq6HyAZ0+koMTtplfvFQBZA0vi8mPNnV5udFLdOa39/s+SGygaYKmoH7vT1hIazrIbIVQwG0OYYCaPYAuSaGHyIr0+krseV4kdngw+nrRPbFAmh5YsEzkRU1NtTF6etE9scCaHlizw+RlRTdumO2qBng9HUiR9JUATR7f1wPe36ILEynr0TulXKs3POL2UJK7slF5HgMK0Bvz9GZ/L1du/8SRj0RiH7BfnY5N7I89vwQWdCmrAIMXrIL8V8dwbHCWybPc08uIsfVUAG0ADB2RQZW771o+5Miq2D4IbKQwpsVmJ+cY7QvlwIsaiZyJo0VQCftOIvV+xiAXAGHvYjaSKevRHZ+Gf6eet6ku1wAWD6Ra/cQOYumCqCXpJzFmH5cfNTZMfwQtcGmrALM/z7H7C7swL/W7uEHJZHzmPBkV/QK9MHYFRkmzxkKoBeM6m37EyOL4bAXUQsZtqjIunyDw1xELqpfsB8SR/Yy+9za/Ze4+KGTY88PUQs0tUUFh7mIXMfUqB7Iv1mBbw8VGh1n74/zY88PUTNxiwoi+Zk5oifM1T+z98e5MfwQNcEwzJXxSym3qCCSmcamv3PxQ+dls/CTlJQEhUKB2bNnS8eEEFi4cCE0Gg28vLwwbNgwnDp1yujrqqqqMHPmTKjVanh7e2PMmDG4cuWKUZuysjLExcVBpVJBpVIhLi4Ot27dssFVkavblFWAIUt2IXbtIcz5n5Mmz7srFNg8fTC+ix+E9PnDuQM0kQuaMlTbYO/PicIym58PtZ1Nwk9WVhbWrFmDJ554wuj4X//6VyxbtgyffPIJsrKyEBgYiGeffRa3b9+W2syePRubN2/Gxo0bkZ6ejl9//RWjR49GbW2t1CY2NhbHjx/Hzp07sXPnThw/fhxxcXG2uDRyYQ0Ncynq9fRwiwoi19ZY78+4lRnYlFVg+5OiNlEI0dAkXcv49ddfMXDgQKxcuRLvv/8++vfvj3/84x8QQkCj0WD27NmYN28egPu9PAEBAfjwww8xdepU6PV6dO7cGV999RUmTJgAACgqKkJwcDBSUlIQExODM2fOoE+fPjh48CAiIiIAAAcPHkRkZCTOnj2Lxx9/vFnnWV5eDpVKBb1eD19fX+vcDHIqu89ew5TPj5gc/+SPLGgmkhudvhJDluwyP/QN4EDiCH4e2Elrfn9bvefnzTffxKhRo/CHP/zB6HheXh6Ki4sRHR0tHVMqlYiKikJGxv21FbKzs1FTU2PURqPRIDQ0VGqTmZkJlUolBR8AGDRoEFQqldTGnKqqKpSXlxs9iID7H3L/70gh/vuHXJPnWNBMJE+GxQ/N/dKsA+t/nI1Vp7pv3LgRR48eRVZWlslzxcXFAICAgACj4wEBAcjPz5faeHp6ws/Pz6SN4euLi4vh7+9v8vr+/v5SG3OSkpKwaNGill0QubxNWQX31+558GdlOzfU1NahTrCgmUjuGlv8cO3+S5gyNISfD07Caj0/hYWFeOutt/D111+jffv2DbZTKIzLyIQQJsfqq9/GXPumXicxMRF6vV56FBYWNtiW5CH/RoVR8AGAmto6FjQTkaRfsB9e5+wvp2e18JOdnY2SkhKEhYWhXbt2aNeuHfbu3YuPP/4Y7dq1k3p86vfOlJSUSM8FBgaiuroaZWVljba5du2ayfe/fv26Sa/Sw5RKJXx9fY0eJE86fSX+eewq4j47ZLI3V50A7lTXcZiLiCSNzf7i2j/OwWrh55lnnkFOTg6OHz8uPcLDwzFp0iQcP34c3bt3R2BgINLS0qSvqa6uxt69ezF48GAAQFhYGDw8PIza6HQ65ObmSm0iIyOh1+tx+PBhqc2hQ4eg1+ulNkQN2ZRVgMFLduGtTcdRUGb6oeWuUCBE3cEOZ0ZEjopr/zg/q9X8+Pj4IDQ01OiYt7c3OnXqJB2fPXs2Fi9ejJ49e6Jnz55YvHgxOnTogNjYWACASqXCq6++ijlz5qBTp07o2LEj5s6di759+0oF1L1798Zzzz2H+Ph4rF69GgDw+uuvY/To0c2e6UXyVHjTdJhLgftT2VnjQ0SNmTJUi7X780x6i1n74xzsurfX22+/jcrKSkyfPh1lZWWIiIhAamoqfHx8pDZ///vf0a5dO7z88suorKzEM888g88//xzu7u5Sm2+++QazZs2SZoWNGTMGn3zyic2vh5yDTl+JYwVlWJZ23uSDi3tzEVFzGHp/1uzPMzrOfb+cg9XX+XEWXOdHHjZlFWD+98Y7sT/MXaFA+vzhDD1E1CSdvhKDk3aZ/CNKAeCHNwejX7CfuS8jC3PIdX6IHEXRrTv3h7ke+qRSgHtzEVHrcOVn52XXYS8ia9PpK5FXWoEAn/ZY8EMOh7mIyKKmDNXis/Q8k5WfhQASk3Pw9GOd+bnigBh+yGVtyiowuzfXwwwrNvPDiYhaw7Dyc2JyDurqPWdY+Zn1P46Hw17kkhralPRPg7rC/cHilxzmIiJLmPBkV2x+0/zSKlz7xzGx54dc0qWSCrM9PiP7avDG8N/icukdDnMRkcUYVn7m7C/nwJ4fcik6fSXSTl3D39LOmTxnWLAwSOXFFZuJyOK48rPzYPghl2FYrTn+qyM4WnALbor7CxYCHOIiIuvjys/Og8Ne5BJ0+kqT1ZoB4Ifpg3Gnuo5DXERkE1z52Tmw54ecXk1tHd7depqbkhKR3bH3xzkw/JDT0ukrsSNHh5c+zcSO3GKT57kpKRHZA2t/HB/DDzklQ33PG98cxfHCW1C2c0PcoG6cxk5EdsfeH8fHvb0e4N5ezsPcfjpuCuDA/BEAwGnsRGR3je37lZE4gp9PFsS9vchl6fSVyLhYisKbFVi05ZTZ+p7LpXc4jZ2IHAJ7fxwbZ3uRw2vuNhWs7yEiR8KZX46LPT/k0BrapmL8AA3re4jIobH3x3Gx54ccWl6p+W0qXgrvij8/14v1PUTk0Nj745jY80MOSaevxIELpdh6osjkOW5TQUTOgr0/jok9P+RwzNX4KHD/w4JDXETkbNj743gYfsihmKvxUSi4TQUROS9D7w93fHccHPYih7L9pM6kxkdwmwoicnJc9dmxMPyQ3en0lcj4pRTLd13A4pQzJs9zGjsROTvW/jgWDnuRXZmr7+kfrMLJK3rUCdb4EJHraKz2Z9QTgegX7GeX85Ijhh+yG7P1PQBWThoIhULBaexE5FIaq/0ZtzIDS8b3xYQnu9rn5GSGw15kN3vPXTet7wGQf6OS09iJyCVNGaqFm5niHyGABd/nsv7HRhh+yC5+On0Ni7aeMjnO+h4icmVBKi8kje9r9pdvrRC4XHrH5uckRww/ZFNFt+5gweaTeO3LI6isqcNv/b2lfwWxvoeI5GDCk12x+c3BZmd/nbx6y9anI0us+SGb+fpgPv7rh1zpzxHajvj6tQiU/lrF+h4ikpV+wX6YP7IXknacNTr+YcpZjOmn4WehlbHnh2zidJHeKPgAwJHLN1H6axXre4hIlvp2UZkcqwOnvtsCww9Z3flrt/HKhsMmx2sFOL5NRLKlVXtz4UM7Yfghq9DpK5FxsRTJR69g/MoMXL9dbdKGxc1EJGdc+NB+GH7I4jZlFWDIkl2IXXsIc/7vCfxadQ8R2o7436P7wF1x/985LG4mIuK2F/bCgmeyqIYWLvzofz2Brp28MbJvIIubiYge4Kan9sGeH7KonAfbUjxMALh66y4AsLiZiKge9v7YHsMPtZmhvifz4g0uXEhE1EKs/bE9DntRm5jbmNSvgwf0lTXcmJSIqJmmDDUd+gKAz9IvYcrQEH6GWphVe36SkpLw5JNPwsfHB/7+/hg3bhzOnTtn1EYIgYULF0Kj0cDLywvDhg3DqVPGvQdVVVWYOXMm1Go1vL29MWbMGFy5csWoTVlZGeLi4qBSqaBSqRAXF4dbt25Z8/Jkz1x9DwB881oEDswfge/iByF9/nBu1EdE1IQglRdeN9P7U8clQazCquFn7969ePPNN3Hw4EGkpaXh3r17iI6ORkVFhdTmr3/9K5YtW4ZPPvkEWVlZCAwMxLPPPovbt29LbWbPno3Nmzdj48aNSE9Px6+//orRo0ejtrZWahMbG4vjx49j586d2LlzJ44fP464uDhrXp7sXSypMAk+AKCvvMfaHiKiFpoyVAuFmeIfbnlheQohhJlfX9Zx/fp1+Pv7Y+/evXj66achhIBGo8Hs2bMxb948APd7eQICAvDhhx9i6tSp0Ov16Ny5M7766itMmDABAFBUVITg4GCkpKQgJiYGZ86cQZ8+fXDw4EFEREQAAA4ePIjIyEicPXsWjz/+eJPnVl5eDpVKBb1eD19fX+vdBBdRUXUPr395BAcu3jA67q5QIH3+cIYeIqJWWL33osmWF/xcbVxrfn/btOBZr9cDADp27AgAyMvLQ3FxMaKjo6U2SqUSUVFRyMjIAABkZ2ejpqbGqI1Go0FoaKjUJjMzEyqVSgo+ADBo0CCoVCqpTX1VVVUoLy83elDTdPpKbDtZhHErDuDAxRto56bgxqRERBZibssL7vZueTYreBZCICEhAUOHDkVoaCgAoLi4GAAQEBBg1DYgIAD5+flSG09PT/j5+Zm0MXx9cXEx/P39Tb6nv7+/1Ka+pKQkLFq0qG0XJTObsgow//scGPoKf6N0x1evRiBQ1Z5r9xARWYC3p7vZ4x08OTnbkmx2N2fMmIGTJ0/iu+++M3lOUW+QUwhhcqy++m3MtW/sdRITE6HX66VHYWFhcy5DtnT6SqPgAwB3qmsRqGrP+h4iIgupqK41e3z7SfP/kKfWsUn4mTlzJrZs2YLdu3ejS5cu0vHAwEAAMOmdKSkpkXqDAgMDUV1djbKyskbbXLt2zeT7Xr9+3aRXyUCpVMLX19foQQ1bteci6leHcRYCEZFlNbTZ6WfpXPDQkqwafoQQmDFjBr7//nvs2rULWq3xND6tVovAwECkpaVJx6qrq7F3714MHjwYABAWFgYPDw+jNjqdDrm5uVKbyMhI6PV6HD78r53DDx06BL1eL7Wh1rlXW4d3/pmLLzPzTZ7j4oVERJbV0IKH/MemZVm15ufNN9/Et99+i3/+85/w8fGRenhUKhW8vLygUCgwe/ZsLF68GD179kTPnj2xePFidOjQAbGxsVLbV199FXPmzEGnTp3QsWNHzJ07F3379sUf/vAHAEDv3r3x3HPPIT4+HqtXrwYAvP766xg9enSzZnqRKZ2+Emd05Vi77xIyL90EADwfGogfTxWjlosXEhFZzZShWnyWnmeylMjJq7cQ2aOTfU7KxVh1qntD9TYbNmzA5MmTAdzvHVq0aBFWr16NsrIyREREYMWKFVJRNADcvXsXf/7zn/Htt9+isrISzzzzDFauXIng4GCpzc2bNzFr1ixs2bIFADBmzBh88skneOSRR5p1rpzq/i/1V21u56bA8j8OwMi+QdDpK1ncTERkZeamvLsBOJA4gp+99bTm97dN1/lxZAw/9+n0lRi8ZJdRfY+bAjgwn3/hiIhsJeNiKWLXHjI5/vpT3bnTez0Ov84POb7/l32Fhc1ERHbWUOEzd3q3DIYfAnB/+HFdeh7+lnre5DkWNhMR2RZ3ercuhh+Z0+krsf/Cdcz5vyfw3rbTAIDfazty1WYiIjubMlTLae9WYrMVnsnx1C9sBoAFz/dC/FPdUVx+l4XNRER2ZOj9WbM/z+i4oRSBn82tx54fmdLpK02Cj5sCeKGfBgqFgqs2ExE5gClDtVJP/MO403vbMPzI1N5z103WkGBhMxGRYwlSeWHec71Mjn+YcpZDX23A8CND+y9cx7sP6nsexsJmIiLHY26n9zqw8LktGH5kQqevRMbFUqzddxFTNmThTnUttGpvFjYTETk4Tnu3PBY8y4C5wuYx/TT46KUncLOimoXNREQOrKHCZ8O0dy562HLs+XFx5gqbFQDmPfc4lO3cWdhMROQEOO3dshh+XNzponKTwmYBoOAm/7IQETkL7vZuWQw/Lkynr8TilDMmx1nYTETkfDjt3XIYflzUGV05/m1FBi5er8BvlO1Y2ExE5OQ47d1yWPDsYnT6Smw9XoT/8/MFVFTXokdnb3w+5fdo565gYTMRkZNrbNo7C5+bj+HHhWzKKsD85BwYSny0am98/8YQqDp4AABDDxGRkzNMe69Xyom1+y9hytAQfs43E4e9XETRrTtGwQcA8m9U4E7NPbudExERWRZ3e7cMhh8XUFNbh8Tvc0z+JcBZAERErofT3tuO4cfJ3b5bg//4PAt7z5eaPMdZXURErofT3tuO4ccJGbaqOFl4Cy99mon9F0rh5eGOyYO7wV1x/98DnNVFROS6pgw1DT8KgP/gbSYWPDsZc1tVqH+jxPrJ4XiiyyOYGtWDs7qIiGSgfuFz/dIHahh7fpyIua0qAGB13EA80eURAOB2FUREMpBXWmE27LDouXkYfpxIXmmFSfABgOp7zPtERHLS0E7vLHpuHoYfJyGEQPoFFjUTERGLntuK4ccJ1NYJLNp6Giv3XAQAKe2zqJmISL6411frseDZgen0lThXfBtfZF7G7rPXAQD/Nao3Rj0RxKJmIiKZM+z1lbTjrNHxD1POYkw/DX8/NILhx0HVn9XlrgD+PnEAxvTTAOBWFURExL2+WovDXg7I3KwuAeDJED+7nRMRETmehgqf1+5n4XNjGH4c0L7zpSazuljERkRE9XGvr9Zh+HEwhy7dwHvbTpkc56wuIiIyh3t9tRzDjwNJydEhbt1h/FpVi24dO0hV/JzVRUREDeG095ZjwbOD+PxAHhZtOw0hgJjfBeD/TByAsjvVnNVFRERNmjJUi8/S80xKJk5evYXIHp3sc1IOjD0/dna17A5mfHsUC7feDz5xg7ph5aQwtPdw51YVRETULIZp7/X9dcc5Dn2ZwZ4fO/rmYD7+8kOu9OeY3wXg3bG/g0JhbvSWiIioYeamvdcKgculd/iP6HrY82MnF67dNgo+APDT6RIUl9+10xkREZEz8/Z0N3u8gyd/1dfHO2IHJeV38doXR0yOGxI6ERFRS1VU15o9fqe6zsZn4vgYfmzs4vVfMX5VBvJvmoYcTmcnIqLW0qq9uddXM7lU+Fm5ciW0Wi3at2+PsLAw7N+/396nZCQ7vwwvrsrAlbJKhHTqgLdjHof7g/oeTmcnIqK2aKjo+cOUsyx6rsdlCp43bdqE2bNnY+XKlRgyZAhWr16NkSNH4vTp0+jatavdzkunr0ReaQUKb1bif/8zF1X36tAv+BGsfyUcnX6jxL8NfJTT2YmIyCK411fzKIQQoulmji8iIgIDBw7EqlWrpGO9e/fGuHHjkJSU1OTXl5eXQ6VSQa/Xw9fX1yLnVH9zUgAY0csfn8QOQAdPl8mdRETkIHT6SgxO2oX6v9jdFMCB+SNc8h/Zrfn97RLDXtXV1cjOzkZ0dLTR8ejoaGRkZJj9mqqqKpSXlxs9LMnc5qQKAIvG9GHwISIiq+Bqz83jEuGntLQUtbW1CAgIMDoeEBCA4uJis1+TlJQElUolPYKDgy16TnmlFSYrbQoAV8o4lZ2IiKxnylAtC5+b4BLhx6D+4oBCiAYXDExMTIRer5cehYWFFj0Xc1X3nM1FRETWxsLnprlE+FGr1XB3dzfp5SkpKTHpDTJQKpXw9fU1elhSkMoLSeP7cjYXERHZXGOFz+Qis708PT0RFhaGtLQ0/Nu//Zt0PC0tDWPHjrXbeU14siuefqwzZ3MREZFNadXeUAAmhc+fpV/ClKEhsv995BLhBwASEhIQFxeH8PBwREZGYs2aNSgoKMC0adPsel5BKi/Zv8mIiMi2DIXPa/bnGR03FD7L/feSy4SfCRMm4MaNG3j33Xeh0+kQGhqKlJQUdOvWzd6nRkREZHNThpqGHwXA2lO4UPgBgOnTp2P69On2Pg0iIiKHUH/oyyUW9rMAlyh4JiIiImN5pRVmww6Lnhl+iIiIXJKh6Lm+z9IvyX7KO8MPERGRC+Jqzw1j+CEiInJRXO3ZPIYfIiIiF9XQas9/3XFO1kNfDD9EREQuzNxqz7VCyHroi+GHiIjIhXl7ups93sFTvhFAvldOREQkAxXVtWaP36mus/GZOA6GHyIiIhemVXuz6Lkehh8iIiIX1lDR84cpZ2Vb9MzwQ0RE5OLMFT3XQb6rPTP8EBERuTiu9myM4YeIiMjFcbVnYww/REREMsDVnv+F4YeIiEgGuNrzvzD8EBERyQRXe76P4YeIiEgmzBU+KwCEqDvY43TshuGHiIhIxoS9T8AOGH6IiIhkIq+0wmzYkdt6Pww/REREMsH1fu5j+CEiIpIJrvdzH8MPERGRjHC9H4YfIiIiWeF6Pww/REREsiP39X4YfoiIiGTG29Pd7PEOnvKIBfK4SiIiIpJUVNeaPX6nus7GZ2IfDD9EREQyo1V7y7romeGHiIhIZhoqev4w5awsip4ZfoiIiGTIXNFzHeSx2jPDDxERkQzJebVnhh8iIiIZkvNqzww/REREMjVlqGn4UQAIUXew/cnYEMMPERGRjJkMfZkbC3MxDD9EREQylVdaAVHvmOCwFxEREbkqua73w/BDREQkU3Jd78dq4efy5ct49dVXodVq4eXlhR49euCdd95BdXW1UbuCggK88MIL8Pb2hlqtxqxZs0za5OTkICoqCl5eXnj00Ufx7rvvQgjjjrq9e/ciLCwM7du3R/fu3fHpp59a69KIiIhchhzX+2lnrRc+e/Ys6urqsHr1avz2t79Fbm4u4uPjUVFRgaVLlwIAamtrMWrUKHTu3Bnp6em4ceMGXnnlFQghsHz5cgBAeXk5nn32WQwfPhxZWVk4f/48Jk+eDG9vb8yZMwcAkJeXh+effx7x8fH4+uuvceDAAUyfPh2dO3fGiy++aK1LJCIicnqG9X7q1/58ln4JU4aGIEjlZY/TsiqFqN+FYkUfffQRVq1ahUuXLgEAduzYgdGjR6OwsBAajQYAsHHjRkyePBklJSXw9fXFqlWrkJiYiGvXrkGpVAIAlixZguXLl+PKlStQKBSYN28etmzZgjNnzkjfa9q0aThx4gQyMzObdW7l5eVQqVTQ6/Xw9fW18JUTERE5rsXbT2PN/jyT49/FD0Jkj052OKPma83vb5vW/Oj1enTs2FH6c2ZmJkJDQ6XgAwAxMTGoqqpCdna21CYqKkoKPoY2RUVFuHz5stQmOjra6HvFxMTgyJEjqKmpMXsuVVVVKC8vN3oQERHJkdzW+7FZ+Ll48SKWL1+OadOmSceKi4sREBBg1M7Pzw+enp4oLi5usI3hz021uXfvHkpLS82eT1JSElQqlfQIDg5u2wUSERE5MTmt99Pi8LNw4UIoFIpGH0eOHDH6mqKiIjz33HN46aWX8Nprrxk9p1CY3l0hhNHx+m0MI3UtbfOwxMRE6PV66VFYWNjUpRMREbkkua330+KC5xkzZmDixImNtgkJCZH+u6ioCMOHD0dkZCTWrFlj1C4wMBCHDh0yOlZWVoaamhqpJycwMFDq4TEoKSkBgCbbtGvXDp06mR+rVCqVRkNpREREcmVY76euXgI6efWWw9f8tEaLe37UajV69erV6KN9+/YAgKtXr2LYsGEYOHAgNmzYADc3428XGRmJ3Nxc6HQ66VhqaiqUSiXCwsKkNvv27TOa/p6amgqNRiOFrMjISKSlpRm9dmpqKsLDw+Hh4dHSSyQiIpIVua33Y7Wan6KiIgwbNgzBwcFYunQprl+/juLiYqMemujoaPTp0wdxcXE4duwYfv75Z8ydOxfx8fFSxXZsbCyUSiUmT56M3NxcbN68GYsXL0ZCQoI0pDVt2jTk5+cjISEBZ86cwfr167Fu3TrMnTvXWpdHRETkUuS03o/V1vlJTU3FL7/8gl9++QVdunQxes5Qj+Pu7o7t27dj+vTpGDJkCLy8vBAbGyutAwQAKpUKaWlpePPNNxEeHg4/Pz8kJCQgISFBaqPVapGSkoL//M//xIoVK6DRaPDxxx9zjR8iIqJmktN6PzZd58eRcZ0fIiKSO2dc78fh1/khIiIixyWX9X4YfoiIiEgih/V+GH6IiIgIgHzW+2H4ISIiIgD/Wu+nvpNXb9n8XKyJ4YeIiIgANLzez193nHOp9X4YfoiIiEhibr2fWiFcauiL4YeIiIgk3p7uZo938HSdyOA6V0JERERtVlFda/b4neo6G5+J9TD8EBERkUQORc8MP0RERCSRQ9Ezww8REREZcfWiZ4YfIiIiMuLqQ18MP0RERGTE1Ye+GH6IiIjIhCsPfTH8EBERkQlXXu/H+a+AiIiILM6V1/th+CEiIiITrlz0zPBDREREJly56Jnhh4iIiMxy1aJnhh8iIiIyS6v2Rv2RLwWAEHUHe5yOxTD8EBERUbMJe5+ABTD8EBERkVl5pRVmw86G9Mu2PhWLYvghIiIis8wNewHAZ+mXnLromeGHiIiIzApSeSH+Ka3J8ToBpy56ZvghIiKiBk0ZqnW5omeGHyIiImoZc2NhToThh4iIiBpkruhZcNiLiIiIXJUrbnPB8ENEREQNcsVtLhh+iIiIqFGuts0Fww8RERE1ytvT3ezxDp7OGSOc86yJiIjIZiqqa80ev1NdZ+MzsQyGHyIiImqUqxU9M/wQERFRo1yt6Jnhh4iIiJrkSkXPNgk/VVVV6N+/PxQKBY4fP270XEFBAV544QV4e3tDrVZj1qxZqK6uNmqTk5ODqKgoeHl54dFHH8W7774LIYyXXNq7dy/CwsLQvn17dO/eHZ9++qm1L4uIiEg2XGnoyybh5+2334ZGozE5Xltbi1GjRqGiogLp6enYuHEjkpOTMWfOHKlNeXk5nn32WWg0GmRlZWH58uVYunQpli1bJrXJy8vD888/j6eeegrHjh3DggULMGvWLCQnJ9vi8oiIiFyeKw19tbP2N9ixYwdSU1ORnJyMHTt2GD2XmpqK06dPo7CwUApHf/vb3zB58mR88MEH8PX1xTfffIO7d+/i888/h1KpRGhoKM6fP49ly5YhISEBCoUCn376Kbp27Yp//OMfAIDevXvjyJEjWLp0KV588UVrXyIREZEsNDb0FaTyssMZtY5Ve36uXbuG+Ph4fPXVV+jQwXT318zMTISGhhr1CsXExKCqqgrZ2dlSm6ioKCiVSqM2RUVFuHz5stQmOjra6LVjYmJw5MgR1NTUmD23qqoqlJeXGz2IiIioYVq1t8kxZ9zh3WrhRwiByZMnY9q0aQgPDzfbpri4GAEBAUbH/Pz84OnpieLi4gbbGP7cVJt79+6htLTU7PdOSkqCSqWSHsHBwS2/SCIiIpmpX/ZTf9NTZ9Di8LNw4UIoFIpGH0eOHMHy5ctRXl6OxMTERl9PoTCtnhJCGB2v38ZQ7NzSNg9LTEyEXq+XHoWFhY2eJxERkdyZ2+EdADakX7b1qbRJi2t+ZsyYgYkTJzbaJiQkBO+//z4OHjxoNFwFAOHh4Zg0aRK++OILBAYG4tChQ0bPl5WVoaamRurJCQwMlHp4DEpKSgCgyTbt2rVDp06dzJ6jUqk0OTciIiJqmFbtDQVMe3s+S7+EKUNDnKbup8XhR61WQ61WN9nu448/xvvvvy/9uaioCDExMdi0aRMiIiIAAJGRkfjggw+g0+kQFBQE4H4RtFKpRFhYmNRmwYIFqK6uhqenp9RGo9EgJCREarN161aj75+amorw8HB4eHi09BKJiIjIjCCVF+Kf0mLN/jyj43UCTlX0bLWan65duyI0NFR6PPbYYwCAHj16oEuXLgCA6Oho9OnTB3FxcTh27Bh+/vlnzJ07F/Hx8fD19QUAxMbGQqlUYvLkycjNzcXmzZuxePFiaaYXAEybNg35+flISEjAmTNnsH79eqxbtw5z58611uURERHJ0pShWpNjzlb0bNcVnt3d3bF9+3a0b98eQ4YMwcsvv4xx48Zh6dKlUhuVSoW0tDRcuXIF4eHhmD59OhISEpCQkCC10Wq1SElJwZ49e9C/f3+89957+PjjjznNnYiIyApMqmnNl9c6LIWov1SyTJWXl0OlUkGv10u9TkRERGQs42IpYtceMjn+XfwgRPYwX2drTa35/c29vYiIiKjZXGGbC4YfIiIiajZX2OaC4YeIiIhaxNl3eGf4ISIiohZx9m0uGH6IiIioxZx5mwuGHyIiImoRZ9/mguGHiIiIWsSwzUV9n6VfcoqiZ4YfIiIiahHDNhf1Gba5cHQMP0RERNRizrzNBcMPERERtYqzbnPB8ENEREQtZq7oWXDYi4iIiFyVuaJnDnsRERGRvHDYi4iIiFwVh72IiIhIVpx5d3eGHyIiImoxZ97dneGHiIiIWsVZd3dn+CEiIqJW8fZ0N3u8g6djxwvHPjsiIiJyWBXVtWaP36mus/GZtAzDDxEREbWKsxY9M/wQERFRqzhr0TPDDxEREbWaMxY9M/wQERFRqznjNhcMP0RERGRZDr7NBcMPERERtZozbnPB8ENERESt5owzvhh+iIiIqNWcccYXww8RERG1ibPN+GL4ISIiojZxtm0uHPOsiIiIyGk42zYXDD9ERETUJs5W9MzwQ0RERG3ibEXPDD9ERETUZs5U9MzwQ0RERG2mVXubHHPUbS4YfoiIiMgiTMp+HHSbC4YfIiIiajNn2ubC6uFn+/btiIiIgJeXF9RqNcaPH2/0fEFBAV544QV4e3tDrVZj1qxZqK6uNmqTk5ODqKgoeHl54dFHH8W7774LIYxv8d69exEWFob27duje/fu+PTTT619aURERPSAM834smr4SU5ORlxcHKZMmYITJ07gwIEDiI2NlZ6vra3FqFGjUFFRgfT0dGzcuBHJycmYM2eO1Ka8vBzPPvssNBoNsrKysHz5cixduhTLli2T2uTl5eH555/HU089hWPHjmHBggWYNWsWkpOTrXl5RERE9IAzzfhSiPpdKBZy7949hISEYNGiRXj11VfNttmxYwdGjx6NwsJCaDQaAMDGjRsxefJklJSUwNfXF6tWrUJiYiKuXbsGpVIJAFiyZAmWL1+OK1euQKFQYN68ediyZQvOnDkjvfa0adNw4sQJZGZmNut8y8vLoVKpoNfr4evr28arJyIikp+Mi6WIXXvI5Ph38YMQ2aOTVb5na35/W63n5+jRo7h69Src3NwwYMAABAUFYeTIkTh16pTUJjMzE6GhoVLwAYCYmBhUVVUhOztbahMVFSUFH0OboqIiXL58WWoTHR1t9P1jYmJw5MgR1NTUmD2/qqoqlJeXGz2IiIio9ZxlxpfVws+lS5cAAAsXLsR//dd/Ydu2bfDz80NUVBRu3rwJACguLkZAQIDR1/n5+cHT0xPFxcUNtjH8uak29+7dQ2lpqdnzS0pKgkqlkh7BwcFtvGIiIiJyhhlfLQ4/CxcuhEKhaPRx5MgR1NXd38/jL3/5C1588UWEhYVhw4YNUCgU+J//+R/p9RQK07sihDA6Xr+NYaSupW0elpiYCL1eLz0KCwtbchuIiIioHmeZ8dWupV8wY8YMTJw4sdE2ISEhuH37NgCgT58+0nGlUonu3bujoKAAABAYGIhDh4zHBsvKylBTUyP15AQGBko9PAYlJSUA0GSbdu3aoVMn82OMSqXSaCiNiIiI2sZZdndvcfhRq9VQq9VNtgsLC4NSqcS5c+cwdOhQAEBNTQ0uX76Mbt26AQAiIyPxwQcfQKfTISgoCACQmpoKpVKJsLAwqc2CBQtQXV0NT09PqY1Go0FISIjUZuvWrUbfPzU1FeHh4fDw8GjpJRIREVErOMvu7laLYr6+vpg2bRreeecdpKam4ty5c3jjjTcAAC+99BIAIDo6Gn369EFcXByOHTuGn3/+GXPnzkV8fLxUsR0bGwulUonJkycjNzcXmzdvxuLFi5GQkCANaU2bNg35+flISEjAmTNnsH79eqxbtw5z58611uURERFRPc6y1o9V+6E++ugjTJw4EXFxcXjyySeRn5+PXbt2wc/PDwDg7u6O7du3o3379hgyZAhefvlljBs3DkuXLpVeQ6VSIS0tDVeuXEF4eDimT5+OhIQEJCQkSG20Wi1SUlKwZ88e9O/fH++99x4+/vhjvPjii9a8PCIiInqIs6z1Y7V1fpwN1/khIiJqO1uv9eNQ6/wQERGR/GjV3iaz2x1trR+GHyIiIrIuB1vrh+GHiIiILMYZ1vph+CEiIiKLcYYZXww/REREZDHOMOOL4YeIiIgsqm8XlcmxWiEcZuiL4YeIiIgsytF3d2f4ISIiIotz5N3dGX6IiIjIohx9xhfDDxEREVmUo+/u7hhnQURERC7D0Xd3Z/ghIiIii3L0tX4YfoiIiMiiHH2tH4YfIiIisjhHXuuH4YeIiIgszpF3d2f4ISIiIttwkLV+GH6IiIjI4hx5rR+GHyIiIrI4R57xxfBDREREFufIM74YfoiIiMgqHHXGF8MPERERWYWj7u7O8ENERERW44i7uzP8EBERkVU46owvhh8iIiKyCkfd3Z3hh4iIiKzCUXd3Z/ghIiIiqzC31o+7QsGCZyIiInJNQSovJI3vC3fF/QTkrlBg8fhQBKm87Hpe7ez63YmIiMilTXiyK55+rDMul95BiLqD3YMPwPBDREREVhak8nKI0GPAYS8iIiKSFYYfIiIikhWGHyIiIpIVhh8iIiKSFYYfIiIikhWGHyIiIpIVhh8iIiKSFauGn/Pnz2Ps2LFQq9Xw9fXFkCFDsHv3bqM2BQUFeOGFF+Dt7Q21Wo1Zs2ahurraqE1OTg6ioqLg5eWFRx99FO+++y6EMN4ndu/evQgLC0P79u3RvXt3fPrpp9a8NCIiInJSVg0/o0aNwr1797Br1y5kZ2ejf//+GD16NIqLiwEAtbW1GDVqFCoqKpCeno6NGzciOTkZc+bMkV6jvLwczz77LDQaDbKysrB8+XIsXboUy5Ytk9rk5eXh+eefx1NPPYVjx45hwYIFmDVrFpKTk615eUREROSMhJVcv35dABD79u2TjpWXlwsA4qeffhJCCJGSkiLc3NzE1atXpTbfffedUCqVQq/XCyGEWLlypVCpVOLu3btSm6SkJKHRaERdXZ0QQoi3335b9OrVy+j7T506VQwaNKjZ56vX6wUA6fsSERGR42vN72+r9fx06tQJvXv3xpdffomKigrcu3cPq1evRkBAAMLCwgAAmZmZCA0NhUajkb4uJiYGVVVVyM7OltpERUVBqVQatSkqKsLly5elNtHR0UbfPyYmBkeOHEFNTY3Z86uqqkJ5ebnRg4iIiFyf1fb2UigUSEtLw9ixY+Hj4wM3NzcEBARg586deOSRRwAAxcXFCAgIMPo6Pz8/eHp6SkNjxcXFCAkJMWpj+Jri4mJotVqzrxMQEIB79+6htLQUQUFBJueXlJSERYsWmRxnCCIiInIeht/bol4tcGNaHH4WLlxoNjQ8LCsrC2FhYZg+fTr8/f2xf/9+eHl54bPPPsPo0aORlZUlBRLFg23uHyaEMDpev43hAlva5mGJiYlISEiQ/nz16lX06dMHwcHBjV4bEREROZ7bt29DpVI1q22Lw8+MGTMwceLERtuEhIRg165d2LZtG8rKyuDr6wsAWLlyJdLS0vDFF19g/vz5CAwMxKFDh4y+tqysDDU1NVJPTmBgoNQLZFBSUgIATbZp164dOnXqZPYclUql0VDab37zGxQWFsLHx6fBwNQa5eXlCA4ORmFhoXQf5Ib3gPcA4D0AeA/kfv0A7wFg+XsghMDt27eNSmia0uLwo1aroVarm2x3584dAICbm3FZkZubG+rq6gAAkZGR+OCDD6DT6aSeoNTUVCiVSqkuKDIyEgsWLEB1dTU8PT2lNhqNRhoOi4yMxNatW42+T2pqKsLDw+Hh4dGs63Jzc0OXLl2a1bY1fH19ZftGN+A94D0AeA8A3gO5Xz/AewBY9h40t8fHwGoFz5GRkfDz88Mrr7yCEydO4Pz58/jzn/+MvLw8jBo1CgAQHR2NPn36IC4uDseOHcPPP/+MuXPnIj4+XrohsbGxUCqVmDx5MnJzc7F582YsXrwYCQkJUg/NtGnTkJ+fj4SEBJw5cwbr16/HunXrMHfuXGtdHhERETkpq4UftVqNnTt34tdff8WIESMQHh6O9PR0/POf/0S/fv0AAO7u7ti+fTvat2+PIUOG4OWXX8a4ceOwdOlS6XVUKhXS0tJw5coVhIeHY/r06UhISDCq19FqtUhJScGePXvQv39/vPfee/j444/x4osvWuvyiIiIyElZbbYXAISHh+PHH39stE3Xrl2xbdu2Rtv07dsX+/bta7RNVFQUjh492uJztDalUol33nnHqL5IbngPeA8A3gOA90Du1w/wHgCOcQ8UoiVzw4iIiIicHDc2JSIiIllh+CEiIiJZYfghIiIiWWH4ISIiIllh+LGylStXQqvVon379ggLC8P+/fvtfUotlpSUhCeffBI+Pj7w9/fHuHHjcO7cOaM2kydPhkKhMHoMGjTIqE1VVRVmzpwJtVoNb29vjBkzBleuXDFqU1ZWhri4OKhUKqhUKsTFxeHWrVvWvsQmLVy40OT6AgMDpeeFEFi4cCE0Gg28vLwwbNgwnDp1yug1nPn6gfsrt9e/BwqFAm+++SYA13wP7Nu3Dy+88AI0Gg0UCgV++OEHo+dt+XMvKCjACy+8AG9vb6jVasyaNQvV1dXWuGwjjd2DmpoazJs3D3379oW3tzc0Gg3+9Kc/oaioyOg1hg0bZvLeqL9TgLPeA8C273173IOmrt/c54JCocBHH30ktXG494DlN5cng40bNwoPDw+xdu1acfr0afHWW28Jb29vkZ+fb+9Ta5GYmBixYcMGkZubK44fPy5GjRolunbtKn799VepzSuvvCKee+45odPppMeNGzeMXmfatGni0UcfFWlpaeLo0aNi+PDhol+/fuLevXtSm+eee06EhoaKjIwMkZGRIUJDQ8Xo0aNtdq0Neeedd8Tvfvc7o+srKSmRnl+yZInw8fERycnJIicnR0yYMEEEBQWJ8vJyqY0zX78QQpSUlBhdf1pamgAgdu/eLYRwzfdASkqK+Mtf/iKSk5MFALF582aj5231c793754IDQ0Vw4cPF0ePHhVpaWlCo9GIGTNm2PUe3Lp1S/zhD38QmzZtEmfPnhWZmZkiIiJChIWFGb1GVFSUiI+PN3pv3Lp1y6iNs94DIWz33rfXPWjq+h++bp1OJ9avXy8UCoW4ePGi1MbR3gMMP1b0+9//XkybNs3oWK9evcT8+fPtdEaWUVJSIgCIvXv3SsdeeeUVMXbs2Aa/5tatW8LDw0Ns3LhROnb16lXh5uYmdu7cKYQQ4vTp0wKAOHjwoNQmMzNTABBnz561/IW0wDvvvCP69etn9rm6ujoRGBgolixZIh27e/euUKlU4tNPPxVCOP/1m/PWW2+JHj16iLq6OiGE678H6n/o2/LnnpKSItzc3MTVq1elNt99951QKpVCr9db5XrNMfeLr77Dhw8LAEb/yIuKihJvvfVWg1/j7PfAVu99R7gHzXkPjB07VowYMcLomKO9BzjsZSXV1dXIzs5GdHS00fHo6GhkZGTY6awsQ6/XAwA6duxodHzPnj3w9/fHY489hvj4eGkDWgDIzs5GTU2N0f3QaDQIDQ2V7kdmZiZUKhUiIiKkNoMGDYJKpXKIe3bhwgVoNBpotVpMnDgRly5dAgDk5eWhuLjY6NqUSiWioqKk83aF639YdXU1vv76a/zHf/yH0UbArv4eeJgtf+6ZmZkIDQ012rgxJiYGVVVVyM7Otup1tpRer4dCocAjjzxidPybb76BWq3G7373O8ydOxe3b9+WnnOFe2CL976j3wMAuHbtGrZv345XX33V5DlHeg9YdYVnOSstLUVtba2087xBQECAyQ70zkQIgYSEBAwdOhShoaHS8ZEjR+Kll15Ct27dkJeXh//+7//GiBEjkJ2dDaVSieLiYnh6esLPz8/o9R6+H8XFxfD39zf5nv7+/na/ZxEREfjyyy/x2GOP4dq1a3j//fcxePBgnDp1Sjo3cz/r/Px8AHD666/vhx9+wK1btzB58mTpmKu/B+qz5c+9uLjY5Pv4+fnB09PToe7L3bt3MX/+fMTGxhptWDlp0iRotVoEBgYiNzcXiYmJOHHiBNLS0gA4/z2w1Xvfke+BwRdffAEfHx+MHz/e6LijvQcYfqzs4X8VA/fDQ/1jzmTGjBk4efIk0tPTjY5PmDBB+u/Q0FCEh4ejW7du2L59u8lfgofVvx/m7o0j3LORI0dK/923b19ERkaiR48e+OKLL6TCxtb8rJ3l+utbt24dRo4cafQvMFd/DzTEVj93R78vNTU1mDhxIurq6rBy5Uqj5+Lj46X/Dg0NRc+ePREeHo6jR49i4MCBAJz7Htjyve+o98Bg/fr1mDRpEtq3b2903NHeAxz2shK1Wg13d3eTNFpSUmKSXJ3FzJkzsWXLFuzevRtdunRptG1QUBC6deuGCxcuAAACAwNRXV2NsrIyo3YP34/AwEBcu3bN5LWuX7/ucPfM29sbffv2xYULF6RZX439rF3p+vPz8/HTTz/htddea7Sdq78HbPlzDwwMNPk+ZWVlqKmpcYj7UlNTg5dffhl5eXlIS0sz6vUxZ+DAgfDw8DB6bzj7PXiYtd77jn4P9u/fj3PnzjX52QDY/z3A8GMlnp6eCAsLk7r0DNLS0jB48GA7nVXrCCEwY8YMfP/999i1axe0Wm2TX3Pjxg0UFhYiKCgIABAWFgYPDw+j+6HT6ZCbmyvdj8jISOj1ehw+fFhqc+jQIej1eoe7Z1VVVThz5gyCgoKkrtyHr626uhp79+6VztuVrn/Dhg3w9/fHqFGjGm3n6u8BW/7cIyMjkZubC51OJ7VJTU2FUqlEWFiYVa+zKYbgc+HCBfz000/o1KlTk19z6tQp1NTUSO8NZ78H9Vnrve/o92DdunUICwtDv379mmxr9/dAi8qjqUUMU93XrVsnTp8+LWbPni28vb3F5cuX7X1qLfLGG28IlUol9uzZYzRN8c6dO0IIIW7fvi3mzJkjMjIyRF5enti9e7eIjIwUjz76qMmU3y5duoiffvpJHD16VIwYMcLsVM8nnnhCZGZmiszMTNG3b1+HmOo9Z84csWfPHnHp0iVx8OBBMXr0aOHj4yP9LJcsWSJUKpX4/vvvRU5OjvjjH/9odsqzs16/QW1trejatauYN2+e0XFXfQ/cvn1bHDt2TBw7dkwAEMuWLRPHjh2TZjLZ6udumOL7zDPPiKNHj4qffvpJdOnSxSbTvBu7BzU1NWLMmDGiS5cu4vjx40afD1VVVUIIIX755RexaNEikZWVJfLy8sT27dtFr169xIABA1ziHtjyvW+ve9DU3wMhhNDr9aJDhw5i1apVJl/viO8Bhh8rW7FihejWrZvw9PQUAwcONJoe7iwAmH1s2LBBCCHEnTt3RHR0tOjcubPw8PAQXbt2Fa+88oooKCgwep3KykoxY8YM0bFjR+Hl5SVGjx5t0ubGjRti0qRJwsfHR/j4+IhJkyaJsrIyG11pwwzrt3h4eAiNRiPGjx8vTp06JT1fV1cn3nnnHREYGCiUSqV4+umnRU5OjtFrOPP1G/z4448CgDh37pzRcVd9D+zevdvse/+VV14RQtj2556fny9GjRolvLy8RMeOHcWMGTPE3bt3rXn5QojG70FeXl6Dnw+G9Z8KCgrE008/LTp27Cg8PT1Fjx49xKxZs0zWwXHWe2Dr97497kFTfw+EEGL16tXCy8vLZO0eIRzzPaAQQoiW9RUREREROS/W/BAREZGsMPwQERGRrDD8EBERkaww/BAREZGsMPwQERGRrDD8EBERkaww/BAREZGsMPwQERGRrDD8EBERkaww/BAREZGsMPwQERGRrDD8EBERkaz8fxK+9p9MT9mCAAAAAElFTkSuQmCC", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "from scipy.integrate import odeint # We will first use odeint, which we are already familiar with\n", "from numpy import *\n", "\n", "def dy(u,t): # appropriate for odeint\n", " \"\"\"\n", " The derivative for projectile motion with air resistance\n", " \"\"\"\n", " g, k = 9.82, 1e-4\n", " x,z,xdot,zdot = u\n", " dx = xdot\n", " dz = zdot\n", " dxdot = -k * xdot * sqrt(xdot**2+zdot**2)\n", " dzdot = -g -k * zdot * sqrt(xdot**2+zdot**2)\n", " return array([dx,dz,dxdot,dzdot])\n", "\n", "# choose an initial state\n", "v0 = 1000. # velocity magnitude in m/s\n", "x0 = [0, 0, v0*cos(pi/4), v0*sin(pi/4)] # initial velocity at 45 degrees\n", "\n", "t0f = (0,100) # initial and final time\n", "\n", "t = linspace(t0f[0], t0f[1], 250) # create linear mesh of time points\n", "# solve the ODE problem\n", "y = odeint(dy, x0, t)\n", "\n", "plt.plot(y[:,0],y[:,1], '.-')" ] }, { "cell_type": "markdown", "id": "6c6dfd72", "metadata": {}, "source": [ "Surprising, this more realistic trajectory suggests only around 16 km range rather than over 100 km in the absence of air resistance." ] }, { "cell_type": "markdown", "id": "7d32416c", "metadata": {}, "source": [ "Next we will use more appropriate solver `solve_ivp`, which chooses time steps automatically, and can resolve with high accuracy certain events, here the time the projectile hits the ground.\n" ] }, { "cell_type": "code", "execution_count": 324, "id": "0a3a9590", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Help on function solve_ivp in module scipy.integrate._ivp.ivp:\n", "\n", "solve_ivp(fun, t_span, y0, method='RK45', t_eval=None, dense_output=False, events=None, vectorized=False, args=None, **options)\n", " Solve an initial value problem for a system of ODEs.\n", " \n", " This function numerically integrates a system of ordinary differential\n", " equations given an initial value::\n", " \n", " dy / dt = f(t, y)\n", " y(t0) = y0\n", " \n", " Here t is a 1-D independent variable (time), y(t) is an\n", " N-D vector-valued function (state), and an N-D\n", " vector-valued function f(t, y) determines the differential equations.\n", " The goal is to find y(t) approximately satisfying the differential\n", " equations, given an initial value y(t0)=y0.\n", " \n", " Some of the solvers support integration in the complex domain, but note\n", " that for stiff ODE solvers, the right-hand side must be\n", " complex-differentiable (satisfy Cauchy-Riemann equations [11]_).\n", " To solve a problem in the complex domain, pass y0 with a complex data type.\n", " Another option always available is to rewrite your problem for real and\n", " imaginary parts separately.\n", " \n", " Parameters\n", " ----------\n", " fun : callable\n", " Right-hand side of the system. The calling signature is ``fun(t, y)``.\n", " Here `t` is a scalar, and there are two options for the ndarray `y`:\n", " It can either have shape (n,); then `fun` must return array_like with\n", " shape (n,). Alternatively, it can have shape (n, k); then `fun`\n", " must return an array_like with shape (n, k), i.e., each column\n", " corresponds to a single column in `y`. The choice between the two\n", " options is determined by `vectorized` argument (see below). The\n", " vectorized implementation allows a faster approximation of the Jacobian\n", " by finite differences (required for stiff solvers).\n", " t_span : 2-member sequence\n", " Interval of integration (t0, tf). The solver starts with t=t0 and\n", " integrates until it reaches t=tf. Both t0 and tf must be floats\n", " or values interpretable by the float conversion function.\n", " y0 : array_like, shape (n,)\n", " Initial state. For problems in the complex domain, pass `y0` with a\n", " complex data type (even if the initial value is purely real).\n", " method : string or `OdeSolver`, optional\n", " Integration method to use:\n", " \n", " * 'RK45' (default): Explicit Runge-Kutta method of order 5(4) [1]_.\n", " The error is controlled assuming accuracy of the fourth-order\n", " method, but steps are taken using the fifth-order accurate\n", " formula (local extrapolation is done). A quartic interpolation\n", " polynomial is used for the dense output [2]_. Can be applied in\n", " the complex domain.\n", " * 'RK23': Explicit Runge-Kutta method of order 3(2) [3]_. The error\n", " is controlled assuming accuracy of the second-order method, but\n", " steps are taken using the third-order accurate formula (local\n", " extrapolation is done). A cubic Hermite polynomial is used for the\n", " dense output. Can be applied in the complex domain.\n", " * 'DOP853': Explicit Runge-Kutta method of order 8 [13]_.\n", " Python implementation of the \"DOP853\" algorithm originally\n", " written in Fortran [14]_. A 7-th order interpolation polynomial\n", " accurate to 7-th order is used for the dense output.\n", " Can be applied in the complex domain.\n", " * 'Radau': Implicit Runge-Kutta method of the Radau IIA family of\n", " order 5 [4]_. The error is controlled with a third-order accurate\n", " embedded formula. A cubic polynomial which satisfies the\n", " collocation conditions is used for the dense output.\n", " * 'BDF': Implicit multi-step variable-order (1 to 5) method based\n", " on a backward differentiation formula for the derivative\n", " approximation [5]_. The implementation follows the one described\n", " in [6]_. A quasi-constant step scheme is used and accuracy is\n", " enhanced using the NDF modification. Can be applied in the\n", " complex domain.\n", " * 'LSODA': Adams/BDF method with automatic stiffness detection and\n", " switching [7]_, [8]_. This is a wrapper of the Fortran solver\n", " from ODEPACK.\n", " \n", " Explicit Runge-Kutta methods ('RK23', 'RK45', 'DOP853') should be used\n", " for non-stiff problems and implicit methods ('Radau', 'BDF') for\n", " stiff problems [9]_. Among Runge-Kutta methods, 'DOP853' is recommended\n", " for solving with high precision (low values of `rtol` and `atol`).\n", " \n", " If not sure, first try to run 'RK45'. If it makes unusually many\n", " iterations, diverges, or fails, your problem is likely to be stiff and\n", " you should use 'Radau' or 'BDF'. 'LSODA' can also be a good universal\n", " choice, but it might be somewhat less convenient to work with as it\n", " wraps old Fortran code.\n", " \n", " You can also pass an arbitrary class derived from `OdeSolver` which\n", " implements the solver.\n", " t_eval : array_like or None, optional\n", " Times at which to store the computed solution, must be sorted and lie\n", " within `t_span`. If None (default), use points selected by the solver.\n", " dense_output : bool, optional\n", " Whether to compute a continuous solution. Default is False.\n", " events : callable, or list of callables, optional\n", " Events to track. If None (default), no events will be tracked.\n", " Each event occurs at the zeros of a continuous function of time and\n", " state. Each function must have the signature ``event(t, y)`` and return\n", " a float. The solver will find an accurate value of `t` at which\n", " ``event(t, y(t)) = 0`` using a root-finding algorithm. By default, all\n", " zeros will be found. The solver looks for a sign change over each step,\n", " so if multiple zero crossings occur within one step, events may be\n", " missed. Additionally each `event` function might have the following\n", " attributes:\n", " \n", " terminal: bool, optional\n", " Whether to terminate integration if this event occurs.\n", " Implicitly False if not assigned.\n", " direction: float, optional\n", " Direction of a zero crossing. If `direction` is positive,\n", " `event` will only trigger when going from negative to positive,\n", " and vice versa if `direction` is negative. If 0, then either\n", " direction will trigger event. Implicitly 0 if not assigned.\n", " \n", " You can assign attributes like ``event.terminal = True`` to any\n", " function in Python.\n", " vectorized : bool, optional\n", " Whether `fun` is implemented in a vectorized fashion. Default is False.\n", " args : tuple, optional\n", " Additional arguments to pass to the user-defined functions. If given,\n", " the additional arguments are passed to all user-defined functions.\n", " So if, for example, `fun` has the signature ``fun(t, y, a, b, c)``,\n", " then `jac` (if given) and any event functions must have the same\n", " signature, and `args` must be a tuple of length 3.\n", " **options\n", " Options passed to a chosen solver. All options available for already\n", " implemented solvers are listed below.\n", " first_step : float or None, optional\n", " Initial step size. Default is `None` which means that the algorithm\n", " should choose.\n", " max_step : float, optional\n", " Maximum allowed step size. Default is np.inf, i.e., the step size is not\n", " bounded and determined solely by the solver.\n", " rtol, atol : float or array_like, optional\n", " Relative and absolute tolerances. The solver keeps the local error\n", " estimates less than ``atol + rtol * abs(y)``. Here `rtol` controls a\n", " relative accuracy (number of correct digits), while `atol` controls\n", " absolute accuracy (number of correct decimal places). To achieve the\n", " desired `rtol`, set `atol` to be smaller than the smallest value that\n", " can be expected from ``rtol * abs(y)`` so that `rtol` dominates the\n", " allowable error. If `atol` is larger than ``rtol * abs(y)`` the\n", " number of correct digits is not guaranteed. Conversely, to achieve the\n", " desired `atol` set `rtol` such that ``rtol * abs(y)`` is always smaller\n", " than `atol`. If components of y have different scales, it might be\n", " beneficial to set different `atol` values for different components by\n", " passing array_like with shape (n,) for `atol`. Default values are\n", " 1e-3 for `rtol` and 1e-6 for `atol`.\n", " jac : array_like, sparse_matrix, callable or None, optional\n", " Jacobian matrix of the right-hand side of the system with respect\n", " to y, required by the 'Radau', 'BDF' and 'LSODA' method. The\n", " Jacobian matrix has shape (n, n) and its element (i, j) is equal to\n", " ``d f_i / d y_j``. There are three ways to define the Jacobian:\n", " \n", " * If array_like or sparse_matrix, the Jacobian is assumed to\n", " be constant. Not supported by 'LSODA'.\n", " * If callable, the Jacobian is assumed to depend on both\n", " t and y; it will be called as ``jac(t, y)``, as necessary.\n", " For 'Radau' and 'BDF' methods, the return value might be a\n", " sparse matrix.\n", " * If None (default), the Jacobian will be approximated by\n", " finite differences.\n", " \n", " It is generally recommended to provide the Jacobian rather than\n", " relying on a finite-difference approximation.\n", " jac_sparsity : array_like, sparse matrix or None, optional\n", " Defines a sparsity structure of the Jacobian matrix for a finite-\n", " difference approximation. Its shape must be (n, n). This argument\n", " is ignored if `jac` is not `None`. If the Jacobian has only few\n", " non-zero elements in *each* row, providing the sparsity structure\n", " will greatly speed up the computations [10]_. A zero entry means that\n", " a corresponding element in the Jacobian is always zero. If None\n", " (default), the Jacobian is assumed to be dense.\n", " Not supported by 'LSODA', see `lband` and `uband` instead.\n", " lband, uband : int or None, optional\n", " Parameters defining the bandwidth of the Jacobian for the 'LSODA'\n", " method, i.e., ``jac[i, j] != 0 only for i - lband <= j <= i + uband``.\n", " Default is None. Setting these requires your jac routine to return the\n", " Jacobian in the packed format: the returned array must have ``n``\n", " columns and ``uband + lband + 1`` rows in which Jacobian diagonals are\n", " written. Specifically ``jac_packed[uband + i - j , j] = jac[i, j]``.\n", " The same format is used in `scipy.linalg.solve_banded` (check for an\n", " illustration). These parameters can be also used with ``jac=None`` to\n", " reduce the number of Jacobian elements estimated by finite differences.\n", " min_step : float, optional\n", " The minimum allowed step size for 'LSODA' method.\n", " By default `min_step` is zero.\n", " \n", " Returns\n", " -------\n", " Bunch object with the following fields defined:\n", " t : ndarray, shape (n_points,)\n", " Time points.\n", " y : ndarray, shape (n, n_points)\n", " Values of the solution at `t`.\n", " sol : `OdeSolution` or None\n", " Found solution as `OdeSolution` instance; None if `dense_output` was\n", " set to False.\n", " t_events : list of ndarray or None\n", " Contains for each event type a list of arrays at which an event of\n", " that type event was detected. None if `events` was None.\n", " y_events : list of ndarray or None\n", " For each value of `t_events`, the corresponding value of the solution.\n", " None if `events` was None.\n", " nfev : int\n", " Number of evaluations of the right-hand side.\n", " njev : int\n", " Number of evaluations of the Jacobian.\n", " nlu : int\n", " Number of LU decompositions.\n", " status : int\n", " Reason for algorithm termination:\n", " \n", " * -1: Integration step failed.\n", " * 0: The solver successfully reached the end of `tspan`.\n", " * 1: A termination event occurred.\n", " \n", " message : string\n", " Human-readable description of the termination reason.\n", " success : bool\n", " True if the solver reached the interval end or a termination event\n", " occurred (``status >= 0``).\n", " \n", " References\n", " ----------\n", " .. [1] J. R. Dormand, P. J. Prince, \"A family of embedded Runge-Kutta\n", " formulae\", Journal of Computational and Applied Mathematics, Vol. 6,\n", " No. 1, pp. 19-26, 1980.\n", " .. [2] L. W. Shampine, \"Some Practical Runge-Kutta Formulas\", Mathematics\n", " of Computation,, Vol. 46, No. 173, pp. 135-150, 1986.\n", " .. [3] P. Bogacki, L.F. Shampine, \"A 3(2) Pair of Runge-Kutta Formulas\",\n", " Appl. Math. Lett. Vol. 2, No. 4. pp. 321-325, 1989.\n", " .. [4] E. Hairer, G. Wanner, \"Solving Ordinary Differential Equations II:\n", " Stiff and Differential-Algebraic Problems\", Sec. IV.8.\n", " .. [5] `Backward Differentiation Formula\n", " `_\n", " on Wikipedia.\n", " .. [6] L. F. Shampine, M. W. Reichelt, \"THE MATLAB ODE SUITE\", SIAM J. SCI.\n", " COMPUTE., Vol. 18, No. 1, pp. 1-22, January 1997.\n", " .. [7] A. C. Hindmarsh, \"ODEPACK, A Systematized Collection of ODE\n", " Solvers,\" IMACS Transactions on Scientific Computation, Vol 1.,\n", " pp. 55-64, 1983.\n", " .. [8] L. Petzold, \"Automatic selection of methods for solving stiff and\n", " nonstiff systems of ordinary differential equations\", SIAM Journal\n", " on Scientific and Statistical Computing, Vol. 4, No. 1, pp. 136-148,\n", " 1983.\n", " .. [9] `Stiff equation `_ on\n", " Wikipedia.\n", " .. [10] A. Curtis, M. J. D. Powell, and J. Reid, \"On the estimation of\n", " sparse Jacobian matrices\", Journal of the Institute of Mathematics\n", " and its Applications, 13, pp. 117-120, 1974.\n", " .. [11] `Cauchy-Riemann equations\n", " `_ on\n", " Wikipedia.\n", " .. [12] `Lotka-Volterra equations\n", " `_\n", " on Wikipedia.\n", " .. [13] E. Hairer, S. P. Norsett G. Wanner, \"Solving Ordinary Differential\n", " Equations I: Nonstiff Problems\", Sec. II.\n", " .. [14] `Page with original Fortran code of DOP853\n", " `_.\n", " \n", " Examples\n", " --------\n", " Basic exponential decay showing automatically chosen time points.\n", " \n", " >>> import numpy as np\n", " >>> from scipy.integrate import solve_ivp\n", " >>> def exponential_decay(t, y): return -0.5 * y\n", " >>> sol = solve_ivp(exponential_decay, [0, 10], [2, 4, 8])\n", " >>> print(sol.t)\n", " [ 0. 0.11487653 1.26364188 3.06061781 4.81611105 6.57445806\n", " 8.33328988 10. ]\n", " >>> print(sol.y)\n", " [[2. 1.88836035 1.06327177 0.43319312 0.18017253 0.07483045\n", " 0.03107158 0.01350781]\n", " [4. 3.7767207 2.12654355 0.86638624 0.36034507 0.14966091\n", " 0.06214316 0.02701561]\n", " [8. 7.5534414 4.25308709 1.73277247 0.72069014 0.29932181\n", " 0.12428631 0.05403123]]\n", " \n", " Specifying points where the solution is desired.\n", " \n", " >>> sol = solve_ivp(exponential_decay, [0, 10], [2, 4, 8],\n", " ... t_eval=[0, 1, 2, 4, 10])\n", " >>> print(sol.t)\n", " [ 0 1 2 4 10]\n", " >>> print(sol.y)\n", " [[2. 1.21305369 0.73534021 0.27066736 0.01350938]\n", " [4. 2.42610739 1.47068043 0.54133472 0.02701876]\n", " [8. 4.85221478 2.94136085 1.08266944 0.05403753]]\n", " \n", " Cannon fired upward with terminal event upon impact. The ``terminal`` and\n", " ``direction`` fields of an event are applied by monkey patching a function.\n", " Here ``y[0]`` is position and ``y[1]`` is velocity. The projectile starts\n", " at position 0 with velocity +10. Note that the integration never reaches\n", " t=100 because the event is terminal.\n", " \n", " >>> def upward_cannon(t, y): return [y[1], -0.5]\n", " >>> def hit_ground(t, y): return y[0]\n", " >>> hit_ground.terminal = True\n", " >>> hit_ground.direction = -1\n", " >>> sol = solve_ivp(upward_cannon, [0, 100], [0, 10], events=hit_ground)\n", " >>> print(sol.t_events)\n", " [array([40.])]\n", " >>> print(sol.t)\n", " [0.00000000e+00 9.99900010e-05 1.09989001e-03 1.10988901e-02\n", " 1.11088891e-01 1.11098890e+00 1.11099890e+01 4.00000000e+01]\n", " \n", " Use `dense_output` and `events` to find position, which is 100, at the apex\n", " of the cannonball's trajectory. Apex is not defined as terminal, so both\n", " apex and hit_ground are found. There is no information at t=20, so the sol\n", " attribute is used to evaluate the solution. The sol attribute is returned\n", " by setting ``dense_output=True``. Alternatively, the `y_events` attribute\n", " can be used to access the solution at the time of the event.\n", " \n", " >>> def apex(t, y): return y[1]\n", " >>> sol = solve_ivp(upward_cannon, [0, 100], [0, 10],\n", " ... events=(hit_ground, apex), dense_output=True)\n", " >>> print(sol.t_events)\n", " [array([40.]), array([20.])]\n", " >>> print(sol.t)\n", " [0.00000000e+00 9.99900010e-05 1.09989001e-03 1.10988901e-02\n", " 1.11088891e-01 1.11098890e+00 1.11099890e+01 4.00000000e+01]\n", " >>> print(sol.sol(sol.t_events[1][0]))\n", " [100. 0.]\n", " >>> print(sol.y_events)\n", " [array([[-5.68434189e-14, -1.00000000e+01]]), array([[1.00000000e+02, 1.77635684e-15]])]\n", " \n", " As an example of a system with additional parameters, we'll implement\n", " the Lotka-Volterra equations [12]_.\n", " \n", " >>> def lotkavolterra(t, z, a, b, c, d):\n", " ... x, y = z\n", " ... return [a*x - b*x*y, -c*y + d*x*y]\n", " ...\n", " \n", " We pass in the parameter values a=1.5, b=1, c=3 and d=1 with the `args`\n", " argument.\n", " \n", " >>> sol = solve_ivp(lotkavolterra, [0, 15], [10, 5], args=(1.5, 1, 3, 1),\n", " ... dense_output=True)\n", " \n", " Compute a dense solution and plot it.\n", " \n", " >>> t = np.linspace(0, 15, 300)\n", " >>> z = sol.sol(t)\n", " >>> import matplotlib.pyplot as plt\n", " >>> plt.plot(t, z.T)\n", " >>> plt.xlabel('t')\n", " >>> plt.legend(['x', 'y'], shadow=True)\n", " >>> plt.title('Lotka-Volterra System')\n", " >>> plt.show()\n", "\n" ] } ], "source": [ "from scipy.integrate import solve_ivp\n", "help(solve_ivp)" ] }, { "cell_type": "code", "execution_count": 325, "id": "48a0ea9e", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " message: A termination event occurred.\n", " success: True\n", " status: 1\n", " t: [ 0.000e+00 1.414e-06 ... 6.601e+01 7.447e+01]\n", " y: [[ 0.000e+00 1.000e-03 ... 1.534e+04 1.605e+04]\n", " [ 0.000e+00 1.000e-03 ... 2.143e+03 1.364e-12]\n", " [ 7.071e+02 7.071e+02 ... 9.370e+01 7.476e+01]\n", " [ 7.071e+02 7.071e+02 ... -2.398e+02 -2.656e+02]]\n", " sol: \n", " t_events: [array([ 7.447e+01]), array([ 3.047e+01])]\n", " y_events: [array([[ 1.605e+04, 1.364e-12, 7.476e+01, -2.656e+02]]), array([[ 1.027e+04, 7.061e+03, 1.986e+02, -2.842e-14]])]\n", " nfev: 86\n", " njev: 0\n", " nlu: 0\n", "Time to target = 74.47 s\n", "Time to highest point = 30.47 s\n", "Distance hit = 16052.5168 m\n" ] } ], "source": [ "from scipy.integrate import solve_ivp\n", "\n", "\n", "def dx(t,x): # appropriate for solve_ivp\n", " return dy(x,t)\n", "\n", "\n", "def hit_target(t, u):\n", " # We've hit the target if the z-coordinate is 0.\n", " return u[1]\n", "# Stop the integration when we hit the target.\n", "hit_target.terminal = True\n", "# We must be moving downwards (don't stop before we begin moving upwards!)\n", "hit_target.direction = -1\n", "\n", "def max_height(t, u):\n", " # The maximum height is obtained when the z-velocity is zero.\n", " return u[3]\n", "\n", "# solve the ODE problem\n", "sol = solve_ivp(dx, t0f, x0, dense_output=True,\n", " events=(hit_target, max_height))\n", "\n", "print(sol)\n", "print('Time to target = {:.2f} s'.format(sol.t_events[0][0]))\n", "print('Time to highest point = {:.2f} s'.format(sol.t_events[1][0]))\n", "print('Distance hit = {:.4f} m'.format(sol.y_events[0][0,0]))" ] }, { "cell_type": "markdown", "id": "37967d25", "metadata": {}, "source": [ "We can plot the projectile motion. Using `sol.y` we get only points at which the calculation was performed. If we need more precise curve, we can use `sol.sol()` with argument being fine mesh." ] }, { "cell_type": "code", "execution_count": 326, "id": "adc3544a", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 326, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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5ionJ8cxZsGCBcrPz0998803KiEhQd17772qcePGKisryzHm4YcfVk2aNFHr1q1TO3bsUIMHD1bdunVTxcXFjjEjRoxQYWFhavPmzWrz5s0qLCxMjRw5strmunXrVtWyZUvVtWtX9dhjj9Wa+Z05c0a1aNFCTZ48WW3ZskUlJSWpH3/8UR08eLBWzPEf//iHatiwoVq9erVKSkpSX331lapXr5567bXXXHJ+33//vXr++efVN998owC1YsWKUs9X11yKi4tVWFiYGjx4sNqxY4dat26dCgkJUTNmzKiy+WVmZqqhQ4eqZcuWqX379qmYmBgVHh6uevXqVeo9XHV+F1qxYoXq1q2bCgkJUa+++qrLzK8sczx48KAKCAhQTz31lNqxY4f6888/1erVq1VaWlqNnqMUMeVw3XXXqYcffrjUYx06dFDPPPOMTonKJj09XQFq/fr1Siml7Ha7slgsasGCBY4x+fn5ymw2q7ffflsppf1i8vDwUEuXLnWMOX78uDIajSo6OloppdSePXsUoGJjYx1jYmJiFKD27dtX5fPKzs5Wbdu2VevWrVMDBw50FDG1YX5PP/20GjBgwBWfd/U53nrrreqBBx4o9djo0aPVxIkTXX5+F39AVOdcvv/+e2U0GtXx48cdY7744gtlMpmU1WqtkvldztatWxXg+AdebZhfcnKyatKkiUpMTFQtWrQoVcS40vyuNMd7773X8f/f5dTUOcrXSWVUWFhIXFwcw4cPL/X48OHD2bx5s06pysZqtQIQEBAAQFJSEqmpqaXmYjKZGDhwoGMucXFxFBUVlRoTEhJCWFiYY0xMTAxms5nw8HDHmL59+2I2m6vlz+TRRx/l1ltvZejQoaUerw3zW7VqFb179+aee+4hKCiIHj168N5779WaOQ4YMICffvqJP/74A4Dff/+djRs3csstt9SK+V2oOucSExNDWFgYISEhjjE33XQTBQUFpb6KrGpWqxWDwUD9+vUB15+f3W4nMjKSp556is6dO1/yfG2Y33fffUe7du246aabCAoKIjw8vNRXTjV1jlLElNGpU6ew2WwEBweXejw4OJjU1FSdUl2bUoonnniCAQMGEBYWBuDIe7W5pKam4unpSYMGDa46Jigo6JKfGRQUVOV/JkuXLmXHjh3Mnz//kudqw/wOHTrEW2+9Rdu2bVmzZg0PP/wws2bN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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import matplotlib.pyplot as plt\n", "\n", "tfine = linspace(0, sol.t_events[0][0], 100)\n", "soln = sol.sol(tfine)\n", "\n", "plt.plot(sol.y[0],sol.y[1], '.-')\n", "plt.plot(soln[0], soln[1])" ] }, { "cell_type": "markdown", "id": "8aa10812", "metadata": {}, "source": [ "Next we are estmating more realistic values for drag coefficient $k$." ] }, { "cell_type": "markdown", "id": "cb465564", "metadata": {}, "source": [ "A typical shell used in WW1 had diameter of 155 mm and length 1m and weighs about 50 kg.\n", "\n", "While most of the time the projectile moves such that the air is cut with the smallest crossection, at times the projectile might move a bit to expose the body of the shell. We estimate that the probability for angle $\\theta$ of projectile's direction is distributed exponentially, and probability for turning for 90$^\\circ$ is only one in a hudred million.\n", "\n", "The air density at normal athmospheric conditions is 1.293 kg/m$^3$, but becomes less dense as projectile moves through higher parts of the athmosphere. We estimate that density drops down to 1.0 kg/m$^3$ at heigh 2000m. We can assume that density distribution is constant between 1.0 kg/m$^3$ and 1.293 kg/m$^3$. More precise calculation would allow air density to be height dependent, but since the density also strongly depends on the weather conditions and clouds, we would not neccessarily get much more realistic values.\n", "\n", "Assume that the coefficient $c$ of air resistance of our projectile is 0.45, but it is normally distributed with standard deviation 0.005. In practice, this coefficient depends strongly on \"aerodinamics\" of an object, and can be meassured in \"wind tunnel\" measurements." ] }, { "cell_type": "markdown", "id": "e43db401", "metadata": {}, "source": [ "" ] }, { "cell_type": "markdown", "id": "c039c779", "metadata": {}, "source": [ "From the picture we can approximate the crossection as a function of angle to be:\n", "$$A = \\pi r^2 + 2 r l \\sin\\theta$$\n", "\n", "Probability for angle is distributed exponentially, hence we can write:\n", "$$P(\\theta) = C e^{-\\alpha \\theta}$$\n", "\n", "The normalization constant $C$ can be eliminated by requiring normalization of probability:\n", "$$1=\\int_0^{\\pi/2} d\\theta P(\\theta) = \\frac{C}{\\alpha}(1-e^{-\\alpha \\pi/2})\\rightarrow C=\\frac{\\alpha}{1-e^{-\\alpha \\pi/2}}$$\n", "\n", "Hence a closed form probability for angle is:\n", "$$P(\\theta) = \\frac{\\alpha e^{-\\alpha \\theta}}{1-e^{-\\alpha \\pi/2}}$$\n", "\n", "The unknown coefficient $\\alpha$ can be obtained by the statement that only one in hundred million of shells turn for 90$^\\circ$:\n", "$$p_0=10^{-8}=\\frac{\\alpha e^{-\\alpha \\pi/2}}{1-e^{-\\alpha \\pi/2}}=\\frac{\\alpha}{e^{\\alpha \\pi/2}-1}$$\n", "\n", "Next we want to calculate the average crossection $$ and its variance. The average is:\n", "$$ =\\int_0^{\\pi/2} d\\theta P(\\theta) (\\pi r^2 + 2 r l \\sin\\theta)=\\pi r^2 + 2r l <\\sin\\theta>$$\n", "where the integral over angle $\\theta$ to get $<\\sin\\theta>$ will need to be carried out numerically.\n", "\n", "To get the variance, we also need:\n", "$$=\\int_0^{\\pi/2} d\\theta P(\\theta) (\\pi r^2 + 2 r l \\sin\\theta)^2=(\\pi r^2)^2+2\\pi r^2 2 r l <\\sin\\theta>+(2 r l)^2 <\\sin^2\\theta>$$\n", "\n", "The standard deviation is the square root of the variance, i.e.,\n", "$$\\sigma_A = \\sqrt{-^2}=2 r l \\sqrt{<\\sin^2\\theta>-<\\sin\\theta>^2}$$\n", "\n", "$$A \\approx \\pi r^2 + 2 r l <\\sin\\theta> \\pm 2 r l \\sqrt{<\\sin^2\\theta>-<\\sin\\theta>^2}$$" ] }, { "cell_type": "markdown", "id": "658ebbd9", "metadata": {}, "source": [ "The air density has maximum $\\rho_{max}=1.293$ kg/m$^3$ and minimum $\\rho_{min}$=1 kg/m$^3$ with the average $<\\rho>=(\\rho_{max}+\\rho_{min})/2=1.1465$ kg/m$^3$ and $\\sigma_\\rho=(\\rho_{max}-\\rho_{min})/(2\\sqrt{3})=0.0846$ kg/m$^3$, because the probability distribution is constant.\n", "\n", "The coefficient $c$ has average $0.45$ with $\\sigma_c=0.005$\n", "\n", "We next compute $<\\theta>$ and $<\\theta^2>$:" ] }, { "cell_type": "code", "execution_count": 330, "id": "a551bc30", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " converged: True\n", " flag: 'converged'\n", " function_calls: 15\n", " iterations: 14\n", " root: 13.378119683088366\n", "Norm= 1.0\n", "= 0.07433358789414495\n", " 0.010930508834082253\n" ] } ], "source": [ "from scipy.integrate import quad\n", "from scipy.optimize import root_scalar\n", "\n", "sr = root_scalar(lambda a: a/(exp(a*pi/2)-1)-10**-8, bracket=[0.01, 20.], method='brentq')\n", "print(sr)\n", "a = sr.root\n", "\n", "def P(th):\n", " return a*exp(-a*th)/(1-exp(-a*pi/2))\n", "\n", "norm=quad(lambda th: P(th),0,pi/2)[0] # checking that probability is normalized\n", "print('Norm=', norm)\n", "tha = quad(lambda th: sin(th)*P(th),0,pi/2)[0] # average \n", "tha2=quad(lambda th: sin(th)**2*P(th),0,pi/2)[0] # average \n", "\n", "print('=',tha)\n", "print('',tha2)" ] }, { "cell_type": "markdown", "id": "d032df46", "metadata": {}, "source": [ "We are now in a position to estimate the coefficient $k$ of drag." ] }, { "cell_type": "code", "execution_count": 332, "id": "3e1ded84", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "c= 0.450+/-0.005 sigma/<>= 0.011111111111111112\n", "A= 0.030+/-0.011 sigma/<>= 0.37496186024270517\n", "rho= 1.15+/-0.08 sigma/<>= 0.07377393321960764\n", "ka= 0.00016+/-0.00006\n" ] } ], "source": [ "m=50. # mass in kg is measured very precisely\n", "\n", "c=ufloat(0.45,0.005) # drag coefficient is known approximately\n", "r = 155e-3/2 # radius of 155mm shell\n", "l = 1. # length of the shell in m\n", "A = ufloat(pi*r**2 + 2*r*l*tha, 2*r*l*sqrt(tha2-tha**2)) # cross-section due to finite angle\n", "\n", "rhomax=1.293\n", "rhomin=1.0\n", "rho = ufloat((rhomax+rhomin)/2, (rhomax-rhomin)/(2*sqrt(3.)))\n", "\n", "print('c=', c, 'sigma/<>=', c.std_dev/c.nominal_value)\n", "print('A=', A, 'sigma/<>=', A.std_dev/A.nominal_value)\n", "print('rho=', rho, 'sigma/<>=',rho.std_dev/rho.nominal_value)\n", "\n", "\n", "ka = c*rho*A/(2*m)\n", "print('ka=', ka)" ] }, { "cell_type": "markdown", "id": "5e6b5f63", "metadata": {}, "source": [ "We see that the worst error is in the projectile crossection, meaning that the projectile is not very stable in the air. This is where some engeneering of the shape is necessary to improve the stability of the direction.\n", "\n", "The second is the density of the air. Here it is hard to improve unless the missile is guided with high tech equipment, otherwise the air density is not possible to control. Of course the \"aerodinamics\" of the projectile could reduce $c$ substantially, which is a major goal of all realistic missile engeneering. " ] }, { "cell_type": "markdown", "id": "9f368960", "metadata": {}, "source": [ "Next we calculate the trajectory with varying $k$ around its average value to estimate the derivative. (Note that the wrap function from module `uncertainty` is not working here). \n", "\n", "We are interested in distance in lateral direction where the projectile falls ($x$ at the point $z=0$) and its error estimate.\n", "\n", "We are thus computing $D(k)$ and we will estimate \n", "$$\\sigma_D = \\sigma_k \\left|\\frac{d D(k)}{dk}\\right|$$\n" ] }, { "cell_type": "code", "execution_count": 333, "id": "0e948f12", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[0.000156794235343206, 0.00016878309811701073, 0.00014480537256940127]\n", " message: A termination event occurred.\n", " success: True\n", " status: 1\n", " t: [ 0.000e+00 1.414e-06 ... 6.405e+01 6.485e+01]\n", " y: [[ 0.000e+00 1.000e-03 ... 1.148e+04 1.152e+04]\n", " [ 0.000e+00 1.000e-03 ... 1.750e+02 1.165e-12]\n", " [ 7.071e+02 7.071e+02 ... 5.382e+01 5.232e+01]\n", " [ 7.071e+02 7.071e+02 ... -2.193e+02 -2.209e+02]]\n", " sol: \n", " t_events: [array([ 6.485e+01]), array([ 2.565e+01])]\n", " y_events: [array([[ 1.152e+04, 1.165e-12, 5.232e+01, -2.209e+02]]), array([[ 7.557e+03, 5.378e+03, 1.610e+02, -1.421e-14]])]\n", " nfev: 92\n", " njev: 0\n", " nlu: 0\n", " message: A termination event occurred.\n", " success: True\n", " status: 1\n", " t: [ 0.000e+00 1.414e-06 ... 6.109e+01 6.334e+01]\n", " y: [[ 0.000e+00 1.000e-03 ... 1.078e+04 1.089e+04]\n", " [ 0.000e+00 1.000e-03 ... 4.758e+02 -4.547e-13]\n", " [ 7.071e+02 7.071e+02 ... 5.355e+01 4.931e+01]\n", " [ 7.071e+02 7.071e+02 ... -2.096e+02 -2.142e+02]]\n", " sol: \n", " t_events: [array([ 6.334e+01]), array([ 2.491e+01])]\n", " y_events: [array([[ 1.089e+04, -4.547e-13, 4.931e+01, -2.142e+02]]), array([[ 7.174e+03, 5.134e+03, 1.555e+02, 2.842e-14]])]\n", " nfev: 92\n", " njev: 0\n", " nlu: 0\n", " message: A termination event occurred.\n", " success: True\n", " status: 1\n", " t: [ 0.000e+00 1.414e-06 ... 5.041e+01 6.650e+01]\n", " y: [[ 0.000e+00 1.000e-03 ... 1.105e+04 1.223e+04]\n", " [ 0.000e+00 1.000e-03 ... 3.310e+03 1.819e-12]\n", " [ 7.071e+02 7.071e+02 ... 9.286e+01 5.577e+01]\n", " [ 7.071e+02 7.071e+02 ... -1.756e+02 -2.284e+02]]\n", " sol: \n", " t_events: [array([ 6.650e+01]), array([ 2.646e+01])]\n", " y_events: [array([[ 1.223e+04, 1.819e-12, 5.577e+01, -2.284e+02]]), array([[ 7.988e+03, 5.652e+03, 1.671e+02, 1.421e-14]])]\n", " nfev: 86\n", " njev: 0\n", " nlu: 0\n", "Distance where projectile hits= 11517.658105652063\n", "Error of the distance= 3341.5938853340604\n" ] } ], "source": [ "def dxn(t,u,k): # approproate for odeint\n", " \"\"\"\n", " The derivative for projectile motion with air resistance\n", " \"\"\"\n", " g = 9.82\n", " x,z,xdot,zdot = u\n", " dx = xdot\n", " dz = zdot\n", " dxdot = -k * xdot * sqrt(xdot**2+zdot**2)\n", " dzdot = -g -k * zdot * sqrt(xdot**2+zdot**2)\n", " return array([dx,dz,dxdot,dzdot])\n", "\n", "def hit_target(t, u, k):\n", " # We've hit the target if the z-coordinate is 0.\n", " return u[1]\n", "\n", "hit_target.terminal = True # Stop the integration when we hit the target.\n", "hit_target.direction = -1 # We must be moving downwards (don't stop before we begin moving upwards!)\n", "\n", "def max_height(t, u, k):\n", " # The maximum height is obtained when the z-velocity is zero.\n", " return u[3]\n", "\n", "\n", "def odes(t0f,x0,k): # solve the ODE problem\n", " sol = solve_ivp(dxn, t0f, x0, dense_output=True, args=(k,),\n", " events=(hit_target, max_height))\n", " print(sol)\n", " return sol.y_events[0][0,0]\n", "\n", "# choose an initial state\n", "v0 = 1000. # velocity magnitude in m/s\n", "x0 = [0, 0, v0*cos(pi/4), v0*sin(pi/4)] # initial velocity at 45 degrees\n", "t0f = (0,100)\n", "\n", "k0=ka.nominal_value\n", "k1=k0 + 0.2*ka.std_dev\n", "k2=k0 - 0.2*ka.std_dev\n", "print([k0,k1,k2])\n", "\n", "fk = odes(t0f,x0,k0)\n", "\n", "dfdk=(odes(t0f,x0,k1)-odes(t0f,x0,k2))/(k1-k2)\n", "\n", "print('Distance where projectile hits=', fk)\n", "print('Error of the distance=', abs(dfdk)*ka.std_dev)\n" ] }, { "cell_type": "markdown", "id": "687c4b80", "metadata": {}, "source": [ "Clearly, this error is enormous. The distance is 11.5 km with a 3.3 km error. This is unacceptable even for WW1 ammunition. Hence, improving the aerodynamic shape such that the cross-sectional area is constant, and coefficient $c$ is reduced, was essential.\n", "\n", "If we eliminate the error of the cross-section, we get an error in distance of around 870 m, which is much more realistic for classical weaponry. Of course the decrease in $c$ could further decrease the error and increase the reach." ] }, { "cell_type": "markdown", "id": "064dbbca", "metadata": {}, "source": [ "## Homework:\n" ] }, { "cell_type": "markdown", "id": "90d9176b", "metadata": {}, "source": [ "In addition to uncertainty in drag coefficient $k$, imagine we also have some uncertainty in the velocity $v_0$ and its lunching angle $\\theta$. First let's eliminate the error in crossection area $A=\\pi r^2$. Next assume that $v_0$ has still average 1000 m/s, but its distribution is triangular between 999 m/s and 1001 m/s. The angle $\\theta$ is much harder to control on uneven surface under constant explosions. Assume that $\\theta$ is distrbuted normally with standard deviation of 2 degrees.\n", "\n", "How large is the error of projectile reach?" ] }, { "cell_type": "code", "execution_count": null, "id": "fff68578", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.18" } }, "nbformat": 4, "nbformat_minor": 5 }