{ "cells": [ { "cell_type": "markdown", "id": "4ab419fc", "metadata": {}, "source": [ "\n", "*This notebook contains material from [CBE60499](https://ndcbe.github.io/CBE60499);\n", "content is available [on Github](git@github.com:ndcbe/CBE60499.git).*\n" ] }, { "cell_type": "markdown", "id": "a72d2a74", "metadata": {}, "source": [ "\n", "< [2.4 Dynamic Optimization: Differential Algebraic Equations (DAEs)](https://ndcbe.github.io/CBE60499/02.04-DAE-modeling.html) | [Contents](toc.html) | [Tag Index](tag_index.html) | [2.6 Dynamic Optimization with Pyomo.DAE](https://ndcbe.github.io/CBE60499/02.06-Pyomo-DAE.html) >

\"Open

\"Download\"" ] }, { "cell_type": "markdown", "metadata": { "nbpages": { "level": 1, "link": "[2.5 Numeric Integration for DAEs](https://ndcbe.github.io/CBE60499/02.05-Numeric-Integration.html#2.5-Numeric-Integration-for-DAEs)", "section": "2.5 Numeric Integration for DAEs" } }, "source": [ "# 2.5 Numeric Integration for DAEs\n", "\n", "The purpose of this notebook/class session is to provide the requisite background on numeric integration of DAEs. This helps appreciate the \"direct transcription\" approach for dynamic optimization used in `Pyomo.dae`." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "nbpages": { "level": 1, "link": "[2.5 Numeric Integration for DAEs](https://ndcbe.github.io/CBE60499/02.05-Numeric-Integration.html#2.5-Numeric-Integration-for-DAEs)", "section": "2.5 Numeric Integration for DAEs" } }, "outputs": [], "source": [ "import numpy as np\n", "import scipy.optimize as opt\n", "import matplotlib.pyplot as plt" ] }, { "cell_type": "markdown", "metadata": { "nbpages": { "level": 2, "link": "[2.5.1 Single-Step Runge-Kutta Methods](https://ndcbe.github.io/CBE60499/02.05-Numeric-Integration.html#2.5.1-Single-Step-Runge-Kutta-Methods)", "section": "2.5.1 Single-Step Runge-Kutta Methods" } }, "source": [ "## 2.5.1 Single-Step Runge-Kutta Methods\n", "* ADD REFERENCE HERE\n", "* Chapter 9 in [Biegler (2010)](https://epubs.siam.org/doi/book/10.1137/1.9780898719383)\n", "* Chapter 17 in [McClarren (2018)](https://www.sciencedirect.com/book/9780128122532/computational-nuclear-engineering-and-radiological-science-using-python)" ] }, { "cell_type": "markdown", "metadata": { "nbpages": { "level": 3, "link": "[2.5.1.1 General Form: Index 0 DAE](https://ndcbe.github.io/CBE60499/02.05-Numeric-Integration.html#2.5.1.1-General-Form:-Index-0-DAE)", "section": "2.5.1.1 General Form: Index 0 DAE" } }, "source": [ "### 2.5.1.1 General Form: Index 0 DAE\n", "\n", "Consider the ODE system:\n", "$$\\begin{equation*}\n", "\\dot{z} = f(t,z), \\quad z(t_0) = z_0\n", "\\end{equation*}$$\n", "\n", "where $z(t)$ are the differentail variables and $f(t,z)$ is a (nonlinear) continous function.\n", "\n", "The general Runge-Kutta formula is:\n", "$$\\begin{align*}\n", "z_{i+1} &= z_{i} + h_i \\sum_{k=1}^{n_s} b_k f(t_i + c_k h_i, \\hat{z}_k) \\\\\n", " \\hat{z}_k &= z_i + h_i \\sum_{j=1}^{n_{rk}} a_{k,j} f(t_i + c_j h_i, \\hat{z}_j), \\quad k=1,...,n_s \n", "\\end{align*}$$\n", "\n", "where\n", "* $z_i$ are the differential variables at the **start** of **step** $i$ (time $t_i$)\n", "* $z_{i+1}$ are the differential variables at the **end** of **step** $i$ (time $t_{i+1}$)\n", "* $\\hat{z}_k$ are differential variables for **intermediate stage** $k$\n", "* $h_i$ is the size for step $i$ such that $t_{i+1} = t_i + h_i$\n", "* $n_s$ is the number of stages\n", "* $n_{rk}$ is the number of $f(\\cdot)$ evaluations to calculate intermediate $k$\n", "* $a_{k,j}$ are coefficients, together known as the *Runge-Kutta matrix*\n", "* $b_k$ are cofficients, known as the *weights*\n", "* $c_k$ are coefficients, know as the *nodes*\n", "\n", "$h_i$ is selected based on error tolerances\n", "\n", "The choice for $A$, $b$ and $c$ selects the specific method in the *Runge-Kutta family*. These coefficients are often specific in a [Butcher block](https://en.wikipedia.org/wiki/Runge%E2%80%93Kutta_methods#Explicit_Runge) (or Butcher tableau).\n", "\n", "A Runge-Kutta method is called [**consistent**](https://en.wikiversity.org/wiki/Numerical_Analysis/stability_of_RK_methods) if:\n", "$$\\begin{equation*}\n", "\\sum_{k=1}^{n_s} b_k = 1 \\quad \\mathrm{and} \\quad \\sum_{j=1}^{n_s} a_{k,j} = c_k\n", "\\end{equation*}$$" ] }, { "cell_type": "markdown", "metadata": { "nbpages": { "level": 3, "link": "[2.5.1.2 Explicit (Forward) Euler](https://ndcbe.github.io/CBE60499/02.05-Numeric-Integration.html#2.5.1.2-Explicit-(Forward)-Euler)", "section": "2.5.1.2 Explicit (Forward) Euler" } }, "source": [ "### 2.5.1.2 Explicit (Forward) Euler\n", "\n", "Consider one of the simplest Runge-Kutta methods:\n", "\n", "$$z_{i+1} = z_{i} + h_i~f(t_i, z_i)$$\n", "\n", "What are $A$, $b$ and $c$ in the general formula?\n", "\n", "$n_s = 1$. This is only a single stage. Thus we only need to determine $c_1$, $b_1$, and $n_{r1}$\n", "\n", "Moreover, $\\hat{z}_1 = z_i$ because $f(\\cdot)$ is only evaluated at $t_i$ and $z_i$. This implies:\n", "* $n_{r1} = 0$\n", "* $c_1 = 0$\n", "* $b_1 = 1$\n", "* $A$ is empty because $n_{r1} = 0$\n", "\n", "The implementation is very straightword (see below). We can calculate $z_{i+1}$ with a single line!" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "nbpages": { "level": 3, "link": "[2.5.1.2 Explicit (Forward) Euler](https://ndcbe.github.io/CBE60499/02.05-Numeric-Integration.html#2.5.1.2-Explicit-(Forward)-Euler)", "section": "2.5.1.2 Explicit (Forward) Euler" } }, "outputs": [], "source": [ "def create_steps(tstart,tend,dt):\n", " n = int(np.ceil((tend-tstart)/dt))\n", " return dt*np.ones(n)\n", "\n", "def explicit_euler(f,h,z0):\n", " '''\n", " Arguments:\n", " f: function that returns rhs of ODE\n", " h: list of step sizes\n", " z0: initial conditions\n", " \n", " Returns:\n", " t: list of time steps. t[0] is 0.0 by default\n", " z: list of differential variable values\n", " '''\n", " \n", " # Number of timesteps\n", " nT = len(h) + 1\n", " \n", " t = np.zeros(nT)\n", " \n", " # Number of states\n", " nZ = len(z0)\n", " Z = np.zeros((nT,nZ))\n", " \n", " # Copy initial states\n", " Z[0,:] = z0\n", " \n", " for i in range(1,nT):\n", " \n", " i_ = i-1\n", " \n", " # Advance time\n", " t[i] = t[i_] + h[i_]\n", " \n", " # Implicit Euler formula\n", " Z[i,:] = Z[i_,:] + h[i_]*f(t[i_],Z[i_,:])\n", " \n", " return t, Z" ] }, { "cell_type": "markdown", "metadata": { "nbpages": { "level": 3, "link": "[2.5.1.3 Implicit (Backward) Euler](https://ndcbe.github.io/CBE60499/02.05-Numeric-Integration.html#2.5.1.3-Implicit-(Backward)-Euler)", "section": "2.5.1.3 Implicit (Backward) Euler" } }, "source": [ "### 2.5.1.3 Implicit (Backward) Euler\n", "\n", "Consider another simple Runge-Kutta method:\n", "\n", "$$z_{i+1} = z_{i} + h_i~f(t_{i+1}, z_{i+1})$$\n", "\n", "What are $A$, $b$ and $c$ to express using the general formula?\n", "\n", "$n_s = 1$. Thus is only a single stage. Moreover, $\\hat{z}_1 = z_{i+1}$ because $f(\\cdot)$ is evaluated at $t_{i+1}$ and $z_{i+1}$. This implies:\n", "* $b_1 = 1$\n", "* $c_1 = 1$\n", "\n", "Moreover, $z_{i+1} = z_{i} + h_i~f(t_{i+1}, z_{i+1})$ implies $\\hat{z}_1 = z_i + h_i f(t_{i+1}, \\hat{z}_1)$. Thus:\n", "* $a_{1,1} = 1$\n", "\n", "Notice that the formula for $z_{i+1}$ is implicit. We need to solve a (nonlinear) system of equations to calculate the step." ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "nbpages": { "level": 3, "link": "[2.5.1.3 Implicit (Backward) Euler](https://ndcbe.github.io/CBE60499/02.05-Numeric-Integration.html#2.5.1.3-Implicit-(Backward)-Euler)", "section": "2.5.1.3 Implicit (Backward) Euler" } }, "outputs": [], "source": [ "def implicit_euler(f,h,z0):\n", " '''\n", " Arguments:\n", " f: function that returns rhs of ODE\n", " h: list of step sizes\n", " z0: initial conditions\n", " \n", " Returns:\n", " t: list of time steps. t[0] is 0.0 by default\n", " z: list of differential variable values\n", " '''\n", " \n", " # Number of timesteps\n", " nT = len(h) + 1\n", " \n", " t = np.zeros(nT)\n", " \n", " # Number of states\n", " nZ = len(z0)\n", " Z = np.zeros((nT,nZ))\n", " \n", " # Copy initial states\n", " Z[0,:] = z0\n", " \n", " for i in range(1,nT):\n", " \n", " i_ = i-1\n", " \n", " # Advance time\n", " t[i] = t[i_] + h[i_]\n", " \n", " ## Implicit Runge-Kutta formula.\n", " ## Need to solve nonlinear system of equations.\n", " \n", " # Use Explicit Euler to calculate initial guess\n", " Z[i,:] = Z[i_,:] + h[i_]*f(t[i_],Z[i_,:])\n", " \n", " # Solve nonlinear equation\n", " implicit = lambda z : Z[i_,:] + h[i_]*f(t[i_],z) - z\n", " Z[i,:] = opt.fsolve(implicit, Z[i,:])\n", " \n", " \n", " return t, Z" ] }, { "cell_type": "markdown", "metadata": { "nbpages": { "level": 3, "link": "[2.5.1.4 Comparison](https://ndcbe.github.io/CBE60499/02.05-Numeric-Integration.html#2.5.1.4-Comparison)", "section": "2.5.1.4 Comparison" } }, "source": [ "### 2.5.1.4 Comparison\n", "\n", "Let's test this on a simple problem:\n", "$$\\dot{z}(t) = -\\lambda z(t), \\qquad z_0 = 1.$$ The solution to this problem is \n", "$$z(t) = e^{-\\lambda t}.$$\n", "\n", "For simplicity, let's numerically analyze $\\lambda = 1$." ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "nbpages": { "level": 3, "link": "[2.5.1.4 Comparison](https://ndcbe.github.io/CBE60499/02.05-Numeric-Integration.html#2.5.1.4-Comparison)", "section": "2.5.1.4 Comparison" } }, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "rhs = lambda t, z: -z\n", "sln = lambda t: np.exp(-t)\n", "\n", "dt = 1.0\n", "h = create_steps(0.0,5.0,dt)\n", "\n", "z0 = [1]\n", "\n", "te, Ze = explicit_euler(rhs, h, z0)\n", "ti, Zi = implicit_euler(rhs, h, z0)\n", "\n", "plt.figure()\n", "\n", "# Use 101 points for exact to make it smooth\n", "texact = np.linspace(0.0,np.sum(h),101)\n", "\n", "# Plot solutions\n", "plt.plot(texact, sln(texact),color='green',label=\"Exact Solution\")\n", "plt.plot(te,Ze,color='red',marker='s',label='Forward Euler')\n", "plt.plot(ti,Zi,color='blue',marker='o',label='Backward Euler')\n", "plt.xlabel('t')\n", "plt.ylabel('z')\n", "plt.legend()\n", "plt.title('Solution with h = '+ str(dt))\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": { "nbpages": { "level": 3, "link": "[2.5.1.5 Stability](https://ndcbe.github.io/CBE60499/02.05-Numeric-Integration.html#2.5.1.5-Stability)", "section": "2.5.1.5 Stability" } }, "source": [ "### 2.5.1.5 Stability\n", "\n", "Keeping $\\lambda = 1$, are there any limits on step size?\n", "\n" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "nbpages": { "level": 3, "link": "[2.5.1.5 Stability](https://ndcbe.github.io/CBE60499/02.05-Numeric-Integration.html#2.5.1.5-Stability)", "section": "2.5.1.5 Stability" } }, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "dt = 2.5\n", "h = create_steps(0.0,10.0,dt)\n", "\n", "z0 = [1]\n", "\n", "te, Ze = explicit_euler(rhs, h, z0)\n", "ti, Zi = implicit_euler(rhs, h, z0)\n", "\n", "plt.figure()\n", "\n", "# Use 101 points for exact to make it smooth\n", "texact = np.linspace(0.0,np.sum(h),101)\n", "\n", "# Plot solutions\n", "plt.plot(texact, sln(texact),color='green',label=\"Exact Solution\")\n", "plt.plot(te,Ze,color='red',marker='s',label='Forward Euler')\n", "plt.plot(ti,Zi,color='blue',marker='o',label='Backward Euler')\n", "plt.xlabel('t')\n", "plt.ylabel('z')\n", "plt.legend()\n", "plt.title('Solution with h = '+ str(dt))\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": { "nbpages": { "level": 3, "link": "[2.5.1.5 Stability](https://ndcbe.github.io/CBE60499/02.05-Numeric-Integration.html#2.5.1.5-Stability)", "section": "2.5.1.5 Stability" } }, "source": [ "**Key observation:** forward (explicit) Euler becomes unstable with large steps whereas backward (implicit) Euler is stable.\n", "\n", "There is a good mathematical reason for this! See http://www.it.uu.se/edu/course/homepage/bridging/ht13/Stability_Analysis.pdf for details.\n", "\n", "**Key results** (for this specific test problem):\n", "* Explicit Euler requires step sizes with $h < 2/\\lambda$.\n", "* Implicit Euler is *unconditionally stable* provided $\\lambda > 0$.\n", "* Similar analysis and concepts extend to Runge-Kutta methods." ] }, { "cell_type": "markdown", "metadata": { "nbpages": { "level": 3, "link": "[2.5.1.6 Error Analysis](https://ndcbe.github.io/CBE60499/02.05-Numeric-Integration.html#2.5.1.6-Error-Analysis)", "section": "2.5.1.6 Error Analysis" } }, "source": [ "### 2.5.1.6 Error Analysis\n", "\n", "How does our choice in step size $h$ impact the error of these numerical techniques?\n", "\n", "Excellent tutorial: http://www.math.unl.edu/~gledder1/Math447/EulerError" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "nbpages": { "level": 3, "link": "[2.5.1.6 Error Analysis](https://ndcbe.github.io/CBE60499/02.05-Numeric-Integration.html#2.5.1.6-Error-Analysis)", "section": "2.5.1.6 Error Analysis" } }, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "Slope for Forward Euler: 1.0220608473216777\n", "Slope for Backward Euler: 0.9874086317220228\n" ] } ], "source": [ "Delta_t = np.array([1.0,.5,.25,.125,.0625,.0625/2])\n", "t_final = 2\n", "error_forward = np.zeros(Delta_t.size)\n", "error_backward = np.zeros(Delta_t.size)\n", "\n", "for i in range(0,len(Delta_t)):\n", " \n", " # create steps\n", " h = create_steps(0.0,t_final,Delta_t[i])\n", " \n", " # solve\n", " t,ze = explicit_euler(rhs, h, z0)\n", " t,zi = implicit_euler(rhs, h, z0)\n", " zsln = np.exp(-t)\n", " \n", " n = len(t) - 1\n", " \n", " # Calculate error\n", " error_forward[i] = np.linalg.norm(ze[:,0] - zsln)/np.sqrt(n)\n", " error_backward[i] = np.linalg.norm(zi[:,0] - zsln)/np.sqrt(n)\n", " \n", "\n", "plt.loglog(Delta_t,error_forward,'s-',color=\"red\",label=\"Forward Euler\")\n", "plt.loglog(Delta_t,error_backward,'o-',color=\"blue\",label=\"Backward Euler\")\n", "\n", "#slope = (np.log(error[-1]) - np.log(error[-2]))/(np.log(Delta_t[-1])- np.log(Delta_t[-2]))\n", "#plt.title(\"Slope of Error is \" + str(slope))\n", "plt.xlabel(\"Step Size (h)\")\n", "plt.ylabel(\"Norm of Error\")\n", "plt.show()\n", "\n", "# Calculate slope\n", "calc_slope = lambda error: (np.log(error[-1]) - np.log(error[-2]))/(np.log(Delta_t[-1])- np.log(Delta_t[-2]))\n", "\n", "print(\"Slope for Forward Euler: \" + str(calc_slope(error_forward)))\n", "print(\"Slope for Backward Euler: \" + str(calc_slope(error_backward)))" ] }, { "cell_type": "markdown", "metadata": { "nbpages": { "level": 3, "link": "[2.5.1.6 Error Analysis](https://ndcbe.github.io/CBE60499/02.05-Numeric-Integration.html#2.5.1.6-Error-Analysis)", "section": "2.5.1.6 Error Analysis" } }, "source": [ "Notice that the error indicates that this is a first-order method in $\\Delta t$: when I decrease $\\Delta t$ by a factor of 2, the error decreases by a factor of 2. In this case we measured the error with a slightly different error norm:\n", "$$\\mathrm{Error} = \\frac{1}{\\sqrt{N}}\\sqrt{\\sum_{n=1}^{N} \\left(y^n_\\mathrm{approx} - y^n_\\mathrm{exact}\\right)^2},$$\n", "where $N$ is the number of steps the ODE is solved over." ] }, { "cell_type": "markdown", "metadata": { "nbpages": { "level": 3, "link": "[2.5.1.6 Error Analysis](https://ndcbe.github.io/CBE60499/02.05-Numeric-Integration.html#2.5.1.6-Error-Analysis)", "section": "2.5.1.6 Error Analysis" } }, "source": [ "**Key Results**:\n", "* Implicit and Explicit Euler have $O(h^2)$ local error and $O(h)$ global error." ] }, { "cell_type": "markdown", "metadata": { "nbpages": { "level": 3, "link": "[2.5.1.7 Extensions to DAEs](https://ndcbe.github.io/CBE60499/02.05-Numeric-Integration.html#2.5.1.7-Extensions-to-DAEs)", "section": "2.5.1.7 Extensions to DAEs" } }, "source": [ "### 2.5.1.7 Extensions to DAEs\n", "\n", "Consider semi-explicit DAEs:\n", "$$\\begin{equation*}\n", "\\dot{z} = f(t,z,y), \\quad g(z,y) = 0, \\quad z(t_0) = z_0\n", "\\end{equation*}$$\n", "\n", "Runge-Kutta methods are easy to extend.\n", "\n", "$$\\begin{align*}\n", "z_{i+1} &= z_{i} + h_i \\sum_{k=1}^{n_s} b_k f(t_i + c_k h_i, \\hat{z}_k, \\hat{y}_k) \\\\\n", " \\hat{z}_k &= z_i + h_i \\sum_{j=1}^{n_{rk}} a_{k,j} f(t_i + c_j h_i, \\hat{z}_j, \\hat{y}_j), \\quad k=1,...,n_s \\\\\n", " 0 &= g(\\hat{z}_k, \\hat{y}_k), \\quad k=1,...,n_s\n", "\\end{align*}$$\n", "\n", "**Key Results**. If DAE is index 1, then similar stability and order properties as for ODE problems.\n", "\n", "**Discussion:** Why are *implicit* RK methods always used for DAE systems?" ] }, { "cell_type": "markdown", "metadata": { "nbpages": { "level": 2, "link": "[2.5.2 Quadrature Rules](https://ndcbe.github.io/CBE60499/02.05-Numeric-Integration.html#2.5.2-Quadrature-Rules)", "section": "2.5.2 Quadrature Rules" } }, "source": [ "## 2.5.2 Quadrature Rules" ] }, { "cell_type": "markdown", "metadata": { "nbpages": { "level": 2, "link": "[2.5.2 Quadrature Rules](https://ndcbe.github.io/CBE60499/02.05-Numeric-Integration.html#2.5.2-Quadrature-Rules)", "section": "2.5.2 Quadrature Rules" } }, "source": [ "* Chapter 16 in [McClarren (2018)](https://www.sciencedirect.com/book/9780128122532/computational-nuclear-engineering-and-radiological-science-using-python).\n", "* Chapter 10 in [Biegler (2010)](https://epubs.siam.org/doi/book/10.1137/1.9780898719383)" ] }, { "cell_type": "markdown", "metadata": { "nbpages": { "level": 3, "link": "[2.5.2.1 Main Idea](https://ndcbe.github.io/CBE60499/02.05-Numeric-Integration.html#2.5.2.1-Main-Idea)", "section": "2.5.2.1 Main Idea" } }, "source": [ "### 2.5.2.1 Main Idea\n", "\n", "Approximate integral $I$ with weighted sum of function evaluations:\n", "\n", "$$\\begin{equation*}\n", "I := \\int_{-1}^{1} f(x) dx \\approx \\underbrace{\\sum_{l=1}^{L} w_l f(x_l)}_{\\text{quadrature rule}}\n", "\\end{equation*}$$\n", "\n", "where:\n", "* $x_l$ are nodes (abscissas)\n", "* $w_l$ are weights\n", "* $n$ number of nodes and weights\n", "\n", "Central questions:\n", "* How to choose *nodes* and *weights*?\n", "* How does this choice impact approximation error?\n", "* How does $n$ impact approximation error?" ] }, { "cell_type": "markdown", "metadata": { "nbpages": { "level": 3, "link": "[2.5.2.2 Degree and order of a polynomial](https://ndcbe.github.io/CBE60499/02.05-Numeric-Integration.html#2.5.2.2-Degree-and-order-of-a-polynomial)", "section": "2.5.2.2 Degree and order of a polynomial" } }, "source": [ "### 2.5.2.2 Degree and order of a polynomial\n", "\n", "Consider the polynomial:\n", "\n", "$$p(t) = a_0 + a_1 t + ... + a_K t^K.$$\n", "\n", "$p(t)$ is said to be of **order K+1** as it has K+1 coefficients $a_0, ... a_K$.\n", "\n", "The **degree** of the polynomial is the highest power with a non-zero coefficient. Thus if $a_K \\neq 0$, then $p(t)$ is degree K.\n", "\n", "Example: What is the degree of $2 x^3 - x^2 + 1$? What can you say about its order?" ] }, { "cell_type": "markdown", "metadata": { "nbpages": { "level": 3, "link": "[2.5.2.3 Gauss-Legrenge Quadrature](https://ndcbe.github.io/CBE60499/02.05-Numeric-Integration.html#2.5.2.3-Gauss-Legrenge-Quadrature)", "section": "2.5.2.3 Gauss-Legrenge Quadrature" } }, "source": [ "### 2.5.2.3 Gauss-Legrenge Quadrature\n", "\n", "For a *specific choice of nodes and weights*, the quadrature rule $\\sum_{l=1}^{L} w_l f(x_l)$ is exact for integral $I$ is $f(x)$ is a polynomial of degree $2L-1$ or less. This specific case is the **optimal** (most accurate) rule known as the Gauss-Legrenge quadrature.\n", "\n", "The weights and abscissas are given for $L$ up to 8:" ] }, { "cell_type": "markdown", "metadata": { "nbpages": { "level": 3, "link": "[2.5.2.3 Gauss-Legrenge Quadrature](https://ndcbe.github.io/CBE60499/02.05-Numeric-Integration.html#2.5.2.3-Gauss-Legrenge-Quadrature)", "section": "2.5.2.3 Gauss-Legrenge Quadrature" } }, "source": [ "\n", "\n", "\n", "

\n", "
$L$$x_l$$w_l$
102.0000000000000000000000000
2±0.57735026918962576450914881.0000000000000000000000000
300.8888888888888888888888889
±0.77459666924148337703585310.5555555555555555555555556
4±0.33998104358485626480266580.6521451548625461426269361
±0.86113631159405257522394650.3478548451374538573730639
500.5688888888888888888888889
±0.53846931010568309103631440.4786286704993664680412915
±0.90617984593866399279762690.2369268850561890875142640
6±0.23861918608319690863050170.4679139345726910473898703
±0.66120938646626451366139960.3607615730481386075698335
±0.93246951420315202781230160.1713244923791703450402961
700.4179591836734693877551020
±0.40584515137739716690660640.3818300505051189449503698
±0.74153118559939443986386480.2797053914892766679014678
±0.94910791234275852452618970.1294849661688696932706114
8±0.18343464249564980493947610.3626837833783619829651504
±0.52553240991632898581773900.3137066458778872873379622
±0.79666647741362673959155390.2223810344533744705443560
±0.96028985649753623168356090.1012285362903762591525314
" ] }, { "cell_type": "markdown", "metadata": { "nbpages": { "level": 3, "link": "[2.5.2.4 Code](https://ndcbe.github.io/CBE60499/02.05-Numeric-Integration.html#2.5.2.4-Code)", "section": "2.5.2.4 Code" } }, "source": [ "### 2.5.2.4 Code" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "nbpages": { "level": 3, "link": "[2.5.2.4 Code](https://ndcbe.github.io/CBE60499/02.05-Numeric-Integration.html#2.5.2.4-Code)", "section": "2.5.2.4 Code" } }, "outputs": [], "source": [ "import numpy as np\n", "import matplotlib.pyplot as plt\n", "def GLQuad(f, L=8,dataReturn = False):\n", " \"\"\"Compute the Gauss-Legendre Quadrature estimate \n", " of the integral of f(x) from -1 to 1\n", " Inputs:\n", " f: name of function to integrate\n", " L: Order of integration rule (8 or less)\n", " \n", " Returns:\n", " G-L Quadrature estimate\"\"\"\n", " assert(L>=1)\n", " if (L==1):\n", " weights = np.ones(1)*2\n", " xs = np.array([0])\n", " elif (L==2):\n", " weights = np.ones(2)\n", " xs = np.array([-np.sqrt(1.0/3.0),np.sqrt(1.0/3.0)])\n", " elif (L==3):\n", " weights = np.array([0.8888888888888888888888889,\n", " 0.5555555555555555555555556,\n", " 0.5555555555555555555555556])\n", " xs = np.array([0.0,-0.7745966692414833770358531,\n", " 0.7745966692414833770358531])\n", " elif (L==4):\n", " weights = np.array([0.6521451548625461426269361,0.6521451548625461426269361,\n", " 0.3478548451374538573730639,0.3478548451374538573730639])\n", " xs = np.array([-0.3399810435848562648026658, 0.3399810435848562648026658,\n", " -0.8611363115940525752239465, 0.8611363115940525752239465])\n", " elif (L==5):\n", " weights = np.array([0.5688888888888888888888889,\n", " 0.4786286704993664680412915,0.4786286704993664680412915,\n", " 0.2369268850561890875142640,0.2369268850561890875142640])\n", " xs = np.array([0.0,-0.5384693101056830910363144,0.5384693101056830910363144,\n", " -0.9061798459386639927976269,0.9061798459386639927976269])\n", " elif (L==6):\n", " weights = np.array([0.4679139345726910473898703,0.4679139345726910473898703,\n", " 0.3607615730481386075698335,0.3607615730481386075698335,\n", " 0.1713244923791703450402961,0.1713244923791703450402961])\n", " xs = np.array([-0.2386191860831969086305017, 0.2386191860831969086305017,\n", " -0.6612093864662645136613996, 0.6612093864662645136613996,\n", " -0.9324695142031520278123016, 0.9324695142031520278123016])\n", " elif (L==7):\n", " weights = np.array([0.4179591836734693877551020,\n", " 0.3818300505051189449503698,0.3818300505051189449503698,\n", " 0.2797053914892766679014678,0.2797053914892766679014678,\n", " 0.1294849661688696932706114,0.1294849661688696932706114])\n", " xs = np.array([0.0,-0.4058451513773971669066064,0.4058451513773971669066064,\n", " -0.7415311855993944398638648,0.7415311855993944398638648,\n", " -0.9491079123427585245261897,0.9491079123427585245261897])\n", " elif (L==8):\n", " weights = np.array([0.3626837833783619829651504,0.3626837833783619829651504,\n", " 0.3137066458778872873379622,0.3137066458778872873379622,\n", " 0.2223810344533744705443560,0.2223810344533744705443560,\n", " 0.1012285362903762591525314,0.1012285362903762591525314])\n", " xs = np.array([-0.1834346424956498049394761, 0.1834346424956498049394761,\n", " -0.5255324099163289858177390, 0.5255324099163289858177390,\n", " -0.7966664774136267395915539, 0.7966664774136267395915539,\n", " -0.9602898564975362316835609, 0.9602898564975362316835609])\n", " else: #use numpy's function\n", " xs, weights = np.polynomial.legendre.leggauss(L)\n", " \n", " quad_estimate = np.sum(weights*f(xs))\n", " if (dataReturn):\n", " return quad_estimate, weights, xs\n", " else:\n", " return quad_estimate" ] }, { "cell_type": "markdown", "metadata": { "nbpages": { "level": 3, "link": "[2.5.2.5 Visualize Weights](https://ndcbe.github.io/CBE60499/02.05-Numeric-Integration.html#2.5.2.5-Visualize-Weights)", "section": "2.5.2.5 Visualize Weights" } }, "source": [ "### 2.5.2.5 Visualize Weights" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "nbpages": { "level": 3, "link": "[2.5.2.5 Visualize Weights](https://ndcbe.github.io/CBE60499/02.05-Numeric-Integration.html#2.5.2.5-Visualize-Weights)", "section": "2.5.2.5 Visualize Weights" } }, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "

" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "L = np.arange(1,15)\n", "f = lambda x: x\n", "for l in L:\n", " quad_est, weights, xs = GLQuad(f,l,dataReturn=True)\n", " levels = weights*0 + l\n", " plt.scatter(xs, levels, s=weights*100)\n", "plt.xlabel(\"x\")\n", "plt.ylabel(\"L\")\n", "plt.title(\"Gauss-Legendre Quadrature Points\\nSize of point is weight\")\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": { "nbpages": { "level": 3, "link": "[2.5.2.6 Why $2L-1$?](https://ndcbe.github.io/CBE60499/02.05-Numeric-Integration.html#2.5.2.6-Why-$2L-1$?)", "section": "2.5.2.6 Why $2L-1$?" } }, "source": [ "### 2.5.2.6 Why $2L-1$?\n", "\n", "Let $f(x) = a_{2L-1} x^{2L-1} + a_{2L-2} x^{2L-2} + ... + a_{1} x^1 + a_{0}$\n", "\n", "This polynomial has $2L$ coefficients. Likewise, $\\int f(x)dx$ has $2L$ coefficients plus the constant of integration. This is the same number of degrees of freedom we have in choosing the *weights* and *nodes*." ] }, { "cell_type": "markdown", "metadata": { "nbpages": { "level": 3, "link": "[2.5.2.7 How to determine the nodes and weights? ](https://ndcbe.github.io/CBE60499/02.05-Numeric-Integration.html#2.5.2.7-How-to-determine-the-nodes-and-weights?)", "section": "2.5.2.7 How to determine the nodes and weights? " } }, "source": [ "### 2.5.2.7 How to determine the nodes and weights? \n", "\n", "One way to derive the Gauss-Legendre quadrature rules is by looking at the integral generic monomials of degree 0 up to $2L-1$ and setting each equal to the $L$ point Gauss-Legendre quadrature rule:\n", "$$ \\int\\limits_{-1}^{1} dx\\, a_0 x^0 = a_0\\sum_{l=1}^L w_l x_l^0,$$\n", "$$ \\int\\limits_{-1}^{1} dx\\, a_1 x^1 = a_1\\sum_{l=1}^L w_l x_l^1,$$\n", "and continuing until\n", "$$ \\int\\limits_{-1}^{1} dx\\, a_{2L-1} x^{2L-1} = a_{2L-1}\\sum_{l=1}^L w_l x_l^{2L-1}.$$\n", "Notice that the $a_i$ **constants cancel out** of each equation so they do not matter. This system is $2L$ equations with $L$ weights, $w_l$, and $L$ abscissas (nodes), $x_l$. We could solve these equations to get the weights and abscissas, though this is not how it is done in practice generally---this is accomplished by using the theory of orthogonal polynomials." ] }, { "cell_type": "markdown", "metadata": { "nbpages": { "level": 3, "link": "[2.5.2.8 Polynomial Example](https://ndcbe.github.io/CBE60499/02.05-Numeric-Integration.html#2.5.2.8-Polynomial-Example)", "section": "2.5.2.8 Polynomial Example" } }, "source": [ "### 2.5.2.8 Polynomial Example\n", "\n", "As a simple demonstration of the Gauss-Legendre quadrature, let's show that it integrates polynomials of degree $2L-1$ exactly. Consider the integral\n", "$$\\int\\limits_{-1}^1 (x+1)^{2L-1}\\,dx = \\frac{2^{2 L-1}}{L}.$$" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "nbpages": { "level": 3, "link": "[2.5.2.8 Polynomial Example](https://ndcbe.github.io/CBE60499/02.05-Numeric-Integration.html#2.5.2.8-Polynomial-Example)", "section": "2.5.2.8 Polynomial Example" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "L = 1 \t Estimate is 2.0 Exact value is 2.0 \n", "Abs. Relative Error is 0.0\n", "L = 2 \t Estimate is 3.9999999999999996 Exact value is 4.0 \n", "Abs. Relative Error is 1.1102230246251565e-16\n", "L = 3 \t Estimate is 10.666666666666668 Exact value is 10.666666666666666 \n", "Abs. Relative Error is 1.6653345369377348e-16\n", "L = 4 \t Estimate is 31.99999999999999 Exact value is 32.0 \n", "Abs. Relative Error is 3.3306690738754696e-16\n", "L = 5 \t Estimate is 102.39999999999995 Exact value is 102.4 \n", "Abs. Relative Error is 5.551115123125783e-16\n", "L = 6 \t Estimate is 341.33333333333337 Exact value is 341.3333333333333 \n", "Abs. Relative Error is 1.6653345369377348e-16\n", "L = 7 \t Estimate is 1170.2857142857135 Exact value is 1170.2857142857142 \n", "Abs. Relative Error is 5.828670879282072e-16\n", "L = 8 \t Estimate is 4096.000000000003 Exact value is 4096.0 \n", "Abs. Relative Error is 6.661338147750939e-16\n", "L = 9 \t Estimate is 14563.555555555577 Exact value is 14563.555555555555 \n", "Abs. Relative Error is 1.4988010832439613e-15\n", "L = 10 \t Estimate is 52428.799999999974 Exact value is 52428.8 \n", "Abs. Relative Error is 5.551115123125783e-16\n", "L = 11 \t Estimate is 190650.181818181 Exact value is 190650.18181818182 \n", "Abs. Relative Error is 4.274358644806853e-15\n" ] } ], "source": [ "L = np.arange(1,12)\n", "for l in L:\n", " \n", " # Create f\n", " f = lambda x: (x+1)**(2*l-1)\n", " \n", " # Evaluate exact (analytic) solution\n", " integral = 2**(2*l - 1)/l\n", " \n", " # Evaluate quadrature rule\n", " GLintegral = GLQuad(f,l)\n", " \n", " # Print results\n", " print(\"L =\", l,\"\\t Estimate is\",GLintegral,\n", " \"Exact value is\",integral, \n", " \"\\nAbs. Relative Error is\", np.abs(GLintegral-integral)/integral)" ] }, { "cell_type": "markdown", "metadata": { "nbpages": { "level": 3, "link": "[2.5.2.9 Generalization](https://ndcbe.github.io/CBE60499/02.05-Numeric-Integration.html#2.5.2.9-Generalization)", "section": "2.5.2.9 Generalization" } }, "source": [ "### 2.5.2.9 Generalization\n", "\n", "We are generally interested in integrals not just over the domain $x\\in [-1,1]$. We'll now make a function that does Gauss-Legendre quadrature over a general range using the formula\n", "$$\\int_a^b f(x)\\,dx = \\frac{b-a}{2} \\int_{-1}^1 f\\left(\\frac{b-a}{2}z + \\frac{a+b}{2}\\right)\\,dz.$$" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "nbpages": { "level": 3, "link": "[2.5.2.9 Generalization](https://ndcbe.github.io/CBE60499/02.05-Numeric-Integration.html#2.5.2.9-Generalization)", "section": "2.5.2.9 Generalization" } }, "outputs": [], "source": [ "def generalGL(f,a,b,L):\n", " \"\"\"Compute the Gauss-Legendre Quadrature estimate \n", " of the integral of f(x) from a to b\n", " Inputs:\n", " f: name of function to integrate\n", " a: lower bound of integral\n", " b: upper bound of integral\n", " L: Order of integration rule (8 or less)\n", " Returns:\n", " G-L Quadrature estimate\"\"\"\n", " assert(L>=1)\n", " #define a re-scaled f\n", " f_rescaled = lambda z: f(0.5*(b-a)*z + 0.5*(a+b))\n", " integral = GLQuad(f_rescaled,L)\n", " return integral*(b-a)*0.5" ] }, { "cell_type": "markdown", "metadata": { "nbpages": { "level": 3, "link": "[2.5.2.9 Generalization](https://ndcbe.github.io/CBE60499/02.05-Numeric-Integration.html#2.5.2.9-Generalization)", "section": "2.5.2.9 Generalization" } }, "source": [ "Let's show that this version integrates polynomials of degree $2L-1$ exactly. Consider the integral\n", "$$\\int\\limits_{-3}^2 (x+1)^{2L-1}\\,dx = \\frac{9^L-4^L}{2 L}.$$" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "nbpages": { "level": 3, "link": "[2.5.2.9 Generalization](https://ndcbe.github.io/CBE60499/02.05-Numeric-Integration.html#2.5.2.9-Generalization)", "section": "2.5.2.9 Generalization" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "L = 1 \t Estimate is 2.5 Exact value is 2.5 \n", "Abs. Relative Error is 0.0\n", "L = 2 \t Estimate is 16.249999999999996 Exact value is 16.25 \n", "Abs. Relative Error is 2.1862853408003084e-16\n", "L = 3 \t Estimate is 110.83333333333336 Exact value is 110.83333333333333 \n", "Abs. Relative Error is 2.5643647606379557e-16\n", "L = 4 \t Estimate is 788.1249999999999 Exact value is 788.125 \n", "Abs. Relative Error is 1.4424975444455643e-16\n", "L = 5 \t Estimate is 5802.500000000002 Exact value is 5802.5 \n", "Abs. Relative Error is 3.1348374037843283e-16\n", "L = 6 \t Estimate is 43945.4166666667 Exact value is 43945.416666666664 \n", "Abs. Relative Error is 8.278403262589113e-16\n", "L = 7 \t Estimate is 340470.35714285733 Exact value is 340470.35714285716 \n", "Abs. Relative Error is 5.128874777992276e-16\n", "L = 8 \t Estimate is 2686324.0625 Exact value is 2686324.0625 \n", "Abs. Relative Error is 0.0\n", "L = 9 \t Estimate is 21508796.944444507 Exact value is 21508796.944444444 \n", "Abs. Relative Error is 2.9443736549946913e-15\n", "L = 10 \t Estimate is 174286791.24999988 Exact value is 174286791.25 \n", "Abs. Relative Error is 6.839835003892255e-16\n", "L = 11 \t Estimate is 1426221150.2272635 Exact value is 1426221150.2272727 \n", "Abs. Relative Error is 6.5195531446713024e-15\n" ] } ], "source": [ "L = np.arange(1,12)\n", "for l in L:\n", " f = lambda x: (x+1)**(2*l-1)\n", " integral = (9**l-4**l)/(2*l)\n", " GLintegral = generalGL(f,-3,2,l)\n", " print(\"L =\", l,\"\\t Estimate is\",GLintegral,\n", " \"Exact value is\",integral, \n", " \"\\nAbs. Relative Error is\", np.abs(GLintegral-integral)/integral)" ] }, { "cell_type": "markdown", "metadata": { "nbpages": { "level": 3, "link": "[2.5.2.10 Another Example](https://ndcbe.github.io/CBE60499/02.05-Numeric-Integration.html#2.5.2.10-Another-Example)", "section": "2.5.2.10 Another Example" } }, "source": [ "### 2.5.2.10 Another Example\n", "\n", "Let's see how Gauss-Quadrature performs on a function that is not polynomial:\n", "$$\\int_{0}^\\pi \\sin(x)\\,dx = 2,$$" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "nbpages": { "level": 3, "link": "[2.5.2.10 Another Example](https://ndcbe.github.io/CBE60499/02.05-Numeric-Integration.html#2.5.2.10-Another-Example)", "section": "2.5.2.10 Another Example" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "L = 1 Estimate is 3.141592653589793 Exact value is 2\n", "L = 2 Estimate is 1.9358195746511373 Exact value is 2\n", "L = 3 Estimate is 2.0013889136077436 Exact value is 2\n", "L = 4 Estimate is 1.999984228457722 Exact value is 2\n", "L = 5 Estimate is 2.000000110284472 Exact value is 2\n", "L = 6 Estimate is 1.9999999994772704 Exact value is 2\n", "L = 7 Estimate is 2.0000000000017906 Exact value is 2\n", "L = 8 Estimate is 1.9999999999999951 Exact value is 2\n", "L = 9 Estimate is 1.9999999999999998 Exact value is 2\n", "L = 10 Estimate is 2.0000000000000004 Exact value is 2\n", "L = 11 Estimate is 2.0000000000000013 Exact value is 2\n", "L = 12 Estimate is 1.9999999999999987 Exact value is 2\n", "L = 13 Estimate is 1.9999999999999998 Exact value is 2\n", "L = 14 Estimate is 1.999999999999999 Exact value is 2\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "L = np.arange(1,15)\n", "errors = np.zeros(L.size)\n", "f = lambda x: np.sin(x)\n", "integral = 2\n", "for l in L:\n", " GLintegral = generalGL(f,0,np.pi,l)\n", " errors[l-1] = np.fabs(GLintegral-integral)\n", " print(\"L =\",l,\"Estimate is\",GLintegral,\"Exact value is\",integral)\n", "plt.loglog(L,errors,'o-')\n", "plt.xlabel(\"L\")\n", "plt.ylabel(\"Absolute Error\")\n", "plt.title(\"Estimate of $\\int_{0}^\\pi \\sin(x)\\,dx = 2$\")\n", "plt.axis([1,20,10**-16,10**1])\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": { "nbpages": { "level": 3, "link": "[2.5.2.10 Another Example](https://ndcbe.github.io/CBE60499/02.05-Numeric-Integration.html#2.5.2.10-Another-Example)", "section": "2.5.2.10 Another Example" } }, "source": [ "Notice that we get to machine-precision by evaluating the integral at only 8 points!\n", "\n", "This exponential convergence will only be obtained on smooth solutions without singularities in the function or its derivatives." ] }, { "cell_type": "markdown", "metadata": { "nbpages": { "level": 3, "link": "[2.5.2.11 A More Complicated Example](https://ndcbe.github.io/CBE60499/02.05-Numeric-Integration.html#2.5.2.11-A-More-Complicated-Example)", "section": "2.5.2.11 A More Complicated Example" } }, "source": [ "### 2.5.2.11 A More Complicated Example\n", "\n", "Consider:\n", "$$ \\int\\limits_0^1 4 \\sqrt{1-x^2}\\,dx = \\pi.$$\n", "This integral has a singularity in its derivative at $x=1$. Gauss-Legendre quadrature will not have exponential convergence on this function." ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "nbpages": { "level": 3, "link": "[2.5.2.11 A More Complicated Example](https://ndcbe.github.io/CBE60499/02.05-Numeric-Integration.html#2.5.2.11-A-More-Complicated-Example)", "section": "2.5.2.11 A More Complicated Example" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "L = 1 Estimate is 3.4641016151377544 Exact value is 3.141592653589793\n", "L = 2 Estimate is 3.184452077509094 Exact value is 3.141592653589793\n", "L = 3 Estimate is 3.156072695039818 Exact value is 3.141592653589793\n", "L = 4 Estimate is 3.1482294686216954 Exact value is 3.141592653589793\n", "L = 5 Estimate is 3.1451817756693496 Exact value is 3.141592653589793\n", "L = 6 Estimate is 3.1437514508015596 Exact value is 3.141592653589793\n", "L = 7 Estimate is 3.1429916780932854 Exact value is 3.141592653589793\n", "L = 8 Estimate is 3.1425508648538196 Exact value is 3.141592653589793\n", "L = 9 Estimate is 3.1422775824170497 Exact value is 3.141592653589793\n", "L = 10 Estimate is 3.1420991700052934 Exact value is 3.141592653589793\n", "L = 11 Estimate is 3.1419777569660723 Exact value is 3.141592653589793\n", "L = 12 Estimate is 3.141892268737024 Exact value is 3.141592653589793\n", "L = 13 Estimate is 3.141830335674392 Exact value is 3.141592653589793\n", "L = 14 Estimate is 3.1417843690029263 Exact value is 3.141592653589793\n", "L = 15 Estimate is 3.1417495357969707 Exact value is 3.141592653589793\n", "L = 16 Estimate is 3.141722658178849 Exact value is 3.141592653589793\n", "L = 17 Estimate is 3.1417015878568084 Exact value is 3.141592653589793\n", "L = 18 Estimate is 3.141684836935859 Exact value is 3.141592653589793\n", "L = 19 Estimate is 3.1416713526382183 Exact value is 3.141592653589793\n", "L = 20 Estimate is 3.1416603757628048 Exact value is 3.141592653589793\n", "L = 21 Estimate is 3.1416513494235643 Exact value is 3.141592653589793\n", "L = 22 Estimate is 3.1416438588294406 Exact value is 3.141592653589793\n", "L = 23 Estimate is 3.1416375907129095 Exact value is 3.141592653589793\n", "L = 24 Estimate is 3.1416323054778177 Exact value is 3.141592653589793\n", "L = 25 Estimate is 3.141627817750008 Exact value is 3.141592653589793\n", "L = 26 Estimate is 3.1416239825825443 Exact value is 3.141592653589793\n", "L = 27 Estimate is 3.141620685530997 Exact value is 3.141592653589793\n", "L = 28 Estimate is 3.141617835418813 Exact value is 3.141592653589793\n", "L = 29 Estimate is 3.141615358999378 Exact value is 3.141592653589793\n", "L = 30 Estimate is 3.1416131969731325 Exact value is 3.141592653589793\n", "L = 31 Estimate is 3.141611300984699 Exact value is 3.141592653589793\n", "L = 32 Estimate is 3.141609631336806 Exact value is 3.141592653589793\n", "L = 33 Estimate is 3.141608155234139 Exact value is 3.141592653589793\n", "L = 34 Estimate is 3.141606845422818 Exact value is 3.141592653589793\n", "L = 35 Estimate is 3.1416056791279456 Exact value is 3.141592653589793\n", "L = 36 Estimate is 3.1416046372177497 Exact value is 3.141592653589793\n", "L = 37 Estimate is 3.141603703541395 Exact value is 3.141592653589793\n", "L = 38 Estimate is 3.141602864400813 Exact value is 3.141592653589793\n", "L = 39 Estimate is 3.1416021081268766 Exact value is 3.141592653589793\n" ] }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYoAAAEnCAYAAAC3/AQgAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8QVMy6AAAACXBIWXMAAAsTAAALEwEAmpwYAAArXElEQVR4nO3deXiU9bn/8fedECAgJLJLWAOIVlBREVFAFi1uVI/aqq32qFRq63L661VbPe1pe85pL7R2dUVQRK1LW7cK6sGFVRZZK4rKkoQlYQcJW4As9++PmegQZibbTGYy+byuay7zPPPM89wozp3v9/4u5u6IiIhEkpboAEREJLkpUYiISFRKFCIiEpUShYiIRKVEISIiUSlRiIhIVEoUIiISlRKFiIhEpUQhEkNmlmVmS8zsgJkNSHQ8IrHQLNEBiKSYQ8DlwIOxuqGZJf3yCe5uiY5B4keJQiSG3L0U2GkWm+9NM8sFxrn7jJjcUKQO1PUkktwuAt5PdBDStClRiNSBmZ1jZp+b2QYzOzuOj2rl7iVxvL9ItZQoROrmEWA18B4wMR4PMLNs4It43LuWcQw1s0VmNtfMXjSzjETHJA1LiUKkbs4E3gF+Bnw/9A0zewv4OjDFzG6uxzPGAjPr8flY2QiMdvcLgXzgygTHIw1MiUJizsxWm9nIRMdRW2bW38xWmtl+M7s7ynWZQAug2N13u3tB6Pvufpm7d3X3oe4+rR4hdXH3bfX4fEy4+5aQ7q8yoKKmnzWzX5rZI/GJTBqKEoV8KdjfXhKcA1D5ivo/efAzF4Wec/fT3H1OnOK7qPor6+ynwBx3b+PuD0W57oTgPw/U9gFm1s/MDpvZX6u5rhlwNMz5O81smZkdMbNptX1+fZhZb+BSoDYjsL4GfByfiKShKFFIVePc/YSQ152JDqgB9SRQd6hOm+A/a50ogEeBpaEnzCwt+Jv3L0NOjwDmh/n8FuA3wNQ6PLvOzKwt8Axwk7sfl8CiOA1YFZ+opKEoUUiNmNnPzKwo2C2zxszGmNlzQA9gerD18dPgtV/+5h/8+R4zW2VmB83sKTPrbGZvB+/1npmdGPKce80sL/jep2b2b8HzkZ7V1cxeMbOdZlZQTZfRqWY2x8z2BrvHvhHy3ixgFPBI8P4nR/nXUacWhZldD+wl/HDXRwnUJCoNcPdPql7k7q+6++vA7to8uwax/c7MXgs5ftDM3jezjGDr5kXg1+6+Jso90szsPjPbZGZbgn/evsAn1T2jjjG3MLN9ZlYe0gIuD7bY4tnybHrcXS+9cHeADcBFYc73BzYDXYPHvYA+kT4Tei7482KgM5AD7ABWAIMI9PPPAn4V8tlvAl0J/BJzHXAQOCncs4LXLAd+CTQHcgkUW8eG+TNkAOuB/wxeOxrYD/QPuWYO8L0a/Hs6H/DQz9bgM22BtUB34NfAX8Nc8zrQM/jz3dXc7zfAtBj+t29PIImdCdxOoLsoK/jeTcCu4L+fOcB1Ee7xa2ABgZZZVvDn/Jo8I+SaGcFrwr1mhHnmLcA7IcdrgRGJ/n8p1V6amS1VvW5mZSHH9wCzCXypf83Mdrr7hlre82F33w5gZvOBHe6+Mnj8GjCm8kJ3/0fI5/5mZvcB5wL/DHPfwUBHd/+f4HG+mU0Bruf40ULnEWgJ3O/uFcAsM5sB3EDgC6426tKi+F/gKXffHGXW9hvAlWb2PjXrAosZd99tZn8GniXwJT/M3YuD7z0HPBft82bWEfgJcIa7bwyee5PAf7tqnxFyzRW1DH0gwRqImbUG+hBswUjsqOtJqrrK3bNDXlPcfT3wIwJfqDvM7CUz61qLe24P+bkkzHHlFy9m9l0z+1ewe2gvMADoEOG+PYGuldcGr/9PAq2XqroCm4NJotJGAq2c2qpVjcLMziQww/pP1Vw6AxgHDAfm1SGu0GfOMTOP8PogwsdWEvjivc/dN9fykWOAz9w9L+RcZ44vZNfnGeF8mSiCP2919z0xuK+EUKKQGnH3F9x9GIEvZwceqHwrVs8ws57AFOBOoL27ZxP47bDyV/Cqz9oMFFRJbG3c/bIwt98CdDez0L/zPYCiOoRa2xbFSALddZvMbBuB37yvMbMVoRe5+w4C3WLtPbBmVJ25+0h3twivYVWvN7OBwOMECta31uGRHQh0K1beLwO4ipBCdk2eEaxdHYjwejvMR0ITxRlohFVcKFFItSwwv2C0mbUADhNoBZQH395OoDYQC60JJIOdwefeQqBFUanqs5YA+4KF9kwzSzezAWY2OMy9PyRQ7/hpsEA7ksBv7y/VIc4TgBJ3L6/2yoDJBLpEzgy+JgFvcmzxutJbBOosYZlZMzNrCaQD6WbWMlhsrjMzywGmE6gb/BAYaLWfB7MGGGZmJ5tZFoGE0IOvuoVq9Ax3v9SPHXUX+rq0StwdgI7Ap8FTpxCoUUiMKVFIVdOr/Bb3GoH6xP0ECprbgE4EunggsHzFL4JdPz+pz4Pd/VPgD8AiAklhIIGCaKVjnhX8oh5H4Mu3IBjfkwT6v6ve+yjwDQLzAHYBjwHfdffP6xDqCdSiPuHuh9x9W+Ur+NnD7r4zzOVPEahVRPILAon6XuDG4M+/qHHkVVhg2OtbwB/d/Q13P0RgifTf1uY+7v4ugaS7jMDw350EfqlYF6tnhHE6kOdfTQYsAr5lZkPqeV+pwtyTfql7kaQQ7LYy4L+B6929b5X3f0tg/sN2AknoUMNHKRJ7alGI1NxG4GYCQ3s/C33DArvZ9XH34QQWCqxLP79IUlKiEKm53xKoNwzm+CG1w4HKYuvbwHEFY5HGSolCpIbcfRLQBejh7survH0iUDknoBho15CxicSTJtyJ1EKEAjQE9o2oLKJnARrLLylDLQqR2PiAr4a7juXY0VoijVrStyiC0/IfI7Dk8hx3fz7BIYkcx90/NrONlUuUAN9NdEwisZKQ4bFmNhW4gsCaPwNCzl8C/IXAZKIn3f1+M7sJ2Ovu083sb+5+XYMHLCLShCWq62kacEnoCTNLJ7DU8qUENju5wcy+BnQjsFQDfDUbWEREGkhCEoW7z+P4Yt+5wHp3zw/Oon2JwN68hQSSBaimIiLS4JKpRpHDVy0HCCSIIcBDBDaTuZzAWjFhmdkEYAJA69atzz7llFPiGKqISOpZvnz5LnfvWPV8MiWKcIv0u7sfJLA5SVTuPpnAZCjOOeccX7ZsWYzDExFJbWa2Mdz5ZOrKKSSw+1elbgSWhq4xMxtnZpOLi4urv1hERGokmRLFUqCfmfU2s+YEdimLtormcdx9urtPyMo6bvFQERGpo4QkCjN7kcBS0v3NrNDMxrt7GYENa2YSWHDt7+5eq+0g1aIQEYm9lFxmXDUKEZHaM7Pl7n5O1fPJ1PVUb2pRiIjEXkolCtUoRERiL6UShYiIxF5KJQp1PYmIxF5KJQp1PYmIxF5KJQoREYk9JQoREYkqpRKFahQiIrGXUolCNQoRkdhLqUQhIiKxp0QhIiJRpVSiUI1CRCT2UipRVNYoNh2AC+6fxesrixIdkohIo5dSiSJU0d4S7nv1YyULEZF6StlEAVBSWs6DM9ckOgwRkUYtpRMFwJa9JYkOQUSkUUupRFFZzA4958B/vLSSddv3JygqEZHGLaUSRWUxu/K4ZUYao0/pyLufbufrf57HHS+s4PNt+xIZoohIo9Ms0QHES052JveM7c9Vg3LYc/AoUz8oYNrCDby5aitjT+vMXaP7MSBHM7hFRKrTpPbM3nvoKFMXbODpBQXsP1zGRad24q7R/Tije3bDBykikmQi7ZndpBJFpeKSUp5ZuIGnPiiguKSUkf07cveYfpzV48QGjFJEJLkoUYSx/3Apzy3eyJR5+XxxqJTh/Tpw95h+DO7VrgGiFBFJLkoUURw8UsbzH25k8rx8dh04ytDc9tw9ph/n5bbDzOIYqYhI8lCiqIGSo+W8sGQTk+bmsXP/Ec7t1Y67x/Tjgr7tlTBEJOU1iURhZuOAcX379r1t3bp1db7P4dJy/rZ0M4/PyWPbvsOc1SObu8f048KTOyphiEjKahKJolJdWxRVHSkr5x/LCnl8Th5Fe0s4o1sWd4/px+hTOilhiEjKUaKoh6NlFby6opBH56xn854STuvalrvH9OPiUzuTlqaEISKpQYkiBkrLK3h9ZRGPzl7Pht2HOKVLG+4e049LTuuihCEijZ4SRQyVlVcwfdUWHp61nvydB+nX6QTuGtOPyweeRLoShog0UkoUcVBe4bz58VYefn8d63YcILdja+4a3Zdxp3elWXpKLaMlIk2AEkUcVVQ4/7d6Gw+9v47Pt+2nZ/tW3DGqL/82KIcMJQwRaSSUKBpARYXz7mfbeXjWOj4p2kf3dpncMbIvV5/VjebNlDBEJLkpUTQgd2f2mh385b11fFRYTE52Jj8Y2YdvntONFs3SExaXiEg0jTZRmFku8HMgy92vrclnEp0oKrk789bt4i/vrWXFpr10aduS2y/M5fpze9AyQwlDRJJLpEQR1/4QM5tqZjvM7JMq5y8xszVmtt7M7o12D3fPd/fx8YwzXsyMC0/uyCs/OJ/nvzeEHu1a8evpnzL8d7N5cn4+JUfLEx2iiEi14tqiMLMRwAHgWXcfEDyXDqwFLgYKgaXADUA6MLHKLW519x3Bz73c2FoU4SzO381D769jYd5uOpzQnNuG53LjeT1p3SJl95ASkUYiUosirt9O7j7PzHpVOX0usN7d84OBvQRc6e4TgSviGU8yOC+3Pefltmfphj089P46Jr79OZPm5vG94bl8d2hP2rTMSHSIIiLHSMRQnBxgc8hxYfBcWGbW3swmAYPM7L4o100ws2Vmtmznzp2xizZOBvdqx3Pjh/DqD8/nzO7ZPDhzDcMemM1D76+juKQ00eGJiHwpEf0d4aYuR+z/cvfdwO3V3dTdJwOTIdD1VOfoGthZPU7k6VvOZVXhXh56fz1/fHctU+bnc8sFvbn1gl5kt2qe6BBFpIlLRIuiEOgectwN2BKLG5vZODObXFxcHIvbNajTu2Xz5L+fw4y7hnFBnw489P46hj0wmwdnfs6eg0cTHZ6INGFxHx4brFHMCClmNyNQzB4DFBEoZn/b3VfH6pnJXMyuqc+37ePhWet56+OtZGakc9PQntw2PJcOJ7RIdGgikqISMo/CzF4ERgIdgO3Ar9z9KTO7DPgzgZFOU939tzF6Xkw2Lkom67bv55HZ65n+0RaaN0vjxiE9mTAil05tWyY6NBFJMY12wl1dpEKLoqq8nQd4dPZ6/vmvLTRLM244twe3X9iHLllKGCISG0oUKWLDroM8Nmc9r64oIs2M6wZ35/aRfcjJzkx0aCLSyDWJRJGKXU+RbN5ziMfm5PHy8sBI42vP7s4PR/ahe7tWCY5MRBqrJpEoKqVyi6Kqor0lPDE3j5eWbKbcnasH5XDHqL706tA60aGJSCOjRJHithUf5ol5ebzw4SbKKpwrz+zKHaP60qfjCYkOTUQaiSaRKJpS11MkO/YfZsq8fJ5bvJGjZRWMO6Mrd47qS7/ObRIdmogkuSaRKCo1xRZFVbsOHOHJ+QU8u2gDJaXlXDbgJO4c3ZdTT2qb6NBEJEkpUTRRew4eZeoHBUxbuIEDR8oYe1pn7hrdjwE5WYkOTUSSTJNIFOp6iqz4UClTFxQwdUEB+w+XcdGpnbhrdD8Kdh3kwZlr2LK3hK7Zmdwztj9XDYq4RqOIpLAmkSgqqUUR2b7DpTyzYANPflBAcUkpaQYVIX8FMjPSmXj1QCULkSYoITvcSfJp2zKDu8b044OfjaJty2bHJAmAktJyHpy5JjHBiUhSUqJootq0zGD/4bKw7xXtLaG0vKKBIxKRZJVSiaIxLzOeCF2jLPsx/IHZPDE3j32HtYmSSFOXUonC3ae7+4SsLI3oqYl7xvYnMyP9mHOZGWlMGNGb3I6tmfj255w/cRa/mfEpRXtLEhSliCRaIna4kyRRWbCONOrpk6Jinpyfz9MLN/D0wg1cPvAkJozI1dBakSZGo56kWkV7S5i2oIAXl2zmwJEyhua2Z8KIXC48uSNpaeF2thWRxkjDY6Xe9h0u5W9LNjN1QQFbiw/Tt9MJ3Da8N1eemUPLKl1YItL4KFFIzJSWV/Dmqq1MnpfPp1v30eGEFtx8fk++M6QnJ7ZunujwRKSOmkSi0MzshuXuLMzbzZT5+cxZs5PMjHS+eU43xg/rTc/2WuZcpLFpEomikloUDW/Ntv08OT+f1/9VRFmFc8lpXbhtRC5n9Tgx0aGJSA0pUUiD2LHvMM8s2sBfF2+iuKSUc3qeyPeG53Lx1zqTrsK3SFJTopAGdfBIGf9YtpmnFhSweU8Jvdq3YvzwXK49qxuZzVX4FklGShSSEGXlFcxcvZ3J8/P5aPNeTmyVwU3n9eSmob3o2KZFosMTkRBKFJJQ7s6yjV8weV4+7322nYz0NK45K4fxw3Lp20nbtYokg0iJQjOzpUGYGYN7tWNwr3bk7TzAUx8U8MryQl5cspmLTu3E94bnMqR3O8xUxxBJNinVotDw2MZl94EjPLd4I88u2sieg0c5vVsWtw3P5dIBXWiWnlLLkIk0CnXqejKzNGCVuw+IZ3Cxpq6nxuVwaTmvrCjkyfkFFOw6SE52JuOH9eZbg7tzQgs1ekUaSp1rFGb2PHCfu2+KV3CxpkTROFVUOO9/voMp8/JZsmEPbVo24ztDenLz+b3oktUy0eGJpLz6JIpZwGBgCXCw8ry7fyPWQcaKEkXjt3LTFzw5v4C3P9lKeprxjTNyuG1Eb07p0jbRoYmkrPokigvDnXf3uTGKLeaUKFLH5j2HeOqDAv6+bDOHjpYzvF8HJozIZdf+I/z+nbVhl0cXkbqp1/BYM+tMoFUBsMTdd8Q4vphSokg9ew8d5fkPNzFt4QZ27j+CAaF/czMz0pl49UAlC5F6iJQoqh1aYmbfItDt9E3gW8CHZnZt7EMUiSy7VXPuGNWXD342iuxWGVT99aaktJwHZ65JSGwiqa4mQ0p+DgyubEWYWUfgPeDleAYmEk6LZukUHwq/j3fR3hK27ztM57YqfIvEUk0Gq6dV6WraXcPPicRF1+zMiO8Ne2AW9/zjI9Zt39+AEYmktpp84f+fmc00s5vN7GbgTeCt+IYlEtk9Y/uTWWVHvcyMdP7r8lP59rk9mL5qCxf/aR63TlvK4vzdpNKkUpFEqG7CnQHdCBSyhwEGzHP31xomvC/juAq4HOgEPOru70S7XsXs1Pf6yiIenLkm7KinLw4e5bnFG5m2cAN7Dh7ljO7ZfH9ELmNP66KlzkWiqM/w2OXufnY9HjwVuALYETrD28wuAf4CpANPuvv9NbjXicDv3X18tOuUKAQCM75fXl7IlPn5bNx9iJ7tW/G94bl88+xu2uNbJIz6JIpHgWnuvrSODx4BHACerUwUZpYOrAUuBgqBpcANBJLGxCq3uDWkkP4H4Hl3XxHtmUoUEqq8wnln9TYmzQssdd6udXO+O7Qn3x3ai3ba41vkS/VJFJ8CJwMbCczMNsDd/fRaPLwXMCMkUQwFfu3uY4PH9xG4adUkUfl5A+4H3nX396p7nhKFhOPuLCnYw+R5+bz/+Q5aZqTxrXO6871hufRo3yrR4YkkXJ2WGQ9+Qd9OIEnEUg6wOeS4EBgS5fq7gIuALDPr6+6Tql5gZhOACQA9evSIYaiSKsyMIbntGZLbnnXb9zN5Xj4vLtnEXxdv5NKBJ/H9Ebmc3i070WGKJJ241yiC9+jFsS2KbwJj3f17weObgHPd/a76PKeSWhRSU9v3HebpBRt4fvFG9h8p47zcdnx/RB9G9u+ovTGkyanzzGxgsZkNrv6yWikEuoccdwO21PemZjbOzCYXFxfX91bSRHRu25J7Lz2FhfeN5ueXncrG3Ye4ZdpSLvnzfF5eXsjRsopEhyiScImqUTQjUMweAxQRKGZ/291X1+HPcBy1KKSujpZVMGPVFp6Ym8+a7fvp0rYltw7rxQ3n9qBNy4xEhycSV/UpZvcMd97da1S3MLMXgZFAB2A78Ct3f8rMLgP+TGCk01R3/21N7lfNs7TDncSEuzN37U4mz8tnYd5u2rRoxreH9OCWC3rTJatl1HkcIo1VrROFmY1291nBn3u7e0HIe1e7+6txi7ae1KKQWPq4sJgn5uXx1seBvTEGdc/mo8JijoR0S2n1WkkFdUkUK9z9rKo/hztOFmpRSDxt2n2Ipz7I55lF4RvTOdmZLLh3dANHJRI7dSlmW4Sfwx0nBXef7u4TsrKyEh2KpKAe7Vvx31cOiPiXf8vekgaNR6ShREsUHuHncMciTUak1WvT04y/L92skVKScqIlilwze8PMpof8XHncu4HiqxUNj5WGEG712ox0o1ObFvz0lVUM/90spszL58CRsgRFKBJb0WoUYffKrqQ9s6UpCzfq6cozuzJv3S4mzcljUf5u2rZsxk1De3Lz+b3p2KZFokMWqVa99sxubJQoJNE+2ryXSXPz+L/V28hIT+ObZ3djwohcerZvnejQRCJSohBJgPydB5gyP59XlhdRVlHBZQNP4vYL+zAgRwMuJPk0iUSh4bGSrHbsO8xTCwp4YfEm9h8pY3i/Dtx+YR/O79Nea0pJ0qh3ojCz1u5+MOaRxYFaFJKs9h0u5fnFm5i6oICd+49wercsbr+wj3bfk6RQ50UBzez84HpPnwWPzzCzx+IQo0jKa9sygx+M7MP8n45i4tUD2VdSyg+fX8FFf5zLCx9u4nBpeaJDFDlOTdZ6+hC4FnjD3QcFz30Suq1pslGLQhqL8gpn5uptTJqbx6rCYjq2acEtF/TixvN6MuuzHVpPShpUfRYF/NDdh5jZypBE8ZG7nxGnWOtMNQpprNydRXm7eXxuHvPX7aJFulHuUFbx1f+fWk9K4q0++1FsNrPzATez5mb2E4LdUMlGS3hIY2VmnN+3A8+NH8KMu4aRlpZ2TJIAKCkt58GZaxIUoTRlNUkUtwN3ENi+tBA4E/hhHGMSadIG5GRFrFVoPSlJhJokiv7u/h137+zundz9RuDUeAcm0pRFWk/Kge9OXcLi/N2k0tB2SW41SRQP1/CciMRIuPWkWmakccXpXfh0SzHXT17MNY8v5N1Pt1NRoYQh8dUs0htmNhQ4H+hoZj8OeastgV3pkk5IMTvRoYjUS2XBOtyop8Ol5fxjeSFPzM3jtmeXcXLnE/jByD5ccXpXMtJr8rufSO1UtyjgSAI1ikkhb+0Hprt70g4r0vBYaQrKyiuYsWorj8/JY832/eRkZ/L9C3P51jndaZmRlL/LSZKr157ZNd0fO1koUUhTUlHhzF6zg8fm5LF84xe0b92cW4f15sbzepKVmZHo8KQRqU+imE2YjYrcPWn3fFSikKbI3Vm64Qsem7OeOWt2ckKLZnznvB6MH9abTm1ahl0aXXMyJFR9EsXZIYctgWuAMnf/aWxDjB0lCmnqVm8pZtLcfN5ctYVm6Wmc3TObFRv3ciRk9z1N4JOqYrp6rJnNdfeoGxslkhKFSMCGXQd5Yl4+Ly7ZFPb9nOxMFtybtJ0D0sDqsyhgu5BXBzMbC3SJS5QiElO9OrRm4tUDibQurSbwSU1EHB4bYjmBGoUBZUABMD6eQYlIbHXNzqQoTFLISE9j7tqdjOjXQftiSETVtijcvbe75wb/2c/dv+7uHzREcLVlZuPMbHJxcXGiQxFJKuEm8GWkGy0z0vj3qUsY98gHvP3xVk3ek7CizaO4OtoH3f3VuEQUA6pRiBwv3KinywaexGsrC5k0N5+CXQfJ7diaH1zYh6sG5WjyXhNU62K2mT0d5X7u7rfGKrhYU6IQqZ3yCuftT7by6Ow8Ptu6j5zsTG4b3pvrBvcgs7km7zUVTWLP7EpKFCJ14+7MWbOTR2evZ1nI5L2bhvakbUtN3kt19ZlHkQX8ChgRPDUX+B93T9pCgBKFSP0tKdjDo7PXM3ftTtq0aMZNQ3tyUnZLJs3J16S9FBUpUdRk1NNU4BPgW8Hjm4Cngag1DBFp3M7t3Y5ze5/LJ0XFPD4nj8fm5B3zftHeEu579WMAJYsUV5NqVR93/5W75wdf/w3kxjswEUkOA3KyePQ7Z9GpTYvj3tOue01DTRJFiZkNqzwwswsAzdIRaWJ27j8S9nzR3hI+3bKvgaORhlSTrqcfAM8EaxUG7AFujmdQIpJ8Ik3aM+Cyh+Yz+pRO3DGqL2f3PLHhg5O4qsmEu3+5+xnA6cBAdx/k7h/FP7QAMzvVzCaZ2ctm9oOGeq6IHCvcpL3MjHR++28D+PHFJ7Ni0xdc8/hCrp+8iA/W7dJWrSmkJms9/YeZtSWwYdEfzWyFmX29Jjc3s6lmtsPMPqly/hIzW2Nm683s3mj3cPfP3P12AsX046rxItIwrhqUw8SrB5KTnYkRWFBw4tUD+faQntw9ph8LfjaaX1x+Kvk7D3LjUx9y1WMLeWf1Ns32TgE1GR77kbufEVwM8A7gv4Cn3f2sam9uNgI4ADzr7gOC59KBtcDFQCGwFLiBwPaqE6vc4lZ332Fm3wDuBR5x9xeqe66Gx4okzuHScl5ZUcikuXls3lNC/85t+OGoPpSXV/CHd9dpaG0Sq888ilXufrqZ/QWY4+6vmdlKdx9Uwwf3AmaEJIqhwK/dfWzw+D4Ad6+aJMLd6013v7y665QoRBKvrLyCNz7awmNz8li/4wDGsTugaT+M5FPnZcaB5Wb2DnAZMNPM2gAV1Xwmmhxgc8hxYfBcWGY20sweMrMngLeiXDfBzJaZ2bKdO3fWIzwRiYVm6WlcfVY33vnRCNq1zjhum0wNrW08ajLqaTxwJpDv7ofMrD1wSz2eGW4t44jNGnefA8yp7qbuPhmYDIEWRR1jE5EYS0szvjhYGva9or0l7D9cShstD5LUajLqqQLoBfzSzP4AjHD3VfV4ZiHQPeS4G7ClHvf7kpYZF0lOXbMzI753wf2z+OO7a/ni4NEGjEhqoyajnh4Dbgc+JrCUx/fN7NF6PHMp0M/MeptZc+B64I163O9L7j7d3SdkZWXF4nYiEiORhtb++OJ+nJfbnofeX8cFD8xi4lufsWP/4QRFKZHUpOvpQmCAB6veZvYMgaRRLTN7ERgJdDCzQuBX7v6Umd0JzCQw0mmqu6+uS/BhnjcOGNe3b99Y3E5EYqSyYF11P4zK859v28djs/OYMj+faQs3cN3g7nz/wj4sLdgT8TPScGoy6ulV4P+5+8bgcU/gfne/oQHiqxONehJpnAp2HWTSnDxeWVFIeYWTlmaUh8zD0Eip+Kr1qCczm25mbwDtgc/MbI6ZzQY+AzrGL1QRaap6d2jNA9eeztyfjqJV8/RjkgRopFSiROt6+n2U95JyVJG6nkRSQ052JoeOlod9b0uY9aYkviK2KNx9brgXUAZc13Ah1pyK2SKpI9JIKQf+feoSlm3Y07ABNWE12j3dzM40s9+Z2QbgNwS6n0RE4ibcSKmWGWlcPrALHxcVc+2kRVw/eREL1msBwniL2PVkZicTGLp6A7Ab+BuB4veoBoqt1tT1JJI6oo2UOnS0jBeXbOaJuXl858kPGdQjm7tG96X4UCm/f2etRknFWMRRT2ZWAcwHxrv7+uC5fHdP+t3tNOpJpGk4XFrOy8sLeXxOHkV7S7SeVD3VZa2na4BtwGwzm2JmYwi//IaISEK0zEjnxvN6MueekWS30npS8RKtmP2au18HnEJgraX/B3Q2s8druh9FQ9MSHiJNU0Z6GsWHIq8ndbSsPuuYSk3Wejro7s+7+xUE1mX6F4G9IZKORj2JNF3R1pMa9fs5PLdoA4dLww+5lehqNOqpkrvvcfcn3H10vAISEamL8OtJpTFheG86tW3Bf/1zNSN+N5sn5+dz6GgZr68s4oL7Z9H73je54P5ZvL6yKEGRJ7+arPUkIpL0oo2ScncW5e3moVnr+M2bn/Gnd9dypKyCsuDM76K9Jdz36sfH3Ee+Uu1aT41JyPDY29atW5focEQkCS3dsIcbn/yQI2HqFjnZmSy4t+l2mNRnh7tGQzUKEanO4F7tIha3tTxIeCmVKEREaiJa4fu3b36qPTGqUKIQkSYnXOG7RbM0zu6ZzVMfFDD8gdn8+o3VbC0uUdEbFbNFpAmKVvjesOsgj81Zz18Xb+TZRRsw+2pPjKZa9E6pYnYlLeEhIvW1ec8hxv55XtjlzlO16N0kitmamS0isdK9XStKtCcGkGKJQqOeRCSWou2JccfzK/hs6z6AlK9jqEYhIhLBPWP7c9+rH1MSsvRHy4w0hvftwNy1O3nz460M6NqWdTsOfDkvIxXrGEoUIiIRRCt6Fx8q5emFBfzlvXURV61VohARaQKuGpQT9gs/q1UGP7roZP7yXvhVIFKpjqFEISJSD12zMykKkxQymqWxcP0uhvZpzz//tSVsq6SxUKIQEamHcHWMjHSjRbrx7Sc/pFf7VmzZe5ij5Y23hpFSo540PFZEGtpVg3KYePVAcrIzMQJzLB689gyW/uJi/vfK09i859CXSaJSY9t5TxPuRETiqPe9bx5X7IbAvtIF91/e0OFE1SQm3ImIJJtIczHS04wZq7ZQXuFJPw9DNQoRkTiKVMM4sVUGd76wkk5tPuWLQ0cpLU/e9aTUohARiaNINYxF913EwzcMYs/Br5JEpWSrYahFISISZ5HmYow7oyt3v7gy7GeSaR6GEoWISAJFmoeRZsYLH26iebrxp/fWJXQOhhKFiEgChathNE9Po0tWC/7ztY+PuTZR9QvVKEREEihcDeN3157O3HtG0b518+OuT0T9Qi0KEZEEi1TD2HPwaNjri/aWcOhoGe+s3t4gS4M0ikRhZq2BecCv3H1GouMREWkIkeoXAIN/8x5Hyiooa4BtWuPa9WRmU81sh5l9UuX8JWa2xszWm9m9NbjVz4C/xydKEZHkdM/Y/mRmpB9zLjMjnbvH9KWswr9MEpXi1S0V7xbFNOAR4NnKE2aWDjwKXAwUAkvN7A0gHZhY5fO3AqcDnwIt4xyriEhSibYfxsPvrw/7mS17S3h9ZVFMu6TimijcfZ6Z9apy+lxgvbvnA5jZS8CV7j4RuKLqPcxsFNAa+BpQYmZvuXtF1etERFJRpPpFpG4pB37yj49i2iWViFFPOcDmkOPC4Lmw3P3n7v4j4AVgSqQkYWYTzGyZmS3buXNnLOMVEUk64bqlWjRLIyPdYt4llYhEYWHOVbuErbtPi1bIdvfJ7n6Ou5/TsWPHegUoIpLswg2rfeCa0ykrD/91WtklVZfFBxMx6qkQ6B5y3A3YEosbm9k4YFzfvn1jcTsRkaQWrlvqwZlrYt4llYgWxVKgn5n1NrPmwPXAG7G4sbtPd/cJWVlZsbidiEijE48uqXgPj30RWAT0N7NCMxvv7mXAncBM4DPg7+6+OkbP0w53ItKk1adLqnmXvmeHu0Y73ImINAEX3D8r4uS99DSjvMLZ+syPOLJ13XF15JRa60ktChGR8CJ1STVPT6O8InqDIaUShWoUIiLhReqSKi2vflpao1jrSURE6q82o6RCpVSLQl1PIiK1E65LqqqUShTqehIRqZ3QLqlINOpJREQAMLPl7n5O1fMp1aIQEZHYS6lEoRqFiEjspVSiUI1CRCT2UipRiIhI7ClRiIhIVCmVKFSjEBGJvZRKFKpRiIjEXkolChERiT0lChERiUqJQkREokqpRKFitohI7KVUolAxW0Qk9lIqUYiISOwpUYiISFRKFCIiEpUShYiIRKVEISIiUSlRiIhIVCmVKDSPQkQk9lIqUWgehYhI7KVUohARkdhTohARkaiUKEREJColChERiUqJQkREolKiEBGRqJQoREQkqqRPFGY20szmm9kkMxuZ6HhERJqauCYKM5tqZjvM7JMq5y8xszVmtt7M7q3mNg4cAFoChfGKVUREwmsW5/tPAx4Bnq08YWbpwKPAxQS++Jea2RtAOjCxyudvBea7+1wz6wz8EfhOnGMWEZEQcU0U7j7PzHpVOX0usN7d8wHM7CXgSnefCFwR5XZfAC3iEqiIiEQU7xZFODnA5pDjQmBIpIvN7GpgLJBNoHUS6boJwITg4ZGq3V1SrSygMa6mmOi4G+L5sX5GLO5Xn3vU5bO1/UwHYFctnyHQL9zJRCQKC3POI13s7q8Cr1Z3U3efDEwGMLNl7n5OnSNsgsxssrtPqP7K5JLouBvi+bF+RizuV5971OWztf2MvgPqxswmhzufiFFPhUD3kONuwJYExCHHmp7oAOoo0XE3xPNj/YxY3K8+96jLZxP937mpCPvv2dwj/jIfE8EaxQx3HxA8bgasBcYARcBS4NvuvjqGz9RvEyJNmL4DYivew2NfBBYB/c2s0MzGu3sZcCcwE/gM+Hssk0RQ2OaTiDQZ+g6Iobi3KEREpHFL+pnZIiKSWEoUIiISlRKFiIhElfKJwsxam9kzZjbFzLT8h0gTZGa5ZvaUmb2c6Fgao0aZKGq52ODVwMvufhvwjQYPVkTiojbfA+6e7+7jExNp49coEwWBxQYvCT0RstjgpcDXgBvM7GsEJvRVLhlS3oAxikh8TaPm3wNSD40yUbj7PGBPldNfLjbo7keBl4ArCcwE7xa8plH+eUXkeLX8HpB6SKUvznCLDeYQWCfqGjN7HC0DIJLqwn4PmFl7M5sEDDKz+xITWuOViEUB4yXsYoPufhC4paGDEZGEiPQ9sBu4vaGDSRWp1KLQYoMiou+BOEilRLEU6Gdmvc2sOXA98EaCYxKRhqXvgTholIkigYsNikiS0PdAw9GigCIiElWjbFGIiEjDUaIQEZGolChERCQqJQoREYlKiUJERKJSohARkaiUKEQaiJkdSHQMInWhRCEiIlEpUYiISFRKFCIiEpUShYiIRKVEISIiUSlRiIhIVEoUIg2nVXA57MrXjxMdkEhNaJlxERGJSi0KERGJSolCRESiUqIQEZGolChERCQqJQoREYlKiUJERKJSohARkaiUKEREJKr/D5gi4KrZt4vjAAAAAElFTkSuQmCC\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "Slope of line from L = 8 to 11 is -2.848973886563485\n" ] } ], "source": [ "L = np.arange(1,40)\n", "errors = np.zeros(L.size)\n", "f = lambda x: 4.0*np.sqrt(1-x**2)\n", "integral = np.pi\n", "for l in L:\n", " GLintegral = generalGL(f,0,1,l)\n", " errors[l-1] = np.fabs(GLintegral-integral)\n", " print(\"L =\",l,\"Estimate is\",GLintegral,\"Exact value is\",integral)\n", "plt.loglog(L,errors,'o-')\n", "plt.xlabel(\"L\")\n", "plt.ylabel(\"Absolute Error\")\n", "plt.title(\"Estimate of $ \\int_0^1 4\\sqrt{1-x^2} \\, dx = \\pi$\")\n", "plt.axis([1,20,10**-5,10**0])\n", "plt.show()\n", "slope = (np.log(errors[-1]) - np.log(errors[0]))/(np.log(L[-1]) - np.log(L[0]) )\n", "print(\"Slope of line from L = 8 to 11 is\",slope)" ] }, { "cell_type": "markdown", "metadata": { "nbpages": { "level": 3, "link": "[2.5.2.11 A More Complicated Example](https://ndcbe.github.io/CBE60499/02.05-Numeric-Integration.html#2.5.2.11-A-More-Complicated-Example)", "section": "2.5.2.11 A More Complicated Example" } }, "source": [ "There is a big difference between exponential convergence we saw in the integral of the sine function and the polynomial convergence in this problem. Even at a high rate of convergence (order 2.8), the error converges slowly in that we are still only accurate to 3 digits at $L=13.$" ] }, { "cell_type": "markdown", "metadata": { "nbpages": { "level": 3, "link": "[2.5.2.12 Radau Quadrature](https://ndcbe.github.io/CBE60499/02.05-Numeric-Integration.html#2.5.2.12-Radau-Quadrature)", "section": "2.5.2.12 Radau Quadrature" } }, "source": [ "### 2.5.2.12 Radau Quadrature\n", "\n", "Sometimes we desire either:\n", "* The first node is at the beginning of the interval, i.e., $x_1 = -1$ or\n", "* The last node is at the end of the interval, i.e., $x_{L} = 1$.\n", "\n", "This is known as **Gauss-Radu quadrature**. The remaining nodes and weights are chosen optimally; thus, Radu quadrature *exactly* integrates *all* polynomials of degree $2L-2$ or less. Specifying one of the nodes leaves only $2L-1$ degrees of freedom.\n", "\n", "More info: http://mathworld.wolfram.com/RadauQuadrature.html\n" ] }, { "cell_type": "markdown", "metadata": { "nbpages": { "level": 3, "link": "[2.5.2.13 Differential Equations](https://ndcbe.github.io/CBE60499/02.05-Numeric-Integration.html#2.5.2.13-Differential-Equations)", "section": "2.5.2.13 Differential Equations" } }, "source": [ "### 2.5.2.13 Differential Equations\n", "\n", "Consider solving the differential equation\n", "\n", "$$\\dot{x} = f(t,x), \\quad x(t_0) = x_0,$$\n", "\n", "to determine $x(t_f)$. This can be expressed as an integral:\n", "\n", "$$x(t_f) = \\int_{t_0}^{t_f} \\frac{dx}{dt} dt + x_0 = \\underbrace{\\int_{t_0}^{t_f} f(t, x(t)) dt}_{\\text{use quadrature rule}} + x_0$$\n", "\n", "Thus, Runge-Kutta methods can be interpreted as a quadrature rule." ] }, { "cell_type": "markdown", "id": "4f557d8f", "metadata": {}, "source": [ "\n", "< [2.4 Dynamic Optimization: Differential Algebraic Equations (DAEs)](https://ndcbe.github.io/CBE60499/02.04-DAE-modeling.html) | [Contents](toc.html) | [Tag Index](tag_index.html) | [2.6 Dynamic Optimization with Pyomo.DAE](https://ndcbe.github.io/CBE60499/02.06-Pyomo-DAE.html) >

\"Open

\"Download\"" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.6" } }, "nbformat": 4, "nbformat_minor": 2 }