{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# L3 Analyse Numérique – TP1\n",
    "\n",
    "[Dequay A](mailto:antoine.dequay@ens-rennes.fr) &\n",
    "[Le Barbenchon P](mailto:pierre.le-barbenchon@ens-rennes.fr). TP ENS Rennes\n",
    "\n",
    "[Boutin B](mailto:benjamin.boutin@univ-rennes1.fr). Cours et TP Université de Rennes 1 - UFR Mathématiques  \n",
    "\n",
    "Python est un langage informatique qui a la particularité d'avoir des commandes relativement simples et énormément de bibliothèques qui permettent une programmation plus fluide. C'est un langage très utilisé à la fois dans des entreprises (Google, NASA,...) et dans la conception de logiciels libres (Blender, LibreOffice,...).\n",
    "\n",
    "Un code Python est executé par un noyau Python installé sur la machine. Ceci peut être fait au choix:\n",
    "\n",
    " - directement dans un terminal: taper `python ExampleInterpolation.py`\n",
    " - dans un environnement de développement (IDE) tel que Pyzo, Spider, etc.\n",
    " - ou encore par l'utilisation d'un **notebook**."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Utilisation du notebook\n",
    "\n",
    "Le Notebook Jupyter est un environnement interactif pour écrire et executer du code. Il y est possible de manipuler de nombreux langages mais nous travaillerons ici exclusivement avec le noyau Python. Le notebook est divisé en *cellules* qui peuvent contenir de façon exclusive:\n",
    "\n",
    " - soit du *texte* au [format Markdown](https://www.markdownguide.org/cheat-sheet/) comprenant d'éventuelles formules mathématiques au [format $\\LaTeX$](http://tug.ctan.org/info/undergradmath/undergradmath.pdf),\n",
    " - soit du *code* Python executable.\n",
    " \n",
    "Une cellule active se reconnaît à son encadrement et sa marge colorée. Elle peut être soit\n",
    "\n",
    "  - en mode *édition* (sa marge est verte)\n",
    "  - en mode *commande* (sa marge est bleue)\n",
    "  \n",
    "Pour une cellule active, les actions suivantes sont possibles:\n",
    "\n",
    "  - `Esc` ou un clic dans la marge bascule en mode commande\n",
    "  - `Enter` ou un clic dans la cellule bascule en mode édition\n",
    "  - `Shift+Enter` ou un clic sur le bouton <i class=\"icon-step-forward fa fa-play\"></i> execute le code (Python) ou met en forme le texte (Markdown)\n",
    "  \n",
    "On peut naviguer dans le notebook à la souris ou, en mode commande utiliser les raccourcis clavier suivants:\n",
    "\n",
    "  - Navigation simple: `Enter`, `Shift+Enter`, `Up`, `Down`\n",
    "  - Sauvegarder le Notebook: `s`\n",
    "  - Passer une cellule en format Mardown `m` ou en format Code `y`\n",
    "  - Créer une cellule: `a`(above), `b`(below)\n",
    "\n",
    "De nombreux autres raccourcis sont disponibles avec le bouton <i class=\"fa-keyboard-o fa\"></i>, la touche `TAB` permet en outre d'accéder durant la frappe de code à des fonctionnalités de complétion."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Quelques premières manipulations"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "1) Executer cette cellule de texte et la cellule de code suivante."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from math import *"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "1) Créer ci-après une cellule de code contenant le code suivant puis l'executer.\n",
    "```python\n",
    "lastname = input(\"Saisir votre Nom: \")\n",
    "firstname = input(\"Saisir votre Prénom: \")\n",
    "P = 1050**2+1728**2\n",
    "print(\"\\nBonne année \"+str(int(sqrt(P)))+' '+firstname+' '+lastname+' !')\n",
    "```\n",
    "> L'utilisation du copier/coller est toujours la bienvenue !"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "2) Dupliquer le code précédent dans une nouvelle cellule ci-après et y ajouter la première ligne suivante, puis l'executer\n",
    "```python\n",
    "%%writefile mycode.py\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "3) Éditer la cellule de texte de cette question de sorte à y reporter vos observations quant à la question précédente.\n",
    "\n",
    "> **Commentaire:**  \n",
    "> Que s'est-il passé ?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "3) Créer une cellule de code contenant la ligne suivante et l'executer.\n",
    "```python\n",
    "%load ExampleInterpolation.py\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Si l'image est jugée trop petite, on peut spécifier la `figsize` par\n",
    "```python\n",
    "plt.figure(figsize=(12,8))\n",
    "```\n",
    "De façon générale, on peut toujours utiliser la documentation des librairies afin de connaître les usages et fonctionnalités des commandes. Celles-ci sont accessibles directement depuis le menu d'Aide: `Matplotlib Reference` par exemple."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "5) Améliorer la figure précédente et y ajouter le tracé des points d'interpolation successifs par la ligne supplémentaire suivante, qui sera placée au bon endroit dans une recopie du code ci-dessous.\n",
    "```python\n",
    "plt.plot(X,val,'o')\n",
    "```\n",
    "Faire un export du tracer dans vos fichiers par la commande\n",
    "```python\n",
    "plt.savefig(\"FigureInterpolation.png\")\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": false
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Prise en main des objets `array`\n",
    "\n",
    "Cette partie vise à comprendre les syntaxes les plus standards pour la manipulations des `array` (type `ndarray`) de la bibliothèque `numpy`. Il faut avoir la fiche Mémo sous la main et prendre quelques notes pour vous."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from math import *\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Définition de vecteurs et matrices\n",
    "\n",
    "Dans la cellule de code suivante, manipuler les lignes suivantes afin d'en saisir l'usage.\n",
    "```python\n",
    "x = np.array([1, 2, 3])\n",
    "y = np.array([[4],[5],[6]])\n",
    "Y = np.array([4,5,6]).T\n",
    "YY = np.array([[4,5,6]]).T\n",
    "z = np.matrix([[1j, 2+1j],[4, pi]])\n",
    "zt = z.H\n",
    "Z = np.array([[1j, 2+1j],[4, pi]])\n",
    "ZT = Z.conj().T\n",
    "t = np.arange(1, 5)\n",
    "u = np.linspace(1, 5, 5)\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = np.array([1, 2, 3])\n",
    "y = np.array([[4],[5],[6]])\n",
    "Y = np.array([4,5,6]).T\n",
    "YY = np.array([[4,5,6]]).T\n",
    "z = np.matrix([[1j, 2+1j],[4, pi]])\n",
    "zt = z.T\n",
    "Z = np.array([[1j, 2+1j],[4, pi]])\n",
    "ZH = Z.conj().T\n",
    "t = np.arange(0, 4)\n",
    "u = np.linspace(1, 5, 5)\n",
    "print(x)\n",
    "x"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Poursuivre avec les constructions suivantes...\n",
    "\n",
    "#### Matrices particulières\n",
    "\n",
    "```python\n",
    "id = np.eye(5, 5)\n",
    "zz = np.zeros((5, 3))\n",
    "zzz = np.zeros_like(y)\n",
    "un = np.ones((6, 2))\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Extraction de coefficients\n",
    "\n",
    "```python\n",
    "x[1]\n",
    "z[0, 1]\n",
    "x[1:3]\n",
    "z[0:1, 0:2]\n",
    "u[t]\n",
    "z[t[0:2], x[0]]\n",
    "z[t[0:2]-1, x[0]]\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(x[1])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "####  Opérations d'algèbre linéaire\n",
    "```python\n",
    "z**2\n",
    "z * np.eye(2)\n",
    "z.T\n",
    "x + y.T\n",
    "z * y[0:2]\n",
    "Z * y[0:2]\n",
    "np.dot(Z,y[0:2])\n",
    "np.linalg.solve(z, y[0:2])\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(z**2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Opérations coefficient par coefficient\n",
    "```python\n",
    "Z**2\n",
    "Z * np.eye(2)\n",
    "x**2\n",
    "x / y.T\n",
    "1 / x\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(Z**2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Attention !!!**  \n",
    "On a utilisé parfois l'objet `np.matrix` qui se distingue de l'objet `np.array`. Dans tous les TP, on utilisera préférentiellement l'objet `np.array` afin de bien distinguer le produit terme à terme `A*B` et le produit matriciel `A.dot(B)` (que l'on peut utiliser pour `B` une matrice ou `B` un vecteur).  \n",
    "On pourra examiner la [documentation](https://numpy.org/doc/stable/reference/generated/numpy.matrix.html?highlight=numpy%20matrix#numpy.matrix) qui recommande d'oublier l'objet numpy.matrix."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Exercice 1. Définition de matrices"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "a) Avec deux boucles, définir la matrice $P$ de taille $5\\times 5$ dont les coefficients sont\n",
    "$$P_{i,j} = \\cos \\dfrac{i\\pi}{5} + \\sin \\dfrac{j\\pi}{7},\\quad 0\\leq i,j\\leq 4.$$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "b) En mettant à profit sa structure très particulière de somme de deux matrices de rang $1$, redéfinir la matrice $P$ sans utiliser de boucles.  \n",
    "*Astuce: on examinera à profit l'identité suivante*\n",
    "$$ \\begin{pmatrix} 1 & 1 \\\\ 2 & 2\\end{pmatrix} = \n",
    "\\begin{pmatrix} 1 \\\\ 2\\end{pmatrix} \\begin{pmatrix} 1 & 1\\end{pmatrix}.$$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "c) À l’aide de la commande `np.diag`, construire de façon \"rapide\" la matrice $L$ de taille $10\\times 10$ suivante:\n",
    "$$L =\n",
    "\\begin{pmatrix}\n",
    "2 & -1 & 0 & \\ldots & 0\\\\\n",
    "-1 & 2 & -1 & \\ddots & \\vdots\\\\ \\\\\n",
    "0 & \\ddots & \\ddots & \\ddots & 0 \\\\\n",
    "\\vdots & \\ddots  & -1 & 2 & -1\\\\\n",
    "0 & \\ldots & 0 & -1 & 2\\\\\n",
    "\\end{pmatrix}.$$\n",
    "*Astuce: on pourra, comme souvent, utiliser la documentation !*"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Exercice 2. Précision machine"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Soit $(u_n)_{n\\in\\mathbb{N}}$ la suite de terme général $u_n = 1+2^{-n}$."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "a) Calculer numériquement les valeurs $(u_n)_{0\\leq n \\leq 60}$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "b) À partir de ces valeurs qui auront été stockées, obtenir numériquement pour $0\\leq n \\leq 60$, celles de la suite \n",
    "$$v_n=u_n-1.$$\n",
    "Qu'observez-vous ?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "c) Sur une figure, tracer les points de coordonnées $(n,w_n)$, toujours pour $0\\leq n \\leq 60$ où on a posé\n",
    "$$w_n = -\\log_2(u_n-1+2^{-100}).$$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "d) Comment interpréter vos observations ?\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> **Commentaire:**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Exercice 3. Quotient de Rayleigh d'une matrice hermitienne"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "a. Programmer la fonction `Rayleigh(A,x)` qui prend en argument une matrice $A\\in\\mathcal{H}_n(\\mathbb{C})$ hermitienne et un vecteur non-nul $x\\in\\mathbb{C}^n$, et renvoie le réel $R_A(x)=\\langle Ax,x\\rangle / \\langle x,x\\rangle$ où $\\langle\\cdot,\\cdot\\rangle$ est le produit scalaire hermitien canonique (utiliser pour cela `np.vdot`)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def Rayleigh(A, x):\n",
    "    "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "b. On considère les matrices\n",
    "$$A=\\begin{pmatrix}2 & 1 \\\\ 1 & -3\\end{pmatrix},\\quad B=\\begin{pmatrix}2 & i \\\\ -i & -3\\end{pmatrix}.$$\n",
    "Avec la commande `np.linalg.eig`, déterminer les valeurs propres et vecteurs propres de $A$ et $B$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "c. Pour tout $\\theta\\in\\mathbb{R}$, on pose $x(\\theta)=(\\cos \\theta,\\sin \\theta)^T\\in\\mathbb{R}^2$.  \n",
    "Tracer la courbe de la quantité $R_A(x(\\theta))$ en fonction de $\\theta\\in[0,2\\pi]$.  \n",
    "Comparer aux valeurs propres de $A$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "d. Pour tout $\\theta\\in\\mathbb{R}$, et tout $\\phi\\in\\mathbb{R}$, on pose $z(\\theta,\\phi)=(\\cos(\\theta)\\mathrm{e}^{i\\phi},\\sin(\\theta))$.  \n",
    "Considérant successivement différentes valeurs de $\\phi\\in[0,2\\pi]$, tracer la courbe de la quantité $R_A(z(\\theta,\\phi))$ en fonction de $\\theta\\in[0,2\\pi]$.  \n",
    "Comparer aux valeurs propres de $B$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Exercice 4. Interpolation polynomiale (s'il reste du temps)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "a) Examiner les programmes proposés dans la fiche mémo pour le problème d'interpolation polynomiale.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "b) Programmer une version de ce même problème d'interpolation utilisant la représentation du polynôme recherché dans la base canonique de $\\mathbb{R}_n[X]$ et de ce fait, l'inversion d'un système linéaire de Vandermonde $V x = y$ faisant intervenir la matrice\n",
    "$$V_{i,j}=x_i^j,\\quad 0\\leq i\\leq n,\\quad 0\\leq j\\leq n.$$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "c) Comparer vos résultats à ceux obtenus par la forme de Newton (utilisée dans la fiche mémo)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "d) Procéder de même avec la base de Lagrange."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**FIN DU SUJET**"
   ]
  }
 ],
 "metadata": {
  "celltoolbar": "Aucun(e)",
  "kernelspec": {
   "display_name": "Python 3.6.5 64-bit",
   "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.2 (v3.9.2:1a79785e3e, Feb 19 2021, 09:09:00) \n[Clang 12.0.0 (clang-1200.0.32.29)]"
  },
  "vscode": {
   "interpreter": {
    "hash": "aee8b7b246df8f9039afb4144a1f6fd8d2ca17a180786b69acc140d282b71a49"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
