{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"*ENSAM-Bordeaux, Mathématiques et informatique. Date : le 09/11/19. Auteur : Éric Ducasse. Version : 1.0*"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
*On pourra faire exécuter ce notebook cellule par cellule $\\left(\\mathtt{Maj+Entrée}\\right)$ ou intégralement par $\\mathtt{\\;Kernel\\rightarrow Restart\\;\\&\\;Run\\;All}$.*
"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"%matplotlib inline\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"import sympy as sb\n",
"sb.init_printing()\n",
"print(\"Version de sympy :\",sb.__version__) \n",
"from IPython.display import display"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# **Calcul formel : TD n°3, première partie
**Pour chaque exercice, faire exécuter la partie *exemples* cellule par cellule $\\left(\\mathtt{Maj+Entrée}\\right)$, avant de passer à la partie *Travail à faire*.**
"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## *Exercice 14* "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 14.1 Objectifs "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### * Savoir déterminer l’approximation par différences finies d’une dérivée d’ordre quelconque à un ordre quelconque et sur une grille quelconque de points, par l'utilisation de la méthode $\\mathtt{as\\underline{\\phantom{m}}finite\\underline{\\phantom{m}}difference}$ ; connaître également la méthode de recherche des coefficients de cette approximation par écriture de développements limités, puis construction et résolution d’un système linéaire.*"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 14.2 Exemples "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
**Principe de la méthode : lorsqu'on veut approcher la dérivée $n$-ème d'une fonction $f$ en $x$ à l'ordre $r$, il faut évaluer cette fonction sur une grille de $(n+r)$ points. En chaque point, on approche la valeur de la fonction $f$ en ce point comme un développement limité de $f$ en $x$ à l'ordre $n+r$.**
"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**On crée d'abord une fonction $\\mathtt{approx\\underline{\\phantom{m}}DL}$ qui renvoie l'équation approchée ainsi que la liste des inconnues :**"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"fonc_test = sb.Function(\"f0\")\n",
"fonc_test.__name__"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"try : print(f\"fonc_test.name : '{fonc_test.name}'\")\n",
"except Exception as e : \n",
" print(f\"'fonc_test.name' non accepté par la version {sb.__version__} de sympy : {e}\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def approx_DL(ordre_DL, fonction=\"f\", variable=\"x\", ecart=\"h\", valeur_dans_grille=True) :\n",
" \"\"\"Cette fonction renvoie une équation approchée de fonction(variable+ecart) \n",
" en fonction des valeurs de fonction(variable) et de ses dérivées jusqu'à\n",
" l'ordre ordre_DL-1, ainsi que le liste de ces dérivées. \n",
" Si valeur_dans_grille est False (cas inhabituel), la liste contient aussi \n",
" fonction(variable).\n",
" \"\"\"\n",
" if not isinstance(fonction,sb.function.UndefinedFunction) : \n",
" fonction = sb.Function(fonction) # fonction est une chaîne de caractères\n",
" if not isinstance(variable,sb.Symbol) : \n",
" variable = sb.symbols(variable) # variable est une chaîne de caractères\n",
" if not isinstance(ecart,sb.Symbol) : \n",
" ecart = sb.symbols(ecart) # ecart est une chaîne de caractères\n",
" DL = fonction(variable+ecart).series(ecart,0,ordre_DL).doit()\n",
" if valeur_dans_grille : inconnues = []\n",
" else : inconnues = [ fonction(variable) ]\n",
" regles = dict()\n",
" if ordre_DL <= 4 :\n",
" for d in range(1,ordre_DL) :\n",
" ddf = sb.Function(fonction.__name__+d*\"'\")\n",
" inconnues.append( ddf(variable) )\n",
" regles[ fonction(variable).diff(variable,d)] = ddf(variable)\n",
" else :\n",
" for d in range(1,4) :\n",
" ddf = sb.Function(fonction.__name__+d*\"'\")\n",
" inconnues.append( ddf(variable) )\n",
" regles[ fonction(variable).diff(variable,d)] = ddf(variable)\n",
" for d in range(4,ordre_DL) :\n",
" ddf = sb.Function(fonction.__name__+f\"^[{d}]\")\n",
" inconnues.append( ddf(variable) )\n",
" regles[ fonction(variable).diff(variable,d)] = ddf(variable)\n",
" \n",
" eq_approchee = sb.Eq( fonction(variable+ecart), DL.xreplace(regles).replace(sb.O,lambda *X : 0) )\n",
" return eq_approchee, inconnues"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"approx_DL(4)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"approx_DL(4, valeur_dans_grille=False)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"approx_DL(6,\"g\",\"t\",\"tau\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
**Exemple de la dérivée première $f^{\\prime}(x)$ à l'ordre 2, en fonction de $f(x)$, $f(x+h)$ et $f(x+k)$ :**
"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"* **Utilisation de la méthode $\\mathtt{as\\underline{\\phantom{m}}finite\\underline{\\phantom{m}}difference}$ : **"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x,h,k = sb.symbols(\"x,h,k\", real=True)\n",
"f = sb.Function(\"f\")\n",
"d1f_ordre2 = f(x).diff(x).as_finite_difference([x,x+h,x+k])\n",
"d1f_ordre2"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def simplifier_termes_somme(S) :\n",
" \"\"\"Simplifie chaque terme de la somme S.\"\"\"\n",
" if S.func.__name__ == 'Add' :\n",
" liste = [ T.simplify() for T in S.args ]\n",
" return sb.Add(*liste)\n",
" else :\n",
" return S"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"simplifier_termes_somme(d1f_ordre2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"* **Recherche de ce développement « à la main » : **"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"eq_h, inconnues = approx_DL(3,f,x,h)\n",
"inconnues"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(\"Développement limité en x+h :\")\n",
"eq_h"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"eq_k = eq_h.xreplace({h:k})\n",
"print(\"Développement limité en x+k :\")\n",
"eq_k"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"solu = sb.solve([eq_h,eq_k], inconnues)\n",
"print(\"La résolution du système de deux équations à deux inconnues donne :\")\n",
"solu"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"d1f_ordre2_trouve = solu[inconnues[0]].expand().collect([f(x),f(x+h),f(x+k)])\n",
"simplifier_termes_somme(d1f_ordre2_trouve)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(\"Vérification :\",d1f_ordre2.equals(d1f_ordre2_trouve))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
**Exemple de la dérivée seconde $f^{\\prime\\prime}(x)$ à l'ordre 2, en fonction de $f(x-h)$, $f(x)$, $f(x+h)$ et $f(x+2\\,h)$ :**
"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"*Si on veut la dérivée seconde à l'ordre 2, il faut prendre $2+2=4$ points.*"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"d2f_ordre2 = f(x).diff(x,2).as_finite_difference( [x-h,x,x+h,x+2*h] )\n",
"d2f_ordre2"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"*Le coefficient de $f(x+2\\,h)$ étant nul, cette approximation est bien « centrée ».*"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"*On peut vérifier le résultat obtenu :*"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"d2f_ordre2.series(h,0,2).doit()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 14.3 Travail à faire "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"$a)$ Approcher $f^{\\prime}(x)$ par différences finies d'ordre 2 en fonction des valeurs de la fonction $f$ en : $\\hspace{2cm}\\displaystyle\\left\\|\\begin{array}{lllll}\n",
"(i) & x-h & x & x+h & \\mathrm{(schéma\\;centré)\\;;} \\\\\n",
"(ii) & x & x+h & x+2\\,h & \\mathrm{(schéma\\;décentré\\;avec\\;les\\;points\\;à\\;droite)\\;;} \\\\\n",
"(iii) & x-2\\,h & x-h & x & \\mathrm{(schéma\\;décentré\\;avec\\;les\\;points\\;à\\;gauche).}\n",
"\\end{array}\\right.$"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"*Il faut bien prendre $3=1+2$ points pour avoir une approximation à l'ordre 2.*"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"b) Donner toutes les approximations possibles à l'ordre 4 de $f^{\\prime}(x)$ et $f^{\\prime\\prime}(x)$ en fonction de valeurs de la fonction $f$ en des points régulièrement espacés (pas $h$) et contenant $x$. Parmi ces approximations, quelles sont celles qui sont centrées ?"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.5"
}
},
"nbformat": 4,
"nbformat_minor": 2
}