{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# L3 E - S5 2018-19 --- TD ordinateurs --- séance 5"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "#  Calcul matriciel\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from pylab import *"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "Voici des exemples de matrices (et de vecteurs, un vecteur colonne étant une matrice à une seule colonne et un vecteur ligne étant une matrice à une seule ligne) :\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "v= array([4,7,9])                  ### a est un vecteur ligne\n",
    "print('v=',v,'\\n')\n",
    "w=array([[2],[-5],[1],[9]])              ### w est un vecteur colonne\n",
    "print(\"w=\",w,'\\n')\n",
    "m = array([[1, 2, 3], [4, 5, 6]])             ### m est une matrice (2,3)\n",
    "print (\"m=\",m,'\\n')\n",
    "M = array([[1, 2, 3,4,5], [6,7,8,9,10],[11,12,13,14,15]])      ### M est une matrice (3,5)\n",
    "print (\"M=\",M,'\\n')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Quelques fonctions élémentaires :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "print (size(v),shape(v))\n",
    "print (size(w),shape(w))\n",
    "print (size(m),shape(m))\n",
    "print (size(M),shape(M))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Addition et multiplication(s)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "On peut bien entendu additionner des matrices de même ${\\rm \\texttt{type}}$ (ou ${\\rm \\texttt{shape}}$) :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "A = array([[-1, 0, 3.5], [1, 1, -4]])\n",
    "m+A\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Par contre, l'addition : "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "m+M"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "n'est bien entendu pas possible. De la même façon que l'addition matricielle se fait terme à termes entre matrices de même taille, $\\texttt{python}$ accepte une multiplication terme à terme :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "print('m=',m,'\\n')\n",
    "print('A=',A,'\\n')\n",
    "print('m*A=',m*A)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "La multiplication matricielle usuelle se note avec la fonction ${\\rm \\texttt{dot}}$ :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "dot(m,M)   ## m est de type (2,3) et M de type (3,5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "print(M)\n",
    "print('\\n')           ### Pour une présentation plus aérée, on saute une ligne \n",
    "N=M.T                 ### N est la transposée de M\n",
    "print(N)\n",
    "print('\\n')\n",
    "print ('MN=\\n',dot(M,N),'\\n')\n",
    "print ('NM=\\n',dot(N,M))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Sélections d'éléments "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "c = array([[1, 2, 3,4,5], [6,7,8,9,10],[11,12,13,14,15]])\n",
    "print('c=\\n',c)\n",
    "\n",
    "\n",
    "print('\\n\\n')      ## je saute 2 lignes pour rendre l'affichage plus clair\n",
    "\n",
    "print (c[1])       ## j'affiche la ligne d'indice 1 (pour python)\n",
    "print (type (c[1]))\n",
    "print (shape(c[1]))\n",
    "\n",
    "\n",
    "####### ATTENTION !!!! Les indexations avec python commencent toujours en 0 avec python\n",
    "####### Donc c[1] est en fait, pour nous, L2, la deuxième ligne\n",
    "####### Si on veut L1, la 1ère ligne de la matrice, il faut demander d'imprimer c[0]\n",
    "\n",
    "print ('\\n') \n",
    "print ('la ligne L1 de la matrice M est ',c[0])\n",
    "print ('\\n')    \n",
    "print (c[2],'\\n')\n",
    "\n",
    "print (c[0,0])           ### RAPPEL : le premier indice est toujours 0\n",
    "print (c[2,4])\n",
    " \n",
    "print (c[:1],'\\n')       ### affichage de la 1ère  ligne de la matrice \n",
    "print (c[:2])            ### affichage des 2 premières lignes\n",
    "print ('\\n')  \n",
    "\n",
    "print (c[2:])            ### On enlève les 2 premières lignes\n",
    "print ('\\n')  \n",
    "print (c[1:2])           ### On enlève la première et la dernière lignes\n",
    "print('\\n')\n",
    "\n",
    "print (len(c[1]))        ### nombre d'éléments dans une ligne\n",
    "\n",
    "print ('\\n')  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "Et pour afficher les colonnes :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print('c=\\n',c,'\\n')\n",
    "print (c[:,:1],'\\n')      ### affichage de la 1ère colonne\n",
    "print (c[:,2:])           ### on enlève les 2 premières colonnes\n",
    "print ('\\n')  \n",
    "print (c[:,4:])           ### on enlève les 4 premières colonnes\n",
    "print ('\\n')  \n",
    "\n",
    "print (c[:,2:4],'\\n')           ### on garde les colonnes : \n",
    "                                ### à partir de l'indice 2 et avant l'indice 4\n",
    "\n",
    "print (c[:,0:1])        ### on enlève des colonnes : avant 0 et à partir de 1\n",
    "                        ### il ne reste donc que la colonne 0 !!\n",
    "print ('\\n')  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "## Des matrices particulières"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "print (zeros(4),'\\n')\n",
    "\n",
    "print (zeros((3,5)) ,'\\n')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "print (ones (3))  ## comme zeros... en remplaçant 0 par 1...\n",
    "print ('\\n')  \n",
    "print (ones((2,5)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### et la matrice de l'application identité :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "print(eye(3),'\\n')\n",
    "eye(5)  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Fonctions basiques (et diagonalisation)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "A=array([[-7,1,9],[-12,3,12],[-6,1,8]])\n",
    "\n",
    "print ('A=\\n',A, '\\n')\n",
    "\n",
    "##### Calcul de l'inverse (il faut que la matrice soit inersible !!!)\n",
    "\n",
    "print ('l\\'inverse de A est :\\n',inv(A), '\\n')  \n",
    "\n",
    "### calcul du déterminant\n",
    "\n",
    "print ('det(A)=',det(A))  \n",
    "\n",
    "##### Diagonalisation de A\n",
    "\n",
    "D,P=eig(A)  \n",
    "print ('D=',D,'\\n')     ### les valeurs propres\n",
    "Diag=zeros((3,3))\n",
    "for i in range(3):      ### on écrit la matrice diagonale associée à X\n",
    "    Diag[i,i]=D[i]\n",
    "print ('La matrice diagonale est\\n',Diag,'\\n')\n",
    "  \n",
    "print ('La matrice de changement de base est P=\\n',P,'\\n') #### les vecteurs propres\n",
    "\n",
    "\n",
    "##### Formule de changement de base\n",
    "\n",
    "B=dot(dot(P,Diag),inv(P))  ### B=P.Diag.inv(P)\n",
    "print (B)                  ### on vérifie que B=A...\n",
    "print(A-B)                 ### cependant...\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "Bien entendu, le calcul précédent a fonctionné parce qu'on avait pris une matrice diagonalisable..."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Exercice 1\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Cherchez par vous-même (i.e. avec une feuille et un stylo) les vecteurs propres de la matrice\n",
    "\n",
    "$$A=\\left(\\begin{array}{ccc}\n",
    "-7&1&9\\\\ -12 & 3 &12 \\\\ -6 & 1 & 8 \\end{array}\\right)$$ \n",
    "\n",
    "et comparez avec les vecteurs propres trouvés par python."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "## Résolution  d'un système linéaire\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "Python est équipé pour résoudre les systèmes linéares :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "M = array([[2,1,1],[1,1,1], [1,2,1]])\n",
    "X = array([1,2,3])\n",
    "Y = solve(M, X)\n",
    "print (Y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "MM = array([[2,1,1],[1,1,1], [5,2,2]])\n",
    "X = array([1,2,3])\n",
    "Y = solve(MM, X)\n",
    "print (Y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "MM = array([[2,1,1],[1,1,1], [5,2,2]])\n",
    "X = array([2,-1,7])\n",
    "Y = solve(MM, X)\n",
    "print (Y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "#  Exercice 2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "Dans les derniers exemples, on demande à python d'étudier les systèmes :\n",
    "\n",
    "$$\\left\\{\\begin{array}{l} 2x+y+z=1\\\\ x+y+z=2 \\\\ 5x+2y+2z=3\\end{array}\\right.$$\n",
    "\n",
    "puis \n",
    "\n",
    "$$\\left\\{\\begin{array}{l} 2x+y+z=2\\\\ x+y+z=-1 \\\\ 5x+2y+2z=7\\end{array}\\right.$$\n",
    "\n",
    "Dans les deux cas, il renvoie que ce n'est pas possible. Etes-vous d'accord avec lui ?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "# Exercice 3"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    " ${\\rm Notations :}$ Si $M=(m_{ij})_{1\\leq i \\leq n, \\: 1\\leq j \\leq p}$ est une matrice\n",
    "à $n$ lignes et $p$ colonnes, on notera $L_i$ (pour $1\\leq i \\leq n$)\n",
    "la i-ème ligne de $M$ et $C_j$ (pour $1\\leq j \\leq p$), la $j$-ème\n",
    "colonne de $M$ (Evidemment, s'il ya un risque de confusion,\n",
    "on pourra préciser $L_i(M)$ ou $C_j(M)$\n",
    "pour préciser qu'il s'agit bien des lignes et colonnes\n",
    "de la matrice $M$. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Ecrire une fonction ${\\rm \\texttt{multiplie(M,i,a)}}$\n",
    "qui renvoie la matrice $M$ avec la ligne $L_i$\n",
    "multipliée par le nombre $a$."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Exercice 4"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "1- Si M est une matrice, l'instruction ${\\rm \\texttt{M[2]}}$\n",
    " va donner la ligne $L_3$ de $M$ (si cette ligne existe...). \n",
    "Et, de façon générale, \n",
    "l'instruction ${\\rm \\texttt{M[i]}}$ va donner la ligne $L_{i+1}$\n",
    "de $M$ (si cette ligne existe...). Pouvez-vous expliquer pourquoi ?\n",
    "\n",
    "\n",
    " 2- Ecrire une fonction ${\\rm \\texttt{echange(M,i,j)}}$ qui échange les lignes\n",
    "$L_i$ et $L_j$ de la matrice $M$.\n",
    "\n",
    "\n",
    " 3-  En déduire une instruction qui  retourne la colonne $i$\n",
    "d'une matrice et une fonction  qui échange les colonnes\n",
    "$C_i$ et $C_j$ d'une matrice.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Exercice 5"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Pour $i$ et $j$ fixés et distincts, $E_{ij}=(e_{ij})$  est la matrice dont l'entrée $e_{ij}$ vaut 1 et toutes les autres entrées sont nulles. Pour tout nombre réel $a$ et pour $ 1\\leq i,j\\leq n$, la matrice carrée d'ordre $n$ égale à \n",
    " ${\\rm I}_n+aE_{ij}$ est appelée matrice de transvection~;\n",
    " par exemple~:\n",
    " $$I_4-3E_{42} \\: = \\: \n",
    " \\left(\n",
    " \\begin{array}{cccc}\n",
    " 1&0&0&0\\\\\n",
    " 0&1&0&0\\\\\n",
    " 0&0&1&0\\\\\n",
    " 0&-3&0&1\n",
    " \\end{array}\n",
    " \\right)\n",
    " $$\n",
    " \n",
    " 1- Si $M$ est une matrice carrée d'ordre $n$,\n",
    "quel  est le résultat du produit $(I_n+aE_{ij}).M$\n",
    "(avec $i\\neq j$ et $1\\leq i,j\\leq4$) ?\n",
    "\n",
    " 2-  Ecrire une fonction ${\\rm \\texttt{tranvection(M,i,j,a)}}$ qui \n",
    "renvoie la matrice $(I_n+aE_{ij}).M$ si $M$ est une matrice carrée d'ordre $n$\n",
    "(et $i\\neq j$, $1\\leq i,j\\leq n$ et $a \\in \\mathbf R$).\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Exercice 6 : la méthode du pivot de Gauss"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Transformations élémentaires "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "$\\bullet$  $T_1 : L_i \\to L_i + \\alpha L_j$\n",
    "(avec \\[i\\neq j\\] : ajouter à une ligne un multiple d'une \\underline{autre} ligne), \n",
    "\n",
    "$\\bullet$ $T_2 : L_i \\to \\alpha L_i,~\\alpha \\neq 0$\n",
    "(multiplier une ligne par un scalaire non nul), \n",
    "\n",
    "$\\bullet$ $T_3 : L_i \\leftrightarrow L_j$ (échanger deux lignes).\n",
    "\n",
    "\n",
    "\n",
    "Si $M$ est inversible, \n",
    "ces transformations élémentaires permettent de passer de $M$ à $I_n$ :\n",
    "\n",
    "$$\\left(\\begin{array}{ccc}*&*&*\\\\ *&*&*\\\\*&*&*\\end{array}\\right)\n",
    "~\\stackrel{T_1}{\\longrightarrow}~\n",
    "\\left(\\begin{array}{ccc}*&*&*\\\\ 0&*&*\\\\0&*&*\\end{array}\\right)~\n",
    "~\\stackrel{T_1}{\\longrightarrow}~\n",
    "\\left(\\begin{array}{ccc}*&*&*\\\\ 0&*&*\\\\0&0&*\\end{array}\\right)~\n",
    "~\\stackrel{T_1}{\\longrightarrow}~\n",
    "\\left(\\begin{array}{ccc}*&*&0\\\\ 0&*&0\\\\0&0&*\\end{array}\\right)~\n",
    "~\\stackrel{T_1}{\\longrightarrow}~\n",
    "\\left(\\begin{array}{ccc}*&0&0\\\\ 0&*&0\\\\0&0&*\\end{array}\\right)~\n",
    "~\\stackrel{T_2}{\\longrightarrow}~\n",
    "\\left(\\begin{array}{ccc}1&0&0\\\\ 0&1&0\\\\0&0&1\\end{array}\\right)\n",
    "$$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Remarques sur ces transformations"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "1- Cette méthode n'aboutit que si la matrice $M$ de départ est inversible...\n",
    "\n",
    "2-  La transformation $T_1$ nécessite d'avoir un $\\texttt{pivot}$ (l'élément diagonal\n",
    " sur lequel on s'appuie)  non nul ; lorsqu'il est nul, on utilise la \n",
    "transformation $T_3$ pour faire apparaître un pivot non nul. \n",
    "\n",
    "3- Le schéma ci-dessus est théorique : dans la pratique, il y aura souvent \n",
    "intérêt à utiliser $T_2$ pour se ramener à des matrices d'entiers ou à effectuer \n",
    "directement des manipulations du type \"remplacer $L_i$ par $\\alpha L_i + \\beta L_j$\".\n",
    "\n",
    "\n",
    "\n",
    "On note que les transformations $T_i$ sont inversibles et que si \n",
    "\n",
    "$$I_n =T_kT_{k-1}\\ldots T_2T_1 M$$\n",
    "\n",
    "cela signifie que\n",
    "\n",
    "$$M^{-1} =T_kT_{k-1}\\ldots T_2T_1 I_n$$\n",
    "\n",
    "\n",
    " Avec $B=\\left(\\begin{array}{ccc}1&-1&2\\\\ 2&0&4\\\\1&1&3\\end{array}\\right)$,\n",
    " on trouve \n",
    "$B^{-1}=\\left(\\begin{array}{ccc}-2&5/2&-2\\\\ -1&1/2&0\\\\1&-1&1\\end{array}\\right)$.\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "- Cela permet aussi de résoudre des systèmes ; par exemple,\n",
    " $BX=(7,10,4)$ a pour solution $X=(3,-2,1)$.\n",
    "\n",
    "- Cette méthode permet aussi de calculer le déterminant \n",
    "(en faisant attention aux cas où on a multiplié une ligne par un scalaire) ; par exemple, ici on voit que ${\\rm det}\\: B=2$.\n",
    "\n",
    "- Cette méthode s'applique également de la même façon en agissant sur les colonnes. \n",
    "Par contre, il ne faudra pas  l'appliquer en mélangeant les 2 méthodes (par les lignes et par les colonnes)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Enoncé de l'exercice"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    " 1- Ecrire une fonction ${\\rm \\texttt{gauss(M)}}$  qui par suites de transformations\n",
    "élémentaires transforme la matrice carrée $M$ en la matrice de l'identité.\n",
    "\n",
    "\n",
    "2- Ecrire une fonction ${\\rm \\texttt{GaussInv(M)}}$ qui \n",
    "retourne l'inverse de la matrice carrée $M$ en appliquant la méthode de Gauss.\n",
    "\n",
    "3- Tester votre programme sur la matrice $B$ donnée en exemple ci-dessus."
   ]
  }
 ],
 "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.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
