{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "d54b4116-d2ec-4cbf-b914-68a322028a25",
   "metadata": {},
   "source": [
    "# Module Sympy et développement limité de fonctions"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "308b01b9",
   "metadata": {},
   "source": [
    "> <font size='3'>**En fin de séance, rendre le fichier source Jupiter Notebook *(.ipynb)* de votre TP obtenu <span style=\"color:red\">après les 3 heures</span> de travail.**<br><br>\n",
    "**Rendre précisément <span style=\"color:red\">une semaines après</span> la séance de TP le fichier source final comportant les reponses aux questions et les calculs demandés.**<br><br>\n",
    "Le but de cette séance est d'utiliser les developpements limités des fonctions qui permettent d'exprimer une fonction quelconque avec des polynômes, qui ont l'avantage de se calculer facilement. <br><br>\n",
    "Vous allez comparer les focntions et leurs developpements limités graphiquement, ainsi que approcher des fonctions et des valeurs à l'aide de DLs.<br><br>\n",
    "\n",
    "<font size='3'>**Ces travaux, contenant vos codes, vos réponses aux questions, seront utilisés pour évaluer les compétences suivantes**</font>\n",
    "- Identifier un modèle mathématique lors de la mise en équation d'une expérience scientifique.\n",
    "- Effectuer un calcul élémentaire à l'aide d'un logiciel de calcul symbolique ou numérique.\n",
    "- Interpréter les résultats obtenus afin de répondre à une problématique.\n",
    "- Utiliser les outils de communication courants.\n",
    "- Structurer/rédiger/présenter selon une méthodologie adaptée.\n",
    "    \n",
    "**Cette évaluation comptera pour 20 % de votre note finale dans ce cours.**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a0dfc63e",
   "metadata": {},
   "outputs": [],
   "source": [
    "# En python, on commence toujours par importer les bibliothèques nécessaires\n",
    "\n",
    "import matplotlib.pyplot as plt \n",
    "import numpy as np\n",
    "from math import *"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4b7b7ab1",
   "metadata": {},
   "source": [
    "## Exercice 1. Le module généraliste SymPy \n",
    "<span style=\"color:red\">**Outre les codes, vous avez une réponse à la question 1 à rédiger !**</span>\n",
    "\n",
    "Module **SymPy** permet de faire du calcul symbolique, ce qu'on appelle parfois aussi du calcul formel, **SymPy** est en réalité un module mathématique assez généraliste\n",
    "Commençons bien sûr par :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ef1d0870",
   "metadata": {},
   "outputs": [],
   "source": [
    "import sympy as sp"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b30a1081",
   "metadata": {},
   "outputs": [],
   "source": [
    "sp.sqrt(2)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c68533b5",
   "metadata": {},
   "source": [
    "Commençons par introduire à **SymPy** un \"symbole\", une \"variable formelle\" (sinon le reste ne marchera pas!)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1c74eef8",
   "metadata": {},
   "outputs": [],
   "source": [
    "x = sp.Symbol(\"x\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "df692747",
   "metadata": {},
   "source": [
    "**SymPy** sait dériver et intégrer :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "92ca07a3",
   "metadata": {},
   "outputs": [],
   "source": [
    "sp.diff(sp.sin(x), x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "51a9e2cd",
   "metadata": {},
   "outputs": [],
   "source": [
    "sp.integrate(1/x, x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "064efc60",
   "metadata": {},
   "outputs": [],
   "source": [
    "sp.integrate(1/x, (x,1,2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7691ff66",
   "metadata": {},
   "outputs": [],
   "source": [
    "sp.integrate(x**x, x)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4399c06a",
   "metadata": {},
   "source": [
    "Cette dernière réponse, tout à fait correcte, signifie que **SymPy** ne voit pas comment simplifier l'expression."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "493b7ed2",
   "metadata": {},
   "source": [
    "1. **Calculer les dérivées, la primitive et l'integrale à la main**\n",
    "\n",
    "    1. $(x^2\\sqrt{x})''$ \n",
    "\n",
    "    1. $(e^{\\cos(x^2)})'$\n",
    "    \n",
    "    1. $\\displaystyle\\int \\left(x+\\frac{1}{\\sqrt{x}}\\right)^2 dx \\quad\\quad\\textit{Indication. } (a+b)^2 = \\ldots$\n",
    "    \n",
    "    1. $\\displaystyle\\int_{-1}^{1} \\sqrt{1-x^2} dx \\quad\\quad\\textit{Indication. Vu en CM, changement de variable? }$\n",
    "\n",
    "et verifier à l'aide de **SymPy**.\n",
    "\n",
    "**Question 1.** Présenter vos calculs (en latex) avant chaque appel de **SymPy** (rajouter des cellules)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5a320146",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "90c3e2b0",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "14247320",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "610d07b9",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "9ec4b94c",
   "metadata": {},
   "source": [
    "**Remarque 1.** À l'aide de l'instruction \n",
    "```python\n",
    "expr.subs(x, 5)\n",
    "```\n",
    "on peut calculer la valeur de l'expression ```expr``` pour $x=5$. Par exemple,"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "bb66ffed",
   "metadata": {},
   "outputs": [],
   "source": [
    "val = sp.diff(x**2*sp.sqrt(x), x)\n",
    "val.subs(x,2)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "91614dcf",
   "metadata": {},
   "source": [
    "**Remarque 2.** L'instruction **sp.lamdify()** traduit les expressions **SymPy** en fonctions Python. **lambdify()** agit comme une fonction lambda, sauf qu'elle convertit les noms **SymPy** en noms de la bibliothèque numérique, généralement NumPy. Très pratique pour tracer les expressions !!! \n",
    "\n",
    "Par exemple,"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a3bab171",
   "metadata": {},
   "outputs": [],
   "source": [
    "x = sp.Symbol(\"x\")\n",
    "expr = sp.sin(x)\n",
    "f = sp.lambdify(x, expr) \n",
    "y = np.linspace(0,2*pi,50)\n",
    "        \n",
    "plt.plot(y,f(y))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2f3f7aae",
   "metadata": {},
   "source": [
    "## Exercice 2. Développements limités \n",
    "\n",
    "<span style=\"color:red\">**Outre les codes, vous avez trois reponses aux Question 2,3,4 à rediger !**</span>\n",
    "\n",
    "Pour demander à **SymPy** afficher le développement limité de $\\tan(x)$ on utilise les instructions suivants\n",
    "\n",
    "```python\n",
    "expr = sp.tan(x)\n",
    "expr.series(x, 0, 6)\n",
    "```\n",
    "\n",
    "1. On va utiliser les développements limités de l'exponentielle, de sinus et de cosinus dans l'exercice suivant. Demander à Sympy d'afficher ces formules."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9498d0e9",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7a6f3f6c",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c532691e",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "28adbf17",
   "metadata": {},
   "source": [
    "**Question 2.** Rappeler la formule générale de Taylor pour une fonction arbitraire $f$ au vosinage d'un point $x_0$."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "125612fb",
   "metadata": {},
   "source": [
    "> Votre reponse ici."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "eaf1dda3",
   "metadata": {},
   "source": [
    "2. Ecrire une fonction **approx_taylor(expr, x, x0, n, a, b)** qui prend une expression expr, un symbole x, un nombre x0, un entier n, et deux nombres a et b, et qui va : \n",
    "\n",
    "* calculer et afficher le polynôme $\\Pi$ qui represente les n premiers termes non-nuls du DL de **expr** (qui est une expression qui dépend de x et des dérivées de expr) en x0 \n",
    "\n",
    "* tracer le graphe de $\\Pi$ sur l'intervalle [a,b], à l'aide de matplotlib.\n",
    "\n",
    "(*Attention.* Pour etre efficace, il ne faut pas recalculer n! à chaque étape) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b604917f",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "92abd115",
   "metadata": {},
   "source": [
    "3. Utilisez votre fonction **approx_taylor(expr, x, x0, n, a, b)** pour l'exponentielle, le sinus et le cosinus et comparer l'affcihage de DL avec vos resultats de la question 1, ainsi que les graphes de polynômes et les fonctions elles-mêmes. Fixer $x_0$ et l'intervalle $[a,b]$ de façon pertinante et faire varier la valeur de $n$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5eeeb7e8",
   "metadata": {},
   "outputs": [],
   "source": [
    "x = sp.Symbol(\"x\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0c85bd63",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9921a776",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "9545c2af",
   "metadata": {},
   "source": [
    "**Question 3**. Commenter les resultats obtenus."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "64fef554",
   "metadata": {},
   "source": [
    "> Votre reponse ici."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9fa94438",
   "metadata": {},
   "source": [
    "3. Modifier votre fonction **approx_taylor(expr, x, x0, n, a, b)** pour afficher le graphique de $f: f(x)=e^x$ ainsi que les polynômes $\\Pi$ de DL sur le même graphique pour $n = 1, 2, 4, 8, 16, 32, 64$ en point $0$ sur l'intervalles $[-4,4]$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "99898153",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "e207d674",
   "metadata": {},
   "source": [
    "**Question 4**. Commenter les resultats obtenus."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c6369d96",
   "metadata": {},
   "source": [
    "> Votre reponse ici."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fc6e5ac6",
   "metadata": {},
   "source": [
    "4. On pose \n",
    "$$f(x)=\\frac{1}{1+x}, \\quad g(x)=e^{-x}, \\quad h(x)=\\sqrt{1 - 2 \\sin x}$$\n",
    "Préciser les positions relatives au voisinage de 0 des graphes des fonctions. Verifier graphiquement à l'aide de Python. \n",
    "\n",
    "*Indication.* Faire un développement limité en 0 à un ordre suffisant pour qu'on puisse distinguer les fonctions."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e63972ed",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d50b406b",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "46e1af91",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c84704ff",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "9f3e735c",
   "metadata": {},
   "source": [
    "## Exercice 3. Estimation de reste et approximation.\n",
    "\n",
    "\n",
    "Nous avons compris que les développements limités, permettent d'approcher **localement** (au voisinage d'un point) une fonction par une fonction plus simple. Nous avons utilisé un développement limité avec le théorème des petits angles, quand nous avons approximé $\\cos \\theta$ par $1$ quand $\\theta$ est petit dans le CM 1.\n",
    "\n",
    "Dans l'exercice precedent nous avons consideré le DL de la focntion sinus, au voisinage de $0$ on peut l'ecrire ainsi\n",
    "\n",
    "$$\n",
    "sin(x) \\approx x-\\frac{x^3}{3!}+\\frac{x^5}{5!} + \\ldots + (-1)^n\\frac{x^{2n+1}}{(2n+1)!} +\\mathcal{o}\\left(x^{2n+2}\\right)\n",
    "$$\n",
    "\n",
    "Dans cette formule, le dernier terme (le petit o) est négligeable quand x tend vers 0. On l'appelle *le reste* du développement, $n$ est l'ordre du développement. \n",
    "\n",
    "Le théorème des petits angles que nous avons utilisé, et qui a son importance egalement dans les application en optique, utilise un développement à l'ordre 0.\n",
    "\n",
    "On vous demande d'écrire un programme qui demande à l'utilisateur un angle compris entre $-\\pi$ et $\\pi$, une précision, et qui calcule le sinus en utilisant la formule du développement limité. Ensuite il affiche le sinus de l'angle calculé et le sinus calculé avec la formule, ainsi que l'ordre nécessaire pour atteindre la précision souhaitée. \n",
    "\n",
    "Par exemple pour l'angle $\\pi/2$ pour obtenir une précision de $0.001$, nous devrions utiliser l'ordre du développement égale à $4$. Verifier avec votre programme.\n",
    "\n",
    "Dans cette exercice on vous invite d'utiliser les bibliotheque de Python numériques **math** et **NumPy** (on les a déjà importé), on va plus se servir de la biblithèque **SymPy**. \n",
    "\n",
    "\n",
    "*Indication.* Pour ce nouveau programme il suffit d'écrire une boucle qui calcule le nouveau terme (ordre n) qui s'arrete dès que le terme d'ordre n est plus petit que la précision. Attention: pour etre efficace, il ne faut pas recalculer (2n+1)! à chaque étape mais utiliser le fait que $(2n+1)!=(2n+1)\\times2n\\times(2n-1)!$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "24ea6d58",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "eba2b421",
   "metadata": {},
   "source": [
    "Faites un test de votre programme pour constater que plus l'angle est proche de $\\pi$, plus il faut un ordre élevé pour atteindre la précision."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e2da766a",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "bb1639cd",
   "metadata": {},
   "source": [
    "## Exercice 4. Calcul de $\\pi$\n",
    "\n",
    "Le développement limité de arcsin est\n",
    "\n",
    "$$\n",
    "\\arcsin (x)=\\sum_{n=0}^{N-1} \\frac{(2 n) !}{\\left(n ! 2^n\\right)^2} \\frac{x^{2 n+1}}{2 n+1}+o\\left(x^{2 N+1}\\right)\n",
    "$$\n",
    "\n",
    "On peut vérifier que le développement limité est convergeant sur $(−1, 1)$. En déduire une formule permettant de calculer $\\pi$. Etudier la dépendance de la precision de l'ordre de DL."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9ca7cd1f",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
