{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# SciPy - Library of scientific algorithms for Python" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "J.R. Johansson (jrjohansson at gmail.com)\n", "\n", "The latest version of this [IPython notebook](http://ipython.org/notebook.html) lecture is available at [http://github.com/jrjohansson/scientific-python-lectures](http://github.com/jrjohansson/scientific-python-lectures).\n", "\n", "The other notebooks in this lecture series are indexed at [http://jrjohansson.github.io](http://jrjohansson.github.io)." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# what is this line all about? Answer in lecture 4\n", "%matplotlib inline\n", "import matplotlib.pyplot as plt\n", "from IPython.display import Image" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Introduction" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The SciPy framework builds on top of the low-level NumPy framework for multidimensional arrays, and provides a large number of higher-level scientific algorithms. Some of the topics that SciPy covers are:\n", "\n", "* Special functions ([scipy.special](http://docs.scipy.org/doc/scipy/reference/special.html))\n", "* Integration ([scipy.integrate](http://docs.scipy.org/doc/scipy/reference/integrate.html))\n", "* Optimization ([scipy.optimize](http://docs.scipy.org/doc/scipy/reference/optimize.html))\n", "* Interpolation ([scipy.interpolate](http://docs.scipy.org/doc/scipy/reference/interpolate.html))\n", "* Fourier Transforms ([scipy.fftpack](http://docs.scipy.org/doc/scipy/reference/fftpack.html))\n", "* Signal Processing ([scipy.signal](http://docs.scipy.org/doc/scipy/reference/signal.html))\n", "* Linear Algebra ([scipy.linalg](http://docs.scipy.org/doc/scipy/reference/linalg.html))\n", "* Sparse Eigenvalue Problems ([scipy.sparse](http://docs.scipy.org/doc/scipy/reference/sparse.html))\n", "* Statistics ([scipy.stats](http://docs.scipy.org/doc/scipy/reference/stats.html))\n", "* Multi-dimensional image processing ([scipy.ndimage](http://docs.scipy.org/doc/scipy/reference/ndimage.html))\n", "* File IO ([scipy.io](http://docs.scipy.org/doc/scipy/reference/io.html))\n", "\n", "Each of these submodules provides a number of functions and classes that can be used to solve problems in their respective topics.\n", "\n", "In this lecture we will look at how to use some of these subpackages.\n", "\n", "To access the SciPy package in a Python program, we start by importing everything from the `scipy` module." ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [], "source": [ "from scipy import *" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If we only need to use part of the SciPy framework we can selectively include only those modules we are interested in. For example, to include the linear algebra package under the name `la`, we can do:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import scipy.linalg as la" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Special functions" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A large number of mathematical special functions are important for many computational physics problems. SciPy provides implementations of a very extensive set of special functions. For details, see the list of functions in the reference documentation at http://docs.scipy.org/doc/scipy/reference/special.html#module-scipy.special. \n", "\n", "To demonstrate the typical usage of special functions we will look in more detail at the Bessel functions:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [], "source": [ "#\n", "# The scipy.special module includes a large number of Bessel-functions\n", "# Here we will use the functions jn and yn, which are the Bessel functions \n", "# of the first and second kind and real-valued order. We also include the \n", "# function jn_zeros and yn_zeros that gives the zeroes of the functions jn\n", "# and yn.\n", "#\n", "from scipy.special import jn, yn, jn_zeros, yn_zeros" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "J_0(0.000000) = 1.000000\n", "Y_0(1.000000) = 0.088257\n" ] } ], "source": [ "n = 0 # order\n", "x = 0.0\n", "\n", "# Bessel function of first kind\n", "print \"J_%d(%f) = %f\" % (n, x, jn(n, x))\n", "\n", "x = 1.0\n", "# Bessel function of second kind\n", "print \"Y_%d(%f) = %f\" % (n, x, yn(n, x))" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAX0AAAD7CAYAAACG50QgAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAIABJREFUeJzsnXl4TNcbx78jsdcW2aW2xr6vpRRFFVFUW0urrbZaRVFdlFJbLbXEvgVVW2urIkgjgpBVJLIQWUQSiWwikT2Tycx9f38c/ES2We7Mncj5PM887cyce+47N+Y7577nXWREBA6Hw+FUDapJbQCHw+FwDAcXfQ6Hw6lCcNHncDicKgQXfQ6Hw6lCcNHncDicKgQXfQ6Hw6lCmEptwFNkMhmPHeVwOBwNISKZJuONaqVPRPxBhCVLlkhug7E8+LXg14Ffi7If2mBUos/hcDgc/cJFn8PhcKoQXPSNkEGDBkltgtHArwWDX4f/w6+Fbsi09QuJjUwmI2OxhcPhcCoDMpkMpOFGrtFE73A4nKqLTKaRblVJxFoUc9HncDhGAb/TLxsxfxS5T5/D4XCqEFz0ORwOpwrBRZ/D4XCqEFz0ORwOpwrBRZ/D4XD0RGxsbIVjkpOTkZ+fbwBrGFz0ORwORw/ExMTAz8+vwnEWFhZYu3atASxicNHncDgcPeDk5IRJkyZVOM7U1BQODg44ePCgAazios/hcDgaceTIETg4OKB3797w9vYudUxISAjs7OzUnrNXr15wd3cXy8Ry4aLP4XA4GjBp0iTUr18fc+fORb9+/Uodc+7cOQwePFijeS0sLBAdHS2GieXCRZ/D4XA0gIhw5cqVckX9xo0baN++vUbzdunSBYGBgbqaVyG8DAOHw+FoQEhICMzNzWFlZVXmmPz8/BKlE5ydnWFiYgJPT0906tQJrq6uWLhwIdq2bQsAaNSoEaKiovRqO8BFn8PhVALEKj0jRnmfS5cuYejQoeWOUalUxZ7Hx8ejffv2sLe3x+LFizF//nw0aNAATZs2fTamdu3aUCgUuhtYATqJvkwm2wfAAcBDIupUxpgtAEYAyAcwhYiCdDknh8OpehhTLTZ3d3fMmDEDjx8/xu7du2FpaYnOnTujR48ez8aYmhaX1qfinpqainr16qFhw4YYNWpUsTFZWVkwMzPTu/26+vT/BDC8rDdlMtlIAPZE1ArA1wB26ng+DofDMSgFBQWwtbVFTEwMUlJSEBYWhsGDB+PPP//EW2+9hU8++QQbNmwodoy1tTVyc3OfPY+IiEBISAhcXFwwYMAAAICLi0uxY5KTk2Fvb6/3z6OT6BORJ4DH5QwZDeDAk7HXATSUyWRlO8I4HA7HyKhRowZmzJiB0NBQODo6wtXVFXXr1kVsbCxsbGxgamqKjIyMYscMHDgQ/v7+z567ubnh3LlzICLI5XKcPn0alpaWxY4JDg4uMxpITPTt028CIOG55w8A2AFI1fN5ORwORxRMTEywaNEiAMDYsWOfvS4IAkxMTACUrHc/btw4rF+//lmEz+zZs8s9h1wuR/369VGrVi0xTS8VQ2zkvrgFU6Z3rnbtpXjlFcDKCnBwGIQ5cwbB1lbP1nE4HI4WtGnTBqmpqTAzM0P9+vWLvdewYUOYm5vj0aNHMDc3r3Cuo0ePYtq0aRWO8/DwgIeHh7YmAxChR65MJmsO4GxpG7kymWwXAA8iOvrkeQSAgURUYqUvk8koLY2QnAzcuAG4ugLu7kCLFsB33wETJwLVq+tkKofDMVKe9HqV2gyNSE9Px759+9CgQQN06tQJffv2LfY+EWHv3r346quvyp0nISEBN2/exJgxY8ocU9b10aZHrr5FfySAb4lopEwm6wNgExH1KWOeEo3RlUrg4kVg3Trg3j3g+++BadMAA9wBcTgcA1IZRd+QGI3oy2SyIwAGAjAH89MvAVAdAIjI6cmYbWARPnkAPieim2XMVUL0n8ffH1ixAoiMBPbuBd58U2uzORyOkcFFv3yMRvTFpCLRf8qpU8C33wKjRwNr1gAvuNI4HE4lhIt++Ygp+pWu9s577wFhYUBREdCjBxAeLrVFHA6HU3modKIPAA0bMhfPokXAwIHA+fNSW8ThcDiVg0rn3nkRPz/g/feB2bOBefPEq9HB4XAMB3fvlE+V9umXxoMHgIMDMGIEsHo1F34Op7LBRb98xBT9l6LKpp0dcPkyMHQoIAhsg5cLP4fD4ZSkUvr0S6NxY+DSJZbQ9eOPxlWVj8PhcIyFl0b0AcDMjAn/1avAr79KbQ2Hw+EYHy+V6ANAo0bAf/8BR4+yCB8Oh8ORitjY2ArHJCcnIz8/3wDWMF460QcACwvAxYWFdLq5SW0Nh8OpisTExMDPz6/CcRYWFli7dq0BLGK8lKIPAK1bA//8A0yeDISESG0Nh8Opajg5OWHSpEkVjjM1NYWDgwMOHjxoAKteYtEHgP79gS1bWMmG9HSpreFwOC8DR44cgYODA3r37g1vb+9Sx4SEhMDOzk7tOXv16gV3d3exTCyXl1r0AVaSefx4tuIXBKmt4XA4lZ1Jkyahfv36mDt3bpmdrs6dO/esgYq6WFhYIDo6WgwTy+WlF30AWLUKyM1l/+VwOBxdICJcuXKlXFG/ceMG2rdvr9G8Xbp0QWBgoK7mVchLkZxVEdWrA8eOAT17An36sCQuDofD0YaQkBCYm5vDyqrsdt/5+fklWig6OzvDxMQEnp6e6NSpE1xdXbFw4UK0bdsWANCoUSNERUXp1Xagiog+ANjaAn/9BXz0ERAYCN6GkcOpRMiWiZNiT0t0z9q8dOkShlawclSpVMWex8fHo3379rC3t8fixYsxf/58NGjQAE2bNn02pnbt2lAoFDrbVxFVRvQB4K23gK+/BqZOZZU5eakGDqdyIIZYi4W7uztmzJiBrKwsXLp0CZGRkViwYEGxMaamxaX1qbinpqaiXr16aNiwIUaNGlVsTFZWFszMzPRrPKqIT/95Fi0C0tIAJyepLeFwOJWBgoIC2NraIiYmBikpKQgLC8OQIUPQoEED9OjRo9TVubW1NXJzc589j4iIQEhICFxcXDBgwAAAgIuLS7FjkpOTYW9vr98Pgyoo+tWrAwcPMvG/e1dqazgcjrFTo0YNzJgxA6GhoXB0dISrqyvq1KlT7jEDBw6Ev7//s+dubm44d+4ciAhyuRynT5+GpaVlsWOCg4PLjAYSkyrl3nlKu3asNs+nnwKenoBplbwKHA5HHUxMTLBo0SIAwNixY9U6Zty4cVi/fv2zCJ/Zs2eXO14ul6N+/fqoVauWbsaqQZVb6T9l1iygbl1g3TqpLeFwOJWVsnoANGzYEObm5nj06JFa8xw9ehTTpk0T07QyqbKiX60aK8jm6MjdPBwOR3Nyc3Nx8uRJBAYG4vbt2yXenzNnDk6dOlXhPAkJCWjUqBHatGmjDzNL8FJ0ztKFDRuAc+dYSWYezcPhSAPvnFU+YnbOqrIr/afMng1kZQEHDkhtCYfD4eifKr/SB4CbN4Hhw4Hbt4EXNtQ5HI4B4Cv98uGN0fXAjz8CKSnA4cOSmcDhVFm46JcPF309kJcHtG/PYvgHDpTMDA6nSsJFv3y4T18P1K0LrF/PQjmVSqmt4XA4HP3ARf85PvgAMDfnJRo4HM7LC3fvvMCtW8CQIcCdO+wHgMPh6B/u3ikf7tPXM7NnA4WFfMXP4RgKLvrlw0Vfzzx+zOrzuLgA3btLbQ2H8/LDRb98+EaunmnUCFi6lIVx8n+HHA5HW2JjYysck5ycjPz8fANYw+CiXwZTpwLJyWy1z+FwOJoSExMDPz+/CsdZWFhg7dq1BrCIwUW/DExNgbVrgXnzeAgnh8PRHCcnJ0yaNKnCcaampnBwcMDBgwcNYBUX/XIZNYqVZdi3T2pLOByOsXDkyBE4ODigd+/e8Pb2LnVMSEgI7Ozs1J6zV69ecHd3F8vEcuGiXw4yGUvYWrIEyMmR2hoOh2MMTJo0CfXr18fcuXPL7HR17ty5Zw1U1MXCwgLR0dFimFguXPQroEcPFre/fr3UlnA4HGOAiHDlypVyRf3GjRto3769RvN26dIFgYGBuppXIbxRoBqsWMHEf+ZMXoWTw6nqhISEwNzcHFZWVmWOyc/Ph+yFBh3Ozs4wMTGBp6cnOnXqBFdXVyxcuBBt27YFADRq1AhRUVF6tR3gK321aN4c+PhjYNUqqS3hcKooMpk4DxG4dOkShg4dWu4YlUpV7Hl8fDzat28PBwcHXLx4EQ4ODpgwYQKaNm36bEzt2rWhUChEsbE8+EpfTRYuZFU4584FmjWT2hoOp4phRAkz7u7umDFjBqKjo3Hr1i2Ehobi3XffRffnMjlNTYtL61NxT01NRb169dCwYUOMGjWq2JisrCyYmZnp3X6+0lcTKyvgm2+A5cultoTD4RiSgoIC2NraIiYmBikpKQgLC8PgwYNx9uxZNGnSBN9//z3Wv7DpZ21tjdzc3GfPIyIiEBISAhcXFwwYMAAA4PJCElBycjLs7e31/nn4Sl8DfvoJaNUKiIgAnrjhOBzOS06NGjUwY8YMhIaGwtvbG66urqhbty7mzp0LALhz5w5atGhR7JiBAwfC39//2Wavm5sbcnJyYGNjA7lcjtOnT5cI6QwODsbUqVP1/nl47R0N+f13IDAQOHFCaks4nJeHylx7Z+XKlZg7dy7q1Knz7LXMzEysX78eK1asUGsOuVyOX375BRs2bCj1fV57R0Jmzwa8vYGgIKkt4XA4UuPs7IzZs2cjMTGx2OsNGzaEubk5Hj16pNY8R48exbRp0/RhYgm46GtInTrAzz8Dy5ZJbQmHw5GSU6dO4bfffsO4ceNw/PjxEu/PmTMHp06dqnCehIQENGrUCG3atNGHmSXg7h0tKCgA7O0BZ2cWv8/hcHSjMrt3DAGvp28EbN0KuLkBZ89qdlyhshAPsh8gNS8VNU1qom6NuqhbvS5s6tnAtBrfV+dUTbjolw8XfSNALmer/VOngF69Sh8jkICQlBC4x7jjYsxFBKcEI6swC7b1bGFV1woKlQJ5RXnIVeQiU56JDhYd0N2mO/ra9cWYtmPQsFZDw34oDkciuOiXDxd9I2H7dlZv//z54q8nZidid+Bu7Lm5B/Vr1sfQlkMxtOVQ9G7SG9avWKOarORWSk5hDkJSQxCUHITLcZdxOfYyBjYbiIkdJ+L9du+jpmlNA30qDsfwcNEvHy76RkJhIYvbP3ECeP11IOxhGJZdXYaLMRcxqeMkzOg1Ax0tO2o1d3ZhNs5EnMGBkAOISo/CvH7z8GW3L1G7em2RPwWHIz1c9MuHi74RsXMn8K/rI7T+eglO3DmB+f3nY2r3qahfs75o5/BP9MeKaysQkBSAxQMX4+seX5d6t8DhVFa46JcPF30jgYiw1W8X5p5ZjPHtPsL28UtgVlt/tTOCkoPw7X/fQiABu0ftRierTno7F4djSLjolw8XfSMgLS8NXzh/gZTcFAzNOYAIz/ZQIyRXZwQSsCdwDxZdWYSvu3+NpYOWorpJdf2fmMPRI1z0y8eoMnJlMtlwmUwWIZPJ7spksp9LeX+QTCbLkslkQU8ei3Q9p9S4x7ijq1NXdLDoAO8vvPHrN+3h5weEhur/3NVk1TCt5zTcmn4LwanBGHRgEB5kP9D/iTkczkuBTit9mUxmAiASwFAAiQBuAJhEROHPjRkE4HsiGl3BXEa/0icibL6+GWu91+LQe4cwpOWQZ++tWwcEBADHjhnOHoEErPFagy3+W3Bg7AEMe22Y4U7O4YgIX+mXjzGt9HsDiCaiOCIqAnAUwJhSxonTvUBClIISs/+bjb0398L3S99igg8A06cDV64A4eFlTKAHqsmqYcGbC3D0/aP4/MznWO+znn9xOBwjIjY2tsIxycnJyM/PN4A1DF1FvwmAhOeeP3jy2vMQgDdkMlmITCZzkclkmjWONAJyFbkYe3QsItMj4f2FN5o1LNlF5ZVXgO++A1auNLx9A5sPxPWp13Eg5AC+c/0OKkFV8UEcDkevxMTEwM/Pr8JxFhYWWLt2rQEsYuia96/OsvImgFeJKF8mk40AcBpA69IGLl269Nn/Dxo0CIMGDdLRPN3JKczByL9Hwt7MHrtH7S530/Tbb4GWLYGYGPZfQ2JX3w6en3vivWPvYfw/43H4vcM8pp/DkRAnJyesWbOmwnGmpqZwcHDAwYMH8emnn5Y71sPDAx4eHjrZpatPvw+ApUQ0/MnzBQAEIirzk8pkslgAPYgo44XXjc6n/1Tw2zZuC6d3ndSKjV+0CHj0CNi1ywAGlkKhshCfn/kciTmJOP/RebxS4xX1DhQEIC4OSEkB0tPZhygsBGrWZI86dViz4JYtgfri5SBwOEDl8ukfOXIEhw8fRlpaGjZu3Ih+/fqVGBMSEoJr165h1qxZas/76aef4uDBg6W+ZzQhmzKZzBRsI3cIgCQA/ii5kWsF4CERkUwm6w3gOBE1L2UuoxJ9bQQfANLSgDZtgNu3AVtbPRtZBgIJmOo8Ffce34PLRy6oW6NuyUHJycDFi4CnJws7CgsDzMyAJk2Axo3Zo1YtJvyFhUBuLnD/PruNqVUL6NYNePNN9ujTB6jN7yo42lOZRB8AJk2ahNGjR2PSpEmlvr9y5UqMHTsWHTp0UHvOH374AdOnTy+1ZaLRiP6Tk44AsAmACYA/iGi1TCabBgBE5CSTyWYCmA5ACSAfLJKnhKPLmERfrpTjncPvoLVZa40E/ynffQeYmgIvtM00KE+FP+ZxDM5/dJ4Jf2QkcPAgKw2akAAMGQK89RbQtSvQsSPQoEHFExMBqamAvz/g5cV+NMLDgREjgAkTgOHD2Y8Ch6MBlUn0iQg2NjYICQmBlZVVqWPGjh2LU6dOQSZTX48PHjyImjVrYsKECSXeMyrRFwtjEX2BBEz8ZyIA4OgHR7Uqd5CQAHTpAty9yxbMUiGQgJnHPkPr/65jTngDVEt4AHz8MfD++6w0qKlIpZzT0oCTJ4GjR9ldwxdfsBZjTZuKMz/npacyiX5wcDAmT56M27dvlzlm2LBhcHNzK/aas7MzTExM4OnpiU6dOsHV1RULFy5E2ycNt8+ePYuoqCj88MMPJeYTU/R5AfcX+NHtR6TmpeLC5Ata17d59VVg3DhgyxYJO2ylpKDatm3Y4eSKG6/VxsrB5liwPBamNfSwCrewAL75hj3u32cfvFs34O23gQUL2C8gh6MDMh03L59CIgSHXLp0CUOHDi13jEpVPIIuPj4e7du3h729PRYvXoz58+ejQYMGaPrcwqh27dpQKBQ621chRGQUD2aKtGzw2UDttrWjjPwMneeKiiJq3JgoO1sEwzQhNZVo1iyihg2Jpk8nunuXCpWF9PbBt+lr569JEATD2JGVRbR+PZGVFdGnnxLdv2+Y83IqJcbw/VeX4cOHk7OzM8XFxdHx48dp1apVFBAQUGzMsGHDSj02JSWFBg4cWOp7//zzD+3atavU98q6Pk9e10hreanGJ5yLOgdHX0f89/F/aFS7kc7ztWoFDB0K7N4tgnHqkJsLLF8OtGsHyGTMf79jB2BvjxomNXBy/EkEJAdg2VUD3XrUrw/88AMQFcXcPN26sVW/AZNQOBwxKCgogK2tLWJiYpCSkoKwsDAMGTIE3t7eaNy4MVq1aoWoqKhix1hbWyM3N/fZ84iICISEhMDFxQUDBgwAALi4uBQ7Jjk5udRNXLHh7h0AkY8i8cWZL+A8ybnUxCtt+flnYNQoFr9fU189UIhYQf+5c4GBA4EbN0pNEqhXsx5cPnJBv339YFffDlO7T9WTQS9Qvz7w22/M9fPTT0DnzsCePWwDuQxSFQqE5eUhPD8f4Xl5eFBYiIdFRXioUCBTqYQAQHji36xvaorG1aujsakp7GrWRJs6ddC2Th10qFsXrWrX1mgjjcMpjRo1amDGjBkIDQ2Ft7c3XF1dUadOHXz00UeIjY2Fm5sbli9fXuyYgQMHwt/fH4MHDwYAuLm5IScnBzY2NpDL5Th9+jTs7OyKHRMcHIypU/X/vazyG7nZhdl4fe/r+L7P9/iqx1eizz98OPDBB4Be/pb37gEzZwKJiSwxoJR44ReJSo9C/339ceLDExjYfKAejKqAc+eAGTOAd94BHB2B+vURnZ8P98eP4ZWVBe/sbGQplehYty7a1amDdnXqoFmtWrCsUQOW1aujoakpTGSyZ3U9slUqpBcVIb2oCAmFhYjIz0dEfj5Cc3ORJwjo36AB+jdogJFmZmhXt5TQVY5RUJk2cl/Ez88Pzs7OWLVq1bPXMjMzsX79eqxYsUKtOeRyOX755Rds2LCh1Pd59I5ICCTg/ePvw6quFXaN0k82lYcH8PXXLKrRxESkSVUqYNMmYPVqYP58YM4coLr65ZUv3ruIT059At8vfdGiUQuRjFIfysqC75o1OC0IODtyJDJNTTGsUSO8+USg29SpI8oK/YFcDq+sLFzLysLZ9HS8YmKCcebmmGBpic6vqJm0xjEIlVH0f/75Z3z22WcoLCzEihUrcPLkyWLvb9q0CZMnT4a5uXmFc+3fvx99+/ZFmzZtSn2fi75IrPZcjbNRZ3Hlsyt660FLBLzxBnNvf/CBCBPGxABTpjC//f79QAvtRHub/zbsCtgFny99RO3yVR7R+fk4lJqKw6mpqFGtGj5IS8PoFSvQY+JEVJs9m30mPSEQISAnByfT0nDk4UPY1KiBaba2mGBpibqi/RpztKUyir6vry/S0tIQFhaG0aNHl0jEIiLs3bsXX31VvgchISEBN2/exJgxpdWqZHDRFwGfBB+MOzYOAV8HwK6+XcUH6MCZM8ytfeOGDrpGBPz5J9soWLCAZYBV034fnogw/fx0JOUk4fTE03prv6giwrn0dGx98ACheXmYZGmJT62t0f2VV9hqPiaGJXU1bQocOMAq1+kZFRH+S0/HrqQk+GZnY0aTJpjTpAnMa9TQ+7k5pVMZRd+QcNHXkccFj9HNqRu2jNiC0W3KLfMvCoLAEl63bGERPRqTk8NqN4eEsAQoDVK7y0OhUuCtA2/BoZUDfnnzF1HmfEquUondycnY8uABrGvUwLdNmuBDS0vULO2HqrCQ+fkDA9kvZDPxNtMrIqagAGvi43EiLQ1fWFvjp6ZNYcXF3+Bw0S8fY6qnX+kgIkw9OxVj2owxiOADbEH+88/A779rcXBICNCzJ6ttc/26aIIPADVMauD4B8ex1X8r3GPcRZnzcVERfouLQ8vr1+GXnY3jHTrAr0cPTLa2Ll3wARbatHcv8NlnQN++gLe3KLaoQ8vateHUpg1Ce/aEgggd/P2x+v59FKh4eWrOS4qmgf36esBAyRk7b+ykrru6krxIbpDzPaWwkOjVV4leyOEon4MHiczNif76S292ERFdirlE1uutKSErQes5souKaFlsLDX29KQp4eEUkZen3UQuLkQWFkQnTmhtiy7czcujcbduUVMfHzqSkmK4ZLYqjqG+/5WVsq4PtEjOklzsnxligD96RFoENV7TmCLSIvR+rtLYsIHoww/VGKhQEM2eTWRvT3T7tt7tIiJa7bma+uztQ4XKQo2Ok6tUtDE+nqy8vOjjsDCKzs/X3ZigICJbW6KdO3WfS0uuPn5Mnfz9aXhICMWK8Zk45cJFv3zEFP0q49NXCkr039cfn3T+BDN7z9TbecojN5cF2/j6AmUm3j18CHz4IdvQ/OsvoGFDg9gmkIAxR8egbeO2WDdsXYXjiQj/PnqEn+7dQ4e6dbGqRQt0EnMT9t49Fss/eTKwZIleI3vKokgQsD4hAY4JCVjYrBlm29nBhCd76QXu0y8fvpGrBas9V+Ny3GWdCqmJwa+/sqKUpTZZuX0bePdd4KOPWLiPDtE52vAo/xG6OXXDnnf3YLj98DLHBeXk4LvoaDxWKrHR3h5DGuletqJUUlNZyeYBA4CNGyURfgCIys/H1MhIyAAcatcOTXnpaNHhol8+Yoq+5G6dpw/o8fYuODmYzNea0/1M6Yt+paYSNWpElJz8whvnzzNf9uHDktj1lCuxV8h6vTUlZSeVeC9DoaAZkZFk5eVFuxITSWkIf/fjx0S9ehF9+y2RhP51pSDQ6rg4svDyoqOpqZLZ8bIC1nqVP8p5lHXdiLt3iqNQKdBrTy/M7TMXU7pOEX1+bZg5k5WkWb36yQtbtwKrVrGa9G+8IaltALD4ymL4PvB9dldERDiUmoqfY2IwpnFjrGrZEmYaZADrTFYWq2fRrRuwbZvB74CeJzAnBx/duYN+DRpge6tWqM0TuzgSwt07pbDMYxkCkgPgPNHZaIpvxcayHiYx0QLqL/sBuHABcHFhPWiNAKWgxFsH3sKoVqPwfvdZmBYVhUylEjtbt0ZvqfrjZmczV0+nTsDOnZK5egAgT6XCV5GRCM/Px8kOHdCSt4rkSAQX/Re4k3YHA/cPRNC0IL1n3WrKpx8WYFHEZLRunA6cOgXoyy+uJfcy76Pz2RWo0Xwyfm3eErObNIGphCtsACxJ7e23WWG59eslFX4iwtbERKy8fx/72raFg5Qt0jhVFp6c9RxPe8QuH7Tc6AQf6enYETUEd+7VRKHzBaMT/OCcHHwQnYbXWr6PxuGLMN3aXHrBB4B69dgdkbs76x0gITKZDLPt7PBvx474OjIS6+Lj+UYkp1JgBN9k/bDzxk5Uk1XDtJ7TpDalOPfvA/364ZV3+mNX/8P46x99FdrXHIUgYHFsLIaFhmJOkyYI7jsMPcxsMd99vtSm/R8zM8DNDfj7b6CMMrSGpF+DBvDr3h1/paZiamQkFIIgtUmiolAAcXGAlxe77Bcvst9cLy/2elGR1BZyNOWldO8kZCWgm1M3eH7uiXYW7USZUxRu3QJGjmQlN7/7Dpcvs5Izd+5IujcJgIVhfhYRgea1amFX69awfdL1JaMgA112dcG+0fvw9mtvS2vk8yQkAG++CSxdyqqOSkyuUomPw8ORpVTi344dDbvRLRKFhSyHxNcX8PMDAgJYeLG1NdCkCUsdYQmdQEEB8OABkJLCWiR3784qaLzxBtC7N1CnjtSfpmrAQzafMPrIaFrmsUy0+UTh6lUiS0uiI0eevSQIRD17Ep0+LZ1ZCpWKlsZWNs+ZAAAgAElEQVTGkoWXFx1KTi617ID7PXdq4thElN7BohIeznrwurhIbQkRsbDOH+7epXbXr9P9ggKpzVELuZzI2Znok09YW+XevYnmziU6fpwoLo5IqSz/+KIiothYVjXj+++J+vQhql+f6IMPiI4eJcrJMcjHqLKAl2EgOhNxhlpvbW3w2jrlcvo0i8G/eLHEW8ePE/XtK00I+u3cXOp+4waNCAmhB/Lyr9e357+lyf9ONpBlGuDjw67t9etSW/IMx/h4svPxoVtGrHjJyUS//sou3ZtvEm3dSpRUMjVDK9LSiPbuJRo+nKhBA6Jp0wxWTaTKoY3ov1TunfyifLTf3h57R+/F0Jba1DDWA/v2AQsXAmfPsmqZL6BSAW3bsmFvvmkYkwQibHrwAKvj47G6RQt8aWNTYThrniIPXZ26Yt3b6zC27VjDGKouzs7AtGnAtWusI70R8HdqKuZGR+OfDh3wpoFKaahDbCxL9j51Cpg0iTVdK6NZkygkJwNOTuzRoQNrBTFkiP7O9zzZhdm4mXwTAUkBuP3wNhJzEpGUk4SU3BQoVIpn4+pWrwubejawecUGr9Z/FV2su6C7TXd0seqC2tWNOxy3yodsLry0EDGZMTjy/hGRrNKRtWuBHTtYHH453ywnJ/abcO6c/k2KKyjAlIgIqAAcaNtWoxhz73hvfHjiQ4ROD4V5nYpbwBmU3buBdeuYM9pIwifdMjLwcXg4Drdrh3fMzCS15fFjlv+3bx/w7bfArFmAGl38RKOwEDh2jP3gNG0KrFwJ9Okj7jkEEhCYFAjnSGecjTqL6IxodLHugp42PdHZqjPs6tvBtp4tbOrZoKbJ/wMochW5SM5NRlJOEu5n3kdwSjACkwMR8SgC3Wy6waGVAxxaOaCzVWejyfV5SpUW/YhHEei/rz9Cp4fCtp6tiJZpAREwbx4LL7xwAbArP2RULmeF2NzcWO6RfkwiHEhJwU8xMZj36qv4/tVXtSoe9qPbj4jPisfxD4/rwUod+flntgt58SKr0W8EeGdl4b3bt+HUujXes7Aw+PkFgf0eLl4MvPce2/e2sTG4Gc8oKmJdPpcvZwmKGzfq3jPnfuZ97Lm5B/uD96NezXoY3Xo0RrcZjdftXodpNVOt55Ur5bh2/xrOR53H+bvnoSIVpnSZgildp6BZQwM1+snPB0JDWajUgwfskZnJLqRSCdnx41VT9IkIQw8NxejWozGnzxyRLdMQpZJ1Qr9zBzh/Xu1V5++/A2FhwKFD4puUplBgWlQUogsKcLhdO52aghcUFaD77u5YNmgZxncYL6KVIiAIwPjxrOHMwYOSJm89z82cHIwMDYWjvT0+trIy2Hnv3QOmTmWLij17WPc2Y0EuZ/l1mzYBP/0EzJ0LaNKwjIhwKfYSNvhuwPXE65jcaTK+6vEVOlrq50MSEYJSgrAvaB+O3D6C7jbd8X2f7zHcfri4q/+0NOC//4DLl1n4VEwM0K4d8NprbPFoZ8fyeqpXB6pXh2zixKoZvXMi7AR12tGJilRFWs8hCgUFRGPHEg0bpnHYQmYmkZkZi4QQk3OPHpGNtzf9FB1NcpVKlDn9EvzIap0VPcx9KMp8opKXx0JQlhlX9Nbt3Fyy9fam/SUq7YmPIBBt3kzUuDGRo2PFEThScu8e0YgRRO3aEfn5VTxeEAS6eO8i9fujH7XZ2ob23dxHeQotG/ZoSUFRAR0MPkgdd3SkLju70JFbR3TTngcPiFavZv9uGzQgGjeO9ZIIDGTdl8oBVTF6J0+RR003NiWPWA+tjheNzEyigQOJxo+v8A9VFvPmsWKSYpBTVERfR0RQc19f8nj8WJxJn+OHCz/QxH8mij6vKCQnEzVtykKjjIiIvDxqomfhz8ggGjOGFSaNitLbaURFEIiOHWMRzYsXsx5CpRGUHEQD/hxAbba2ob9C/yKlStpfM0EQ6HzUeer3Rz9qt60dOUc4q99praiIxbmOGMHK7n71FZG7u8baUSVFf8mVJTT+xHitjhWNlBSirl2JZszQaVmVlMT+/g91XEB7Z2bSa76+NCU8nLKK9HP3k6/Ip1ZbWtGp8FN6mV9ngoJYq8nAQKktKYY+hd/fn6hFC6I5c7Red0hKYiIL8+zZkyjiueZ2j/Ie0fRz08lynSU5BThJLvYvIggCnYs8R+23t6eBfw6kG4k3yh6cl0e0bRtR8+ZE/fsTHTrEXtOSKif6cY/jyGyNmbR18mNiWFvDpUtFCbb/6isWP60NcpWK5t+7R1ZeXvSvrr8cauB535NsHW0pPT9d7+fSin/+YY2JDeBS0YSnwn9QRLv27WMx9//8I9qUkiAIRDt2sN/rI0cE+iv0L7JcZ0kzz8803n9nTyhSFdHugN1kvd6aZpybQZkFmf9/s6CAaN06lkw4ZgzLLxGBKif6Hxz/gJZ7LNf4ONF42st12zbRpoyKYr7Y7GzNjgvJyaHO/v40JjSUUgy4zJvlMos+PfWpwc6nMUuXsjRRI8uQDc/NJRtvbzqmY0MWlYpo/nyili1ZgvLLwiXfh1T38/ep0aJ25BNXzsrZCMnIz6Cvnb8mW0dbOhZ6hIRDh4iaNWNiL3KWWpUS/csxl6n5puaUr5CoafWVK2xppQe/8fjxbFGgDkUqFa2IiyNzLy/al5Skvk9RJHIKc6j5pub0393/DHpetVGpWE2AL76QtPNWaYTk5JCVlxedSUvT6vi8PKL33yfq149lwb4snI08S9brrWnW2Z9o1NgCev118bKFDUnQub10q2ktinytET12PaOXc1QZ0VeqlNR5Z2c6EXZCk+sjHidOMMG/fFkv09+8yW4gKqiMQHdyc6lXQAC9HRwsaa0Xt2g3arqxKWXLNbw9MRQ5OUQdO4p6RyYWN7KyyMLLi1zTNXNdZGSw8h0ff1zxv5PKgkKpoHlu86jpxqbked+TiNjv9IoVzEsXECCxgeqSnc02ViwtSbF3N/3o+gPZrLehs5FnRT9VlRH9PYF76M19bxp8VUtERJs2MUW+eVOvpxk+nMjJqfT3ilQq+v3+fWrs6Um7EhOluQ4v8Pnpz+nb8yKFHumD6GgWHnL1qtSWlMArM5MsvLzIU80oq+Rkos6dWWE0kaJwJedB1gPqv68/DT88nNLySt62/Puv3m6sxeXCBfYLNWVKsduvq3FXqfmm5jTt7DRRvRNVQvSz5dlks96m/B1yfaBSsW9Z27biB9OXwtWrRK+9xiK7nudWTg71DAigocHBFJsvkWurFDLyM8jW0fbZCs0ocXUlsrYmio+X2pISuKWnk6WXFwVVsJkTF0fUqhXR8uVG563SGu94b7JZb0Mrrq4glVD2r1hQEHONr1xphJ89P59o1iwiOzsiN7dSh2TJs2jCiQnUZWcXinwUKcppq4ToL3BfYPiNw4ICog8/ZOUINbwN1xZBIHrjjf9XYi5UqWhZbCyZe3nRHiNZ3b/IyTsnqc3WNlRQZFybpsVYs4aoRw+j29glIjqRmko23t4UWUYIX3Q0Sz/YvNnAhumRg8EHyWKtBblEqVceOymJRUd/803JBZFk3LzJsssmTKhQHwRBoB3+O8h8rTkduXWk3LHq8NKLfuzjWDJbY0YPsh5oc320IzWVOU/Hjze4UJw9S9SlC5Hn40xqf/06vRsaSvFGKFbPM+7YOPrF/RepzSgbQTDajV0ior1JSdTMx6fE3zkmhgn+rl0SGSYyKkFFC9wXUMvNLel2qmYRLdnZLOn93XeJcnP1ZKA6CALzwZqbEx0+rNGhN5NuUsvNLWmu61ydsnlfetGfcGICLb2yVJtrox1hYSzbZdEiSZynGQoFNf4tkswuedPx1FSjXN2/SFJ2ElmstaDg5GCpTSmb7Gyi9u3L3jSRmHX371O769fp0ZPU1Lg4lstjhPvQWiEvktOEExOo/77+pfrv1UGhIPrsM6LXXzfYzXdxcnOJJk9mAQLPZ5JpQHp+Og07NIwGHxis9XV4qUXfL8GPmjg2odxCA/20X7jAdo4OHjTM+Z5DEAQ6lJxM1t7eNOR8BPUcpDDGRWmZ7A3cSz2cekhfC6k8IiLY31edgi8S8GN0NPUJDKTI+0pq2ZLFD7wMZMmzaMiBITTu2Did3YCCQPTjj0x3ExNFMlAdoqPZST/7TKdsWiIWifjzxZ+pxaYWFJISovHxL63oC4JA/ff1p30392l8UTRGEFiVKmtromvX9H++F7idm0uDgoKo240b5JeVRUolUevWRJcuGdwUrREEgQYfGEzrvNVMNpCKU6dYpIWOCVL6QCUINDHoDtXdGkKr1r4cITrJOcnUbVc3+ubsN6KVUhAEVqusZUumxXrn0iWWVbt9u6juwSO3jpDFWgs6F3lOo+NeWtH/986/1GlHJ/3X3MjPZ7ds3bqxe2oDkqFQ0KyoKDL38qItCQlU9Jw7af9+osGDDWqOzkSnR1PjNY0pOt0Q30QdWLCAXVyj2RVk5OQQ9eyjoteOhdLkO3dIVZlu9UrhfuZ9st9iT0uvLNWLm3LXLhZJrde2jNu3M8HXU36OX4If2ay3oY2+G9W+Ri+l6BcqC8l+iz1diL6g1kXQmthYFtUxaZLOt2yaoFCpaPuDB2Tp5UXfREZSWiklFBQK5tMVqVyHwVjnvY4GHxhs3HsRSiXR0KGsloGRIJcTvf020ZdfEuUWKalvYCDNM8gyVj9Ep0dT803NaaPvRr2e56+/2A16UJDIEyuVRLNnswgdPf8d4h7HUccdHembs9+o5R59KUV/i98WGnZoWIUfXiecnVnijqOjwSI6BEGgUw8fUms/PxoSFETBFdTf37mTyMHBIKaJRpGqiHo49aC9gXulNqV8Hj5koTGnpK8YqlKxyL+xY/9/8/FIoaC216/TRiPML6iIiLQIsttgRztv7DTI+f75h32V/f1FmjAvj+i994jeeotIDyXKSyNLnkXDDg2jUX+PqnAP86UT/cyCTLJcZ6nVBodaKBREP/3E/Lre3vo5RylcffyY+t+8SZ38/ck1PV2tlXBBgUESgUUnODmYLNZaUFK2kRdPuX6dbexGipM0oy0//cRq6bwYmRtXUEB2Pj50JCVFGsO0IOxhGNk62tKfQX8a9LzOzuxP6eWl40QPH7JifZMnG7xWtUKpoCmnp1DP3T0pJafsv/lLJ/oL3BfQlNNTNLpYanP3LvuDDh9usGpVPpmZNCQoiFr6+tL+5GRSanhXsXEjW3RUNhZeWkjjjo2T2oyK2bmTRWVIFPy9fTvbtH/0qPT3Q3NyyNLLiy5lZBjWMC0ITwsnW0dbOhRySJLzPw2+0zoWIzaWpT7/8otk+RyCINCSK0uo5eaWFPWo9I44L5XoJ2QlkNkaM0rIStDqgpWJIBDt3s0SKjZv1nv8vSAIdCUjg4YFB1NTHx/anZhICi3PmZfHfJYherrx0RcFRQXUZmsbOnnnpNSmlI8gEH36KatiZuAvurMz+9veu1f+uCsZGWTh5UUhGrbjNCSRjyKpiWMT2h+0X1I7Ll5kwq9xuaVbt1g5ha1b9WKXpuwJ3EPW661LLT3zUon+56c/p/kXRd5ce/CApfF17coSr/SIShDoTFoa9Q0MpFZ+frQ3KUmUHrXr17OE0srG04YrGflGvkrNy2PVzLZvN9gpAwPZGkTdlIFjqalk5+MjaWXVsohOjya7DXb0x80/pDaFiFgHQgsLVgldLXx8WITO33/r0yyNOR1+mszXmpNbdPG6Pi+N6IemhJLlOsvinWd0QaViX2Jzc9aEU4/+uayiItqUkECv+fpSz4AAOpaaqrEbpzxyc9m/yVu3RJvSYMw8P5M+P/251GZUzN27TCl8ffV+qqQktqV0QsMq4Rvj46nd9euUXlZDWQmIz4yn5pua064bxlUr4vJl9uf08KhgoJsbG/ifcfaGuBZ3jSzXWRar2fPSiP7Iv0aKF94VFMQql73xhl5X94HZ2fRNZCQ18vSk8bdvk3dmpt5CFdesYaWAKhvZ8mxqtrGZ/sNvxeDMGb0nbuXnswbmv/2m3fE/3L1L/QIDKV+HvsxikZqbSm22tiFHH0epTSmVS5fYmq9MV8/T3V9PI64SS2xB3MSxCW27vo2KVKqXQ/SvxF6hFptakLxIx84QSUmsqJaVFcvc0IPv/mFhIW178IC637hBzXx8aHlsLCUY4JY7J4eFpenZQ6UXLkRfoGYbm1FOofH6pJ/xyy96S9wSBBaaOWmS9tsHKkGgSWFhNO7WLVHvJjUlIz+DuuzsQkuuLJHMBnVwd2fCX2Jz9+hRkeM89UtMRgy12NKOWl35p/KLviAI1Gt3L/o7VAd/2uPHrC9q48ZE8+YRZYrkInpChkJBB5OTaURICDW4do0+Cgsj1/R0g2dMrl5NNHGiQU8pGlNOTzHuhitP0WPi1vLlRL17s9W+LshVKhocFEQzIyMlSYLLLcylvnv70lzXucadhPeEp5u7z8I59+8nsrGpVNERDwsLqZu/LzU6vabyi/7x28epu1P3chsplElaGluZmZmxrjUVhUFowL38fNqakEBDgoKo3rVr9G5oKP2dkkK5Et5WZ2ezxUll9O0/bbhyLc7wtY00Ji2NJW79+69oU54+TdSkiXh9XzOLiqizvz+tMnDpkEJlIb1z6B36/PTnlULwn/LUdR+9YC/7Q1SijvL38vPJ3s+PFt67Rxn5GdKIPoDhACIA3AXwcxljtjx5PwRAtzLGkP0We7p476JmVyEggGjqVKJGjYi+/poVHteRJLmcTqSm0rSICGrp60vW3t706Z079O/Dh5IK/YusW8caY1dGToefJvst9pSnMFzJC615mrilZQnd5wkL0yxSR10S5XJq5uND+5OTxZ24DFSCiib+M5HGHBlj3NVUy+DWLCdKqPYqBR0vPf7dGAnKziZbb2/a8eD//UQMLvoATABEA2gOoDqAYADtXhgzEoDLk/9/HYBfGXPR2wffVu/Tx8cTbdlC1LMn65+2ahVrHKoF2UVFdO3xY9qUkECT79yhFr6+ZObpSaNCQ8kxPp5Cc3KMdhWTl8fuTCtblu5TJv0ziea6zpXaDPXYvZvV4K+gnWF5ZGQQ2dszj4I+uJObS1ZeXuRSVnaXSAiCQDPPz6QBfw4Qtd+rwdixg6hpU7qyN5osLCqHK/9pfsaJFwILpBD9vgBcn3s+H8D8F8bsAjDhuecRAKxKmYtuJpWhXvn5LN7qt9+YI9TMjNWydnFhftcKkKtUFJWXR27p6eSUmEjf371LI0NCqIWvL9W9epVeDwig6ZGRtCcxkcJycytVRcMtW4hGjZLaCu1Iy0sj6/XW5HVf13x5AzF1KkuS0OLfh1LJkr/nzNGDXc/hnZlJ5l5e5J+VpbdzLPdYTl12dhEvpNqQbN/OFopP3L9nzzI36Q0Dt9zWhH8fPiSLMjKxtRF9GTtOO2Qy2QcA3iGir548nwzgdSKa9dyYswBWE5HPk+fuT9xAgS/MRYkBAaDcXNDDh6C4OAjx8aC7d6GMjoaybVsoe/RA4ZtvorBbNxRWq4YCQUCuSoVclQo5KhUeFxUhQ6lERlERHhYVIUWhQIpCgSylEq/WrInmtWqhWa1aaFOnDtrWqYN2deqgRa1aMK1WTetrIDVyOdC6NXDiBPD661Jbozn/hv+LBZcWIHhaMGpXry21OeUjlwMDBgAffgj89JNGhy5cCPj6Am5ugKmpnux7gvOjR5gWFYVrXbuiVZ06os699+ZerPJcBZ8vfWD9irWoc+udnTuBNWuAy5eBli2fvXz2LDB1KuDiAvToIaF9pbA3KQm/xsXhfKdO6F6vXon3ZTIZiEimyZy6/vNT9xfjRaNKPa7NunWATAbIZKjVtStqjx4NWfXqqF6zJkyrVYOJTIaa1aqh5v37qCmTobaJCeqZmOCVJw8zU1O8Vrs2etarB8vq1WFTsyasa9SAefXqMJFpdF0qDbVqAYsWAb/+ygSlsjGu3TgcDzuORZcXwfEdR6nNKZ9atYCTJ4HevYFu3YChQ9U67NQp4PBhICBA/4IPAKPNzfFQocA7oaHw6tYNtjVrijKvc6Qzfr3yK65OuVo5Bf/334ErV4oJPgC8+y6wezcwciTw339A9+4S2fgCa+PjsSMxEVe7dkXrJz/eHh4e8PDw0G1iTW8NqLhLpg+Ku3cW4IXNXDD3zsTnnpfp3uFoh0LBOgdVmHFopKTlpZHNepvKEc1DxHL6razUChoIDyfJ/MYr4+Kok78/PRYha9c73pvM15qT/4NK4AB/kV27WARWBRF9p04xV09goIHsKgNBEGhedDS1v369wrwfSODTNwVwD2wjtwYq3sjtg3I2cjnac/gwKxpaibYjinEm4gy13NyyciRtEbHNlM6dy63ImZVF1LYt0R8SlaERBIFmR0XRmzdv6pS1e+fhHbJcZ0n/3TXO8gTlsns3y6xWs/nJU+EPCNCzXWWgFASaGhFBvQIC6JEaP9YGF312TowAEAkWxbPgyWvTAEx7bsy2J++HAOhexjy6Xa0qjkpF1KWLqOHkBuezU5/RN2e/kdoM9RAEos8/J/rww1J/aQWBaNw4omnTJLDtOVSCQB+FhdG7oaFaVXdNzE6kZhubSV4xUyv27mXVMu/e1eiw06elSdCVq1T0we3bNCQoiLLVzAKXRPTFenDR1x0XF7ayNLJ2r2qTWZBJr254lVzvukptinoUFLBospUrS7y1Zg17S65jNRExUKhUNDIkRONeu5kFmdRlZxdaea3k5zN6/vyTJV5FaReHf+YMc8uJnU9RFjlFRfR2cDCNu3VLo2q8XPSrOIJANGgQ0Z49UluiPRfvXSS7DXaUnp8utSnqkZjIxOXMmWcvXbrEauMbU3fDPKWS+t+8SbOiotTKOylUFtKQA0NoxrkZRpunUiYHDrA2czom0507p2MjFjVJVyioT2AgfR4eTkUa3o1x0eeQnx/TIAP2dhed2S6zafyJ8ZVHbK5fZ2m2ISEUH88E/9IlqY0qyWOFgrreuEGLK9iAVgkq+ujkRzT26FhSqownA10tDh9mgn/njijTPa3V4+4uynQleCCXU4fr1+nH6Git/r1z0ecQESvNsHq11FZoT74inzps70AHgg9IbYr6/P03Cc2a0/DuqfT771IbUzaphYXUxs+P1t6/X+aYn9x+on5/9Kt82bZ//81S1EUuP3v1KhN+FxdRp6WovDxq7utLq+PitF7gcNHnEBHr7W1urtdS8HonJCWEzNeaU0yG7rWUDIVL94V0x6wfCQVG4Mgvh4SCAmrp60vbnqvh8pRNvpuo7ba2lce99pSjR9ktlp4qEPr6ss3dY8fEme9mdjbZeHuTU2KiTvNw0ec8Y84com8qSSBMWTj6ONIbf7xRKQp67d9P1KaVihTvjiOaPNnoY2dj8vPpVR8f+uO5Up/Hbx+nJo5NKO5xnISWacFTwQ8N1etpQkKY52j3bt3meVpH55+HD3W2iYs+5xnp6eyWtDKWXn6KSlDR0INDjb45R1AQu7O6fZvYZkqvXkRLlkhtVoVE5uWRrbc3HU5Jocsxl8lynSWFpFSeuvJEZDDBf8rdu0TNm7PoLG04+aSOzuVS6uhoAxd9TjE2byZ65x2prdCNpOwksl5vTZdjLkttSqmkp7Ns6CNHnnsxJYWoRQsWRWLkhOXmkoWnB9Xb+x5dib0itTmaceSIQQX/KQ8eELVrRzR3rmYN+ZwSE8nG25tu6lCp9UW0Ef3KW2mMUyHTpwOxsayeSGXFpp4N9o/Zj09OfYKHeQ+lNqcYggBMngyMHg1MnPjcG1ZWwLlzrCibrnVS9EydojTIQufBtNVMJNZuJ7U56nP4MPD996zgVKdOBj11kyaAlxdw4wbw0UdAYWH544kIi2NjsS4hAde6dkW3UgqnGRIu+i8x1asD69cDP/wAFBVJbY32vGP/Dj7p/Ak+O/0ZBBKkNucZy5YBeXnA2rWlvNm+PXD0KDBhAhAaanDb1CEtLw3vHH4Hi3pMhmePPvjp3j38lZoqtVkV8+efwM8/A+7uBhf8p5iZARcvAkolMHw4kJlZ+rgiQcCXkZH4LyMD3t26wV7kqqdaoemtgb4e4O4dvSAIzMXj6Ci1JbqhUCqo796+tMZLS2eqyDg7swz/lJQKBh47xhInYmMNYZbaZMmzqIdTD1p0adGz127n5pKttzft0TGiRK/s3s0uvAhdzMRAqWRBE+3alSzvk11URMNDQmhESAjl6ClNHtynzymNqCjWJ96Yv8vqcD/zPlmts5Lc93z3Ltsk9/VV84AtW4hatyYSIVpDDAqKCuit/W/RtLPTSsSHR+XlUVMfH9qUkCCRdeWwcSNrgKJhLR1DsH07K7x69Sp7nlBQQF38/emriAitah6pCxd9TpksXEg0aZLUVuiOW7Qb2ay3oQdZJWPMDUF2NlGHDkQ7d2p44MKFLKpHxE08bShSFdG4Y+Pow+MflpltG1dQQPZ+frRCh6QhUREEohUrWK/JcpLKpMbNjcXyLzmUTXY+PrTm/n29Xz9tRF+nzlliIpPJyFhseRnJz2du5n37gMGDpbZGN1Z5rsK5qHPwmOKBGiY1DHZeItY0q1Ej1nRDo748RGxnPTyc7axL4NsVSMCXzl8iMTsRZyedRU3TspurJBcW4u2QELxtZgbH115DNamaEBEBv/zC2ltdvAjY2Ehjh5rsDH6EWfGRGHyrFc7+aAmR+teUiTads/hGbhWhTh1g0ybg228BhUJqa3Rjfv/5sKhrgR8u/GDQ865eDSQmAtu2aSj4ADtgxw6gWTNg7FjWetGAEBG+c/0Od9Pv4tSEU+UKPgDY1KwJz27dEJiTg4/u3EGhIMEGukoFfPMNE3sPD6MWfCLC6vv3sTI/Cm69OuGVQEsMGADEx0ttWUm46FchxowBmjcHHI28K2FFVJNVw4GxB3Dh3gX8cfMPg5zTxQXYvp11S9R69VatGrvVatgQGD/eoCFVv175Fd4J3jj/0XnUre4DYNIAABJkSURBVFFXrWMaVa+OC507Q0GEEaGhyFIq9Wzlc8jl7Brdu8daHJqbG+7cGlKgUmFyeDj+ffQI13v0wGCb+jh5EvjgA9ZZ08VFagtfQFN/kL4e4D59gxAbyzZ1IyOltkR3ItIiyHKdJXnEeuj3PBFs49bLS6QJFQqid98leu89osJCkSYtm1XXVlG7be3oYa52G8lKQaAZkZHU4fp1isk3QBG2rCyit94i+uAD42hIUA6x+fnU48YNmhQWVmp3Mg8P1qlx1iwifVw68I1cjjps3kz05puaZRMaK27RbmS1zoqi09Vrh6cpGRlErVrpoeWhXE40diyRgwNrxqIn1nqtpVZbWlFitm6hW4Ig0OaEBLL29iavzEyRrCuFhATWAm76dBYPacS4pqeTlZcXbYyPL3fDNiODaPx4oo4diYKDxbWBiz5HLZRKor59iXbskNoScdjuv53abmtLmQXiilFREdHbbxN9952o0/4fhYKpwbBhemmA4OjjSK9tfk3USCeXR4/IwsuL9icnizbnM4KCWAz+mjVGXbBOKQi0LDaWbL296erjx2odIwisKJ+FBQvkEut3nos+R23CwliRMGPq7qQL357/lgYfGEzyIvHcAXPmMD3Wa/vJoiKiTz4hGjiQSMQV9EbfjdRyc0uKzxT/D3w7N5fs/fxoemSkRq39yuW//5giilW7WE88kMvpraAgGnDzJiVq4XpKSmL9Llq3/n9Mvy5w0edoxPLlRCNGGPWiSm2UKmWF8eeasGsX+2KKVAyxfFQq5vTt1IlV89KR3z1/p5abW9L9TP3FtGcWFdG4W7eoV0AAxemybBUEog0bWOE0b2/xDNQDZ9PSyMrLi5bHxpJSxy/NqVPspmbCBN2StbnoczRCoSDq2fPlcfMUFBXQwD8H0szzM3VKinF1ZdmVBk38FASitWvZrt/t21pOIdDiy4up7ba2BkleEwSBHOPjydLLi/7VJts4P5/d5XTtShQXJ76BIpFdVETTIiKomY+PqPsZeXls4dW4MdG8eURqeoqKwUWfozEREczNEx4utSXikFmQSV12dqHfrv6m1fGhoczL4OkpsmHqcugQS+vUsMmuIAj0w4UfqPPOzpSaa9iWaT6ZmfSary99Hh5OWer6wu7fZyuOCROMuqGze0YGNfPxoS/CwylTT36+xESiL78kMjMj+vlnNeo5PQcXfY5W7NpF1L27QaIHDUJSdhLZb7Gndd7rNDsuiS20//5bT4apy5UrzN2xcaNavrciVRF9cfoL6rW7l2RtDnOKiuiriAhq4etLHhUtWc+cYT9sa9carW8xXaGgryMiyM7Hh1wePTLIOWNjiWbOJGrUiHW9u3mz4mO46HO0QhBY2Pj8+VJbIh4JWQn02ubX1Bb+rCyibt2IftPuBkF8YmOZ2+PTT8sN8M4tzKWRf42kEYdHUE5hjuHsKwPntDSy8/Ghz8PDKe3FVURhIes80rSp0frvVYJAe5OSyNLLi2ZGRtJjhcLgNiQnEy1dyi5T9+7M/VrW6p+LPkdrUlOJbGyILl6U2hLxUFf45XKiwYPZ6sqoFp55eUQTJzLxv3OnxNsPcx9S7z29acrpKaRQGl6cyiK7qIjm3r1Lll5etDcpiW163r7NFGz0aNZuzAjxysykPoGB1CcwkAIlLoxHxEKrL1xgHrAGDYh692aLEl/f/4d8ctHn6MTly8yr8LKEcRIx4bffYk/LPJaVurmrUrFQ+XHjjDQXSBCInJzYbt+uXc9+lW6n3qaWm1vSwksLjaMSZinczM6mNwICqOP583R22DASdu82sl9VRmhODr0bGkrNfHxof3IyqYzQxsJCInd3FkbctStR7drsN1Qb0edVNjnFWLuW1Ze5dk2HGjNGRkpuCkb+NRK9bHthu8N2mFYzBcAKOM6eDdy6Bbi6ArVqSWxoeYSHs958zZrhwg9j8YnfPGx4ZwMmd54stWVlExwM+uYbnO3WDQsmT4ZZnTpY0qwZhjRqBJlUVTuf40Z2NtYnJOBqZiYWNGuGb2xtUbNa5ShHVlAABAcDb7yheZVNLvqcYhAB778PWFuzopAvCzmFORh3fBzqVK+DI+8fQW3TOvjlFyb2Hh5AgwZSW1gxgrwAvl+PQNt/PZEz/3s0X/A7YGIitVklycgAFi8GTpwAVqwAvvwSKpkMh1NTsTY+HtVlMnz/6quYaGmJGgYW2SJBgEtGBjYkJCBOLsdcOzt8aWODeqamBrVDLLQprcxFn1OCrCxWHXDBAmDKFKmtEQ+FSoEvznyBqPQo9E86iYv/vGrsBRyfkZaXhilnpiCjIAOnO62C1Y9L2HJvyxagb1+pzWMUFgJ79jChf/994LffWDPZ5yAiXMjIgOODBwjNzcVES0tMtrJCz3r19Lb6JyKE5uXhQEoK/k5NRcvatTGrSRN8aGEB00qysi8LLvoc0QgPBwYNAo4cqfxNV56HiDBy5VpczN2Eox8exgc9hkhtUoV4xHlg8r+TMbnzZPz21m+oblKd3ZIdPAj8+ivQuTMT2q5dpTFQoWDNyleu1MiW6Px8/PXwIQ6npkIGwKFxYwxt1AgDGzTAKzquvPNUKnhkZuK/9HT8l5EBJRE+sbLCp9bWaG0MzclFgos+R1SuXmWdoi5fBjp2lNoacVizBti7F1jx9yV8d20y5rw+B/P6zUM1mfGt+AqKCrDs6jIcCDmA/WP24x37d0oOkstZG6/Vq4E33gBmzQIGDtSiy4sWPHzILuauXawt27JlwOuvazwNEeFmbi4uZGTA/fFj3MjJQZvatdHplVfQsW5dtKtTB1Y1asC8enWYV68OU5kMSiIoiZCjVCJRoUBiYSHuy+UIys1FYE4OYuVy9KxXDw6NG2OEmRk61a1rFPsIYsNFnyM6f/8NzJ8P+PoCTZpIbY32EAGLFgGnTrFGTE2aAAlZCZh0chKqyarhj9F/oFXjVlKb+YyrcVfx1dmv0NW6K7aO2AqrV6zKPyAvj622d+xggj9jBmtCYmEhrmGFhWwV8NdfwPnzzI0zYwbQvbtop8hXqRCam4tbeXm4lfe/9u4/tsrqjuP4+5tWoLRAFbEgIIihEchQEJQIk4aJMw4cGtNNN6lG0Oh+MBOm4hJnjKLGnwvT6JwoKDoJG0xF3YqTRGTID7vChG4UJIKWwuSH/FJa+t0f5yqNlpZy23sKz+eV3OS5l97nfvOE+3nOfc55ztnHf/bvZ3tNDdtravhfTQ117mSZkW1GXlYWPdu3p2e7dvTu0IFzcnM5r1MnBuXmZry/IIZjCf3oQzW/eqAhm23W/fe7Dx7cZodXN+mr+cyGDHH/5hQxtYdq/bF/PuZdH+zqjy59tEUma0tH1Z4qn/TXSd7zkZ6+YN2C5u+gri6MvS0udu/c2X3UKPeHHnIvLz+26ULr6tw3bHB/8UX3a65xz893HznS/fHHMzQbnTQGDdmU1uAOt98eWsiLFkHXrrErOnoHD8LkyWHVvddfDysVNqRyRyU3vHoDu7/YzYMXP8glZ12S0csBew/u5eGlDzNj+QxKzinhrtF3kd/hCMUerS++CK3yBQvCGNwtW8I193PPhV69wpqz3btDu3ZhPdpDh2DPHti8OSzuunEjLF8O2dmhs3jMGLjiija9Vm3S6PKOtBr3MJrnrbdC8B8PI1527IArrwzDMV96CXKbWBrW3ZlfMZ9pb0+jV+deTB8znQt6Nf8adXN8tv8znl71NDOWz+B7Z36Pe8fcS9/8vq3zYbt3Q1kZlJdDVVV4bN0a1urNygqPvDw444zw6NMHhg0LJ4gT8Hr4iUChL63KHe68Myz0XFoKp50Wu6IjW78exo2D8eND521zhrPX1tUys2wm9717Hz3yenDL8FsoHlRMh+yWuXvL3SmvLueplU/xyoevMOHsCdw64lYGFwxukf1Lcij0pdW5h0Eas2fDa6/BoEGxK/q2N9+E66+He+6BG2889v0cqjvEwvULeXLFk6yqWsX4wvFc1v8yxvYbS5cOzbub6+Chg5RVlTG/Yj7z1s6jzuuYeM5Ebh52c9OdtCJHoNCXjJk9G6ZOhRdegO83MJIwhpqaMEJnzpzwGD265fb90c6PWLh+IW+sf4MlHy+hsGshA7sNZMCpA+jftT+d2nUi56QccrJz2HNwD9V7q9m2bxsbdm5gxacrWF29mn4n92N84XiuGngVQ7oPOSGHEEpmKfQlo5YsCeP4b7sNpkyBmCPkNm0KU9N06RJOSC09UrG+/TX7WV29mrXb17Ju+zoqd1ay7+A+DtQe4EDNAXLb5VKQW0BBbgF98vsw/PThDO0xlE7tO7VeUZJICn3JuI0b4eqrQ9jOnBn6/DKptjbMRDB9ejj5TJ0a9+QjkknHEvr6ekha+vWD996Diy4K9+fMmROu+2fCypXhBtCFC2Hp0hD6CnyRxqmlLy1m1arQgdq5MzzwAIwa1Tqfs2ZN6KRdsiSMzLn2Wo0olGRSS1+iOu+8MAz8pptCEI8bF34FtMS53D2EfHExjB0LI0ZAZSVMnKjAF2kOtfSlVXz5ZZgH7IknQmBfd93Xa4AcNXeoqIC5c0PnbPv2MGlSOKk0daOVSBKoI1faHHd4/314/vmwIldOTmilX3AB9O4NJ58cHmawfXuYuHHzZli2LEzylpcXbrAqKQm/JNSqFzlMoS9tmnuYA2fZsnAiqKqCnTth1y6oqwt3+HbrFqZ2GT4cRo48vmf2FGltCn0RkQRRR66IiDRKoS8ikiAKfRGRBFHoi4gkiEJfRCRBFPoiIgmSfaxvNLNTgFeAPsAmoNjddzXwd5uAz4FDQI27n3+snykiIulJp6V/B1Dq7oXA26nnDXGgyN2HKPBFROJKJ/QvB2altmcBExr5W908LyLSBqQT+gXuXp3argaOtNCnA4vMbKWZTU7j80REJE2NXtM3s1KgewP/9Jv6T9zdzexIcyiMdPcqM+sGlJpZhbu/29Af3n333V9vFxUVUVRU1Fh5IiKJsnjxYhYvXpzWPo557h0zqyBcq99qZj2Ad9z97Cbe81tgr7s/0sC/ae4dEZFmyPTcO68CJantEmBBAwV1NLNOqe1c4BJgTRqfKSIiaUinpX8KMBc4g3pDNs3sdOAZd/+BmfUD/pJ6SzYwx93vP8L+1NIXEWkGTa0sIpIgmlpZREQapdAXEUkQhb6ISIIo9EVEEkSh3wale/PFiUTHItBxOEzHIj0K/TZI/6kP07EIdBwO07FIj0JfRCRBFPoiIgnSpm7Oil2DiMjx5ri9I1dERFqfLu+IiCSIQl9EJEGih76ZXWpmFWa23sxuj11PLGbW28zeMbMPzezfZvbL2DXFZmZZZlZmZq/FriUmM8s3s3lmts7M1prZiNg1xWJm01LfkTVm9pKZtY9dU6aY2UwzqzazNfVeO8XMSs3sv2b2dzPLb2o/UUPfzLKA3wOXAgOBq81sQMyaIqoBbnX3QcAI4GcJPhZfmQKsJSy5mWS/A95w9wHAYGBd5HqiMLO+wGRgqLt/B8gCfhyzpgx7jpCV9d0BlLp7IfB26nmjYrf0zwcq3X2Tu9cAfwJ+GLmmKNx9q7v/K7W9l/DFPj1uVfGYWS/gMuCPQLNGJ5xIzKwL8F13nwng7rXuvjtyWbF8TmgcdTSzbKAj8EnckjIntczszm+8fDkwK7U9C5jQ1H5ih35PYHO951tSryVaqkUzBHg/biVRPQb8GqiLXUhkZwLbzew5M/vAzJ4xs46xi4rB3XcAjwAfA58Cu9x9Udyqoitw9+rUdjVQ0NQbYod+0n+2f4uZ5QHzgCmpFn/imNk4YJu7l5HgVn5KNjAUeNLdhwL7OIqf8CciMzsL+BXQl/ArOM/MfhK1qDYktQpVk5kaO/Q/AXrXe96b0NpPJDM7Cfgz8KK7f2vN4QS5ELjczD4CXgbGmNnsyDXFsgXY4u4rUs/nEU4CSTQMWOrun7l7LWEp1gsj1xRbtZl1BzCzHsC2pt4QO/RXAv3NrK+ZtQN+RFhwPXHMzIBngbXu/njsemJy9zvdvbe7n0noqPuHu0+MXVcM7r4V2GxmhamXLgY+jFhSTBXACDPLSX1fLiZ09CfZq0BJarsEaLKxmN2q5TTB3WvN7OfA3wg98c+6eyJHJgAjgZ8Cq82sLPXaNHd/K2JNbUXSLwP+ApiTahhtAK6PXE8U7l6e+sW3ktDX8wHwh7hVZY6ZvQyMBk41s83AXcADwFwzuwHYBBQ3uR9NwyAikhyxL++IiEgGKfRFRBJEoS8ikiAKfRGRBFHoi4gkiEJfRCRBFPoiIgmi0BcRSZD/AzioDQbST2I5AAAAAElFTkSuQmCC", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "x = linspace(0, 10, 100)\n", "\n", "fig, ax = plt.subplots()\n", "for n in range(4):\n", " ax.plot(x, jn(n, x), label=r\"$J_%d(x)$\" % n)\n", "ax.legend();" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([ 2.40482556, 5.52007811, 8.65372791, 11.79153444])" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# zeros of Bessel functions\n", "n = 0 # order\n", "m = 4 # number of roots to compute\n", "jn_zeros(n, m)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Integration" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Numerical integration: quadrature" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Numerical evaluation of a function of the type\n", "\n", "$\\displaystyle \\int_a^b f(x) dx$\n", "\n", "is called *numerical quadrature*, or simply *quadature*. SciPy provides a series of functions for different kind of quadrature, for example the `quad`, `dblquad` and `tplquad` for single, double and triple integrals, respectively.\n", "\n" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false }, "outputs": [], "source": [ "from scipy.integrate import quad, dblquad, tplquad" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The `quad` function takes a large number of optional arguments, which can be used to fine-tune the behaviour of the function (try `help(quad)` for details).\n", "\n", "The basic usage is as follows:" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# define a simple function for the integrand\n", "def f(x):\n", " return x" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "integral value = 0.5 , absolute error = 5.55111512313e-15\n" ] } ], "source": [ "x_lower = 0 # the lower limit of x\n", "x_upper = 1 # the upper limit of x\n", "\n", "val, abserr = quad(f, x_lower, x_upper)\n", "\n", "print \"integral value =\", val, \", absolute error =\", abserr " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If we need to pass extra arguments to integrand function we can use the `args` keyword argument:" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0.736675137081 9.3891268825e-13\n" ] } ], "source": [ "def integrand(x, n):\n", " \"\"\"\n", " Bessel function of first kind and order n. \n", " \"\"\"\n", " return jn(n, x)\n", "\n", "\n", "x_lower = 0 # the lower limit of x\n", "x_upper = 10 # the upper limit of x\n", "\n", "val, abserr = quad(integrand, x_lower, x_upper, args=(3,))\n", "\n", "print val, abserr " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For simple functions we can use a lambda function (name-less function) instead of explicitly defining a function for the integrand:" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "numerical = 1.77245385091 1.42026367809e-08\n", "analytical = 1.77245385091\n" ] } ], "source": [ "val, abserr = quad(lambda x: exp(-x ** 2), -Inf, Inf)\n", "\n", "print \"numerical =\", val, abserr\n", "\n", "analytical = sqrt(pi)\n", "print \"analytical =\", analytical" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As show in the example above, we can also use 'Inf' or '-Inf' as integral limits.\n", "\n", "Higher-dimensional integration works in the same way:" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0.785398163397 1.63822994214e-13\n" ] } ], "source": [ "def integrand(x, y):\n", " return exp(-x**2-y**2)\n", "\n", "x_lower = 0 \n", "x_upper = 10\n", "y_lower = 0\n", "y_upper = 10\n", "\n", "val, abserr = dblquad(integrand, x_lower, x_upper, lambda x : y_lower, lambda x: y_upper)\n", "\n", "print val, abserr " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note how we had to pass lambda functions for the limits for the y integration, since these in general can be functions of x." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Ordinary differential equations (ODEs)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "SciPy provides two different ways to solve ODEs: An API based on the function `odeint`, and object-oriented API based on the class `ode`. Usually `odeint` is easier to get started with, but the `ode` class offers some finer level of control.\n", "\n", "Here we will use the `odeint` functions. For more information about the class `ode`, try `help(ode)`. It does pretty much the same thing as `odeint`, but in an object-oriented fashion.\n", "\n", "To use `odeint`, first import it from the `scipy.integrate` module" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": false }, "outputs": [], "source": [ "from scipy.integrate import odeint, ode" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A system of ODEs are usually formulated on standard form before it is attacked numerically. The standard form is:\n", "\n", "$y' = f(y, t)$\n", "\n", "where \n", "\n", "$y = [y_1(t), y_2(t), ..., y_n(t)]$ \n", "\n", "and $f$ is some function that gives the derivatives of the function $y_i(t)$. To solve an ODE we need to know the function $f$ and an initial condition, $y(0)$.\n", "\n", "Note that higher-order ODEs can always be written in this form by introducing new variables for the intermediate derivatives.\n", "\n", "Once we have defined the Python function `f` and array `y_0` (that is $f$ and $y(0)$ in the mathematical formulation), we can use the `odeint` function as:\n", "\n", " y_t = odeint(f, y_0, t)\n", "\n", "where `t` is and array with time-coordinates for which to solve the ODE problem. `y_t` is an array with one row for each point in time in `t`, where each column corresponds to a solution `y_i(t)` at that point in time. \n", "\n", "We will see how we can implement `f` and `y_0` in Python code in the examples below." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Example: double pendulum" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's consider a physical example: The double compound pendulum, described in some detail here: http://en.wikipedia.org/wiki/Double_pendulum" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Image(url='http://upload.wikimedia.org/wikipedia/commons/c/c9/Double-compound-pendulum-dimensioned.svg')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The equations of motion of the pendulum are given on the wiki page:\n", "\n", "${\\dot \\theta_1} = \\frac{6}{m\\ell^2} \\frac{ 2 p_{\\theta_1} - 3 \\cos(\\theta_1-\\theta_2) p_{\\theta_2}}{16 - 9 \\cos^2(\\theta_1-\\theta_2)}$\n", "\n", "${\\dot \\theta_2} = \\frac{6}{m\\ell^2} \\frac{ 8 p_{\\theta_2} - 3 \\cos(\\theta_1-\\theta_2) p_{\\theta_1}}{16 - 9 \\cos^2(\\theta_1-\\theta_2)}.$\n", "\n", "${\\dot p_{\\theta_1}} = -\\frac{1}{2} m \\ell^2 \\left [ {\\dot \\theta_1} {\\dot \\theta_2} \\sin (\\theta_1-\\theta_2) + 3 \\frac{g}{\\ell} \\sin \\theta_1 \\right ]$\n", "\n", "${\\dot p_{\\theta_2}} = -\\frac{1}{2} m \\ell^2 \\left [ -{\\dot \\theta_1} {\\dot \\theta_2} \\sin (\\theta_1-\\theta_2) + \\frac{g}{\\ell} \\sin \\theta_2 \\right]$\n", "\n", "To make the Python code simpler to follow, let's introduce new variable names and the vector notation: $x = [\\theta_1, \\theta_2, p_{\\theta_1}, p_{\\theta_2}]$\n", "\n", "${\\dot x_1} = \\frac{6}{m\\ell^2} \\frac{ 2 x_3 - 3 \\cos(x_1-x_2) x_4}{16 - 9 \\cos^2(x_1-x_2)}$\n", "\n", "${\\dot x_2} = \\frac{6}{m\\ell^2} \\frac{ 8 x_4 - 3 \\cos(x_1-x_2) x_3}{16 - 9 \\cos^2(x_1-x_2)}$\n", "\n", "${\\dot x_3} = -\\frac{1}{2} m \\ell^2 \\left [ {\\dot x_1} {\\dot x_2} \\sin (x_1-x_2) + 3 \\frac{g}{\\ell} \\sin x_1 \\right ]$\n", "\n", "${\\dot x_4} = -\\frac{1}{2} m \\ell^2 \\left [ -{\\dot x_1} {\\dot x_2} \\sin (x_1-x_2) + \\frac{g}{\\ell} \\sin x_2 \\right]$" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "collapsed": false }, "outputs": [], "source": [ "g = 9.82\n", "L = 0.5\n", "m = 0.1\n", "\n", "def dx(x, t):\n", " \"\"\"\n", " The right-hand side of the pendulum ODE\n", " \"\"\"\n", " x1, x2, x3, x4 = x[0], x[1], x[2], x[3]\n", " \n", " dx1 = 6.0/(m*L**2) * (2 * x3 - 3 * cos(x1-x2) * x4)/(16 - 9 * cos(x1-x2)**2)\n", " dx2 = 6.0/(m*L**2) * (8 * x4 - 3 * cos(x1-x2) * x3)/(16 - 9 * cos(x1-x2)**2)\n", " dx3 = -0.5 * m * L**2 * ( dx1 * dx2 * sin(x1-x2) + 3 * (g/L) * sin(x1))\n", " dx4 = -0.5 * m * L**2 * (-dx1 * dx2 * sin(x1-x2) + (g/L) * sin(x2))\n", " \n", " return [dx1, dx2, dx3, dx4]" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# choose an initial state\n", "x0 = [pi/4, pi/2, 0, 0]" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# time coordinate to solve the ODE for: from 0 to 10 seconds\n", "t = linspace(0, 10, 250)" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# solve the ODE problem\n", "x = odeint(dx, x0, t)" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# plot the angles as a function of time\n", "\n", "fig, axes = plt.subplots(1,2, figsize=(12,4))\n", "axes[0].plot(t, x[:, 0], 'r', label=\"theta1\")\n", "axes[0].plot(t, x[:, 1], 'b', label=\"theta2\")\n", "\n", "\n", "x1 = + L * sin(x[:, 0])\n", "y1 = - L * cos(x[:, 0])\n", "\n", "x2 = x1 + L * sin(x[:, 1])\n", "y2 = y1 - L * cos(x[:, 1])\n", " \n", "axes[1].plot(x1, y1, 'r', label=\"pendulum1\")\n", "axes[1].plot(x2, y2, 'b', label=\"pendulum2\")\n", "axes[1].set_ylim([-1, 0])\n", "axes[1].set_xlim([1, -1]);" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Simple animation of the pendulum motion. We will see how to make better animation in Lecture 4." ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "collapsed": false }, "outputs": [], "source": [ "from IPython.display import display, clear_output\n", "import time" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAARMAAAEACAYAAACQ65KNAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAADytJREFUeJzt3XuMHeV5x/HvUwNGJg6ORWJuJggBMpAoMkGGQFHPHwUZI3GRuJQoghQJA4IokaJgCFFw/4KQG4q4FKo0QkpdgsRFTsEJpmIbIIKADNRQzEWpG0PBVArmZhKw/fSPObjLdnd9dufdnTlnvx/pyHPOvOfM82p2f573nTmzkZlIUl1/0XQBkgaDYSKpCMNEUhGGiaQiDBNJRRgmkoqoHSYRsTQiNkTESxGxYpT1nYh4KyKe6j6+U3ebktpntzpvjohZwI3AXwOvAk9ExOrMfH5E03/LzNPqbEtSu9U9MlkCvJyZGzPzQ+AO4PRR2kXN7UhqubphcgCwadjzV7qvDZfA8RHxTETcHxFH1tympBaqNcyhCopdWQcszMytEXEKcC9weM3tSmqZumHyKrBw2POFVEcnO2XmO8OW10TEzRExPzP/OLxdRPglIakhmVl7KqLuMOdJ4LCIODgi9gDOBVYPbxARCyIiustLgBgZJB/JzIF9XHPNNY3XYN/s32iPUmodmWTmtoi4HPg1MAv4aWY+HxEXd9ffCpwFXBoR24CtwN/UrFlSC9Ud5pCZa4A1I167ddjyTcBNdbcjqd28AnaadDqdpkuYMoPcNxj8/pUSJcdMdUREtqUWaSaJCLIFE7CSBBgmkgoxTCQVYZhIKsIwkVSEYSKpCMNEUhGGiaQiDBNJRRgmkoowTCQVYZhIKsIwkVSEYSKpCMNEUhGGiaQiDBNJRRgmkoowTCQVYZhIKsIwkVSEYSKpCMNEUhGGiaQiDBNJRRgmkoowTCQVYZhIKsIwkVSEYSKpCMNEUhGGiaQiDBNJRRgmkoowTCQVYZhIKsIwkVSEYSKpCMNEUhGGiaQiDBNJRRgmkoowTCQVYZhIKsIwkVRE7TCJiKURsSEiXoqIFWO0+Ul3/TMRsbjuNiW1T60wiYhZwI3AUuBI4LyIOGJEm2XAoZl5GLAcuKXONiW1U90jkyXAy5m5MTM/BO4ATh/R5jTgdoDMfByYFxELam5XUsvUDZMDgE3Dnr/SfW1XbQ6suV21xfLlcPzxsGwZbNnSdDVq0G413589tote3rdy5cqdy51Oh06nM6miNI2efhqeeKJaXr4c7ryz2Xq0S0NDQwwNDRX/3MjsNQ9GeXPEccDKzFzafX4VsCMzvzeszd8DQ5l5R/f5BuCvMnPziM/KOrWoIcuWwZo1sM8+8NJLMG9e0xVpgiKCzBz5H/6E1R3mPAkcFhEHR8QewLnA6hFtVgPnw87w2TIySNTHVq2CM86A3XeH9eubrkYNqnVkAhARpwA3ALOAn2bmtRFxMUBm3tpt89EZn/eAv83MdaN8jkcm/ezuu+Hqq6thz+zZTVejCSh1ZFI7TEoxTPpcZnWE8sUvwne/23Q1mgDDRO2zaRMsXgyPPAKLFjVdjXrUljkT6f8sXFgdlVx8MezY0XQ1mmaGicq67DJ4/3342c+arkTTzGGOynvmGTjppOrszgIvdm4750zUbitWVHMoq1Y1XYl2wTBRu23dCp//PNx0Eyxd2nQ1GocTsGq3OXPgllvg0kvhvfearkbTwCMTTa2vfAX22w++//2mK9EYHOaoP7zxRjXc+dWvqmtQ1DoOc9QfPvMZuO666hvF27c3XY2mkGGiqffVr8InPgE33th0JZpCDnM0PV58sbqJ0rp1cNBBTVejYRzmqL8cfjh84xvVFbL+pzGQDBNNnyuugN//Hu66q+lKNAUc5mh6PfoonHMOPPecd2VrCU8Nq39dcglEVBe1qXGGifrXli1w1FHVzadPOKHpamY8J2DVv+bNgxtuqK49+eCDpqtRIYaJmnHWWXDIIXD99U1XokIc5qg5f/hDdc/YRx+tTh2rEQ5z1P8OOqi6o/0ll3jtyQAwTNSsr30N3nkHbr+96UpUk8McNe+pp6obKK1fX30xUNPKU8MaLN/6Frz2Gvz8501XMuMYJhos770Hn/sc3HornHxy09XMKE7AarDstRfcfHN1m8etW5uuRpPgkYna5ctfrs7yXHdd05XMGA5zNJg2b65u87h2LXzhC01XMyM4zNFgWrAArr3W2zz2IcNE7XPhhbDnntUcivqGwxy104YNcOKJ1W0eFy5supqB5jBHg23RIrj88uoKWfUFw0TtdeWV8MILcM89TVeiHjjMUbs9/DCcd151m8e99266moHkqWHNHMuXw+67V38EXcUZJpo53nyzus3jXXfBl77UdDUDxwlYzRyf+hT8+MfVEcqHHzZdjcZgmKg/nHNOdZn9D37QdCUag8Mc9Y+NG+GYY+Cxx+DQQ5uuZsr86U9w0UVVd+fOhVWrpvZPDDlnopnpRz+C+++vvrsTtX/+i9qxo7pp3Ntvw1tvVY/JLGdWj23bqs89++zqr4JMFcNEM9O2bXDssfD1r8P55xf72D//ubdf+PHWv/suzJlTncHee2/45Cc//m+vy7Nnw6mnwpo11YHY2rUemUyIYaKerVsHy5bBs8+yY/4+vPtu/aOB7dsn9gs/2vLcuTBrVpkubtlSzTffdtvU/xVVw0QzWmev3/Hw1qPZwSzmzIF582LCv/zDX9tzz9aNmqZNqTDZrUQx0nTbPms2O7o/vqfO/y13bjq+4YrkqWH1pbmzqz8resyc57jtkaMarkbgMEd9ast/vcXyv6yCZN5n/c5OHc6ZSCqi8TmTiJgP/AL4LLAROCczt4zSbiPwNrAd+DAzl0x2m5Laq86cyZXA2sw8HPjX7vPRJNDJzMUGiTS46oTJacBHfyD2duCMcdrO0JNu0sxRJ0wWZObm7vJmYMEY7RJ4MCKejIiLamxPUouNO2cSEWuBfUdZdfXwJ5mZETHW7OkJmflaRHwaWBsRGzLz4dEarly5cudyp9Oh0+mMV56kSRgaGmJoaKj45076bE5EbKCaC3k9IvYDHsrMRbt4zzXAu5n5w1HWeTZHakAbbo60Grigu3wBcO/IBhExJyLmdpf3Ak4G1tfYpqSWqnNkMh+4EziIYaeGI2J/4B8y89SIOAS4u/uW3YB/ysxrx/g8j0ykBnjRmqQi2jDMkaSdDBNJRRgmkoowTCQVYZhIKsIwkVSEYSKpCMNEUhGGiaQiDBNJRRgmkoowTCQVYZhIKsIwkVSEYSKpCMNEUhGGiaQiDBNJRRgmkoowTCQVYZhIKsIwkVSEYSKpCMNEUhGGiaQiDBNJRRgmkoowTCQVYZhIKsIwkVSEYSKpCMNEUhGGiaQiDBNJRRgmkoowTCQVYZhIKsIwkVSEYSKpCMNEUhGGiaQiDBNJRRgmkoowTCQVYZhIKsIwkVSEYSKpiEmHSUScHRHPRcT2iDh6nHZLI2JDRLwUESsmuz1J7VbnyGQ9cCbwm7EaRMQs4EZgKXAkcF5EHFFjm5JaarfJvjEzNwBExHjNlgAvZ+bGbts7gNOB5ye7XUntNNVzJgcAm4Y9f6X7mqQBM+6RSUSsBfYdZdW3M/OXPXx+TqSYlStX7lzudDp0Op2JvF1SD4aGhhgaGir+uZE5od/3//8BEQ8B38zMdaOsOw5YmZlLu8+vAnZk5vdGaZt1a5E0cRFBZo47X9GLUsOcsQp5EjgsIg6OiD2Ac4HVhbYpqUXqnBo+MyI2AccB90XEmu7r+0fEfQCZuQ24HPg18B/ALzLTyVdpANUe5pTiMEdqRtuGOZJmOMNEUhGGiaQiDBNJRRgmkoowTCQVYZhIKsIwkVSEYSKpCMNEUhGGiaQiDBNJRRgmkoowTCQVYZhIKsIwkVSEYSKpCMNEUhGGiaQiDBNJRRgmkoowTCQVYZhIKsIwkVSEYSKpCMNEUhGGiaQiDBNJRRgmkoowTCQVYZhIKsIwkVSEYSKpCMNEUhGGiaQiDBNJRRgmkoowTCQVYZhIKsIwkVSEYSKpCMNEUhGGiaQiDBNJRRgmkoowTCQVMekwiYizI+K5iNgeEUeP025jRPx7RDwVEb+b7PYktVudI5P1wJnAb3bRLoFOZi7OzCU1ttfXhoaGmi5hygxy32Dw+1fKpMMkMzdk5os9No/JbmdQDPIP5CD3DQa/f6VMx5xJAg9GxJMRcdE0bE9SA3Ybb2VErAX2HWXVtzPzlz1u44TMfC0iPg2sjYgNmfnwRAuV1G6RmfU+IOIh4JuZua6HttcA72bmD0dZV68QSZOWmbWnIsY9MpmAUQuJiDnArMx8JyL2Ak4G/m60tiU6I6k5dU4NnxkRm4DjgPsiYk339f0j4r5us32BhyPiaeBx4F8y84G6RUtqn9rDHEmCab4CNiL+MSI2R8T6cdr8JCJeiohnImLxdNZXV0QsjYgN3fpXjLK+ExFvdS/geyoivtNEnZO1q/512/Tt/vtIRMyPiLUR8WJEPBAR88Zo15cXZE7ggtNd7u+PycxpewAnAouB9WOsXwbc310+FnhsOuur2bdZwMvAwcDuwNPAESPadIDVTdc6hf3r2/03oh/XA1d0l1cA143R7j+B+U3XO4n+LQIOBx4Cjp7s/h75mNYjk6xOCb85TpPTgNu7bR8H5kXEgumorYAlwMuZuTEzPwTuAE4fpV2/TjT30r9+3n/D7exH998zxmnbd/sze7vgtNef553a9kW/A4BNw56/AhzYUC0TNVrtB4xok8Dx3SHA/RFx5LRVV18v/evn/Tfcgszc3F3eDIwViIN8QWYv+/tjSp0aLmlk0vfLDHEvda4DFmbm1og4BbiX6nCzH/S6H/pi/41zQebVw59kZo5zDVRrL8gscMHphPdb28LkVWDhsOcHdl/rByNrX0iV5jtl5jvDltdExM0RMT8z/zhNNdaxy/6N0qa1+y8zTxprXfckwb6Z+XpE7Ae8McZnvNb9938i4h6qoUErwmS8/vWol/39MW0b5qwGzgeIiOOALcMON9vuSeCwiDg4IvYAzqXqz04RsSAioru8hOrUfD8ECfTQP/p7/w23Grigu3wB1RHkx0TEnIiY213+6ILMMc9StthYcz697O+Pm+ZZ5H8G/hv4gGo8diFwMXDxsDY3Us0iP8MYM81tfQCnAC9067+q+9rO/gGXAc9SzYz/Fjiu6ZpL9q/f99+wPswHHgReBB4A5nVf3x+4r7t8SHc/Pt3dp1c1XfcE+ndm9/fvfeB1YM3I/o21v8d7eNGapCLaNsyR1KcME0lFGCaSijBMJBVhmEgqwjCRVIRhIqkIw0RSEf8LB+U5EoL/HJ8AAAAASUVORK5CYII=", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "fig, ax = plt.subplots(figsize=(4,4))\n", "\n", "for t_idx, tt in enumerate(t[:200]):\n", "\n", " x1 = + L * sin(x[t_idx, 0])\n", " y1 = - L * cos(x[t_idx, 0])\n", "\n", " x2 = x1 + L * sin(x[t_idx, 1])\n", " y2 = y1 - L * cos(x[t_idx, 1])\n", " \n", " ax.cla() \n", " ax.plot([0, x1], [0, y1], 'r.-')\n", " ax.plot([x1, x2], [y1, y2], 'b.-')\n", " ax.set_ylim([-1.5, 0.5])\n", " ax.set_xlim([1, -1])\n", "\n", " clear_output() \n", " display(fig)\n", "\n", " time.sleep(0.1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Example: Damped harmonic oscillator" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "ODE problems are important in computational physics, so we will look at one more example: the damped harmonic oscillation. This problem is well described on the wiki page: http://en.wikipedia.org/wiki/Damping\n", "\n", "The equation of motion for the damped oscillator is:\n", "\n", "$\\displaystyle \\frac{\\mathrm{d}^2x}{\\mathrm{d}t^2} + 2\\zeta\\omega_0\\frac{\\mathrm{d}x}{\\mathrm{d}t} + \\omega^2_0 x = 0$\n", "\n", "where $x$ is the position of the oscillator, $\\omega_0$ is the frequency, and $\\zeta$ is the damping ratio. To write this second-order ODE on standard form we introduce $p = \\frac{\\mathrm{d}x}{\\mathrm{d}t}$:\n", "\n", "$\\displaystyle \\frac{\\mathrm{d}p}{\\mathrm{d}t} = - 2\\zeta\\omega_0 p - \\omega^2_0 x$\n", "\n", "$\\displaystyle \\frac{\\mathrm{d}x}{\\mathrm{d}t} = p$\n", "\n", "In the implementation of this example we will add extra arguments to the RHS function for the ODE, rather than using global variables as we did in the previous example. As a consequence of the extra arguments to the RHS, we need to pass an keyword argument `args` to the `odeint` function:" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "collapsed": false }, "outputs": [], "source": [ "def dy(y, t, zeta, w0):\n", " \"\"\"\n", " The right-hand side of the damped oscillator ODE\n", " \"\"\"\n", " x, p = y[0], y[1]\n", " \n", " dx = p\n", " dp = -2 * zeta * w0 * p - w0**2 * x\n", "\n", " return [dx, dp]" ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# initial state: \n", "y0 = [1.0, 0.0]" ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# time coordinate to solve the ODE for\n", "t = linspace(0, 10, 1000)\n", "w0 = 2*pi*1.0" ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# solve the ODE problem for three different values of the damping ratio\n", "\n", "y1 = odeint(dy, y0, t, args=(0.0, w0)) # undamped\n", "y2 = odeint(dy, y0, t, args=(0.2, w0)) # under damped\n", "y3 = odeint(dy, y0, t, args=(1.0, w0)) # critical damping\n", "y4 = odeint(dy, y0, t, args=(5.0, w0)) # over damped" ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "fig, ax = plt.subplots()\n", "ax.plot(t, y1[:,0], 'k', label=\"undamped\", linewidth=0.25)\n", "ax.plot(t, y2[:,0], 'r', label=\"under damped\")\n", "ax.plot(t, y3[:,0], 'b', label=r\"critical damping\")\n", "ax.plot(t, y4[:,0], 'g', label=\"over damped\")\n", "ax.legend();" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Fourier transform" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Fourier transforms are one of the universal tools in computational physics, which appear over and over again in different contexts. SciPy provides functions for accessing the classic [FFTPACK](http://www.netlib.org/fftpack/) library from NetLib, which is an efficient and well tested FFT library written in FORTRAN. The SciPy API has a few additional convenience functions, but overall the API is closely related to the original FORTRAN library.\n", "\n", "To use the `fftpack` module in a python program, include it using:" ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "collapsed": false }, "outputs": [], "source": [ "from numpy.fft import fftfreq\n", "from scipy.fftpack import *" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To demonstrate how to do a fast Fourier transform with SciPy, let's look at the FFT of the solution to the damped oscillator from the previous section:" ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "collapsed": false }, "outputs": [], "source": [ "N = len(t)\n", "dt = t[1]-t[0]\n", "\n", "# calculate the fast fourier transform\n", "# y2 is the solution to the under-damped oscillator from the previous section\n", "F = fft(y2[:,0]) \n", "\n", "# calculate the frequencies for the components in F\n", "w = fftfreq(N, dt)" ] }, { "cell_type": "code", "execution_count": 30, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "fig, ax = plt.subplots(figsize=(9,3))\n", "ax.plot(w, abs(F));" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Since the signal is real, the spectrum is symmetric. We therefore only need to plot the part that corresponds to the positive frequencies. To extract that part of the `w` and `F` we can use some of the indexing tricks for NumPy arrays that we saw in Lecture 2:" ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "collapsed": false }, "outputs": [], "source": [ "indices = where(w > 0) # select only indices for elements that corresponds to positive frequencies\n", "w_pos = w[indices]\n", "F_pos = F[indices]" ] }, { "cell_type": "code", "execution_count": 32, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "fig, ax = plt.subplots(figsize=(9,3))\n", "ax.plot(w_pos, abs(F_pos))\n", "ax.set_xlim(0, 5);" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As expected, we now see a peak in the spectrum that is centered around 1, which is the frequency we used in the damped oscillator example." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Linear algebra" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The linear algebra module contains a lot of matrix related functions, including linear equation solving, eigenvalue solvers, matrix functions (for example matrix-exponentiation), a number of different decompositions (SVD, LU, cholesky), etc. \n", "\n", "Detailed documentation is available at: http://docs.scipy.org/doc/scipy/reference/linalg.html\n", "\n", "Here we will look at how to use some of these functions:\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Linear equation systems" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Linear equation systems on the matrix form\n", "\n", "$A x = b$\n", "\n", "where $A$ is a matrix and $x,b$ are vectors can be solved like:" ] }, { "cell_type": "code", "execution_count": 33, "metadata": { "collapsed": true }, "outputs": [], "source": [ "from scipy.linalg import *" ] }, { "cell_type": "code", "execution_count": 34, "metadata": { "collapsed": false }, "outputs": [], "source": [ "A = array([[1,2,3], [4,5,6], [7,8,9]])\n", "b = array([1,2,3])" ] }, { "cell_type": "code", "execution_count": 35, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([-0.33333333, 0.66666667, 0. ])" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x = solve(A, b)\n", "\n", "x" ] }, { "cell_type": "code", "execution_count": 36, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([ -1.11022302e-16, 0.00000000e+00, 0.00000000e+00])" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# check\n", "dot(A, x) - b" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can also do the same with\n", "\n", "$A X = B$\n", "\n", "where $A, B, X$ are matrices:" ] }, { "cell_type": "code", "execution_count": 37, "metadata": { "collapsed": false }, "outputs": [], "source": [ "A = rand(3,3)\n", "B = rand(3,3)" ] }, { "cell_type": "code", "execution_count": 38, "metadata": { "collapsed": false }, "outputs": [], "source": [ "X = solve(A, B)" ] }, { "cell_type": "code", "execution_count": 39, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[ 1.19168749, 1.34543171, 0.38437594],\n", " [-0.88153715, -3.22735597, 0.66370273],\n", " [ 0.10044006, 1.0465058 , 0.39801748]])" ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "X" ] }, { "cell_type": "code", "execution_count": 40, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "2.0014830212433605e-16" ] }, "execution_count": 40, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# check\n", "norm(dot(A, X) - B)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Eigenvalues and eigenvectors" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The eigenvalue problem for a matrix $A$:\n", "\n", "$\\displaystyle A v_n = \\lambda_n v_n$\n", "\n", "where $v_n$ is the $n$th eigenvector and $\\lambda_n$ is the $n$th eigenvalue.\n", "\n", "To calculate eigenvalues of a matrix, use the `eigvals` and for calculating both eigenvalues and eigenvectors, use the function `eig`:" ] }, { "cell_type": "code", "execution_count": 41, "metadata": { "collapsed": false }, "outputs": [], "source": [ "evals = eigvals(A)" ] }, { "cell_type": "code", "execution_count": 42, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([ 1.08466629+0.j, 0.33612878+0.j, -0.28229973+0.j])" ] }, "execution_count": 42, "metadata": {}, "output_type": "execute_result" } ], "source": [ "evals" ] }, { "cell_type": "code", "execution_count": 43, "metadata": { "collapsed": false }, "outputs": [], "source": [ "evals, evecs = eig(A)" ] }, { "cell_type": "code", "execution_count": 44, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([ 1.08466629+0.j, 0.33612878+0.j, -0.28229973+0.j])" ] }, "execution_count": 44, "metadata": {}, "output_type": "execute_result" } ], "source": [ "evals" ] }, { "cell_type": "code", "execution_count": 45, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[-0.20946865, -0.48428024, -0.14392087],\n", " [-0.79978578, 0.8616452 , -0.79527482],\n", " [-0.56255275, 0.15178997, 0.58891829]])" ] }, "execution_count": 45, "metadata": {}, "output_type": "execute_result" } ], "source": [ "evecs" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The eigenvectors corresponding to the $n$th eigenvalue (stored in `evals[n]`) is the $n$th *column* in `evecs`, i.e., `evecs[:,n]`. To verify this, let's try multiplying eigenvectors with the matrix and compare to the product of the eigenvector and the eigenvalue:" ] }, { "cell_type": "code", "execution_count": 46, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "3.243515426387745e-16" ] }, "execution_count": 46, "metadata": {}, "output_type": "execute_result" } ], "source": [ "n = 1\n", "\n", "norm(dot(A, evecs[:,n]) - evals[n] * evecs[:,n])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There are also more specialized eigensolvers, like the `eigh` for Hermitian matrices. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Matrix operations" ] }, { "cell_type": "code", "execution_count": 47, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[ 2.0031935 , -0.63411453, 0.49891784],\n", " [-4.63643938, -0.2212669 , 3.35170585],\n", " [ 1.06421936, 1.37366073, -1.42726809]])" ] }, "execution_count": 47, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# the matrix inverse\n", "inv(A)" ] }, { "cell_type": "code", "execution_count": 48, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "-0.10292296739753022" ] }, "execution_count": 48, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# determinant\n", "det(A)" ] }, { "cell_type": "code", "execution_count": 49, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(1.3060382297688262, 1.591998214728641)" ] }, "execution_count": 49, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# norms of various orders\n", "norm(A, ord=2), norm(A, ord=Inf)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Sparse matrices" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Sparse matrices are often useful in numerical simulations dealing with large systems, if the problem can be described in matrix form where the matrices or vectors mostly contains zeros. Scipy has a good support for sparse matrices, with basic linear algebra operations (such as equation solving, eigenvalue calculations, etc.).\n", "\n", "There are many possible strategies for storing sparse matrices in an efficient way. Some of the most common are the so-called coordinate form (COO), list of list (LIL) form, and compressed-sparse column CSC (and row, CSR). Each format has some advantages and disadvantages. Most computational algorithms (equation solving, matrix-matrix multiplication, etc.) can be efficiently implemented using CSR or CSC formats, but they are not so intuitive and not so easy to initialize. So often a sparse matrix is initially created in COO or LIL format (where we can efficiently add elements to the sparse matrix data), and then converted to CSC or CSR before used in real calculations.\n", "\n", "For more information about these sparse formats, see e.g. http://en.wikipedia.org/wiki/Sparse_matrix\n", "\n", "When we create a sparse matrix we have to choose which format it should be stored in. For example, " ] }, { "cell_type": "code", "execution_count": 50, "metadata": { "collapsed": false }, "outputs": [], "source": [ "from scipy.sparse import *" ] }, { "cell_type": "code", "execution_count": 51, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[1, 0, 0, 0],\n", " [0, 3, 0, 0],\n", " [0, 1, 1, 0],\n", " [1, 0, 0, 1]])" ] }, "execution_count": 51, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# dense matrix\n", "M = array([[1,0,0,0], [0,3,0,0], [0,1,1,0], [1,0,0,1]]); M" ] }, { "cell_type": "code", "execution_count": 52, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "<4x4 sparse matrix of type ''\n", "\twith 6 stored elements in Compressed Sparse Row format>" ] }, "execution_count": 52, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# convert from dense to sparse\n", "A = csr_matrix(M); A" ] }, { "cell_type": "code", "execution_count": 53, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "matrix([[1, 0, 0, 0],\n", " [0, 3, 0, 0],\n", " [0, 1, 1, 0],\n", " [1, 0, 0, 1]])" ] }, "execution_count": 53, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# convert from sparse to dense\n", "A.todense()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "More efficient way to create sparse matrices: create an empty matrix and populate with using matrix indexing (avoids creating a potentially large dense matrix)" ] }, { "cell_type": "code", "execution_count": 54, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "<4x4 sparse matrix of type ''\n", "\twith 6 stored elements in LInked List format>" ] }, "execution_count": 54, "metadata": {}, "output_type": "execute_result" } ], "source": [ "A = lil_matrix((4,4)) # empty 4x4 sparse matrix\n", "A[0,0] = 1\n", "A[1,1] = 3\n", "A[2,2] = A[2,1] = 1\n", "A[3,3] = A[3,0] = 1\n", "A" ] }, { "cell_type": "code", "execution_count": 55, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "matrix([[ 1., 0., 0., 0.],\n", " [ 0., 3., 0., 0.],\n", " [ 0., 1., 1., 0.],\n", " [ 1., 0., 0., 1.]])" ] }, "execution_count": 55, "metadata": {}, "output_type": "execute_result" } ], "source": [ "A.todense()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Converting between different sparse matrix formats:" ] }, { "cell_type": "code", "execution_count": 56, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "<4x4 sparse matrix of type ''\n", "\twith 6 stored elements in LInked List format>" ] }, "execution_count": 56, "metadata": {}, "output_type": "execute_result" } ], "source": [ "A" ] }, { "cell_type": "code", "execution_count": 57, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "<4x4 sparse matrix of type ''\n", "\twith 6 stored elements in Compressed Sparse Row format>" ] }, "execution_count": 57, "metadata": {}, "output_type": "execute_result" } ], "source": [ "A = csr_matrix(A); A" ] }, { "cell_type": "code", "execution_count": 58, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "<4x4 sparse matrix of type ''\n", "\twith 6 stored elements in Compressed Sparse Column format>" ] }, "execution_count": 58, "metadata": {}, "output_type": "execute_result" } ], "source": [ "A = csc_matrix(A); A" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can compute with sparse matrices like with dense matrices:" ] }, { "cell_type": "code", "execution_count": 59, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "matrix([[ 1., 0., 0., 0.],\n", " [ 0., 3., 0., 0.],\n", " [ 0., 1., 1., 0.],\n", " [ 1., 0., 0., 1.]])" ] }, "execution_count": 59, "metadata": {}, "output_type": "execute_result" } ], "source": [ "A.todense()" ] }, { "cell_type": "code", "execution_count": 60, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "matrix([[ 1., 0., 0., 0.],\n", " [ 0., 9., 0., 0.],\n", " [ 0., 4., 1., 0.],\n", " [ 2., 0., 0., 1.]])" ] }, "execution_count": 60, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(A * A).todense()" ] }, { "cell_type": "code", "execution_count": 61, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "matrix([[ 1., 0., 0., 0.],\n", " [ 0., 3., 0., 0.],\n", " [ 0., 1., 1., 0.],\n", " [ 1., 0., 0., 1.]])" ] }, "execution_count": 61, "metadata": {}, "output_type": "execute_result" } ], "source": [ "A.todense()" ] }, { "cell_type": "code", "execution_count": 62, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "matrix([[ 1., 0., 0., 0.],\n", " [ 0., 9., 0., 0.],\n", " [ 0., 4., 1., 0.],\n", " [ 2., 0., 0., 1.]])" ] }, "execution_count": 62, "metadata": {}, "output_type": "execute_result" } ], "source": [ "A.dot(A).todense()" ] }, { "cell_type": "code", "execution_count": 63, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[1],\n", " [2],\n", " [3],\n", " [4]])" ] }, "execution_count": 63, "metadata": {}, "output_type": "execute_result" } ], "source": [ "v = array([1,2,3,4])[:,newaxis]; v" ] }, { "cell_type": "code", "execution_count": 64, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[ 1.],\n", " [ 6.],\n", " [ 5.],\n", " [ 5.]])" ] }, "execution_count": 64, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# sparse matrix - dense vector multiplication\n", "A * v" ] }, { "cell_type": "code", "execution_count": 65, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "matrix([[ 1.],\n", " [ 6.],\n", " [ 5.],\n", " [ 5.]])" ] }, "execution_count": 65, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# same result with dense matrix - dense vector multiplication\n", "A.todense() * v" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Optimization" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Optimization (finding minima or maxima of a function) is a large field in mathematics, and optimization of complicated functions or in many variables can be rather involved. Here we will only look at a few very simple cases. For a more detailed introduction to optimization with SciPy see: http://scipy-lectures.github.com/advanced/mathematical_optimization/index.html\n", "\n", "To use the optimization module in scipy first include the `optimize` module:" ] }, { "cell_type": "code", "execution_count": 66, "metadata": { "collapsed": false }, "outputs": [], "source": [ "from scipy import optimize" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Finding a minima" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's first look at how to find the minima of a simple function of a single variable:" ] }, { "cell_type": "code", "execution_count": 67, "metadata": { "collapsed": false }, "outputs": [], "source": [ "def f(x):\n", " return 4*x**3 + (x-2)**2 + x**4" ] }, { "cell_type": "code", "execution_count": 68, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "fig, ax = plt.subplots()\n", "x = linspace(-5, 3, 100)\n", "ax.plot(x, f(x));" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can use the `fmin_bfgs` function to find the minima of a function:" ] }, { "cell_type": "code", "execution_count": 69, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Optimization terminated successfully.\n", " Current function value: -3.506641\n", " Iterations: 6\n", " Function evaluations: 30\n", " Gradient evaluations: 10\n" ] }, { "data": { "text/plain": [ "array([-2.67298164])" ] }, "execution_count": 69, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x_min = optimize.fmin_bfgs(f, -2)\n", "x_min " ] }, { "cell_type": "code", "execution_count": 70, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Optimization terminated successfully.\n", " Current function value: 2.804988\n", " Iterations: 3\n", " Function evaluations: 15\n", " Gradient evaluations: 5\n" ] }, { "data": { "text/plain": [ "array([ 0.46961745])" ] }, "execution_count": 70, "metadata": {}, "output_type": "execute_result" } ], "source": [ "optimize.fmin_bfgs(f, 0.5) " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can also use the `brent` or `fminbound` functions. They have a bit different syntax and use different algorithms. " ] }, { "cell_type": "code", "execution_count": 71, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "0.46961743402759754" ] }, "execution_count": 71, "metadata": {}, "output_type": "execute_result" } ], "source": [ "optimize.brent(f)" ] }, { "cell_type": "code", "execution_count": 72, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "-2.6729822917513886" ] }, "execution_count": 72, "metadata": {}, "output_type": "execute_result" } ], "source": [ "optimize.fminbound(f, -4, 2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Finding a solution to a function" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To find the root for a function of the form $f(x) = 0$ we can use the `fsolve` function. It requires an initial guess: " ] }, { "cell_type": "code", "execution_count": 73, "metadata": { "collapsed": false }, "outputs": [], "source": [ "omega_c = 3.0\n", "def f(omega):\n", " # a transcendental equation: resonance frequencies of a low-Q SQUID terminated microwave resonator\n", " return tan(2*pi*omega) - omega_c/omega" ] }, { "cell_type": "code", "execution_count": 74, "metadata": { "collapsed": false }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/Users/rob/miniconda/envs/py27-spl/lib/python2.7/site-packages/IPython/kernel/__main__.py:4: RuntimeWarning: divide by zero encountered in divide\n" ] }, { "data": { "image/png": "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", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "fig, ax = plt.subplots(figsize=(10,4))\n", "x = linspace(0, 3, 1000)\n", "y = f(x)\n", "mask = where(abs(y) > 50)\n", "x[mask] = y[mask] = NaN # get rid of vertical line when the function flip sign\n", "ax.plot(x, y)\n", "ax.plot([0, 3], [0, 0], 'k')\n", "ax.set_ylim(-5,5);" ] }, { "cell_type": "code", "execution_count": 75, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([ 0.23743014])" ] }, "execution_count": 75, "metadata": {}, "output_type": "execute_result" } ], "source": [ "optimize.fsolve(f, 0.1)" ] }, { "cell_type": "code", "execution_count": 76, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([ 0.71286972])" ] }, "execution_count": 76, "metadata": {}, "output_type": "execute_result" } ], "source": [ "optimize.fsolve(f, 0.6)" ] }, { "cell_type": "code", "execution_count": 77, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([ 1.18990285])" ] }, "execution_count": 77, "metadata": {}, "output_type": "execute_result" } ], "source": [ "optimize.fsolve(f, 1.1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Interpolation" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Interpolation is simple and convenient in scipy: The `interp1d` function, when given arrays describing X and Y data, returns and object that behaves like a function that can be called for an arbitrary value of x (in the range covered by X), and it returns the corresponding interpolated y value:" ] }, { "cell_type": "code", "execution_count": 78, "metadata": { "collapsed": false }, "outputs": [], "source": [ "from scipy.interpolate import *" ] }, { "cell_type": "code", "execution_count": 79, "metadata": { "collapsed": false }, "outputs": [], "source": [ "def f(x):\n", " return sin(x)" ] }, { "cell_type": "code", "execution_count": 80, "metadata": { "collapsed": false }, "outputs": [], "source": [ "n = arange(0, 10) \n", "x = linspace(0, 9, 100)\n", "\n", "y_meas = f(n) + 0.1 * randn(len(n)) # simulate measurement with noise\n", "y_real = f(x)\n", "\n", "linear_interpolation = interp1d(n, y_meas)\n", "y_interp1 = linear_interpolation(x)\n", "\n", "cubic_interpolation = interp1d(n, y_meas, kind='cubic')\n", "y_interp2 = cubic_interpolation(x)" ] }, { "cell_type": "code", "execution_count": 81, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "fig, ax = plt.subplots(figsize=(10,4))\n", "ax.plot(n, y_meas, 'bs', label='noisy data')\n", "ax.plot(x, y_real, 'k', lw=2, label='true function')\n", "ax.plot(x, y_interp1, 'r', label='linear interp')\n", "ax.plot(x, y_interp2, 'g', label='cubic interp')\n", "ax.legend(loc=3);" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Statistics" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The `scipy.stats` module contains a large number of statistical distributions, statistical functions and tests. For a complete documentation of its features, see http://docs.scipy.org/doc/scipy/reference/stats.html.\n", "\n", "There is also a very powerful python package for statistical modelling called statsmodels. See http://statsmodels.sourceforge.net for more details." ] }, { "cell_type": "code", "execution_count": 82, "metadata": { "collapsed": false }, "outputs": [], "source": [ "from scipy import stats" ] }, { "cell_type": "code", "execution_count": 83, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# create a (discrete) random variable with Poissonian distribution\n", "\n", "X = stats.poisson(3.5) # photon distribution for a coherent state with n=3.5 photons" ] }, { "cell_type": "code", "execution_count": 84, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "n = arange(0,15)\n", "\n", "fig, axes = plt.subplots(3,1, sharex=True)\n", "\n", "# plot the probability mass function (PMF)\n", "axes[0].step(n, X.pmf(n))\n", "\n", "# plot the cumulative distribution function (CDF)\n", "axes[1].step(n, X.cdf(n))\n", "\n", "# plot histogram of 1000 random realizations of the stochastic variable X\n", "axes[2].hist(X.rvs(size=1000));" ] }, { "cell_type": "code", "execution_count": 85, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# create a (continuous) random variable with normal distribution\n", "Y = stats.norm()" ] }, { "cell_type": "code", "execution_count": 86, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "x = linspace(-5,5,100)\n", "\n", "fig, axes = plt.subplots(3,1, sharex=True)\n", "\n", "# plot the probability distribution function (PDF)\n", "axes[0].plot(x, Y.pdf(x))\n", "\n", "# plot the cumulative distribution function (CDF)\n", "axes[1].plot(x, Y.cdf(x));\n", "\n", "# plot histogram of 1000 random realizations of the stochastic variable Y\n", "axes[2].hist(Y.rvs(size=1000), bins=50);" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Statistics:" ] }, { "cell_type": "code", "execution_count": 87, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(3.5, 1.8708286933869707, 3.5)" ] }, "execution_count": 87, "metadata": {}, "output_type": "execute_result" } ], "source": [ "X.mean(), X.std(), X.var() # Poisson distribution" ] }, { "cell_type": "code", "execution_count": 88, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(0.0, 1.0, 1.0)" ] }, "execution_count": 88, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Y.mean(), Y.std(), Y.var() # normal distribution" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Statistical tests" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Test if two sets of (independent) random data come from the same distribution:" ] }, { "cell_type": "code", "execution_count": 89, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "t-statistic = -0.901953297251\n", "p-value = 0.367190391714\n" ] } ], "source": [ "t_statistic, p_value = stats.ttest_ind(X.rvs(size=1000), X.rvs(size=1000))\n", "\n", "print \"t-statistic =\", t_statistic\n", "print \"p-value =\", p_value" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Since the p value is very large we cannot reject the hypothesis that the two sets of random data have *different* means." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To test if the mean of a single sample of data has mean 0.1 (the true mean is 0.0):" ] }, { "cell_type": "code", "execution_count": 90, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "Ttest_1sampResult(statistic=-3.1644288210071765, pvalue=0.0016008455559249511)" ] }, "execution_count": 90, "metadata": {}, "output_type": "execute_result" } ], "source": [ "stats.ttest_1samp(Y.rvs(size=1000), 0.1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Low p-value means that we can reject the hypothesis that the mean of Y is 0.1." ] }, { "cell_type": "code", "execution_count": 91, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "0.0" ] }, "execution_count": 91, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Y.mean()" ] }, { "cell_type": "code", "execution_count": 92, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "Ttest_1sampResult(statistic=2.2098772438652992, pvalue=0.027339807364469011)" ] }, "execution_count": 92, "metadata": {}, "output_type": "execute_result" } ], "source": [ "stats.ttest_1samp(Y.rvs(size=1000), Y.mean())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Further reading" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* http://www.scipy.org - The official web page for the SciPy project.\n", "* http://docs.scipy.org/doc/scipy/reference/tutorial/index.html - A tutorial on how to get started using SciPy. \n", "* https://github.com/scipy/scipy/ - The SciPy source code. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Versions" ] }, { "cell_type": "code", "execution_count": 93, "metadata": { "collapsed": false }, "outputs": [ { "data": { "application/json": { "Software versions": [ { "module": "Python", "version": "2.7.10 64bit [GCC 4.2.1 (Apple Inc. build 5577)]" }, { "module": "IPython", "version": "3.2.1" }, { "module": "OS", "version": "Darwin 14.1.0 x86_64 i386 64bit" }, { "module": "numpy", "version": "1.9.2" }, { "module": "matplotlib", "version": "1.4.3" }, { "module": "scipy", "version": "0.16.0" } ] }, "text/html": [ "
SoftwareVersion
Python2.7.10 64bit [GCC 4.2.1 (Apple Inc. build 5577)]
IPython3.2.1
OSDarwin 14.1.0 x86_64 i386 64bit
numpy1.9.2
matplotlib1.4.3
scipy0.16.0
Sat Aug 15 11:13:18 2015 JST
" ], "text/latex": [ "\\begin{tabular}{|l|l|}\\hline\n", "{\\bf Software} & {\\bf Version} \\\\ \\hline\\hline\n", "Python & 2.7.10 64bit [GCC 4.2.1 (Apple Inc. build 5577)] \\\\ \\hline\n", "IPython & 3.2.1 \\\\ \\hline\n", "OS & Darwin 14.1.0 x86\\_64 i386 64bit \\\\ \\hline\n", "numpy & 1.9.2 \\\\ \\hline\n", "matplotlib & 1.4.3 \\\\ \\hline\n", "scipy & 0.16.0 \\\\ \\hline\n", "\\hline \\multicolumn{2}{|l|}{Sat Aug 15 11:13:18 2015 JST} \\\\ \\hline\n", "\\end{tabular}\n" ], "text/plain": [ "Software versions\n", "Python 2.7.10 64bit [GCC 4.2.1 (Apple Inc. build 5577)]\n", "IPython 3.2.1\n", "OS Darwin 14.1.0 x86_64 i386 64bit\n", "numpy 1.9.2\n", "matplotlib 1.4.3\n", "scipy 0.16.0\n", "Sat Aug 15 11:13:18 2015 JST" ] }, "execution_count": 93, "metadata": {}, "output_type": "execute_result" } ], "source": [ "%reload_ext version_information\n", "\n", "%version_information numpy, matplotlib, scipy" ] } ], "metadata": { "kernelspec": { "display_name": "Python 2", "language": "python", "name": "python2" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", "version": "2.7.10" } }, "nbformat": 4, "nbformat_minor": 0 }