diff --git a/5 Derive Numerique.ipynb b/5 Derive Numerique.ipynb new file mode 100644 index 0000000..e4d24bd --- /dev/null +++ b/5 Derive Numerique.ipynb @@ -0,0 +1,305 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 2 Dérivée numérique" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Soit $f:[a,b]\\rightarrow \\mathbf R$, de classe $C^1$ et $x_0\\in[a,b]$.\n", + "La dérivée $f'(x_o)$ est donnée par\n", + "\n", + "$$\\begin{array}{lcl}\n", + "f'(x_0)&=&\\displaystyle\\lim_{h\\rightarrow 0^+}\\frac{f(x_0+h)-f(x_0)}{h},\\\\[2mm]\n", + "&=&\\displaystyle\\lim_{h\\rightarrow 0^+}\\frac{f(x_0)-f(x_0-h)}{h},\\\\[2mm]\n", + "&=&\\displaystyle\\lim_{h\\rightarrow 0}\\frac{f(x_0+h)-f(x_0-h)}{2h}.\n", + "\\end{array}$$\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "Soient $x_0\\in[a,b]$, $(Dy)$ une approximation de $f'(x_0)$\n", + "et $(D^2y)$ une approximation de $f\"(x_0)$.\n", + "\n", + "On appelle\n", + "\n", + "* **différence finie progressive** l'approximation\n", + " $$(Dy)^{P} = \\frac{f(x_0+h) - f(x_0)}{h}$$\n", + "\n", + "* **différence finie rétrograde** l'approximation\n", + " $$(Dy)^{R} = \\frac{f(x_0) - f(x_0-h)}{h}$$\n", + "\n", + "* **différence finie centrée** l'approximation\n", + " $$(Dy)^{C} = \\frac{f(x_0+\\frac12h) - f(x_0-\\frac12h)}{h}$$\n", + "\n", + "* **différence finie centrée d'ordre 2** l'approximation\n", + " $$(D^2y)^{C} = \\frac{f(x_0+h) - 2f(x_0) + f(x_0-h)}{h^2}$$\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# importing libraries used in this book\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Les différences finies progressive, rétrograde et centrée approchent la dérivée de la fonction en le point $x_0$." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Define a function and a point x0\n", + "f = lambda x : 0.25*(x-4)**3 - 4*(x-4)**2 +6\n", + "x0 = 5 \n", + "\n", + "# Choosing finite difference size\n", + "h = 4\n", + "\n", + "\n", + "# Defininig first order finite differences\n", + "DP = ( f(x0 + h) - f(x0) ) / h\n", + "DR = ( f(x0) - f(x0-h) ) / h\n", + "DC = ( f(x0 + h/2) - f(x0-h/2) ) / h\n", + "\n", + "# defining the straight lines with slope equal to the FDs\n", + "dfp = lambda x : f(x0) + DP*(x-x0)\n", + "dfr = lambda x : f(x0) + DR*(x-x0)\n", + "dfc = lambda x : f(x0-h/2) + DC*(x-x0+h/2)\n", + "\n", + "# Drowing points\n", + "z = np.linspace(-5, 22, 100)\n", + "\n", + "plt.plot(z, dfp(z), 'g:', z, dfr(z), 'b:', z, dfc(z), 'r:' )\n", + "plt.plot(z, f(z), 'k', x0,f(x0),'ro')\n", + "\n", + "plt.xlabel('x'); plt.ylabel('$f(x)$');\n", + "plt.legend(['$D^P$', '$D^R$', '$D^C$', '$f$'])\n", + "plt.show()\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "La différence finie d'ordre 2 approche la dérivée deuxième de la fonction en le point $x_0$. \n", + "\n", + "Pour le voir graphiquement, on peut dessiner une fonction quadratique qui a la forme\n", + "\n", + "$$ p_2(x) = f(x_0) + (Dy)^{C}\\, (x-x_0) + \\frac12 (D^2y)\\, (x-x_0)^2$$" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Define a function and a point x0\n", + "f = lambda x : 0.25*(x-4)**3 - 4*(x-4)**2 +6\n", + "x0 = 5 \n", + "\n", + "# Choosing finite difference size\n", + "h = 4\n", + "\n", + "\n", + "# Defininig first order centered finite differences\n", + "DC = ( f(x0 + h/2) - f(x0-h/2) ) / h\n", + "\n", + "# Defininig second order centered finite differences\n", + "D2 = ( f(x0 + h) - 2* f(x0) + f(x0-h) ) / (h**2)\n", + "\n", + "\n", + "# defining the parabola going through (x_0, y_0)\n", + "parabola = lambda x : f(x0) + DC*(x-x0) + 0.5 * D2 * (x-x0)**2\n", + "\n", + "# Drowing points\n", + "z = np.linspace(-5, 22, 100)\n", + "\n", + "plt.plot(z, parabola(z), 'g:' )\n", + "plt.plot(z, f(z), 'k', x0,f(x0),'ro')\n", + "\n", + "plt.xlabel('x'); plt.ylabel('$f(x)$');\n", + "plt.legend(['parabola', '$f$'])\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Exercice\n", + "\n", + "Il s'agit de vérifier numériquement que\n", + "\n", + "$$\\left\\vert f'(x_0)- (Dy)^{P} \\right\\vert=O(h^1).$$\n", + "\n", + "On pose $x_0=1$, $f(x)=\\sin(x)$ $\\forall x\\in\\mathbb R$\n", + "\n", + "Calculez l'erreur commise en utilisant la différence finie progressive.\n", + "\n", + "Quelle est la valeur de l'erreur pour h=0.1?\n", + "\n", + "Ensuite verifiez numériquement l'ordre pour $(Dy)^{R}$ et $(Dy)^{C}$." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def DPerror(f,df, x0,h) :\n", + " # formule de differences finies \n", + " DP = ( f(x0 + h) - f(x0) ) / h\n", + " err = abs(DP-df(x0));\n", + " return err\n", + "\n", + "# code :\n", + "# def DRerror(f,df, x0,h) :\n", + " # formule de differences finies \n", + "\n", + "# def DCerror(f,df, x0,h) :\n", + " # formule de differences finies \n", + "\n", + "\n", + "# This function just provides a line to compare the convergence in a log-log plot.\n", + "from FiniteDifferenceLib import sampleConvergence\n", + "# sampleConvergence(h,order,ref) :\n", + "# computes a pseudo order of convergence on h\n", + "# ref is a reference maximum value \n", + "\n", + "\n", + "x0 = 0.2\n", + "\n", + "h = 2**np.linspace(-10,-1,10)\n", + "plt.plot(h, DPerror(np.sin, np.cos, x0, h) , 'o' )\n", + "#plt.plot(h, DRerror(np.sin, np.cos, x0, h) , '*' )\n", + "#plt.plot(h, DCerror(np.sin, np.cos, x0, h) , '*' )\n", + "\n", + "\n", + "plt.plot(h, sampleConvergence(h, 1, 1e-1) , ':',\n", + " h, sampleConvergence(h, 2, 1e-1) , ':')\n", + "\n", + "plt.xlabel('h'); plt.ylabel('BDF2 error');\n", + "#plt.legend(['DP error','DR error', 'DC error', '$O(h^1)$', '$O(h^2)$'])\n", + "plt.xscale('log') \n", + "plt.yscale('log')\n", + "plt.show()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Exercice\n", + "\n", + "Il s'agit de vérifier numériquement que\n", + "\n", + "$$\\left\\vert f\"(x_0)- (D^2y) \\right\\vert=O(h^2).$$\n", + "\n", + "On pose $x_0=1$, $f(x)=\\sin(x)$ $\\forall x\\in\\mathbb R$\n", + "\n", + "Calculez l'erreur commise par ce schéma.\n", + "\n", + "Que vaut l'erreur pour h=0.1?\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Code\n", + "# def D2error(f,df, x0,h) :\n", + " # formule de differences finies BDF2\n", + "\n", + "x0 = 0.2\n", + "\n", + "df = lambda x : -np.sin(x)\n", + "\n", + "h = 2**np.linspace(-10,-1,10)\n", + "#plt.plot(h, D2error(np.sin, df, x0, h) , 'o' )\n", + "plt.plot(h, sampleConvergence(h, 1, 1e-2) , ':',\n", + " h, sampleConvergence(h, 2, 1e-2) , ':')\n", + "\n", + "plt.xlabel('h'); plt.ylabel('D2 error');\n", + "#plt.legend(['D2 error', '$O(h^1)$', '$O(h^2)$'])\n", + "plt.xscale('log') \n", + "plt.yscale('log')\n", + "plt.show()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Exercice\n", + "\n", + "Il s'agit de vérifier numériquement que\n", + "\n", + "$$\\left\\vert f'(x_0)-\\dfrac{3f(x_0)-4f(x_0-h)+f(x_0-2h)}{2h}\\right\\vert=O(h^2).$$\n", + "\n", + "Cette formule de différences finies est à l'origine du schéma \"BDF2'' pour résoudre numériquement des équations différentielles (Chapitre 9 du livre).\n", + "\n", + "On pose $x_0=1$, $f(x)=\\sin(x)$ $\\forall x\\in\\mathbb R$\n", + "\n", + "Calculez l'erreur commise par ce schéma.\n", + "\n", + "Que vaut l'erreur pour h=0.1?

" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.7" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/FiniteDifferenceLib.py b/FiniteDifferenceLib.py new file mode 100644 index 0000000..db4550a --- /dev/null +++ b/FiniteDifferenceLib.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on Thu Jan 30 + +@author: Simone Deparis +""" + +import numpy as np + +# This function just provides a line to compare the convergence in a log-log plot. +def sampleConvergence(h,order,ref) : + # computes a pseudo order of convergence on h + # ref is a reference maximum value + return h**order * (ref/np.max(np.abs(h))**order) + + + + +