diff --git a/Chapitre 1 - Systemes equations lineaires/1.3-4. Notation Matricielle.ipynb b/Chapitre 1 - Systemes equations lineaires/1.3-4. Notation Matricielle.ipynb index 7ad3d1c..3fccc3a 100644 --- a/Chapitre 1 - Systemes equations lineaires/1.3-4. Notation Matricielle.ipynb +++ b/Chapitre 1 - Systemes equations lineaires/1.3-4. Notation Matricielle.ipynb @@ -1,431 +1,431 @@ { "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Concept(s)-clé(s) et théorie\n", "\n", "On considère un système d'équations linéaires aux inconnues $x_1,\\ldots,x_n$\n", "\n", "$$S=\\left\\{\\begin{array}{ccccccc}\n", "a_{11}x_1 &+a_{12}x_2 & + &\\cdots &+a_{1n}x_n &= &b_1 \\\\\n", "a_{21}x_1 &+a_{22}x_2 & + &\\cdots &+a_{2n}x_n &= &b_2 \\\\\n", "\\vdots & & & &\\vdots & \\vdots &\\vdots \\\\\n", "a_{m1}x_1 &+a_{m2}x_2 & + &\\cdots &+a_{mn}x_n &= &b_m\n", "\\end{array},\\right. $$\n", "\n", "où $a_{ij},b_i\\in \\mathbb{R}$ pour tout $1\\leq i\\leq m$ et tout $1\\leq j\\leq n.$ \n", "\n", "Le système $S$ peut s'écrire sous forme matricielle $A\\overrightarrow{x}=\\overrightarrow{b}$ où la matrice $A$ est appelée *la matrice des coefficients* et $\\overrightarrow{x}$ et $\\overrightarrow{b}$ sont des vecteurs contant les composantes $x_i$ et $b_i$ respectivement. \n", "\n", "Plus précisemment\n", "$$A=\\begin{pmatrix}\n", "a_{11} & a_{12} & \\cdots & a_{1n}\\\\\n", "a_{21} & a_{22} &\\cdots & a_{2n}\\\\\n", "\\vdots & \\vdots & \\ddots & \\vdots\\\\\n", "a_{m1} & a_{m2} & \\cdots & a_{mn}\n", "\\end{pmatrix},\\hskip1em\n", "\\overrightarrow{x}=\\begin{pmatrix}\n", "x_1\\\\\n", "x_2\\\\\n", "\\vdots\\\\\n", "x_n\n", "\\end{pmatrix},\\hskip1em\n", "\\overrightarrow{b}=\n", "\\begin{pmatrix}\n", "b_1\\\\\n", "b_2\\\\\n", "\\vdots\\\\\n", "b_m\n", "\\end{pmatrix}.\n", "$$\n", "\n", "---\n", "\n", "La matrice $A$ est de taille $m\\times n$ où **m correspond au nombre de lignes** et **n au nombre de colonnes**.\n", "Le vecteur $\\overrightarrow{x}$ est de taille $n\\times 1$ et le vecteur $\\overrightarrow{b}$ de taille $m\\times 1$.\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import Librairie.AL_Fct as al\n", "import Corrections.corrections as corrections\n", "import numpy as np\n", "import ipywidgets as widgets\n", "import random\n", "\n", "from ipywidgets import interact, interactive, fixed, interact_manual, Layout" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### **EXERCICE 1**\n", "\n", "Ci-dessous est générée une matrice $A$ de taille $m\\times n$. Trouver la dimension de la matrice en remplissant les deux champs dans lesquels vous pouvez rentrer une valeur pour $m$ et $n$. \n", "\n", "Vérifier en cliquant sur **Run Interact**" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "A=al.randomA()\n", "al.dimensionA(A)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### **Nouvelles notations**\n", "\n", "Pour rentrer une matrice on utilise *la syntaxe suivante*\n", "$$A=\\quad [\\quad [ a_{11} , a_{12}, \\ldots, a_{1n} ], \\quad [ a_{21}, a_{22}, \\ldots, a_{2n}]\\quad, \\ldots , \\quad[a_{m1}, a_{m2}, \\ldots, a_{mn}]\\quad].$$\n", "\n", "Comme nous souhaitons différencier les vecteurs colonnes - ceux usuel - des vecteurs lignes, nous les différencions **à partir de maintenant** en utilisant *la syntaxe suivante*\n", "\n", "\n", "\\begin{align*}\n", "\\overrightarrow{b}&=\\begin{pmatrix}b_1 \\\\ b_2 \\\\ \\vdots \\\\ b_m\\end{pmatrix}\n", "&&\\Rightarrow b=\\quad [\\quad [ b_{1} ], \\quad [b_{2}], \\quad \\ldots, \\quad [b_m] \\quad]\\\\\n", "\\overrightarrow{v}&=\\begin{pmatrix} v_1 & v_2 & \\cdots v_n\\end{pmatrix}\n", "&&\\Rightarrow v=\\quad[ \\quad v_1, \\quad v_2, \\quad \\ldots, \\quad v_n \\quad ]\n", "\\end{align*}\n", "\n", "\n", "---\n", "\n", "Entrez les vecteurs et matrices ci-dessous.\n", "$$\n", "\\begin{pmatrix}\n", "1 & -3 \\\\\n", "3 & 5\n", "\\end{pmatrix} \\hskip1em \\begin{pmatrix}\n", "1 \\\\\n", "2 \n", "\\end{pmatrix}\\hskip1em\\begin{pmatrix}\n", "1 \\\\\n", "0.3\\\\\n", "1/4\n", "\\end{pmatrix}\\hskip1em\\begin{pmatrix}\n", "1 &2 &-1\n", "\\end{pmatrix}\\hskip1em\\begin{pmatrix}\n", "1 & 0 & -1\\\\\n", "0 & -1 & 1\\\\\n", "1 & 1 & 0\n", "\\end{pmatrix}\n", "$$" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "al.bgc('seashell')\n", "A=[[1]]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "al.printA(A)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Lorsqu'on travaille avec des systèmes, on s'intéresse à la matrice augmentée - dans laquelle on retrouve la matrice des coefficients $A$ et une colonne additionnelle correspondant au vecteur $\\overrightarrow{b}$ regroupant les termes de droite.\n", "\n", "\\begin{align*}\n", "\\text{Notation système} \\quad &\\Leftrightarrow \\quad\\text{Notation matricielle}\\\\\n", "\\begin{cases}\n", "a_{11}x_1 + a_{12}x_2&=b_1\\\\\n", "a_{21}x_1 + a_{22}x_2&=b_2\n", "\\end{cases} \\quad &\\Leftrightarrow \\quad \\left(\\begin{array}{cc|c}\n", "a_{11} & a_{12} & b_1\\\\\n", "a_{21} & a_{22} & b_2\n", "\\end{array}\\right)\n", "\\end{align*}\n", "\n", "\n", "---\n", "Pour entrer les matrices augmentées des systèmes, on utilise la syntaxe suivante\n", "\n", "\n", "\\begin{align*}\n", "A&=\\quad[\\quad [ a_{11} , a_{12}, \\ldots, a_{1n} ], \\quad [ a_{21}, a_{22}, \\ldots, a_{2n}]\\quad, \\ldots , \\quad[a_{m1}, a_{m2}, \\ldots, a_{mn}]\\quad]\\\\\n", "b&=\\quad[\\quad [b_1], \\quad [b_2], \\ldots, [b_m]\\quad ] \\leftarrow\\text{ceci nous permet de différencier un vecteur colonne d'un vecteur ligne!}\n", "\\end{align*}\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### **EXERCICE 2**\n", "Entrez les matrices augmentées des systèmes ci-dessous.\n", "\n", "$$\n", "1) \\quad \\begin{cases}\n", "2x_1 -x_2&=3\\\\\n", "x_1 + x_2&=0,\n", "\\end{cases}\\hskip2em\n", "2)\\quad \\begin{cases}\n", "\\dfrac{1}{3}x_1 + x_2 - x_3&=-6\\\\\n", "x_1 + x_3&=2\\\\\n", "-x_1 + \\dfrac{27}{9}x_2- x_3&=-1,\n", "\\end{cases}\\hskip2em\n", "3)\\quad \\begin{cases}\n", "x_1 - 4x_2=7\n", "\\end{cases}\\hskip2em\n", "4) \\begin{cases}\n", "x_1 &=3\\\\\n", "x_2 &= 4\\\\\n", "x_3 &= -1\\\\\n", "x_4&=0\n", "\\end{cases}\\hskip1em\n", "$$" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "al.bgc('seashell')\n", "#Entrer la matrice des coeff et le vecteur des termes de droite. Attention aux dimensions!\n", "A=[[1,1], [1,1]]\n", "b=[[1],[1]]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print('Le système est\\n')\n", "\n", "al.printSyst(A,b)\n", "print('\\n')\n", "print(' Son écriture matricielle est\\n')\n", "al.printA(A,b)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Concept(s)-clé(s) et théorie\n", "\n", "Il existe trois type d'opérations que l'on peut effectuer sur les lignes d'un système d'équations linéaires, ou sur la matrice augmentée correspondante, sans changer son ensemble de solution. \n", "\n", "Ces opérations sont appelées *opérations élémentaires* \n", "\n", "\n", "1. $E_{ij}$ (Échange) Échanger la ligne $i$ avec la ligne $j$. \n", "2. $E_{i}(\\alpha)$ (Multiplication par un scalaire) Multiplier tous les coefficients de la ligne $i$ par une constante non-nulle $(\\alpha)$.\n", "3. $E_{ij}(\\alpha)$ (Remplacement) Remplacer la ligne $i$ par la ligne obtenue en lui ajoutant un multiple ($\\alpha$) de la ligne $j$. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### EXEMPLE 1 :\n", "\n", "Entrer la matrice (augmentée) correspondante au système ci-dessous et effectuer les trois opérations suivantes sur la matrice de départ. \n", "\n", "1. Échanger la ligne $1$ et la ligne $2$.\n", "2. Multiplier tous les coefficients de la ligne $2$ par $-\\dfrac{1}{2}$.\n", "3. Remplacer la ligne 2 par la ligne obtenue en lui ajoutant 3 fois la ligne $3$. \n", "\n", "Le systèmes est \n", "$$\n", "\\begin{cases}\n", "x_1 -3x_2 + \\dfrac{1}{3}x_3&=0\\\\\n", "x_1 -7 x_3&=2\\\\\n", "-2x_1 + 3x_2 -4x_3&=5\n", "\\end{cases}\n", "$$\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "al.bgc('seashell')\n", "#Entrer la matrice des coeff et le vecteur des termes de droite. Attention aux dimensions!\n", "A=[[1, 1, 1], [1, 1, 1],[1, 1, 1]]\n", "b=[[1],[1],[1]]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "al.printA(A,b)\n", "al.manualOp(A,b)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### **EXERCICE 3**\n", "\n", "Parmi les couples de systèmes d'équations linéaires ci-dessous, lesquels ont le même ensemble de solutions? Si c'est le cas, c'est qu'on peut passer d'un système à l'autre en utilisant des opérations élémentaires. Cliquez sur Run Interact pour voir de quelles opérations élémentaires il s'agit.\n", "\n", "\\begin{align*}\n", "&a) \\begin{cases}\n", "2x_1 - 8x_2=2\\\\\n", "x_1 + x_2=3\n", "\\end{cases} \\quad \\rm{et}\\quad \\begin{cases}\n", "x_1 =3-x_2\\\\\n", "-x_1 + 4x_2=-1\n", "\\end{cases}\\\\[2em]\n", "&b) \\begin{cases}\n", "x_1 -x_2=2\\\\\n", "-x_1 + x_2 =-2\n", "\\end{cases} \\quad \\rm{et}\\quad \\begin{cases}\n", "-x_1 + x_2=2\\\\\n", "x_1 -x_2=-2\n", "\\end{cases}\\\\[2em]\n", "&c) \\begin{cases}\n", "\\dfrac{1}{4}x_1 -2x_2+ x_3=5\\\\\n", "x_2-x_3=0\\\\\n", "x_1 + 2x_2-x_3=0\n", "\\end{cases} \\quad \\rm{et}\\quad \\begin{cases}\n", "x_1-8x_2+ 4x_3=20\\\\\n", "x_2-x_3=0\\\\\n", "2x_2-x_3=-4\n", "\\end{cases}\n", "\\end{align*}" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "corrections.Ex3Chapitre1_3_4()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### **EXERCICE 4**\n", "\n", "Parmi les systèmes ci-dessous, lesquels ont le même ensemble de solutions?\n", "\n", "\\begin{align*}\n", "&a) \\quad \\begin{cases}\n", "2x_1 + x_2 &=2\\\\\n", "x_1 + 3x_2 -x_3 &=1\\\\\n", "3x_1 + 4x_2 &=0\n", "\\end{cases}\\hskip2em\n", "&&b)\\quad \\begin{cases}\n", "x_1 + \\dfrac{1}{2}x_2 &=2\\\\\n", "x_2 - \\dfrac{2}{5}x_3 &=1\\\\\n", "x_3 &=0\n", "\\end{cases}\\hskip2em\n", "&&c)\\quad \\begin{cases}\n", "2x_1 + x_2 &=2\\\\\n", "\\dfrac{5}{2}x_2 - x_3 &=0\\\\\n", "x_3 &= -3\n", "\\end{cases}\\hskip2em\n", "&&d) \\quad \\begin{cases}\n", "x_1 + 3x_2 - x_3 &= 1\\\\\n", "2x_1 + x_2 &= 2\\\\\n", "3x_1 + 4x_2 &= 0\\\\\n", "-x_1 -\\frac{1}{2}x_2 &= -1\n", "\\end{cases}\\mbox{}\\\\\n", "\\\\\n", "&e) \\quad \\begin{cases}\n", "2x_1 + x_2 &= 2\\\\\n", "3x_1 + 4x_3 &= 0\\\\\n", "x_1 + 3x_2 - x_3 &= 1\n", "\\end{cases}\\hskip2em\n", "&&f) \\quad \\begin{cases}\n", "2x_1 + x_2 &= 2\\\\\n", "3x_1 + 4x_2 &= 0\\\\\n", "3x_1 + 4x_3 &= 0\\\\\n", "x_1 + 3x_2 - x_3 &= 1\\hskip2em\n", "\\end{cases}\n", "&&g) \\quad \\begin{cases}\n", "x_1 + \\dfrac{1}{2}x_2 &= 1\\\\\n", "\\dfrac{5}{2}x_2 - x_3 &= 1\\\\\n", "\\dfrac{3}{2}x_1 + 2x_2 &= 0\n", "\\end{cases}\\hskip2em\n", "&&h) \\quad \\begin{cases}\n", "x_1 + 3x_2 - x_3 &= 1\\\\\n", "-\\dfrac{5}{2}x_2 + x_3 &= 0\\\\\n", "\\dfrac{3}{4}x_1 + x_2 &= 0\\\\\n", "\\end{cases}\\hskip2em\n", "\\end{align*}" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "corrections.Ex4Chapitre1_3_4() " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[Passez au notebook du chapitre 1.5-1.6: Matrices Echelonnées](./1.5-1.6.%20Matrices%20Echelonnées.ipynb)" ] } ], "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.9" + "version": "3.7.4" } }, "nbformat": 4, "nbformat_minor": 4 } diff --git "a/Chapitre 1 - Systemes equations lineaires/1.5-6. Matrices Echelonn\303\251es.ipynb" "b/Chapitre 1 - Systemes equations lineaires/1.5-6. Matrices Echelonn\303\251es.ipynb" index dc76cdb..0924801 100644 --- "a/Chapitre 1 - Systemes equations lineaires/1.5-6. Matrices Echelonn\303\251es.ipynb" +++ "b/Chapitre 1 - Systemes equations lineaires/1.5-6. Matrices Echelonn\303\251es.ipynb" @@ -1,391 +1,392 @@ { "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Concept(s)-clé(s) \n", "\n", "DEFINITION 1\n", "\n", "Soit $A$ une matrice de taille $m\\times n$ à coefficients réels. On dit que $A$ est *échelonnée* si l'indice de colonne du premier élément non-nul de chaque ligne est supérieur à l'indice de colonne du premier élément non-nul de la ligne précédente. C'est à dire que le nombre de zéros pécédant le premier élément non-nul une ligne augmente ligne par ligne, jusqu'à obtenir peut-être des lignes ne contenant que des zéros.\n", "\n", "Le premier élément non-nul de chaque ligne s'appelle un *pivot*, on les dénote par $\\color{red}\\oplus$. Les éléments quelconques sont dénotés par $*$. Attention $\\color{red}\\oplus$ est un élément non-nul, alors que $*$ peut être un élément nul. Les colonnes possédant un pivots s'appellent des *colonnes pivots*.\n", "\n", "Voici un exemple d'une telle matrice $A$ (ici de taille $7\\times 9$). Les colonnes $1,3,4,6$ et $9$ sont des colonnes pivots.\n", "\n", "$$\n", "A=\\begin{pmatrix}\n", "\\color{red}\\oplus & * & * & * & * & * & * &* & * \\\\\n", "0 & 0 &\\color{red}\\oplus & *& * & * & * & *&* \\\\\n", "0 & 0 & 0 & \\color{red}\\oplus& *& * &* & *& *\\\\\n", "0 & 0 & 0 & 0 & 0 &\\color{red}\\oplus & * & * & *\\\\\n", "0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 &\\color{red}\\oplus\\\\\n", "0 & 0 & 0 & 0 & 0& 0 & 0 &0&0\\\\\n", "0 & 0 & 0 & 0 & 0& 0 & 0 &0&0\n", "\\end{pmatrix}\n", "$$\n", "\n", "DEFINITON 2\n", "\n", "Soit $A$ une matrice de taille $m\\times n$ à coefficients réels. On dit que $A$ est *échelonnée réduite* si $A$ est échelonnée avec les propriétés suivantes\n", "1. tous ses pivots valent $1$ ($\\color{red}\\oplus=1$ dans ce cas)\n", "2. les pivots sont les seules valeurs non-nulles de leur colonne pivot (en dessous et en dessous d'un pivot il n'y a que des zéros).\n", "\n", "Voici un exemple d'une telle matrice $A$ (ici de taille $7\\times 9$). Les colonnes $1,3,4,6$ et $9$ sont des colonnes pivots et ne contiennent qu'un seul élément non-nul (les pivots valant 1).\n", "\n", "\n", "$$\n", "A=\\begin{pmatrix}\n", "\\require{enclose}\\enclose{circle}[mathcolor=\"red\"]{1} & * & 0 & 0 & * & 0 & * &* &0 \\\\\n", "0 & 0 &\\require{enclose}\\enclose{circle}[mathcolor=\"red\"]{1} &0& * & 0 & * & *&0 \\\\\n", "0 & 0 & 0 &\\require{enclose}\\enclose{circle}[mathcolor=\"red\"]{1}& *& 0 &* & *& 0\\\\\n", "0 & 0 & 0 & 0 & 0 &\\require{enclose}\\enclose{circle}[mathcolor=\"red\"]{1} & * & * & 0\\\\\n", "0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 &\\require{enclose}\\enclose{circle}[mathcolor=\"red\"]{1}\\\\\n", "0 & 0 & 0 & 0 & 0& 0 & 0 &0&0\\\\\n", "0 & 0 & 0 & 0 & 0& 0 & 0 &0&0\n", "\\end{pmatrix}\n", "$$\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import Librairie.AL_Fct as al\n", "import Corrections.corrections as corrections\n", "import numpy as np\n", "import ipywidgets as widgets\n", "import random\n", - "\n", "from ipywidgets import interact, interactive, fixed, interact_manual" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### **EXERCICE 1**\n", "Parmi les matrices ci-dessous, indiquez lesquelles sont sous formes échelonnées et échelonnées réduites.\n", "\n", "$$\n", "A=\\begin{pmatrix}\n", "1 & 0 & 0 &1\\\\\n", "0 & 1 & 1 & 0\\\\\n", "0 & 1 & 0 & 3\\\\\n", "0 & 0 & 1 & 0\n", "\\end{pmatrix}\\hspace{1cm}\n", "B=\\begin{pmatrix}1&1& 0 & 0 & 1\\\\\n", " 0& 0 &1 &0 &1\\\\\n", " 0 & 0& 0& 0& 0\\\\\n", " 0 & 0 & 0 & 1 & 0\n", "\\end{pmatrix}\\hspace{1cm}\n", "C=\\begin{pmatrix}\n", "1& 0 & 0 & 2\\\\\n", "0 & 1 & 0 & -2\\\\\n", "0 & 0 & -1 & 0 \\\\\n", "0 & 0 & 0 & 0\n", "\\end{pmatrix}\n", "\\hspace{1cm}\n", "D=\\begin{pmatrix}\n", "0 & 1 & 1 & 0 & 0 & 1\\\\\n", "0 & 0 & 0 & 1 & 0 & 1\\\\\n", "0 &0 &0 &0 &1 & 1\n", "\\end{pmatrix}\n", "\\hspace{1cm}\n", "E=\\begin{pmatrix}1 & 1 & 0 \\\\\n", "0 & 2 &0 &-3\\\\\n", "0 & 0 & 3& 1\\\\\n", "0 & 0 & 0 &0\n", "\\end{pmatrix}\\\\\n", "F=\\begin{pmatrix}\n", "1\\\\\n", "0\\\\\n", "1\n", "\\end{pmatrix}\\hspace{1cm}\n", "G=\\begin{pmatrix}0 & 0 \\\\\n", "0 & 4\n", "\\end{pmatrix}\\hspace{1cm}\n", "H=\\begin{pmatrix}\n", "0 & 0 \\\\\n", "0 & 0\n", "\\end{pmatrix}\\hspace{1cm}\n", "I=\\begin{pmatrix}1\\end{pmatrix}\\hspace{1cm} \n", "J=\\begin{pmatrix}\n", "1 & 0 & 1\\end{pmatrix}\n", "$$" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "data=al.Ex1Chapitre1_5_6() " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "corrections. Ex1Chapitre1_5_6(data)" + "corrections.Ex1Chapitre1_5_6(data)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Théorie\n", "\n", "\n", "La **méthode d'élimination de Gauss** est un algorithme central en algèbre linéaire qui consiste à appliquer une séquence appropriée d'opérations élémentaires à une matrice (voir [Notebook du chapitre 1.3-4: Notation Matricielle](./1.3-4.%20Notation%20Matricielle.ipynb)) jusqu'à ce qu'elle soit échelonnée. On peut continuer à appliquer des opérations élémentaires pour obtenir une matrice échelonnée réduite. \n", "\n", "\n", "La structure de la méthode d'élimination de Gauss est la suivante:\n", "![title](gauss_elimination.png)\n", "\n", "Soit le système linéaire suivant $$A\\overrightarrow{x} = \\overrightarrow{b}$$ où $A$ est la matrice des coefficients de taille $m\\times n$ et $\\overrightarrow{b}$ est le vecteur regrouppant les termes de droite.\n", "En appliquant la méthode d'élimination de Gauss à la matrice augmentée $(A|b)$ on obtient:\n", "\\begin{align*}\n", "\\text{Système Original} \\quad (A|b) \\quad & \\Leftrightarrow \\quad \\text{Système Échelonné} \\quad (\\tilde{A}|\\tilde{b}) \\quad & \\Leftrightarrow \\quad \\text{Système Réduit} \\quad (\\hat{A}|\\hat{b})\\\\\n", "\\left(\\begin{array}{cccc|c}\n", "a_{11} & a_{12} & \\dots & a_{1n} & b_1\\\\\n", "a_{21} & a_{22} & \\dots & a_{2n} & b_2\\\\\n", "\\vdots & \\vdots & \\ddots & \\vdots & \\vdots \\\\\n", "a_{m1} & a_{m2} & \\dots & a_{mn} & b_m\n", "\\end{array}\\right) \\quad & \\Leftrightarrow \\quad \\left(\\begin{array}{cccc|c}\n", "\\tilde{a}_{11} & \\tilde{a}_{12} & \\dots & \\tilde{a}_{1n} & \\tilde{b}_1\\\\\n", "0 & \\tilde{a}_{22} & \\dots & \\tilde{a}_{2n} & \\tilde{b}_2\\\\\n", "\\vdots & \\vdots & \\ddots & \\vdots & \\vdots \\\\\n", "0 & 0 & \\dots & \\tilde{a}_{mn} & \\tilde{b}_m\n", "\\end{array}\\right) \\quad & \\Leftrightarrow \\quad \\left(\\begin{array}{cccc|c}\n", "1 & 0 & \\dots & 0 & \\hat{b}_1\\\\\n", "0 & 1 & \\dots & 0 & \\hat{b}_2\\\\\n", "\\vdots & \\vdots & \\ddots & \\vdots & \\vdots \\\\\n", "0 & 0 & \\dots & 1 & \\hat{b}_m\n", "\\end{array}\\right)\\\\\n", "\\end{align*}\n", "\n", "**Remarque** Il s'agit d'un exemple, les pivots pouvant êtres à d'autres emplacements. Des lignes de zéros peuvent aussi êtres présentes.\n", "\n", "\n", "Comme seules des opérations élémentaires sur les lignes ont été utilisées, le système linéaire résultant est équivalent au système d'origine. Leur ensemble de solutions sont donc les mêmes. Mais le système resultant est beaucoup plus facile et plus rapide à résoudre. En utilisant d'abord la dernière équation, puis en substituant progressivement les variables dans les équations précédantes.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### **EXERCICE 2**\n", "\n", "À l'aide des opérations élémentaires, échelonner et réduire les matrices ci-dessous.\n", "\n", - "$$\n", + "$$A_1 = \n", "\\begin{pmatrix}\n", "2 & -1\\\\\n", "1 &2\n", "\\end{pmatrix}\\hskip2em\n", + "A_2 = \n", "\\begin{pmatrix}\n", "\\dfrac{1}{2} & 3 & 0\\\\\n", "2 & -4 & 6\\\\\n", "1 & 3 &-1\n", "\\end{pmatrix}\\hskip2em\n", + "A_3 =\n", "\\begin{pmatrix}\n", "1 & 0 &1\\\\\n", "0 & 1 & -1\\\\\n", "1 & 1 &-1\n", "\\end{pmatrix}\n", "\\hskip2em\n", "\\begin{pmatrix}\n", "1 & 0 &1 & 3\\\\\n", "0 & 2 & -2&1\\\\\n", "1 & 1 &-1 & 0\n", "\\end{pmatrix}\\hskip2em\n", "\\begin{pmatrix}\n", "1 & 1 &-1 & 1\\\\\n", "1 & -1 & -2&2\\\\\n", "1 & 1 &1 & 1\\\\\n", "1 & 3 & 2 & 0\n", "\\end{pmatrix}\n", "$$\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "A=[[1,1], [1,1], [1,1]]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print('Vous allez échelonner la matrice')\n", "al.printA(A)\n", "[i,j,r,alpha]= al.manualEch(A)\n", "MatriceList=[np.array(A)]\n", "m=np.array(A)\n", "print('\\033[1mExecutez la ligne suivante pour effectuer l\\'opération choisie \\033[0m')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m=al.echelonnage(i, j, r, alpha, A, m, MatriceList)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### **EXERCICE 3**\n", "À l'aide des opérations élémentaires, échelonner et réduire les matrices (augmentées) ci-dessous.\n", "\n", "$$A=\n", "\\begin{pmatrix}\n", "2 & -1\\\\\n", "1 &2\n", "\\end{pmatrix}\\hskip1em\n", "b=\n", "\\begin{pmatrix}\n", "1\\\\\n", "2\n", "\\end{pmatrix}\\hskip4em\n", "A=\n", "\\begin{pmatrix}\n", "\\dfrac{1}{2} & 3 & 0\\\\\n", "2 & -4 & 6\\\\\n", "1 & 3 &-1\n", "\\end{pmatrix}\\hskip1em\n", "b=\n", "\\begin{pmatrix}\n", "1\\\\\n", "2\\\\\n", "-1\n", "\\end{pmatrix}\\hskip4em\n", "A=\n", "\\begin{pmatrix}\n", "1 & 0 &1\\\\\n", "0 & 1 & -1\\\\\n", "1 & 1 &-1\n", "\\end{pmatrix}\\hskip1em\n", "b=\n", "\\begin{pmatrix}\n", "1\\\\\n", "0\\\\\n", "-1\n", "\\end{pmatrix}\n", "$$" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "A=[[1,1,1], [1,1,1],[1,1,1]]\n", "b =[[1], [1], [1]]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print('Vous allez échelonner la matrice augmenteé')\n", "al.printAAug(A,b)\n", "[i,j,r,alpha]= al.manualEch(A)\n", "MatriceList=[np.array(A)]\n", "RHSList = [np.array(b)]\n", "m=np.concatenate((A,b), axis=1)\n", "print('\\033[1mExecutez la ligne suivante pour effectuer l\\'opération choisie \\033[0m')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m=al.echelonnage(i, j, r, alpha, A, m, MatriceList, RHSList)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### **VERIFICATION**\n", "À l'aide des cellules ci-dessous, vous pouvez entrer la matrice (des coefficients ou augmentée) de votre choix et obtenir une forme échelonnée et sa forme échelonnée réduite.\n", "\n", "Pour **les formes échelonnées** on utilise la syntaxe suivante\n", "\n", "1. Pour la matrice $A$ : al.echelonMat('E', A)\n", "2. Pour la matrice augmentée $(A | b)$ : al.echelonMat('E', A, b)\n", "\n", "Pour obenir **les formes échelonnées réduites** mettez 'ER' au lieu de 'E'" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "A=[[2,1,1], [1,-1,1], [1,4,5]]\n", - "b=[[1], [3], [1]]" + "A = [[2,-1], [1,2]]\n", + "b = [[1], [2]]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "M=al.echelonMat('ER',A,b)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[Passez au notebook du chapitre 1.7: Résolutions de système linéarires](./1.7.%20Résolutions%20de%20systèmes%20linéaires.ipynb)" ] } ], "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.9" + "version": "3.7.4" } }, "nbformat": 4, "nbformat_minor": 4 } diff --git "a/Chapitre 2 - Algebre matricielle/2.10 D\303\251composition LU (applications aux syst\303\250mes lin\303\251aires).ipynb" "b/Chapitre 2 - Algebre matricielle/2.10 D\303\251composition LU (applications aux syst\303\250mes lin\303\251aires).ipynb" index e56bc91..1262f0a 100644 --- "a/Chapitre 2 - Algebre matricielle/2.10 D\303\251composition LU (applications aux syst\303\250mes lin\303\251aires).ipynb" +++ "b/Chapitre 2 - Algebre matricielle/2.10 D\303\251composition LU (applications aux syst\303\250mes lin\303\251aires).ipynb" @@ -1,287 +1,351 @@ { "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Concept(s)-clé(s) et théorie\n", "\n", "## APPLICATION DE LA DÉCOMPOSITION AUX SYSTÈMES LINÉAIRES \n", "Soit un système $Ax=b$ d'équations linéaires aux inconnues $x_1, \\dots, x_n$ et supposons que $A=LU$ où $L$ est triangulaire inférieure et $U$ triangulaire supérieure. Alors on résout le système de la manière suivante :\n", "\n", - "1. Poser $Y = [y_1, y_2, \\dots, y_n]^T$\n", + "1. Poser $Y = (y_1, y_2, \\dots, y_n)^T$\n", "2. Résoudre le système $LY=b$ avec la méthode de substitution en avant\n", "3. Résoudre le sytème $Ux=y$ avec la méthode de substitution en arrière" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + " \n", + " " + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + " \n", + " " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "import Librairie.AL_Fct as al\n", "import Corrections.corrections as corrections\n", "from ipywidgets import interact_manual\n", "import numpy as np\n", "import time\n", "from scipy.linalg import solve_triangular\n", "import matplotlib.pyplot as plt" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Exercise 1\n", "\n", "Considerez le système linéaire $Ax=b$, avec $A$ et $b$ donné par:\n", "\n", "\\begin{equation}\n", "A =\n", - "\\begin{bmatrix}\n", + "\\begin{pmatrix}\n", "1 & -1 & 0 \\\\\n", "2 & 0 & 1 \\\\\n", "1 & 1 & 1 \n", - "\\end{bmatrix}\n", + "\\end{pmatrix}\n", "\\qquad b = \n", - "\\begin{bmatrix}\n", + "\\begin{pmatrix}\n", "2 \\\\\n", "1 \\\\\n", "-1 \n", - "\\end{bmatrix}\n", + "\\end{pmatrix}\n", "\\end{equation}\n", "\n", "**Sans calculer aucune décomposition LU ni résoudre explicitement le système**, lesquelles des affirmations suivantes sont clairement correctes? [Exécutez la cellule suivante]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "corrections.Ex1Chapitre2_10()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Exercise 2 \n", "\n", - "Considerez le système linéaire $Ax=b$ avec $A \\in \\mathbb{R}^{4 \\times 4}$ et $b \\in \\mathbb{R}^{4} $ donné par:\n", + "Considerez le système linéaire $Ax=b$ avec $A \\in \\mathcal{M}_{4 \\times 4}(\\mathbb{R})$ et $b \\in \\mathcal{M}_{4 \\times 1}(\\mathbb{R})$ donné par:\n", "\n", "\\begin{equation}\n", "A = \n", - "\\begin{bmatrix}\n", + "\\begin{pmatrix}\n", "1 & 0 & -1 & -2 \\\\\n", "0 & -2 & -2 & 1 \\\\\n", "1 & 2 & 2 & 1 \\\\\n", "0 & 1 & 1 & -1\n", - "\\end{bmatrix}\n", + "\\end{pmatrix}\n", "\\qquad b = \n", - "\\begin{bmatrix}\n", + "\\begin{pmatrix}\n", "1 \\\\\n", "-2 \\\\\n", "1 \\\\\n", "0\n", - "\\end{bmatrix}\n", + "\\end{pmatrix}\n", "\\end{equation}\n", "\n", "Profitant de la décomposition LU, résolvez, si possible, le système linéaire." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "A=[[1,0,-1,-2], [0,-2,-2,1], [1,2,2,1], [0,1,1,-1]]\n", "b = [[1], [-2], [1], [0]]\n", "print('Vous allez échelonner la matrice A')\n", "al.printA(A)\n", "[i,j,r,alpha]= al.manualEch(A)\n", "LList = [np.eye(4)]\n", "UList=[np.array(A).astype(float)]\n", "print('\\033[1mExecutez la ligne suivante pour effectuer l\\'opération choisie \\033[0m')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m=al.LU_interactive(i,j,r,alpha, LList, UList)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Insert the values of the temporary variable y and of the system solution x in the following cell**" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "y = [[1], [-2], [-2], [-1]] # temporary variable\n", "x = [[-5], [12], [-10], [2]] # system solution\n", "\n", "corrections.Ex2Chapitre2_10(LList[-1], UList[-1], b, x, y)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Exercise 3\n", "\n", - "Considerez le système linéaire $Ax=b$ avec $A \\in \\mathbb{R}^{3 \\times 4}$ et $b \\in \\mathbb{R}^{3} $ donné par:\n", + "Considerez le système linéaire $Ax=b$ avec $A \\in \\mathcal{M}_{3 \\times 4}(\\mathbb{R})$ et $b \\in \\mathcal{M}_{3 \\times 1}(\\mathbb{R})$ donné par:\n", "\n", "\\begin{equation}\n", "A = \n", - "\\begin{bmatrix}\n", + "\\begin{pmatrix}\n", "1 & 2 & 0 & -1 \\\\\n", "-2 & -2 & -1 & 0 \\\\\n", "0 & 2 & -2 & 1\n", - "\\end{bmatrix}\n", + "\\end{pmatrix}\n", "\\qquad b = \n", - "\\begin{bmatrix}\n", + "\\begin{pmatrix}\n", "1 \\\\\n", "-1 \\\\\n", "2 \n", - "\\end{bmatrix}\n", + "\\end{pmatrix}\n", "\\end{equation}\n", "\n", "Profitant de la décomposition LU, résolvez, si possible, le système linéaire et marquez ceux des énoncés suivants qui sont corrects" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "A = [[1,2,0,-1], [-2,-2,-1,0], [0,2,-2,1]]\n", "b = [[1], [-1], [2]]\n", "print('Vous allez échelonner la matrice A')\n", "al.printA(A)\n", "[i,j,r,alpha]= al.manualEch(A)\n", "LList = [np.eye(3)]\n", "UList=[np.array(A).astype(float)]\n", "print('\\033[1mExecutez la ligne suivante pour effectuer l\\'opération choisie \\033[0m')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m=al.LU_interactive(i,j,r,alpha, LList, UList)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "0214334953bb438a8a6eb92790c5edac", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "interactive(children=(Checkbox(value=False, description='If L is such that all its diagonal elements equal 1, …" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "corrections.Ex3Chapitre2_10()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Exemple 1\n", "\n", "Il peut être difficile de comprendre pourquoi la décomposition LU est si importante. En effet il semble que ce ne soit rien de plus qu'une manière différente de mettre en œuvre la méthode d'élimination de Gauss, où au lieu d'impliquer le vecteur droit b dans la procédure de réduction, une matrice (L) codant toutes les opérations élémentaires effectuées sur les lignes de la matrice du système est construit.\n", "\n", "En fin de compte, de toute façon, ce changement apparemment simple est la clé qui rend la décomposition LU (avec toutes ses variantes) très utile dans la pratique réelle; en effet, dans de nombreux cas d'utilisation, il est nécessaire de résoudre plusieurs systèmes linéaires (grands ou énormes), tous présentant la même matrice, mais différents vecteurs du côté droit. Dans de telles situations, il est très utile de s'appuyer sur la décomposition LU; en particulier, la décomposition LU de la matrice est calculée avant la résolution de tous les systèmes linéaires, puis chacun d'eux est rapidement résolu via des schémas de substitution avant / arrière (sur les matrices diagonales supérieure et inférieure L et U). Si la décomposition LU n'est pas utilisée, à chaque étape un système linéaire complet devrait être résolu, conduisant à une augmentation significative en termes de nombre d'opérations et de temps de calcul.\n", "\n", "Afin de le montrer, nous présentons ci-dessous comment le nombre d'opérations et le temps d'exécution se comparent si plusieurs grands systèmes linéaires (partageant tous la même matrice) sont résolus en s'appuyant ou non sur la décomposition LU.\n", "\n", "**Exécutez la cellule suivante et évaluez les différences de performances ... cela peut prendre quelques minutes**" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "N = 1000 # dimension of the linear systems\n", "Nt = 10000 # number of linear systems to be solved\n", "A = np.random.rand(N, N);\n", "start = time.time()\n", "L, U = al.LU_no_pivoting(A)\n", "time_lu = 0\n", "n_op_lu = 2/3*(N**3 - N)\n", "n_op_no_lu = 0\n", "\n", "# solve without using LU \n", "start = time.time()\n", "for cnt in range(Nt):\n", " b = np.random.rand(N,1)\n", " x = np.linalg.solve(A, b)\n", " n_op_no_lu += N**3 # --> N^3 operations per cycle, according to Numpy/LAPACK documentation on benchmark cases\n", "time_no_lu = time.time() - start\n", "\n", "# solve using LU\n", "start = time.time()\n", "for cnt in range(Nt):\n", " b = np.random.rand(N,1)\n", " y = solve_triangular(L, b)\n", " n_op_lu += 2*N**2 - N # computational cost of forward substitution\n", " x = solve_triangular(U, y)\n", " n_op_lu += 2*N**2 - N # computational cost of backward substitution\n", "time_lu += time.time() - start\n", "\n", "print(\"Sans décomposition LU: nombre d'opérations:% e, temps d'exécution:% f s\" %(n_op_no_lu, time_no_lu))\n", "print(\"Avec décomposition LU: nombre d'opérations:% e, temps d'exécution:% f s %(n_op_lu, time_lu))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "**Vous pouvez comparer les temps d'exécution et le nombre d'opérations pour différentes tailles de matrice (c'est-à-dire changer le paramètre N) et pour un nombre différent de systèmes de lienar (c'est-à-dire changer le paramètre N_t)**" + "**Vous pouvez comparer les temps d'exécution et le nombre d'opérations pour différentes tailles de matrice (c'est-à-dire changer le paramètre N) et pour un nombre différent de systèmes lineaires (c'est-à-dire changer le paramètre N_t)**" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[Passez au notebook 2.11: Décomposition en blocs](2.11%20Décomposition%20en%20blocs.ipynb)" ] } ], "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.4" } }, "nbformat": 4, "nbformat_minor": 4 } diff --git "a/Chapitre 2 - Algebre matricielle/2.11 D\303\251composition en blocs.ipynb" "b/Chapitre 2 - Algebre matricielle/2.11 D\303\251composition en blocs.ipynb" index 7fec515..2125ccd 100644 --- "a/Chapitre 2 - Algebre matricielle/2.11 D\303\251composition en blocs.ipynb" +++ "b/Chapitre 2 - Algebre matricielle/2.11 D\303\251composition en blocs.ipynb" @@ -1,6 +1,198 @@ { - "cells": [], - "metadata": {}, + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Concept(s)-clé(s) et théorie\n", + "\n", + "## DÉFINITION:\n", + "Soit $A$ une matrice de taille $m \\times n$ à coefficients réels. Une décomposition par blocs de $A$ est une manière de partitionner cette dernière matrice en plus petites matrices, que l'on obtient en traçant des lignes verticales et horizontales dans la matrice.\n", + "\n", + "## EXEMPLE\n", + "Étant donné une matrice $A \\in \\mathcal{M}_{3 \\times 3}(\\mathbb{R})$, des exemples de sa décomposition en blocs sont les suivants:\n", + "\n", + "$$\n", + "A_1 = \n", + "\\left(\\begin{array}{@{}c|cc@{}}\n", + "a_{11} & a_{12} & a_{13} \\\\\n", + "a_{21} & a_{22} & a_{23} \\\\\\hline\n", + "a_{31} & a_{32} & a_{33}\n", + "\\end{array}\\right) \\quad\n", + "A_2 = \n", + "\\left(\\begin{array}{@{}ccc@{}}\n", + "a_{11} & a_{12} & a_{13} \\\\\\hline\n", + "a_{21} & a_{22} & a_{23} \\\\\n", + "a_{31} & a_{32} & a_{33}\n", + "\\end{array}\\right) \\quad\n", + "A_3 = \n", + "\\left(\\begin{array}{@{}cc|c@{}}\n", + "a_{11} & a_{12} & a_{13} \\\\\n", + "a_{21} & a_{22} & a_{23} \\\\\n", + "a_{31} & a_{32} & a_{33}\n", + "\\end{array}\\right) \\quad\n", + "A_4 = \n", + "\\left(\\begin{array}{@{}c|c|c@{}}\n", + "a_{11} & a_{12} & a_{13} \\\\\\hline\n", + "a_{21} & a_{22} & a_{23} \\\\\\hline\n", + "a_{31} & a_{32} & a_{33}\n", + "\\end{array}\\right) \\quad\n", + "$$\n", + "\n", + "En général, une matrice de taille $m \\times n$ peut être décomposée en blocs de différentes manières $(m+1)(n+1)$.\n", + "\n", + "\n", + "## PROPRIÉTÉS\n", + "### Lemma 1: addition par blocs ###\n", + "Soient $A,B \\in \\mathcal{M}_{m \\times n}(\\mathbb{R})$ deux matrices décomposées en matrices par blocs de la même façon, alors on peut additionner $A$ et $B$ par blocs comme suit:\n", + "\n", + "$$\n", + "A = \n", + "\\left(\\begin{array}{@{}c|c|c@{}}\n", + "A_{11} & \\cdots & A_{1Q} \\\\\\hline\n", + "\\vdots & \\ddots & \\vdots \\\\\\hline\n", + "A_{P1} & \\cdots & A_{PQ} \\\\\n", + "\\end{array}\\right) \\quad\n", + "B = \n", + "\\left(\\begin{array}{@{}c|c|c@{}}\n", + "B_{11} & \\cdots & B_{1Q} \\\\\\hline\n", + "\\vdots & \\ddots & \\vdots \\\\\\hline\n", + "B_{P1} & \\cdots & B_{PQ} \\\\\n", + "\\end{array}\\right)\n", + "\\quad \\Longrightarrow \\quad\n", + "A+B = \n", + "\\left(\\begin{array}{@{}c|c|c@{}}\n", + "A_{11}+B_{11} & \\cdots & A_{1Q}+B_{1Q} \\\\\\hline\n", + "\\vdots & \\ddots & \\vdots \\\\\\hline\n", + "A_{P1}+B_{P1} & \\cdots & A_{PQ}+B_{PQ} \\\\\n", + "\\end{array}\\right) \\quad\n", + "$$\n", + "\n", + "### Lemma 2: multiplication par un scalaire par blocs ###\n", + "Soit $A \\in \\mathcal{M}_{m \\times n}(\\mathbb{R})$ un matrice decomposée en matrices par blocs. Alors il est possible de multiplier $A$ par un scalaire, simplement en multipliant chaque bloc de $A$ par un tel scalaire.\n", + "C'est à dire:\n", + "$$\n", + "A = \n", + "\\left(\\begin{array}{@{}c|c|c@{}}\n", + "A_{11} & \\cdots & A_{1Q} \\\\\\hline\n", + "\\vdots & \\ddots & \\vdots \\\\\\hline\n", + "A_{P1} & \\cdots & A_{PQ} \\\\\n", + "\\end{array}\\right), \\quad \\lambda \\in \\mathbb{R}\n", + "\\quad \\Longrightarrow \\quad\n", + "\\lambda A = \n", + "\\left(\\begin{array}{@{}c|c|c@{}}\n", + "\\lambda A_{11} & \\cdots & \\lambda A_{1Q} \\\\\\hline\n", + "\\vdots & \\ddots & \\vdots \\\\\\hline\n", + "\\lambda A_{P1} & \\cdots & \\lambda A_{PQ} \\\\\n", + "\\end{array}\\right)\n", + "$$\n", + "\n", + "### Lemma 3: multiplication matricielle par blocs ###\n", + "Soient $A \\in \\mathcal{M}_{m \\times n}(\\mathbb{R}), B \\in \\mathcal{M}_{n \\times p}(\\mathbb{R})$ deux matrices décomposées en matrices par blocs telles que:\n", + "- le nombre de blocs dans chaque ligne de la matrice A est égal au nombre de blocs dans chaque colonne de la matrice B \n", + "- le nombre de colonnes de chaque bloc $A_{ik}$ soit égal au nombre de lignes de chaque bloc $B_{kj}$.\n", + "Alors on peut multiplier $A$ et $B$ par blocs comme suit:\n", + "\n", + "$$\n", + "A = \n", + "\\left(\\begin{array}{@{}c|c|c@{}}\n", + "A_{11} & \\cdots & A_{1Q} \\\\\\hline\n", + "\\vdots & \\ddots & \\vdots \\\\\\hline\n", + "A_{P1} & \\cdots & A_{PQ} \\\\\n", + "\\end{array}\\right) \\quad\n", + "B = \n", + "\\left(\\begin{array}{@{}c|c|c@{}}\n", + "B_{11} & \\cdots & B_{1R} \\\\\\hline\n", + "\\vdots & \\ddots & \\vdots \\\\\\hline\n", + "B_{Q1} & \\cdots & B_{QR} \\\\\n", + "\\end{array}\\right)\n", + "\\quad \\Longrightarrow \\quad\n", + "AB = \n", + "\\left(\\begin{array}{@{}c|c|c@{}}\n", + "\\sum\\limits_{i=0}^Q A_{1i}B_{i1} & \\cdots & \\sum\\limits_{i=0}^Q A_{1i}B_{iQ} \\\\\\hline\n", + "\\vdots & \\ddots & \\vdots \\\\\\hline\n", + "\\sum\\limits_{i=0}^Q A_{Pi}B_{i1} & \\cdots & \\sum\\limits_{i=0}^Q A_{Pi}B_{iQ} \\\\\n", + "\\end{array}\\right) \\quad\n", + "$$\n", + "\n", + "### Lemma 4 ###\n", + "Soit $A \\in \\mathcal{M}_{n \\times n}(\\mathbb{R})$ une matrice carrée, decomposée en blocs $\\left(\\begin{array}{@{}c|c@{}} A_{11} & A_{12} \\\\\\hline 0 & A_{22} \\\\ \\end{array}\\right)$, avec $A_{11} \\in \\mathcal{M}_{r \\times r}(\\mathbb{R})$, $A_{22} \\in \\mathcal{M}_{s \\times s}(\\mathbb{R})$ et $r+s=n$. Si $A_{11}$ et $A_{22}$ sont inversibles, alors $A$ l'est egalment et sont inverse est:\n", + "\n", + "$$\n", + "A^{-1} = \n", + "\\left(\\begin{array}{@{}c|c@{}}\n", + "A_{11}^{-1} & -A_{11}^{-1}A_{12}A_{22}^{-1} \\\\\\hline\n", + "0 & A_{22}^{-1}\n", + "\\end{array}\\right)\n", + "$$\n", + "\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import Librairie.AL_Fct as al\n", + "import Corrections.corrections as corrections\n", + "from ipywidgets import interact_manual" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## EXERCICE 1\n", + "Give some couples (like 3) of matrices with block decomposition already made (only literal, not numeric); ask whether and if they can be summed up, multiplied, summed up by blocs, multiplied by blocks." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## EXERCICE 2\n", + "Like in MOOC, give a matrix already decoposed in blocs and one not (in this case, give B and not A). Ask how many ways of block decomposing A exist so that it can be multipled by blocks with B." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## EXERCICE 3\n", + "Given some couples of matrices (like 3), compute their block multiplication, if possible." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# TODO: implement block multiplier in library??" + ] + } + ], + "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.4" + } + }, "nbformat": 4, "nbformat_minor": 4 } diff --git a/Chapitre 2 - Algebre matricielle/2.2 Multiplication de matrices.ipynb b/Chapitre 2 - Algebre matricielle/2.2 Multiplication de matrices.ipynb index 1bcdcbd..0a863df 100644 --- a/Chapitre 2 - Algebre matricielle/2.2 Multiplication de matrices.ipynb +++ b/Chapitre 2 - Algebre matricielle/2.2 Multiplication de matrices.ipynb @@ -1,169 +1,165 @@ { "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# **Concept(s)-clé(s) et théorie**\n", "\n", "Soient $A\\in \\mathcal{M}_{m\\times p}(\\mathbb{R})$ et $B\\in \\mathcal{M}_{p\\times n}(\\mathbb{R}).$ On définit *le produit matriciel* $A B \\in \\mathcal{M}_{m\\times n}(\\mathbb{R})$ comme étant la matrice satisfaisant \n", "$$\n", "(A B)_{ij}=\\sum_{k=1}^p{a_{ik}b_{kj}},\n", "$$\n", "\n", "ceci pour tout $1\\leq i \\leq m$ et tout $1\\leq j\\leq n.$\n", "\n", "**Remarque** On remarque que les matrices $A$ et $B$ sont de la taille $m\\times \\color{red}p$ et $\\color{red}p\\times n$ respectivement. Ceci veut dire que le nombre de colonnes de $A$ ($\\color{red}p$ colonnes) est égal au nombre de lignes de $B$ ($\\color{red}p$ lignes). Sans cette condition, le produit matriciel n'existe pas!" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import Librairie.AL_Fct as al\n", "import Corrections.corrections as corrections" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### **Exercice 1**\n", "Soient $A$ et $B$ données par\n", "$$\n", "A=\\begin{pmatrix}\n", "1 & 2 \\\\\n", "3 & -1\\\\\n", "2 & 0\\\\\n", "\\end{pmatrix}\\hskip2em\n", "B=\\begin{pmatrix}\n", "-1 & 2\\\\\n", "0 & 3\\\\\n", "\\end{pmatrix}\n", "$$\n", "\n", "Alors le produit matriciel $AB$ vaut: " ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "ename": "NameError", "evalue": "name 'corrections' is not defined", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mcorrections\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mEx1Chapitre2_2\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0;31m#Here : modif in corrections remove Le produit AB vaut and leave AB=... with round parenthesis and no dots to avoid confusion with dot product.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0;31m#Also Le produit AB n'est pas défini\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mNameError\u001b[0m: name 'corrections' is not defined" ] } ], "source": [ - "corrections.Ex1Chapitre2_2() \n", - "#Here : modif in corrections remove Le produit AB vaut and leave AB=... with round parenthesis and no dots to avoid confusion with dot product. \n", - "#Also Le produit AB n'est pas défini" + "corrections.Ex1Chapitre2_2() " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### **Exercice 2**\n", "\n", "Soient $A$ et $B$ données par\n", "$$\n", "A=\\begin{pmatrix}\n", "5 & 2 &-2\\\\\n", "3 & -1 & 0\n", "\\end{pmatrix}\\hskip2em\n", "B=\\begin{pmatrix}\n", "2 \\\\\n", "0\\\\\n", "-2\n", "\\end{pmatrix}\n", "$$\n", "\n", - "Alors le produit matriciel $AB$ appartient à l'espace des matrices" + "Alors:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "corrections.Ex2Chapitre2_2()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Exercice 3\n", "\n", "Soient $A$ et $B$ deux matrices de taille $2\\times 2$ données par\n", "\n", "$$\n", "A=\\begin{pmatrix}\n", "-1 & 2 \\\\\n", "5 & -2\n", "\\end{pmatrix}\\hspace{2em}\n", "B=\\begin{pmatrix}\n", "-1 & 1 \\\\\n", "a & b\n", "\\end{pmatrix}\n", "$$\n", "\n", "Trouver les valeurs de $a$ et $b$ - si elles existentent - telles que\n", "$$\n", "AB=BA\n", "$$" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "corrections.Ex3Chapitre2_2()\n", - "#Insérer les valeurs de a et b. \n", - "#Correct, les produits AB et BA valent .." + "corrections.Ex3Chapitre2_2()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[Passez au notebook du chapitre 2.3: Matrices carées, inversibles](./2.3%20Matrices%20carrées%2C%20inversibles.ipynb)" ] } ], "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.9" + "version": "3.7.4" } }, "nbformat": 4, "nbformat_minor": 4 } diff --git "a/Chapitre 2 - Algebre matricielle/2.3 Matrices carr\303\251es, inversibles.ipynb" "b/Chapitre 2 - Algebre matricielle/2.3 Matrices carr\303\251es, inversibles.ipynb" index 5148533..5219ae6 100644 --- "a/Chapitre 2 - Algebre matricielle/2.3 Matrices carr\303\251es, inversibles.ipynb" +++ "b/Chapitre 2 - Algebre matricielle/2.3 Matrices carr\303\251es, inversibles.ipynb" @@ -1,277 +1,277 @@ { "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# **Concept(s)-clé(s) et théorie**\n", "\n", "### DÉFINITION 1 :\n", "On dit qu'une matrice $A$ est *carrée* si elle est de taille $n\\times n$ pour un certain entier $n\\in \\mathbb{N}^*,$ c'est-à-dire si elle possède le même nombre de lignes et de colonnes. \n", "\n", "Une matrice est dite *inversible* s'il existe une matrice $B\\in \\mathcal{M}_{n\\times n}(\\mathbb{R})$ telle que: \n", "\\begin{equation*}\n", "AB=I_n=BA\n", "\\end{equation*}\n", "où $I_n$ représente la matrice d'identité avec $n$ lignes et $n$ colonnes. Dans ce cas, on dit que $B$ est l'*inverse* de la matrice $A$. On note l'inverse de $A$ par $A^{-1}$.\n", "\n", "**Remarque** Une matrice inversible est forcément carrée car les produits matriciels $AB$ et $BA$ existent et sont égaux (ils valent $I_n$). Pour la définition du produit matriciel, voir [2.2 Multiplication de matrices](./2.2%Multiplication%de%matrices.ipynb).\n", "\n", "---\n", "### DÉFINITION 2 :\n", "Soit $A$ une matrice de taille $m\\times n$ à coefficients réels. La *diagonale principale* de $A$ est la \"ligne oblique\" formée des composantes $(i,i)$ de $A.$\n", "\n", "---\n", "### DÉFINITION 3 :\n", "On dit d'une matrice $A=(a_{ij})\\in \\mathcal{M}_{m\\times n}(\\mathbb{R})$ qu'elle est:\n", "\n", "$\\bullet$ *triangulaire supérieure*  si $a_{ij}=0$ pour tout $i>j$;\n", "\n", "$\\bullet$ *triangulaire inférieure*  si $a_{ij}=0$ pour tout $i\n", " window.PlotlyConfig = {MathJaxConfig: 'local'};\n", " if (window.MathJax) {MathJax.Hub.Config({SVG: {font: \"STIX-Web\"}});}\n", " if (typeof require !== 'undefined') {\n", " require.undef(\"plotly\");\n", " requirejs.config({\n", " paths: {\n", " 'plotly': ['https://cdn.plot.ly/plotly-latest.min']\n", " }\n", " });\n", " require(['plotly'], function(Plotly) {\n", " window._Plotly = Plotly;\n", " });\n", " }\n", " \n", " " ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ " \n", " " ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import Librairie.AL_Fct as al\n", "import Corrections.corrections as corrections\n", "import numpy as np\n", "from numpy.linalg import *" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### **Exercice 1**\n", "\n", "Soit $A$ la matrice\n", "$$\n", "A=\\begin{pmatrix}\n", "-2 & 4/3 & -1\\\\\n", "0 & 3 & -5\\\\\n", "1/2 & 1 & 1/2\n", "\\end{pmatrix}.\n", "$$\n", "\n", "Trouver une matrice $B$ et une matrice $C$ telles que:\n", "1. $A + B$ soit diagonale\n", "2. $A + C$ soit symétrique mais non diagonale\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Reportez ici le matrices B et C\n", "A=[[-2, 4/3,-1],[0,3,-5],[1/2,1,1/2]]\n", "B=[[0,0,0],[0,0,0],[0,0,0]]\n", "C=[[0,0,0],[0,0,0],[0,0,0]]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print('La matrice B entrée est:')\n", "al.printA(B)\n", "print('La matrice C entrée est:')\n", "al.printA(C)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "corrections.Ex1Chapitre2_3(A,B,C)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### **Exemple 1**\n", "\n", "Soit $A$ la matrice carrée $3\\times 3$ donnée par\n", "$$\n", "A=\\begin{pmatrix}\n", "1 & 2 & 3\\\\\n", "0 & -1 & 0\\\\\n", "0 & 2 & 3\n", "\\end{pmatrix}\n", "$$\n", "\n", "Nous allons trouver l'inverse de $A$ en appliquant des oéprations élémentaires à la matrice $(A|I)$ (il s'agit de la matrice $A$ augmentée de la matrice $I$, où $I$ est la matrice identité de la même dimension que $A$). Les opérations élémentaires que nous appliquons à $(A|I)$ sont les suivantes:\n", "1. $L_1-L_3$\n", "2. $(-1)L_2$\n", "3. $L_3-2L_2$\n", "4. $\\dfrac{1}{3}L_3$\n", "\n", "où $L_i$ représente la i-ème ligne de la matrice $(A|I)$. En particulier, nous allons transformer $(A|I)$ en la nouvelle matrice augmentée $(I|\\tilde{A})$. À la place de $A$ nous aurons l'identité $I$ et, en même temps, à la place de $I$ nous aurons une matrice $\\tilde{A}$ de taille $n\\times n$. Cette matrice $\\tilde{A}$ est enfait l'inverse de $A$. Nous avons le schéma suivant\n", "$$\n", "(A|I) \\sim \\quad \\stackrel{\\text{op. élémentaires}}{\\ldots\\ldots\\ldots} \\quad\\sim (I|A^{-1})\n", "$$\n", "\n", "**Remarque** Cet algorithme n'est rien d'autre que l'algorithme de Gauss expliqué dans le chapitre [](). La forme échelonnée réduite de la matrice $A$ sera l'identité $I$. Il s'agira d'une des propriétés des matrices inversibles. Nous pouvons donc reformuler l'algorithme ci-dessus de la manière suivante: appliquer à $(A|I)$ des opérations élémentaires jusqu'à obtenir la forme échelonnée de la matrice $A$ à gauche. L'inverse de la matrice $A$ sera la matirce obtenue à droite. " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "A=[[1,2,3],[0,-1,0],[0,2,3]]\n", "I=[[1,0,0],[0,1,0],[0,0,1]]\n", "\n", "print(\"Appliquer les opérations élémentaires données pour obtenir l'identité à gauche (la forme échelonnée de A).\\n\"\n", " \"L'inverse de A se trouvera alors à droite, la où il y avait\" \n", " \"à l'origine la matrice identité I.\")\n", "al.printA(A,I)\n", "[i,j,r,alpha]= al.manualEch(A,I)\n", "m=np.concatenate((A,I), axis=1)\n", "MatriceList=[A]\n", "RhSList=[I]\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m=al.echelonnage(i,j,r,alpha,A,m,MatriceList,RhSList)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print('La matrice inverse de A est donnée par: ' )\n", "al.printA(inv(A))\n", "print('Le produit entre A et son inverse est en effet égal à: ')\n", "I=np.dot(A,inv(A))\n", "al.printA(I)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### **Exercice 2**\n", "\n", "Soit $A$ la matrice ci-dessous\n", "$$\n", "A=\\begin{pmatrix}\n", "-1 & 0 & 0 \\\\\n", "3 & \\dfrac{1}{2} & 0 \\\\\n", "1 & 2 & 1 \n", "\\end{pmatrix}.\n", "$$\n", "\n", "Laquelle des affirmations ci-dessous est correcte?\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "corrections.Ex2Chapitre2_3()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[Passez au notebook 2.4: Systèmes d'équations et matrices](2.4%20Systèmes%20d'équations%20et%20matrices.ipynb)" ] } ], "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.9" + "version": "3.7.4" } }, "nbformat": 4, "nbformat_minor": 4 } diff --git "a/Chapitre 2 - Algebre matricielle/2.4 Syst\303\250mes d'\303\251quations et matrices.ipynb" "b/Chapitre 2 - Algebre matricielle/2.4 Syst\303\250mes d'\303\251quations et matrices.ipynb" index 4598c22..3da7068 100644 --- "a/Chapitre 2 - Algebre matricielle/2.4 Syst\303\250mes d'\303\251quations et matrices.ipynb" +++ "b/Chapitre 2 - Algebre matricielle/2.4 Syst\303\250mes d'\303\251quations et matrices.ipynb" @@ -1,642 +1,529 @@ { "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# **Concept(s)-clé(s) et théorie**\n", "\n", "## Théorème\n", "Soit $A$ une matrice $n\\times n $ inversible. Alors pour tout vecteur $\\overrightarrow{b}\\in \\mathbb{R}^n$, l'équation $A\\overrightarrow{x}=\\overrightarrow{b}$ admet pour unique solution le vecteur $$\n", "\\overrightarrow{\\tilde{x}}=A^{-1}\\overrightarrow{b}$$" ] }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": { "scrolled": true }, - "outputs": [ - { - "data": { - "text/html": [ - " \n", - " " - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - " \n", - " " - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "import Librairie.AL_Fct as al\n", "import Corrections.corrections as corrections\n", "import numpy as np" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### EXEMPLE 1\n", "Considérez le système linéaire $ Ax = b $, avec:\n", "\\begin{equation}\n", "A = \n", - "\\begin{bmatrix}\n", + "\\begin{pmatrix}\n", "2 & 0 & 1\\\\\n", "0 & 3 & 4 \\\\\n", "2 & 2 & 1\n", - "\\end{bmatrix}; \\qquad b = \n", - "\\begin{bmatrix}\n", + "\\end{pmatrix}; \\qquad b = \n", + "\\begin{pmatrix}\n", "2\\\\\n", "4\\\\\n", "3\\\\\n", - "\\end{bmatrix};\n", + "\\end{pmatrix};\n", "\\end{equation}\n" ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": { "scrolled": true }, "outputs": [], "source": [ "A = [[2, 0, 1], [0, 3, 4], [2, 2, 1]]\n", "b = [[2], [4], [3]]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### ÉTAPE 1: résoudre le système linéaire en utilisant la méthode d'élimination de Gauss" ] }, { "cell_type": "code", +<<<<<<< HEAD "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Vous allez échelonner la matrice augmenteé\n" ] }, { "data": { "text/latex": [ "$\\left(\\begin{array}{ccc| cc} 2 & 0 & 1 & 2 \\\\0 & 3 & 4 & 4 \\\\2 & 2 & 1 & 3 \\end{array}\\right)$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "Régler les paramètres et évaluer la cellule suivante\n", "Répéter cela jusqu'à obtenir une forme échelonnée réduite\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "a335480cf87d452fb14da54f9faccd29", "version_major": 2, "version_minor": 0 }, "text/plain": [ "RadioButtons(description='Opération:', options=('Eij', 'Ei(alpha)', 'Eij(alpha)', 'Revert'), value='Eij')" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "1ac4b957938e4af1a0a062018d5cbd5a", "version_major": 2, "version_minor": 0 }, "text/plain": [ "BoundedIntText(value=1, description='Ligne i:', max=3, min=1)" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "22a213ee957342cb98d57e4363ad154c", "version_major": 2, "version_minor": 0 }, "text/plain": [ "BoundedIntText(value=1, description='Ligne j:', max=3, min=1)" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "3788864db10c45569be6bdea2479be02", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Text(value='1', description='Coeff. alpha:')" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1mExecutez la ligne suivante pour effectuer l'opération choisie \u001b[0m\n" ] } ], +======= + "execution_count": null, + "metadata": { + "scrolled": false + }, + "outputs": [], +>>>>>>> e05dd5c1c87dd88990947782050b038375e5cfae "source": [ "print('Vous allez échelonner la matrice augmenteé')\n", "al.printAAug(A,b)\n", "[i,j,r,alpha]= al.manualEch(A)\n", "MatriceList=[np.array(A)]\n", "RHSList = [np.array(b)]\n", "m=np.concatenate((A,b), axis=1)\n", "print('\\033[1mExecutez la ligne suivante pour effectuer l\\'opération choisie \\033[0m')" ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": { "scrolled": true }, - "outputs": [ - { - "data": { - "text/latex": [ - "$\\left[\\begin{array}{ccc| cc} 2 & 0 & 1 & 2 \\\\0 & 3 & 4 & 4 \\\\2 & 2 & 1 & 3 \\end{array}\\right]\\quad \\sim \\quad\\left[\\begin{array}{ccc| cc} 2 & 0 & 1 & 2 \\\\0 & 3 & 4 & 4 \\\\2 & 2 & 1 & 3 \\end{array}\\right]$" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "m=al.echelonnage(i, j, r, alpha, A, m, MatriceList, RHSList)" ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": { "scrolled": true }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Insérez ici la valeur de la solution calculée\n", - "La suite entrée n'est pas une solution de l'équation 1\n", - "La suite entrée n'est pas une solution de l'équation 2\n", - "La suite entrée n'est pas une solution de l'équation 3\n", - "Ce n'est pas une solution du système\n" - ] - } - ], + "outputs": [], "source": [ "print('Insérez ici la valeur de la solution calculée')\n", "x1 = [[1], [1], [1]]\n", "res1 = al.SolOfSyst(x1, A, b)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### TASK 2: calculer l'inverse de la matrice A ([voir le Notebook 2.3](./2.3%20Matrices%20carrées%2C%20inversibles.ipynb)) et dériver la solution du système linéaire en fonction du résultat obtenu" ] }, { "cell_type": "code", +<<<<<<< HEAD "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Vous allez échelonner la matrice augmenteé avec la matrice identité\n" ] }, { "data": { "text/latex": [ "$\\left[\\begin{array}{ccc| cccc} 2 & 0 & 1 & 1 & 0 & 0 \\\\0 & 3 & 4 & 0 & 1 & 0 \\\\2 & 2 & 1 & 0 & 0 & 1 \\end{array}\\right]$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "Régler les paramètres et évaluer la cellule suivante\n", "Répéter cela jusqu'à obtenir une forme échelonnée réduite\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "ff9b416fec6a4fcb8a3c4a05b6e775fd", "version_major": 2, "version_minor": 0 }, "text/plain": [ "RadioButtons(description='Opération:', options=('Eij', 'Ei(alpha)', 'Eij(alpha)', 'Revert'), value='Eij')" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "4d7fd6e14c014932b5e29a10697c04c2", "version_major": 2, "version_minor": 0 }, "text/plain": [ "BoundedIntText(value=1, description='Ligne i:', max=3, min=1)" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "8f3c7d22892c48dea9ebfc070b7bb766", "version_major": 2, "version_minor": 0 }, "text/plain": [ "BoundedIntText(value=1, description='Ligne j:', max=3, min=1)" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "51ec7a7353aa4228959840ebd2325deb", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Text(value='1', description='Coeff. alpha:')" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1mExecutez la ligne suivante pour effectuer l'opération choisie \u001b[0m\n" ] } ], +======= + "execution_count": null, + "metadata": { + "scrolled": false + }, + "outputs": [], +>>>>>>> e05dd5c1c87dd88990947782050b038375e5cfae "source": [ "I=[[1,0,0],[0,1,0],[0,0,1]]\n", "print('Vous allez échelonner la matrice augmenteé avec la matrice identité')\n", "al.printA(A,I)\n", "[i,j,r,alpha]= al.manualEch(A,I)\n", "m=np.concatenate((A,I), axis=1)\n", "MatriceList=[A]\n", "RhSList=[I]\n", "print('\\033[1mExecutez la ligne suivante pour effectuer l\\'opération choisie \\033[0m')" ] }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "metadata": { "scrolled": true }, - "outputs": [ - { - "data": { - "text/latex": [ - "$\\left[\\begin{array}{ccc| cccc} 2 & 0 & 1 & 1 & 0 & 0 \\\\0 & 3 & 4 & 0 & 1 & 0 \\\\2 & 2 & 1 & 0 & 0 & 1 \\end{array}\\right]\\quad \\sim \\quad\\left[\\begin{array}{ccc| cccc} 2 & 0 & 1 & 1 & 0 & 0 \\\\0 & 3 & 4 & 0 & 1 & 0 \\\\2 & 2 & 1 & 0 & 0 & 1 \\end{array}\\right]$" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "m=al.echelonnage(i,j,r,alpha,A,m,MatriceList,RhSList)" ] }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "metadata": { "scrolled": true }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Insérez ici la valeur de la solution calculée\n", - "La suite entrée n'est pas une solution de l'équation 1\n", - "La suite entrée n'est pas une solution de l'équation 2\n", - "La suite entrée n'est pas une solution de l'équation 3\n", - "Ce n'est pas une solution du système\n" - ] - } - ], + "outputs": [], "source": [ "print('Insérez ici la valeur de la solution calculée')\n", "A_inv = [[1,0,0], [0,1,0], [0,0,1]]\n", "x2 = np.dot(np.array(A_inv), np.array(b))\n", "res2 = al.SolOfSyst(x2, A, b)" ] }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "metadata": { "scrolled": true }, "outputs": [], "source": [ "if res1 and res2:\n", " print(f'Tu as raison! Et en plus, x1 = {x1} est la seule solution au système linéaire')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### EXERCICE 1\n", "Considérez le système d'équations suivant:\n", "\\begin{equation}\n", "\\begin{cases}\n", "x_1 + 2x_2 - x_3 &=0\\\\\n", "2x_1 - x_2 - x_3 &=1\\\\\n", "x_1 - 2x_2 + x_3 &=2\n", "\\end{cases}\n", "\\end{equation}\n", "Laquelle des affirmations suivantes est correcte?" ] }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "metadata": { - "scrolled": true + "scrolled": false }, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "5db253618ea244038a6bef4c133d9e03", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "interactive(children=(Checkbox(value=False, description='Le système admet une solution unique et elle est:$$\\\\…" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "corrections.Ex1Chapitre2_4()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Vous pouvez exécuter les cellules suivantes pour vous aider à calculer (éventuellement) la solution du système linéaire et l'inverse de la matrice $A$, si elle existe" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true }, "outputs": [], "source": [ "A = [[1,2,-1],[2,-1,-1],[1,-2,1]]\n", "b = [[1], [-2], [1]]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true }, "outputs": [], "source": [ "print('Vous allez échelonner la matrice augmenteé')\n", "al.printAAug(A,b)\n", "[i,j,r,alpha]= al.manualEch(A)\n", "MatriceList=[np.array(A)]\n", "RHSList = [np.array(b)]\n", "m=np.concatenate((A,b), axis=1)\n", "print('\\033[1mExecutez la ligne suivante pour effectuer l\\'opération choisie \\033[0m')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true }, "outputs": [], "source": [ "m=al.echelonnage(i, j, r, alpha, A, m, MatriceList, RHSList)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true }, "outputs": [], "source": [ "I=[[1,0,0],[0,1,0],[0,0,1]]\n", "print('Vous allez échelonner la matrice augmenteé avec la matrice identité')\n", "al.printA(A,I)\n", "[i,j,r,alpha]= al.manualEch(A,I)\n", "m=np.concatenate((A,I), axis=1)\n", "MatriceList=[A]\n", "RhSList=[I]\n", "print('\\033[1mExecutez la ligne suivante pour effectuer l\\'opération choisie \\033[0m')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true }, "outputs": [], "source": [ "m=al.echelonnage(i,j,r,alpha,A,m,MatriceList,RhSList)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### EXERCICE 2\n", "\n", "Considérez le système linéaire $Ax = b$ avec:\n", "\\begin{equation}\n", "A = \n", - "\\begin{bmatrix}\n", + "\\begin{pmatrix}\n", "1 & 3 & 2\\\\\n", "0 & 4 & 1\\\\\n", "1 & -5 & 0\n", - "\\end{bmatrix}\n", + "\\end{pmatrix}\n", "\\qquad b=\n", - "\\begin{bmatrix}\n", + "\\begin{pmatrix}\n", "3\\\\\n", "5\\\\\n", "\\alpha\n", - "\\end{bmatrix}\n", + "\\end{pmatrix}\n", "\\end{equation}\n", "Laquelle des affirmations suivantes est correcte?" ] }, { "cell_type": "code", - "execution_count": 11, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "930c847bedab4e0fad8a1171b8469c7c", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "interactive(children=(Checkbox(value=False, description=\"Le système n'admet une solution unique que si $\\\\alph…" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "corrections.Ex2Chapitre2_4()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[Passez au notebook 2.5: Matrices élémentaires](2.5%20Matrices%20élémentaires.ipynb)" ] } ], "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.9" } }, "nbformat": 4, "nbformat_minor": 4 } diff --git "a/Chapitre 2 - Algebre matricielle/2.5 Matrices \303\251l\303\251mentaires.ipynb" "b/Chapitre 2 - Algebre matricielle/2.5 Matrices \303\251l\303\251mentaires.ipynb" index 887c5d0..4344abb 100644 --- "a/Chapitre 2 - Algebre matricielle/2.5 Matrices \303\251l\303\251mentaires.ipynb" +++ "b/Chapitre 2 - Algebre matricielle/2.5 Matrices \303\251l\303\251mentaires.ipynb" @@ -1,211 +1,211 @@ { "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# **Concept(s)-clé(s) et théorie**\n", "\n", "## Rappel\n", "\n", - "Etant donné une matrice générique $A \\in M_{m \\times n}(\\mathbb{R})$, nous définissons les opérations élémentaires de type:\n", + "Etant donné une matrice générique $A \\in \\mathcal{M}_{m \\times n}(\\mathbb{R})$, nous définissons les opérations élémentaires de type:\n", "* (I): échanger deux lignes de matrice A\n", "* (II): multiplier une ligne de matrice A par un scalaire\n", "* (III): ajouter à une ligne de matrice A le multiple d'une autre ligne de la même matrice\n", "\n", "## Définition\n", "Une matrice élémentaire (de taille $n \\times n$) est une matrice obtenue en effectuant une (et une seule) opération élémentaire, de type (I), (II) ou (III), sur les lignes de la matrice $I_n$ (i.e. la matrice d'identité de taille $n \\times n$). Concrétement, on adoptera les notations suivantes:\n", "\n", "* (I) La matrice $T_{ij}$ est la matrice obtenue en échangeant les lignes $i$ et $j$ de $I_n$.\n", "* (II) La matrice $D_r(\\lambda)$ est la matrice obtenue en multipliant la $r$-ème ligne de $I_n$ par $\\lambda \\in \\mathbb{R}$.\n", "* (III) La matrice $L_{rs}(\\lambda)$ est la matrice obtenue en ajoutant $\\lambda$ fois la ligne $s$ à la ligne $r$ de $I_n$.\n", "\n", "## Théorème\n", - "Soient $A \\in M_{m \\times n}(\\mathbb{R})$ une matrice arbitraire et $E \\in M_{m \\times m}(\\mathbb{R})$ une matrice élémentaire de type (I), (II) ou (III). Alors $EA$ est la matrice obtenue en effectuant sur les lignes de $A$ l'opération de type (I), (II) ou (III), qui définit la matrice $E$.\n", + "Soient $A \\in \\mathcal{M}_{m \\times n}(\\mathbb{R})$ une matrice arbitraire et $E \\in \\mathcal{M}_{m \\times m}(\\mathbb{R})$ une matrice élémentaire de type (I), (II) ou (III). Alors $EA$ est la matrice obtenue en effectuant sur les lignes de $A$ l'opération de type (I), (II) ou (III), qui définit la matrice $E$.\n", "\n", "## Corollaire\n", "Les matrices élémentaires sont inversibles. On a en effet:\n", "* (I): $T_{ij}^{-1} = T_{ji} = T_{ij}$\n", "* (II): $D_r(\\lambda)^{-1} = D_r(\\lambda^{-1})$\n", "* (III): $L_{rs}(\\lambda)^{-1} = L_{rs}(-\\lambda)$" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import Librairie.AL_Fct as al\n", "import Corrections.corrections as corrections\n", "import numpy as np\n", "from numpy.linalg import *\n", "from ipywidgets import interact_manual" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Exercice 1\n", "Soient les deux matrices élémentaires ci-dessous.\n", "$$\n", - "E_1=\\begin{bmatrix}\n", + "E_1=\\begin{pmatrix}\n", "1 & 0 & 0 & 0\\\\\n", "0 & 1 & 0 & -6 \\\\\n", "0 & 0 & 1 &0 \\\\\n", "0 & 0 & 0 & 1\n", - "\\end{bmatrix}\\hspace{3cm}\n", - "E_2=\\begin{bmatrix}\n", + "\\end{pmatrix}\\hspace{3cm}\n", + "E_2=\\begin{pmatrix}\n", "0 & 0 & 1 & 0\\\\\n", "0 & 1 & 0 & 0 \\\\\n", "1 & 0 & 0 &0 \\\\\n", "0 & 0 & 0& 1\n", - "\\end{bmatrix}\n", + "\\end{pmatrix}\n", "$$\n", "**ÉTAPE 1**: Laquelle des affirmations ci-dessous est correcte?\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "corrections.Ex1aChapitre2_5()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**ÉTAPE 2**: Donner l'inverse de $E_1E_2$\n", "\n", "**Aide** \n", "Considérez deux matrices inversibles $A, B \\in M_{n \\times n}(\\mathbb{R})$; alors $$(AB)^{- 1}=B^{- 1}A^{- 1}$$\n", "\n", "*Observation*: Inverser l'effet de $n$ opérations élémentaires consécutives consiste à appliquer l'inverse de chaque opération, de la dernière à la première." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print('Insérez ici la valeur de la matrice inverse')\n", "inverse= [[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]]\n", "corrections.Ex1bChapitre2_5(inverse)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Exercice 2\n", "Soient $A$ et $B$ les deux matrices ci-dessous. \n", "\n", "$$\n", - "A=\\begin{bmatrix}\n", + "A=\\begin{pmatrix}\n", "-2 &1& 4\\\\\n", "1 & 0 & 2\\\\\n", "-1 & -\\dfrac{1}{2} & 3\n", - "\\end{bmatrix}, \\hspace{2em}\n", - "B=\\begin{bmatrix}\n", + "\\end{pmatrix}, \\hspace{2em}\n", + "B=\\begin{pmatrix}\n", "-1 & -\\dfrac{1}{2} & 3 \\\\\n", "5 & 2 & -10\\\\\n", "-10 & 5 & 20\n", - "\\end{bmatrix}\n", + "\\end{pmatrix}\n", "$$" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "A=[[-2,1,4],[1,0,2],[-1, -1/2 , 3]]\n", "B=[[-1, -1/2, 3],[5, 2, -10],[-10,5,20]]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "On passe de la matrice $A$ à la matrice $B$ à l'aide de trois matrices élémentaires $T_{ij}$, $D_{r}(\\lambda)$ et $L_{rs}(\\lambda)$\n", "$$\n", "L_{rs}(\\lambda) \\cdot D_{r}(\\lambda)\\cdot T_{ij}\\cdot A =B\n", "$$\n", "\n", "**ÉTAPE 1**: Trouvez les 3 matrices et insérez-les ci-dessous." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "T=[[1,0,0],[0,1,0],[0,0,1]]\n", "D=[[1,0,0],[0,1,0],[0,0,1]]\n", "L=[[1,0,0],[0,1,0],[0,0,1]]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "corrections.Ex2aChapitre2_5(A, B, T, D, L)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**ÉTAPE 2**: Donner l'inverse de $L_{rs}(\\lambda) \\cdot D_{r}(\\lambda)\\cdot T_{ij}$" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print('Insérez ici la valeur de la matrice inverse')\n", "inverse= [[1,0,0],[0,1,0],[0,0,1]]\n", "corrections.Ex2bChapitre2_5(inverse)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[Passez au notebook 2.6-7: Critéres d'inversibilité](2.6-2.7%20Critères%20d'inversibilité.ipynb)" ] } ], "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.4" } }, "nbformat": 4, "nbformat_minor": 2 } diff --git "a/Chapitre 2 - Algebre matricielle/2.6-2.7 Crit\303\250res d'inversibilit\303\251.ipynb" "b/Chapitre 2 - Algebre matricielle/2.6-2.7 Crit\303\250res d'inversibilit\303\251.ipynb" index 7d73810..f3eca54 100644 --- "a/Chapitre 2 - Algebre matricielle/2.6-2.7 Crit\303\250res d'inversibilit\303\251.ipynb" +++ "b/Chapitre 2 - Algebre matricielle/2.6-2.7 Crit\303\250res d'inversibilit\303\251.ipynb" @@ -1,270 +1,272 @@ { "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# **Concept(s)-clé(s) et théorie**\n", "\n", "## PREMIER CRITÈRE D'INVERSIBILITÉ \n", - "Une matrice $A \\in M_{n \\times n}(\\mathbb{R})$ est inversible si et seulement si le système homogène $Ax=0$ possède une solution unique, à savoir, la solution triviale.\n", + "Une matrice $A \\in \\mathcal{M}_{n \\times n}(\\mathbb{R})$ est inversible si et seulement si le système homogène $Ax=0$ possède une solution unique, à savoir, la solution triviale.\n", "\n", "## COROLLAIRE DU PREMIER CRITÈRE D'INVERSIBILITÉ \n", - "Soit $A \\in M_{n \\times n}(\\mathbb{R})$ alors les deux affirmations suivantes sont vérifiées.\n", + "Soit $A \\in \\mathcal{M}_{n \\times n}(\\mathbb{R})$ alors les deux affirmations suivantes sont vérifiées.\n", "\n", - "1. La matrice $A$ est inversible si et seulement s'il existe $B \\in M_{n \\times n}(\\mathbb{R})$ telle que $BA = I_n$.\n", - "2. La matrice $A$ est inversible si et seulement s'il existe $C \\in M_{n \\times n}(\\mathbb{R})$ telle que $AC = I_n$.\n", + "1. La matrice $A$ est inversible si et seulement s'il existe $B \\in \\mathcal{M}_{n \\times n}(\\mathbb{R})$ telle que $BA = I_n$.\n", + "2. La matrice $A$ est inversible si et seulement s'il existe $C \\in \\mathcal{M}_{n \\times n}(\\mathbb{R})$ telle que $AC = I_n$.\n", "\n", "## RAPPEL: ALGORITHME POUR TROUVER L'INVERSE D'UNE MATRICE DONNÉE\n", - "Soit $A \\in M_{n \\times n}(\\mathbb{R})$ une matrice carrée. Afin de déterminer si $A$ est inversible et de calculer son inverse (lorsque c'est possible), on procède comme suit :\n", + "Soit $A \\in \\mathcal{M}_{n \\times n}(\\mathbb{R})$ une matrice carrée. Afin de déterminer si $A$ est inversible et de calculer son inverse (lorsque c'est possible), on procède comme suit :\n", "\n", "1. Ecrire les matrices $A$ et $I_n$ l'une à côté de l'autre, formant ainsi une nouvelle matrice de taille $n \\times 2n$\n", "2. Opérer sur les lignes de cette matrice ainsi obtenue, afin de réduire le côté gauche à $I_n$\n", "3. Si l'on y arrive, alors $A$ est inversible et son inverse $A^{-1}$ est donnée par la matrice à droite." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import Librairie.AL_Fct as al\n", "import Corrections.corrections as corrections\n", "from ipywidgets import interact_manual\n", "import plotly as py\n", "import plotly.graph_objs as go\n", - "from ipywidgets import interactive, HBox, VBox, widgets, interact, FloatSlider" + "from ipywidgets import interactive, HBox, VBox, widgets, interact, FloatSlider\n", + "import numpy as np" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### EXERCICE 1\n", - "Considérez le système linéaire générique $Ax=b$ avec $A \\in \\mathbb{R}^{n \\times n}$ et $b \\in \\mathbb{R}^n$; marquez celles des déclarations suivantes qui pourraient être vraies pour certaines valeurs de $A$ et $b$." + "Considérez le système linéaire générique $Ax=b$ avec $A \\in \\mathcal{M}_{n \\times n}(\\mathbb{R})$ et $b \\in \\mathcal{M}_{n \\times 1}(\\mathbb{R})$; marquez celles des déclarations suivantes qui pourraient être vraies pour certaines valeurs de $A$ et $b$." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "corrections.Ex1Chapitre2_6_7()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## EXERCICE 2 ##\n", "Mark those of the following matrices which are invertible.\n", "\\begin{equation}\n", "A_1 = \n", - "\\begin{bmatrix}\n", + "\\begin{pmatrix}\n", "2 & 0 & 1\\\\\n", "0 & 6 & 4 \\\\\n", "2 & 2 & 1\n", - "\\end{bmatrix}; \\qquad A_2 = \n", - "\\begin{bmatrix}\n", + "\\end{pmatrix} \\qquad A_2 = \n", + "\\begin{pmatrix}\n", "3 & -7 & 0\\\\\n", "1 & 0 & 1\\\\\n", "-5 & 35/3 & 0\n", - "\\end{bmatrix}; \\qquad A_3 = \n", - "\\begin{bmatrix}\n", + "\\end{pmatrix} \\qquad A_3 = \n", + "\\begin{pmatrix}\n", "2 & 1 & -1\\\\\\\n", "2 & -5 & 4\\\\\n", "6 & -3 & 2\n", - "\\end{bmatrix}\n", + "\\end{pmatrix}\n", "\\end{equation}" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "corrections.Ex2Chapitre2_6_7()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Vous pouvez vous aider à déterminer si les matrices suivantes sont inversibles ou non en exécutant les cellules suivantes et en calculant manuellement leurs inverses (éventuelles)**" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "A=[[2,0,1], [0,6,4], [2,2,1]]\n", "I=[[1,0,0],[0,1,0],[0,0,1]]\n", "print('Vous allez échelonner la matrice augmenteé avec la matrice identité')\n", "al.printA(A,I)\n", "[i,j,r,alpha]= al.manualEch(A,I)\n", "m=np.concatenate((A,I), axis=1)\n", "MatriceList=[A]\n", "RhSList=[I]\n", "print('\\033[1mExecutez la ligne suivante pour effectuer l\\'opération choisie \\033[0m')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m=al.echelonnage(i,j,r,alpha,A,m,MatriceList,RhSList)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## EXERCISE 3 ##\n", "Considéz le système linéaire générique $Ax = b$, avec:\n", "\\begin{equation}\n", "A = \n", - "\\begin{bmatrix}\n", + "\\begin{pmatrix}\n", "2 & -\\alpha\\\\\n", "\\beta & -4 \\\\\n", - "\\end{bmatrix}; \\qquad b = \n", - "\\begin{bmatrix}\n", + "\\end{pmatrix} \\qquad b = \n", + "\\begin{pmatrix}\n", "1\\\\\n", "-2\\\\\n", - "\\end{bmatrix}\n", + "\\end{pmatrix}\n", "\\end{equation}\n", "Identifiez les valeurs des paramètres $\\alpha$ et $\\beta$ pour lesquels $A$ n'est pas inversible et marquez celles des déclarations suivantes qui sont correctes." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "corrections.Ex3Chapitre2_6_7()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "**HINT: you can run the following interactive cell to better visualize the parametrized system**" + "**AIDE: vous pouvez exécuter la cellule interactive suivante pour mieux visualiser le système paramétré**" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "np.seterr(divide='ignore', invalid='ignore')\n", "\n", "A=[[2, 0], [0, -4]] # we initialize the problem. The values of alpha and beta are fixed\n", "b=[1, -2]\n", "\n", "m=len(A)\n", "MatCoeff = [A[i]+[b[i]]for i in range(m)] #becomes augmented matrix\n", "MatCoeff=np.array(MatCoeff)\n", "data=[]\n", "x=np.linspace(-15,15,101)\n", "y=np.linspace(-10,10,101)\n", "MatCoeff=np.array(MatCoeff)\n", "for i in range(len(MatCoeff)):\n", " trace=go.Scatter(x=x, y= (MatCoeff[i,2]-MatCoeff[i,0]*x)/MatCoeff[i,1], name='d) Droite %d'%(i+1))\n", " data.append(trace)\n", " \n", "f=go.FigureWidget(data=data,\n", " layout=go.Layout(xaxis=dict(\n", " range=[-15, 15]\n", " ),\n", " yaxis=dict(\n", " range=[-10, 10]\n", " ) ) \n", ")\n", "\n", "def update_y(alpha, beta):\n", " MatCoeff= [[2, -alpha, 1],[beta, -4, -2]]\n", " MatCoeff=np.array(MatCoeff)\n", " if MatCoeff[0,1] == 0:\n", " MatCoeff[0,1] += 1e-3\n", " f.data[0].y = (MatCoeff[0,2]-MatCoeff[0,0]*x)/MatCoeff[0,1]\n", " if MatCoeff[1,1] == 0:\n", " MatCoeff[1,1] += 1e-3\n", " f.data[1].y=(MatCoeff[1,2]-MatCoeff[1,0]*x)/MatCoeff[1,1]\n", "\n", "freq_slider = interactive(update_y, alpha=(-20, 20, 1/2), beta=(-20, 20, 1/2))\n", "\n", "vb = VBox((f, freq_slider))\n", "vb.layout.align_items = 'center'\n", "vb" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## EXERCISE 4\n", "\n", - "Consider the following matrices:\n", + "Considérez les matrices suivantes:\n", "\\begin{equation}\n", "A = \n", - "\\begin{bmatrix}\n", + "\\begin{pmatrix}\n", "0.5 & a & 1\\\\\n", "0 & 2 & -1\\\\\n", "-2 & 1 & b\n", - "\\end{bmatrix}; \\qquad B = \n", - "\\begin{bmatrix}\n", + "\\end{pmatrix}; \\qquad B = \n", + "\\begin{pmatrix}\n", "-6 & -2 & -2\\\\\n", "4 & 2 & 1\\\\\n", "8 & 3 & 2\n", - "\\end{bmatrix}\n", + "\\end{pmatrix}\n", "\\end{equation}\n", - "Find the vlaues of the parameters $a$ and $b$ for which $A$ and $B$ are one the inverse of the other." + "\n", + "Trouvez les valeurs des paramètres $a$ et $b$ pour lesquels $A$ et $B$ sont l'un l'inverse de l'autre." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "corrections.Ex4Chapitre2_6_7()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[Passez au notebook 2.8-2.9: Décomposition LU (existance et algorithm)](2.8-2.9%20Décomposition%20LU%20(existance%20et%20algorithm).ipynb)" ] } ], "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.4" } }, "nbformat": 4, "nbformat_minor": 2 } diff --git "a/Chapitre 2 - Algebre matricielle/2.8-2.9 D\303\251composition LU (existance et algorithm).ipynb" "b/Chapitre 2 - Algebre matricielle/2.8-2.9 D\303\251composition LU (existance et algorithm).ipynb" index f007f02..26654ce 100644 --- "a/Chapitre 2 - Algebre matricielle/2.8-2.9 D\303\251composition LU (existance et algorithm).ipynb" +++ "b/Chapitre 2 - Algebre matricielle/2.8-2.9 D\303\251composition LU (existance et algorithm).ipynb" @@ -1,512 +1,347 @@ { "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# **Concept(s)-clé(s) et théorie**\n", "\n", "## Propriété: Opérations élémentaires sur les colonnes d'une matrice\n", - "Soit $A \\in \\mathbb{M}_{m \\times n}(\\mathbb{R})$. Alors les affirmations suivantes sont vérifiées:\n", + "Soit $A \\in \\mathcal{M}_{m \\times n}(\\mathbb{R})$. Alors les affirmations suivantes sont vérifiées:\n", "\n", "* La matrice $AT_{ij}$ est obtenue en échangeant les colonnes $i$ et $j$ de $A$.\n", "* La matrice $AD_{r}(\\lambda)$ est obtenue en multipliant la $r$-ème colonne de $A$ par $\\lambda$.\n", "* La matrice $AL_{rs}(\\lambda)$ est obtenue en ajoutant $\\lambda$ fois la $r$-ème colonne de $A$ à la s-ème.\n", "\n", "## Theoréme: Existance de la dècomposition LU d'une matrice\n", "Soit $A$ une matrice de taille $m \\times n$ et supposons qu'il soit possible de réduire $A$ à une forme échelonnée en n'utilisant que des opérations élémentaires de la forme $D_r(\\lambda), L_{rs}(\\lambda)$ (avec $r>s$) sur les lignes de $A$. Alors il existe une matrice triangulaire inférieure $L$ et une matrice triangulaire supérieure $U$ telles que $A=LU$.\n", "\n", "## Algorithme: Trouver L et U dans la dècomposition LU d'une matrice\n", "Soit $A$ une matrice admettant une décomposition $LU$. Afin de déterminer les matrices $L$ et $U$ dans une telle décomposition, on procède comme suit:\n", "\n", "1. On applique successivement les opérations élémentaires de types **(II)** (i.e. $D_{r}(\\lambda)$) et **(III)** (i.e. $L_{rs}(\\lambda)$), avec matrices élémentaires correspondantes $E_1, E_2, \\dots, E_k$, aux lignes de la matrice $A$ afin de la rendre échelonnée.\n", "2. On pose $U = E_k \\dots E_1A$, c'est-à-dire $U$ est la forme échelonnée de $A$ obtenue à l'aide des opérations élémentaires ci-dessus.\n", "3. La matrice $L$ est alors obtenue en opérant sur les colonnes de $I_n$ par $E_1^{-1} \\dots E_k^{-1}$, dans cet ordre." ] }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - " \n", - " " - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - " \n", - " " - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "import Librairie.AL_Fct as al\n", "import Corrections.corrections as corrections\n", "from ipywidgets import interact_manual\n", "import numpy as np" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Exercice 1\n", "\n", "Considérez la matrice suivante:\n", "\n", "\\begin{equation}\n", "A = \n", - "\\begin{bmatrix}\n", + "\\begin{pmatrix}\n", "2 & 0 & 4 & 2 \\\\\n", "3 & 0 & -1 & 0 \\\\\n", "0 & 2 & -2 & 1 \\\\\n", "1 & 1 & 0 & 2\n", - "\\end{bmatrix}\n", + "\\end{pmatrix}\n", "\\end{equation}\n", "\n", "Insérez les valeurs des matrices élémentaires par lesquelles $A$ doit être pré et post multiplié afin d'obtenir chacune des matrices suivantes.\n", "\n", "\\begin{equation}\n", "A_1 = \n", - "\\begin{bmatrix}\n", + "\\begin{pmatrix}\n", "4 & 0 & 4 & 2 \\\\\n", "3 & 0 & -1 & 0 \\\\\n", "1 & 2 & -2 & 1 \\\\\n", "-1 & 1 & 0 & 2\n", - "\\end{bmatrix}\n", + "\\end{pmatrix}\n", "\\quad A_2 = \n", - "\\begin{bmatrix}\n", + "\\begin{pmatrix}\n", "2 & 0 & 2 & -2 \\\\\n", "0 & 2 & -1 & -1 \\\\\n", "3 & 2 & -0.5 & 0 \\\\\n", "1 & 1 & 0 & 2\n", - "\\end{bmatrix}\n", + "\\end{pmatrix}\n", "\\quad A_3 = \n", - "\\begin{bmatrix}\n", + "\\begin{pmatrix}\n", "2 & 0 & 4 & -6 \\\\\n", "3 & 0 & -1 & 1 \\\\\n", "0 & 2 & -2 & 1 \\\\\n", "1 & 1 & 0 & 2\n", - "\\end{bmatrix}\n", + "\\end{pmatrix}\n", "\\quad A_4 = \n", - "\\begin{bmatrix}\n", + "\\begin{pmatrix}\n", "1 & 0 & 2 & -1 \\\\\n", "3 & 0 & -1 & 0 \\\\\n", "0 & 2 & 0 & -1 \\\\\n", "1 & 1 & 1 & 2\n", - "\\end{bmatrix}\n", + "\\end{pmatrix}\n", "\\end{equation}" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# MATRIX A1\n", "E_pre_1 = [[1,0,0,0], [0,1,0,0], [0,0,1,0], [0,0,0,1]]\n", - "E_post_1 = [[1,0,0,0], [0,1,0,0], [0,0,1,0], [-1,0,0,1]]\n", + "E_post_1 = [[1,0,0,0], [0,1,0,0], [0,0,1,0], [0,0,0,1]]\n", "\n", "# MATRIX A2\n", "E_pre_2 = [[1,0,0,0], [0,0,1,0], [0,1,0,0], [0,0,0,1]]\n", - "E_post_2 = [[1,0,0,0], [0,1,0,0], [0,0,1/2,0], [0,0,0,1]]\n", + "E_post_2 = [[1,0,0,0], [0,1,0,0], [0,0,1,0], [0,0,0,1]]\n", "\n", "# MATRIX A3\n", "E_pre_3 = [[1,0,0,0], [0,1,0,0], [0,0,1,0], [0,0,0,1]]\n", - "E_post_3 = [[1,0,0,0], [0,1,0,0], [0,0,1,-1], [0,0,0,1]]\n", + "E_post_3 = [[1,0,0,0], [0,1,0,0], [0,0,1,0], [0,0,0,1]]\n", "\n", "# MATRIX A4\n", - "E_pre_4 = [[1/2,0,0,0], [0,1,0,0], [0,0,1,0], [0,0,0,1]]\n", - "E_post_4 = [[1,0,0,0], [0,1,1,0], [0,0,1,0], [0,0,0,1]]" + "E_pre_4 = [[1,0,0,0], [0,1,0,0], [0,0,1,0], [0,0,0,1]]\n", + "E_post_4 = [[1,0,0,0], [0,1,0,0], [0,0,1,0], [0,0,0,1]]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "corrections.Ex1Chapitre2_8_9([E_pre_1, E_post_1],\n", " [E_pre_2, E_post_2], \n", " [E_pre_3, E_post_3], \n", " [E_pre_4, E_post_4])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Exercice 2\n", "\n", - "Pour chacune des matrices suivantes appartenant à $\\mathbb{R}^{4 \\times 4}$, déterminez si elles admettent ou non une décomposition LU.\n", + "Pour chacune des matrices suivantes appartenant à $\\mathcal{M}_{4 \\times 4}(\\mathbb{R})$, déterminez si elles admettent ou non une décomposition LU.\n", "\n", "\\begin{equation}\n", "A_1 = \n", - "\\begin{bmatrix}\n", + "\\begin{pmatrix}\n", "2 & -1 & -4 & 0 \\\\\n", "-1 & 2 & 0 & 3 \\\\\n", "3 & 1 & -3 & 5 \\\\\n", "1 & -3 & -5 & -5\n", - "\\end{bmatrix}\n", + "\\end{pmatrix}\n", "\\quad A_2 = \n", - "\\begin{bmatrix}\n", + "\\begin{pmatrix}\n", "3 & 2 & 1 & -1 \\\\\n", "0 & -1 & 1 & -2 \\\\\n", "2 & -3 & 2 & 0 \\\\\n", "1 & 0 & 0 & -1 \n", - "\\end{bmatrix}\n", + "\\end{pmatrix}\n", "\\quad A_3 = \n", - "\\begin{bmatrix}\n", + "\\begin{pmatrix}\n", "1 & 0 & -1 & 2 \\\\\n", "0 & 2 & -1 & 1 \\\\\n", "0 & -4 & 2 & 3 \\\\\n", "2 & 3 & -1 & -1\n", - "\\end{bmatrix}\n", + "\\end{pmatrix}\n", "\\end{equation}\n", "\n", "\n", "**Exécutez les cellules suivantes pour effectuer la méthode d'élimination de Gauss sur les 3 matrices**" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "A=[[1,0,0,0], [0,1,0,0], [0,0,1,0], [0,0,0,1]] # INSERT HERE THE VALUE OF THE MATRIX!!\n", + "A=[[1,0,0,0], [0,1,0,0], [0,0,1,0], [0,0,0,1]] # INSEREZ ICI LA VALEUR DE LA MATRICE!!\n", "print('Vous allez échelonner la matrice A')\n", "[i,j,r,alpha]= al.manualEch(A)\n", "m=np.array(A)\n", "MatriceList=[A]\n", "print('\\033[1mExecutez la ligne suivante pour effectuer l\\'opération choisie \\033[0m')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m=al.echelonnage(i,j,r,alpha,A,m,MatriceList)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "corrections.Ex3Chapitre2_8_9()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Exercice 3\n", "\n", - "Considérez la matrice carrée $A \\in \\mathbb{R}^{3 \\times 3}$ suivante:\n", + "Considérez la matrice carrée $A \\in \\mathcal{M}_{3 \\times 3}(\\mathbb{R})$ suivante:\n", "\n", "\\begin{equation}\n", "A = \n", - "\\begin{bmatrix}\n", + "\\begin{pmatrix}\n", "2 & 0 & 1 \\\\\n", "0 & 6 & 4 \\\\\n", "2 & 2 & 1\n", - "\\end{bmatrix}\n", + "\\end{pmatrix}\n", "\\end{equation}\n", "\n", "En utilisant la la méthode d'élimination de Gauss, calculez, si possible, la décomposition LU de $A$. Profitez des cellules interactives suivantes et comprenez, à chaque passage, comment ont été dérivées $L$ et $U$." ] }, { "cell_type": "code", - "execution_count": 22, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Vous allez échelonner la matrice A\n" - ] - }, - { - "data": { - "text/latex": [ - "$\\left[\\begin{array}{cccc} 1 & 0 & -1 & -2 \\\\0 & -4 & -2 & 1 \\\\1 & 2 & 2 & 1 \\\\-2 & 1 & 1 & -1 \\end{array}\\right]$" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Régler les paramètres et évaluer la cellule suivante\n", - "Répéter cela jusqu'à obtenir une forme échelonnée réduite\n" - ] - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "890cec3e201f4cebb1e61cf000d7748b", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "RadioButtons(description='Opération:', options=('Eij', 'Ei(alpha)', 'Eij(alpha)', 'Revert'), value='Eij')" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "87040d6f1d06421286308be9015a45bd", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "BoundedIntText(value=1, description='Ligne i:', max=4, min=1)" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "86d7cd4b61f34db294277e881909a896", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "BoundedIntText(value=1, description='Ligne j:', max=4, min=1)" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "1c5757e81b6b4ea180c9a57e545ff801", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "Text(value='1', description='Coeff. alpha:')" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[1mExecutez la ligne suivante pour effectuer l'opération choisie \u001b[0m\n" - ] - } - ], + "outputs": [], "source": [ "A=[[2,0,1], [0,6,4], [2,2,1]]\n", "print('Vous allez échelonner la matrice A')\n", "al.printA(A)\n", "[i,j,r,alpha]= al.manualEch(A)\n", "LList = [np.eye(3)]\n", "UList=[np.array(A).astype(float)]\n", "print('\\033[1mExecutez la ligne suivante pour effectuer l\\'opération choisie \\033[0m')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m=al.LU_interactive(i,j,r,alpha, LList, UList)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Exécutez la cellule suivante pour calculer les valeurs corrects de $ L $ et $ U $ et comparez-les à celles que vous venez de dériver**" ] }, { "cell_type": "code", - "execution_count": 23, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/latex": [ - "$L = \\left[\\begin{array}{cccc} 1 & 0 & 0 & 0 \\\\0 & 1 & 0 & 0 \\\\1 & -0.5 & 1 & 0 \\\\-2 & -0.25 & -0.75 & 1 \\end{array}\\right]$" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/latex": [ - "$U = \\left[\\begin{array}{cccc} 1 & 0 & -1 & -2 \\\\0 & -4 & -2 & 1 \\\\0 & 0 & 2 & 3.5 \\\\0 & 0 & 0 & -2.125 \\end{array}\\right]$" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "L_ref, U_ref = al.LU_no_pivoting(A)\n", "al.printA(L_ref, name='L')\n", "al.printA(U_ref, name='U')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Exercice 4\n", "\n", - "Considérez la matrice rectangulaire $B \\in \\mathbb{R}^{3 \\times 4}$ (**représentant un système linéaire sous-déterminé**) suivante:\n", + "Considérez la matrice rectangulaire $B \\in \\mathcal{M}_{3 \\times 4}(\\mathbb{R})$ (**représentant un système linéaire sous-déterminé**) suivante:\n", "\n", "\\begin{equation}\n", "B = \n", - "\\begin{bmatrix}\n", + "\\begin{pmatrix}\n", "-1 & 2 & 0 & 3 \\\\\n", "-1 & 0 & 2 & 4 \\\\\n", "0 & -2 & 1 & 1\n", - "\\end{bmatrix}\n", + "\\end{pmatrix}\n", "\\end{equation}\n", "\n", "En utilisant la la méthode d'élimination de Gauss, calculez, si possible, la décomposition LU de $A$. Profitez des cellules interactives suivantes et comprenez, à chaque passage, comment ont été dérivées $L$ et $U$." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "B=[[-1,2,0,3], [-1,0,2,4], [0,-2,1,1]]\n", "print('Vous allez échelonner la matrice A')\n", "al.printA(B)\n", "[i,j,r,alpha]= al.manualEch(B)\n", "LList = [np.eye(3)]\n", "UList=[np.array(B).astype(float)]\n", "print('\\033[1mExecutez la ligne suivante pour effectuer l\\'opération choisie \\033[0m')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m=al.LU_interactive(i,j,r,alpha, LList, UList)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Exécutez la cellule suivante pour calculer les valeurs corrects de $ L $ et $ U $ et comparez-les à celles que vous venez de dériver**" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "L_ref, U_ref = al.LU_no_pivoting(B)\n", "al.printA(L_ref, name='L')\n", "al.printA(U_ref, name='U')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[Passez au notebook 2.10: Décomposition LU (applications au systèmes linéaires)](2.10%20Décomposition%20LU%20(applications%20aux%20systèmes%20linéaires).ipynb)" ] } ], "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.4" } }, "nbformat": 4, "nbformat_minor": 4 } diff --git a/Chapitre 2 - Algebre matricielle/Corrections/corrections.py b/Chapitre 2 - Algebre matricielle/Corrections/corrections.py index ebb4efa..5e07bfe 100644 --- a/Chapitre 2 - Algebre matricielle/Corrections/corrections.py +++ b/Chapitre 2 - Algebre matricielle/Corrections/corrections.py @@ -1,1059 +1,1062 @@ import sys sys.path.insert(0, './../') import numpy as np import plotly plotly.offline.init_notebook_mode(connected=True) import ipywidgets as widgets from IPython.display import display, Latex from ipywidgets import interact_manual, Layout from Librairie.AL_Fct import printA, texMatrix, isDiag, isSym def Ex2Chapitre2_1(): """Provides the correction of exercise 2 of notebook 2_1 """ a = widgets.Checkbox( value=False, description=r'Il existe \(\lambda\in \mathbb{R}\) tel que \((A-\lambda B)^T\) soit échelonnée réduite', disabled=False, layout=Layout(width='80%', height='30px') ) b = widgets.Checkbox( value=False, description=r'Il existe \(\lambda\in \mathbb{R}\) tel que \((A-\lambda B)^T\) soit échelonnée (mais pas réduite)', disabled=False, layout=Layout(width='80%', height='30px') ) c = widgets.Checkbox( value=False, description=r"Il n'existe pas de \(\lambda\in \mathbb{R}\) tel que \((A-\lambda B)^T\) soit échelonnée", disabled=False, layout=Layout(width='80%', height='30px') ) def correction(a, b, c): if a and not c and not b: display(Latex("C'est correct! Pour $\lambda=-3$ La matrice échelonnée réduite est:")) A = [[1, 0, -2, 3], [0, 1, -1, 7]] printA(A) else: display(Latex("C'est faux.")) interact_manual(correction, a=a, b=b, c=c) return def Ex3Chapitre2_1(): """Provides the correction of exercise 3 of notebook 2_1 """ a = widgets.Checkbox( value=False, description=r'\(C_{32}\) vaut -14', disabled=False, layout=Layout(width='80%', height='30px') ) b = widgets.Checkbox( value=False, description=r'\(C_{32}\) vaut 14', disabled=False, layout=Layout(width='80%', height='30px') ) c = widgets.Checkbox( value=False, description=r'\(C_{32}\) vaut -10', disabled=False, layout=Layout(width='80%', height='30px') ) d = widgets.Checkbox( value=False, description=r"\(C_{32}\) n'existe pas", disabled=False, layout=Layout(width='80%', height='30px') ) def correction(a, b, c, d): if c and not a and not b and not d: display(Latex("C'est correct! La matrice C vaut:")) - A = [[-6, 64], [-32, -22], [28, -10], [-2, 6]] - printA(A) + C = [[-6, 64], [-32, -22], [28, -10], [-2, 6]] + printA(C) else: display(Latex("C'est faux.")) interact_manual(correction, a=a, b=b, c=c, d=d) return def Ex1Chapitre2_2(): """Provides the correction of exercise 1 of notebook 2_2 """ a = widgets.Checkbox( value=False, - description=r'Le produit $A \cdot B$ vaut:
' - r'\begin{equation*} \qquad A \cdot B = \begin{bmatrix}-1 & 4\\-3& -3\\2 & 0\end{bmatrix}\end{equation*}', + description=r'Le produit $AB$ vaut:
' + r'\begin{equation*} \qquad AB = \begin{pmatrix}-1 & 4\\-3& -3\\2 & 0\end{pmatrix}\end{equation*}', disabled=False, layout=Layout(width='100%', height='110px') ) b = widgets.Checkbox( value=False, - description=r'Le produit $A \cdot B$ vaut:
' - r'\begin{equation*} \qquad A \cdot B =\begin{bmatrix}-1 & 8\\-3& 3\\-2 & 4\end{bmatrix}\end{equation*}', + description=r'Le produit $AB$ vaut:
' + r'\begin{equation*} \qquad AB =\begin{pmatrix}-1 & 8\\-3& 3\\-2 & 4\end{pmatrix}\end{equation*}', disabled=False, layout=Layout(width='100%', height='110px') ) c = widgets.Checkbox( value=False, - description=r'Le produit $A \cdot B$ vaut:
' - r'\begin{equation*} \qquad A \cdot B =\begin{bmatrix}5 & -4\\1 & 0\end{bmatrix}\end{equation*}', + description=r'Le produit $AB$ vaut:
' + r'\begin{equation*} \qquad AB =\begin{pmatrix}5 & -4\\1 & 0\end{pmatrix}\end{equation*}', disabled=False, layout=Layout(width='100%', height='90px') ) d = widgets.Checkbox( value=False, - description=r"Le produit $A \cdot B$ n'est pas définie", + description=r"Le produit $AB$ n'est pas défini", disabled=False, layout=Layout(width='100%', height='60px') ) def correction(a, b, c, d): if b and not a and not c and not d: display(Latex("C'est correct!")) else: display(Latex("C'est faux.")) interact_manual(correction, a=a, b=b, c=c, d=d) return def Ex2Chapitre2_2(): """Provides the correction of exercise 2 of notebook 2_2 """ a = widgets.Checkbox( value=False, - description=r'Le produit $A \cdot B$ appartient à $M_{3 \times 3}(\mathbb{R})$', + description=r'Le produit $AB$ appartient à $\mathcal{M}_{3 \times 3}(\mathbb{R})$', disabled=False, layout=Layout(width='80%', height='50px') ) b = widgets.Checkbox( value=False, - description=r'Le produit $A \cdot B$ appartient à $M_{3 \times 2}(\mathbb{R})$', + description=r'Le produit $AB$ appartient à $\mathcal{M}_{3 \times 2}(\mathbb{R})$', disabled=False, layout=Layout(width='80%', height='50px') ) c = widgets.Checkbox( value=False, - description=r'Le produit $A \cdot B$ appartient à $M_{2 \times 1}(\mathbb{R})$', + description=r'Le produit $AB$ appartient à $\mathcal{M}_{2 \times 1}(\mathbb{R})$', disabled=False, layout=Layout(width='80%', height='50px') ) d = widgets.Checkbox( value=False, - description=r"$A \cdot B$ n'est pas définie", + description=r"$AB$ n'est pas définie", disabled=False, layout=Layout(width='80%', height='50px') ) def correction(a, b, c, d): if c and not a and not b and not d: A = [[14], [6]] texA = '$' + texMatrix(A) + '$' - display(Latex(r"C'est correct! Le produit $ A \cdot B$ vaut: $A \cdot B$ = " + texA)) + display(Latex(r"C'est correct! Le produit $ AB$ vaut: $AB$ = " + texA)) else: display(Latex("C'est faux.")) interact_manual(correction, a=a, b=b, c=c, d=d) return def Ex3Chapitre2_2(): """Provides the correction of exercise 3 of notebook 2_2 """ - display(Latex("Insert the values of a and b as floating point numbers")) + display(Latex("Insérez les valeurs de a et b")) a = widgets.FloatText( value=0.0, step=0.1, description='a:', disabled=False ) b = widgets.FloatText( value=0.0, step=0.1, description='b:', disabled=False ) display(a) display(b) def f(): A = np.array([[-1, 2], [5, -2]]) B = np.array([[-1, 1], [a.value, b.value]]) AB = np.dot(A,B) texAB = '$' + texMatrix(AB) + '$' BA = np.dot(B,A) texBA = '$' + texMatrix(BA) + '$' if a.value == 5/2 and b.value == -3/2: - display(Latex(r"Correcte! Le produits $A \cdot B$ et $B \cdot A$ valent chacun: " + texAB)) + display(Latex(r"Correcte! Le produits $AB$ et $BA$ valent chacun: " + texAB)) else: - display(Latex(r"Incorrecte! Le produit $A \cdot B$ vaut " + texAB + r"et par contre le produit " - r"$B \cdot A$ vaut " + texBA + r" Entrez de nouvelles valeurs!")) + display(Latex(r"Incorrecte! Le produit $AB$ vaut " + texAB + r"et par contre le produit " + r"$BA$ vaut " + texBA + r". Entrez de nouvelles valeurs!")) interact_manual(f) return def Ex1Chapitre2_3(A, B, C): """Provides the correction to exercise 1 of notebook 2_3 :param A: original matrix :type A: list[list] or numpy.ndarray :param B: matrix such that A+B should be diagonal :type B: list[list] or numpy.ndarray :param C: matrix such that A+C should be symmetric and not diagonal :type C: list[list] or numpy.ndarray :return: :rtype: """ if not type(A) is np.ndarray: A = np.array(A) if not type(B) is np.ndarray: B = np.array(B) if not type(C) is np.ndarray: C = np.array(C) ans1 = isDiag(A+B) ans2 = isSym(A+C) and not isDiag(A+C) if ans1 and ans2: display(Latex('Correcte!')) else: display(Latex('Incorrecte! Entrez des nouvelles valeurs pur le matrices B et C!\n')) if ans1: display(Latex("A+B est bien diagonale!")) else: display(Latex("A+B est n'est pas diagonale!")) texAB = '$' + texMatrix(A+B) + '$' display(Latex(r"A+B=" + texAB)) if ans2: display(Latex("A+C est bien symétrique et non diagonale!")) elif isSym(A + C) and isDiag(A + C): display(Latex("A+C est bien symétrique mais elle est aussi diagonale!")) else: display(Latex("A + C n'est pas symétrique")) texAC = '$' + texMatrix(A + C) + '$' display(Latex(r"A+C=" + texAC)) return def Ex2Chapitre2_3(): """Provides the correction to exercise 2 of notebook 2_3 """ a = widgets.Checkbox( value=False, description=r'$(A^{-1})^T$ et $(A^T)^{-1}$ sont triangulaires supérieures mais différentes', disabled=False, layout=Layout(width='80%', height='40px') ) b = widgets.Checkbox( value=False, description=r'$(A^{-1})^T$ et $(A^T)^{-1}$ sont triangulaires inférieures mais différentes', disabled=False, layout=Layout(width='80%', height='40px') ) c = widgets.Checkbox( value=False, description=r'$(A^{-1})^T$ et $(A^T)^{-1}$ sont triangulaires inférieures et identiques', disabled=False, layout=Layout(width='80%', height='40px') ) d = widgets.Checkbox( value=False, description=r'$(A^{-1})^T$ et $(A^T)^{-1}$ sont triangulaires supérieures et identiques', disabled=False, layout=Layout(width='80%', height='40px') ) def correction(a, b, c, d): if d and not a and not c and not b: A = np.array(([-1, 0, 0], [3, 1/2, 0], [1, 2, 1])) res = np.transpose(np.linalg.inv(A)) texAres = '$' + texMatrix(res) + '$' display(Latex("C'est correct! $(A^T)^{-1}$ est donnée par: $\quad$" + texAres)) else: display(Latex("C'est faux.")) interact_manual(correction, a=a, b=b, c=c, d=d) return def Ex1Chapitre2_4(): """Provides the correction to exercise 2 of notebook 2_4 """ a = widgets.Checkbox( value=False, description=r'Le système admet une solution unique et elle est:' - r'$$\qquad \qquad x = \begin{bmatrix} 1&4/3&4/3\end{bmatrix}^T$$', + r'$$\qquad \qquad x = \begin{pmatrix} 1&4/3&4/3\end{pmatrix}^T$$', disabled=False, layout=Layout(width='80%', height='70px') ) b = widgets.Checkbox( value=False, description=r"Le système n'admet aucune solution", disabled=False, layout=Layout(width='80%', height='40px') ) c = widgets.Checkbox( value=False, description=r'Le système admet une solution unique et elle est:' - r'$$\qquad \qquad x = \begin{bmatrix} 1&4/3&8/3\end{bmatrix}^T$$', + r'$$\qquad \qquad x = \begin{pmatrix} 1&4/3&8/3\end{pmatrix}^T$$', disabled=False, layout=Layout(width='80%', height='70px') ) d = widgets.Checkbox( value=False, description=r'Le système admet plusieurs solutions', disabled=False, layout=Layout(width='80%', height='40px') ) e = widgets.Checkbox( value=False, description=r'$A$ est inversible et son inverse est:
' - r'$$\qquad \qquad A^{-1} = \begin{bmatrix} 1/2&0&1/2\\1/2&-1/3&5/3\\1/2&-2/3&5/6\end{bmatrix}$$', + r'$$\qquad \qquad A^{-1} = \begin{pmatrix} 1/2&0&1/2\\1/2&-1/3&5/3\\1/2&-2/3&5/6\end{pmatrix}$$', disabled=False, layout=Layout(width='80%', height='100px') ) f = widgets.Checkbox( value=False, description=r"$A$ n'est pas inversible", disabled=False, layout=Layout(width='80%', height='40px') ) g = widgets.Checkbox( value=False, description=r'$A$ est inversible et son inverse est:' - r'$$\qquad \qquad A^{-1} = \begin{bmatrix} 1/2&0&1/2\\1/2&-1/3&5/3\\1/2&-2/3&-1/2\end{bmatrix}$$', + r'$$\qquad \qquad A^{-1} = \begin{pmatrix} 1/2&0&1/2\\1/2&-1/3&5/3\\1/2&-2/3&-1/2\end{pmatrix}$$', disabled=False, layout=Layout(width='80%', height='100x') ) def correction(a, b, c, d, e, f, g): if c and e and not a and not b and not d and not f and not g: display(Latex("C'est correct!")) else: display(Latex("C'est faux.")) interact_manual(correction, a=a, b=b, c=c, d=d, e=e, f=f, g=g) return def Ex2Chapitre2_4(): """Provides the correction to exercise 3 of notebook 2_4 """ a = widgets.Checkbox( value=False, description=r"Le système n'admet une solution unique que si $\alpha < 2$", disabled=False, layout=Layout(width='80%', height='40px') ) b = widgets.Checkbox( value=False, description=r"Le système n'admet une solution unique que si $\alpha \geq 2$", disabled=False, layout=Layout(width='80%', height='40px') ) c = widgets.Checkbox( value=False, description=r'Le système admet une solution unique $\forall \alpha \in \mathbb{R}$', disabled=False, layout=Layout(width='80%', height='40px') ) d = widgets.Checkbox( value=False, description=r"Le système n'admet aucune solution si $\alpha < 2$, alors qu'il admet une solution unique si " r"$\alpha \geq 2$", disabled=False, layout=Layout(width='80%', height='40px') ) e = widgets.Checkbox( value=False, description=r"Le système admet plusieurs solutions si $\alpha \neq 2$, alors qu'il admet une solution unique si" r" $\alpha = 2$", disabled=False, layout=Layout(width='80%', height='40px') ) f = widgets.Checkbox( value=False, description=r"Le système n'admet jamais une solution unique, quelle que soit $\alpha \in \mathbb{R}$", disabled=False, layout=Layout(width='80%', height='40px') ) def correction(a, b, c, d, e, f): if f and not a and not b and not c and not d and not e: display(Latex("C'est correct!")) else: display(Latex("C'est faux.")) interact_manual(correction, a=a, b=b, c=c, d=d, e=e, f=f) return def Ex1aChapitre2_5(): """Provides the correction to exercise 1a of notebook 2_5 """ a = widgets.Checkbox( value=False, description=r'\(E_1E_2\) multiplie la ligne 4 par -6 et échange les lignes 2 et 3', disabled=False, layout=Layout(width='80%', height='40px') ) b = widgets.Checkbox( value=False, description=r'\(E_1E_2\) ajoute 6 fois la ligne 4 à la ligne 2 et échange les lignes 1 et 3', disabled=False, layout=Layout(width='80%', height='40px') ) c = widgets.Checkbox( value=False, description=r'\(E_1E_2\) échange les lignes 1 et 3 et ajoute -6 fois la ligne 4 à la ligne 2', disabled=False, layout=Layout(width='80%', height='40px') ) d = widgets.Checkbox( value=False, description=r"\(E_1E_2\) ajoute -6 fois la ligne 4 à la ligne 2 et échange les lignes 1 et 2", disabled=False, layout=Layout(width='80%', height='40px') ) def correction(a, b, c, d): if c and not(a) and not(d) and not(b): display(Latex("C'est correct! Par exemple, si on applique le produit à la matrice ci-dessous")) A=[[1,-1,0,0], [0,0,0,1], [1,2,1,2], [1,0,0,1]] B=[[1,0,0,0], [0,1,0,-6], [0,0,1,0], [0,0,0,1]] C=[[0,0,1,0], [0,1,0,0], [1,0,0,0], [0,0,0,1]] BCA = np.linalg.multi_dot([B,C,A]) texA = '$' + texMatrix(A) + '$' texBCA = '$' + texMatrix(BCA) + '$' display(Latex('$\qquad A = $' + texA)) display(Latex("on obtient")) display((Latex('$\qquad \hat{A} = $' + texBCA))) else: display(Latex("C'est faux.")) interact_manual(correction,a=a,b=b,c=c,d=d) return def Ex1bChapitre2_5(inv): """Provides the correction to exercise 1b of notebook 2_5 :param inv: inverse of the matrix to be calculated :type inv: list[list] """ if inv == [[0, 0, 1, 0], [0, 1, 0, 6], [1, 0, 0, 0], [0, 0, 0, 1]]: display(Latex("C'est correct!")) else: display(Latex("C'est faux.")) return def Ex2aChapitre2_5(A, B, T, D, L): """Provides the correction to exercise 2a of notebook 2_5 :param A: starting matrix :type A: list[list] :param B: target matrix :type B: list[list] :param T: permutation (type I) matrix :type T: list[list] :param D: scalar multiplication (type II) matrix :type D: list[list] :param L: linear combination (type III) matrix :type L: list[list] """ if ~(B - np.linalg.multi_dot([L, D, T, A])).any(): display(Latex("C'est correct!")) else: display(Latex("C'est faux.")) str = 'Il faut entrer la/les matrice(s) {' if (np.asmatrix(T) - np.asmatrix([[0, 0, 1], [0, 1, 0], [1, 0, 0]])).any(): str = str + ' T, ' if (np.asmatrix(D) - np.asmatrix([[1, 0, 0], [0, 1, 0], [0, 0, 5]])).any(): str = str + ' D, ' if (np.asmatrix(L) - np.asmatrix([[1, 0, 0], [-4, 1, 0], [0, 0, 1]])).any(): str = str + ' L, ' str = str + '}. Le produit des matrices entrées vaut:' display(Latex(str)) tmp = np.linalg.multi_dot([L, D, T, A]) texM = '$' + texMatrix(tmp) + '$' display(Latex('$\qquad \hat{B} = $' + texM)) return def Ex2bChapitre2_5(inv): """Provides the correction to exercise 2b of notebook 2_5 :param inv: inverse of the matrix to be calculated :type inv: list[list] """ if inv == [[0, 0, 1/5], [4, 1, 0], [1, 0, 0]]: display(Latex("C'est correct!")) else: display(Latex("C'est faux.")) return def Ex1Chapitre2_6_7(): """Provides the correction to exercise 1 of notebook 2_6-7 """ a = widgets.Checkbox( value=False, description=r'$A^{-1}$ existe et le système admet plusieurs solutions, quelle que soit la valeur de $b$', disabled=False, layout=Layout(width='80%', height='40px') ) b = widgets.Checkbox( value=False, description=r'$A^{-1}$ existe et le système admet une solution unique ou plusieurs solutions en fonction ' r'de la valeur de $b$', disabled=False, layout=Layout(width='80%', height='40px') ) c = widgets.Checkbox( value=False, description=r'$A$ est inversible et le système admet une solution unique, quelle que soit la valeur de $b$', disabled=False, layout=Layout(width='80%', height='40px') ) d = widgets.Checkbox( value=False, description=r'$A^{-1}$ existe et le système admet au moins une solution, quelle que soit la valeur de $b$', disabled=False, layout=Layout(width='80%', height='40px') ) e = widgets.Checkbox( value=False, description=r"$A$ n'est pas inversible et le système admet une unique solution ou plusieurs solutions, " r"selon la valeur de $b$ ", disabled=False, layout=Layout(width='80%', height='40px') ) f = widgets.Checkbox( value=False, description=r"$A$ n'est pas inversible et le système admet une solution unique, " r"quelle que soit la valeur de $b$", disabled=False, layout=Layout(width='80%', height='40px') ) g = widgets.Checkbox( value=False, description=r"Le système admet une solution unique et $A$ n'est pas inversible", disabled=False, layout=Layout(width='80%', height='40px') ) h = widgets.Checkbox( value=False, description=r'Le système admet une solution unique et $A$ est inversible', disabled=False, layout=Layout(width='80%', height='40px') ) def correction(a, b, c, d, e, f, g, h): if c and d and h and not a and not b and not e and not f and not g: display(Latex("C'est correct!")) else: display(Latex("C'est faux.")) interact_manual(correction, a=a, b=b, c=c, d=d, e=e, f=f, g=g, h=h) return def Ex2Chapitre2_6_7(): """Provides the correction to exercise 2 of notebook 2_6-7 """ a = widgets.Checkbox( value=False, description=r'$A_1$ est inversible', disabled=False, layout=Layout(width='80%', height='40px') ) b = widgets.Checkbox( value=False, description=r'$A_2$ est inversible', disabled=False, layout=Layout(width='80%', height='40px') ) c = widgets.Checkbox( value=False, description=r'$A_3$ est inversible', disabled=False, layout=Layout(width='80%', height='40px') ) def correction(a, b, c): if a and not b and not c: A1 = np.array([[2, 0, 1], [0, 6, 4], [2, 2, 1]]) A1_inv = np.linalg.inv(A1) texA1inv = '$' + texMatrix(A1_inv) + '$' display(Latex("C'est correct! $A_1$ est la seule matrice inversible et son inverse est: $\quad A_1^{-1} = $" + texA1inv)) else: display(Latex("C'est faux.")) interact_manual(correction, a=a, b=b, c=c) return def Ex3Chapitre2_6_7(): """Provides the correction to exercise 3 of notebook 2_6-7 """ style = {'description_width': 'initial'} a = widgets.Checkbox( value=False, description=r"Si $\alpha = 4$ et $\beta = 2$, alors $A$ n'est pas inversible et le système linéaire " r"admet une infinité de solutions", disabled=False, style=style, layout=Layout(width='80%', height='40px') ) b = widgets.Checkbox( value=False, description=r"Si $\alpha=8$ et $\beta=-1$, alors $A$ n'est pas inversible et le système linéaire n'admet pas de" r" solutions", disabled=False, style=style, layout=Layout(width='80%', height='40px') ) c = widgets.Checkbox( value=False, description=r"Si $\alpha=-2$ et $\beta=-4$, alors $A$ n'est pas inversible et le système linéaire admet " r"une infinité de solutions", disabled=False, style=style, layout=Layout(width='80%', height='40px') ) d = widgets.Checkbox( value=False, description=r"Si $\alpha=8$ et $\beta=1$, alors $A$ n'est pas inversible et le système linéaire admet " r"une infinité de solutions", disabled=False, style=style, layout=Layout(width='80%', height='40px') ) e = widgets.Checkbox( value=False, description=r"Si $\alpha=-4$ et $\beta=-2$, alors $A$ n'est pas inversible et le système linéaire n'admet pas" r"de solutions", disabled=False, style=style, layout=Layout(width='80%', height='40px') ) f = widgets.Checkbox( value=False, description=r'Si $\alpha=4$ et $\beta=1$, alors $A$ est inversible et le système linéaire admet une infinité ' r'de solutions', disabled=False, style=style, layout=Layout(width='80%', height='40px') ) g = widgets.Checkbox( value=False, description=r'Si $\alpha=4$ et $\beta=1$, alors $A$ est inversible et le système linéaire admet une solution' r' unique', disabled=False, style=style, layout=Layout(width='80%', height='40px') ) h = widgets.Checkbox( value=False, description=r"Pour infinite de valeurs de $\alpha$ et $\beta$ $A$ n'est pas inversible, mais seulement pour l'un" r" d'eux le système admet une infinité de solutions", disabled=False, style=style, layout=Layout(width='100%', height='40px') ) def correction(a, b, c, d, e, f, g, h): if c and e and h and not a and not b and not d and not f and not g: display(Latex(r"C'est correct! En effet $A$ n'est pas inversible si $\alpha = \dfrac{8}{\beta}$ (résultat " r"obtenu en divisant par élément les lignes de A les unes par les autres et en imposant que " r"les résultats des divisions soient les mêmes). De plus, si $\alpha = -2$ et $\beta = -4$, " r"alors le système admet une infinité de solutions, puisque les rapports obtenus par la " r"division est $-\dfrac{1}{2}$).")) else: display(Latex("C'est faux.")) interact_manual(correction, a=a, b=b, c=c, d=d, e=e, f=f, g=g, h=h) return def Ex4Chapitre2_6_7(): """Provides the correction of exercise 4 of notebook 2_6-7 """ - display(Latex("Insert the values of a and b as floating point numbers")) + display(Latex("Insérez les valeurs de a et b")) a = widgets.FloatText( value=0.0, step=0.1, description='a:', disabled=False ) b = widgets.FloatText( value=0.0, step=0.1, description='b:', disabled=False ) display(a) display(b) def f(): A = np.array([[0.5, a.value, 1], [0, 2, -1], [-2, 1, b.value]]) B = np.array([[-6, -2, -2], [4, 2, 1], [8, 3, 2]]) AB = np.dot(A, B) texAB = '$' + texMatrix(AB) + '$' BA = np.dot(B, A) texBA = '$' + texMatrix(BA) + '$' if a.value == -1 and b.value == -2: - display(Latex(r"Correcte! Le produits $A \cdot B$ et $B \cdot A$ valent chacun: $I$ = " + texAB)) + display(Latex(r"Correcte! Le produits $AB$ et $BA$ valent chacun: $I$ = " + texAB)) else: - display(Latex(r"Incorrecte! Le produit $A \cdot B$ vaut " + texAB + r" et le produit " - r"$B \cdot A$ vaut " + texBA + r" donc, $A$ ne peut pas être l'inverse de $B$. " + display(Latex(r"Incorrecte! Le produit $AB$ vaut " + texAB + r" et le produit " + r"$BA$ vaut " + texBA + r", donc $A$ ne peut pas être l'inverse de $B$. " r"Entrez de nouvelles valeurs!")) interact_manual(f) return def Ex1Chapitre2_8_9(E1, E2, E3, E4): """Provides the correction of exercise 2 of notebook 2_8_9 :param E1: :type E1: :param E2: :type E2: :param E3: :type E3: :param E4: :type E4: :return: :rtype: """ # MATRIX A1 E_pre_1 = [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]] E_post_1 = [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [-1, 0, 0, 1]] # MATRIX A2 E_pre_2 = [[1, 0, 0, 0], [0, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 1]] E_post_2 = [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1/2, 0], [0, 0, 0, 1]] # MATRIX A3 E_pre_3 = [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]] E_post_3 = [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, -1], [0, 0, 0, 1]] # MATRIX A4 E_pre_4 = [[1/2, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]] E_post_4 = [[1, 0, 0, 0], [0, 1, 1, 0], [0, 0, 1, 0], [0, 0, 0, 1]] E_bool = np.zeros(4).astype(bool) E_bool[0] = E1[0] == E_pre_1 and E1[1] == E_post_1 E_bool[1] = E2[0] == E_pre_2 and E2[1] == E_post_2 E_bool[2] = E3[0] == E_pre_3 and E3[1] == E_post_3 E_bool[3] = E4[0] == E_pre_4 and E4[1] == E_post_4 correct = set(np.where(E_bool)[0]+1) wrong = set(np.arange(1,5)) - correct if wrong: - display(Latex(f"Corrects: {correct}")) + if correct: + display(Latex(f"Corrects: {correct}")) + else: + display((Latex("Corrects: {}"))) display(Latex(f"Manqué: {wrong}")) else: display(Latex("C'est correcte.")) return def Ex3Chapitre2_8_9(): """Provides the correction of exercise 3 of notebook 2_8_9 """ a_1 = widgets.Checkbox( value=False, description=r'La matrice $A_1$ admet la décomposition LU', disabled=False, layout=Layout(width='80%', height='30px') ) a_2 = widgets.Checkbox( value=False, description=r'La matrice $A_2$ admet la décomposition LU', disabled=False, layout=Layout(width='80%', height='30px') ) a_3 = widgets.Checkbox( value=False, description=r'La matrice $A_3$ admet la décomposition LU', disabled=False, layout=Layout(width='80%', height='30px') ) def correction(a_1, a_2, a_3): if not a_1 and a_2 and not a_3: display(Latex("C'est correct! Plus précisément, la matrice $A_1$ n'admet pas décomposition LU car elle n'est pas inversible, la matrice $A_2$ admet décomposition LU et la matrice $A_3$ n'admet pas décomposition LU car elle ne peut pas être réduite sans échanger deux lignes pendant la méthode d'élimination de Gauss")) else: display(Latex("C'est faux.")) interact_manual(correction, a_1=a_1, a_2=a_2, a_3=a_3) return def Ex1Chapitre2_10(): """Provides the correction to exercise 1 of notebook 2_10 """ a = widgets.Checkbox( value=False, description=r"Le système linéaire n'admet aucune solution", disabled=False, layout=Layout(width='80%', height='40px') ) b = widgets.Checkbox( value=False, description=r"Le système linéaire admet une solution unique", disabled=False, layout=Layout(width='80%', height='40px') ) c = widgets.Checkbox( value=False, description=r"Le système linéaire admet deux solutions distinctes", disabled=False, layout=Layout(width='80%', height='40px') ) d = widgets.Checkbox( value=False, description=r"Le système linéaire admet une infinité de solutions", disabled=False, layout=Layout(width='80%', height='40px') ) e = widgets.Checkbox( value=False, description=r"La décomposition LU de $A$ ne peut pas être calculée", disabled=False, layout=Layout(width='80%', height='40px') ) f = widgets.Checkbox( value=False, description=r"La dernière colonne de $U$ est entièrement composée de zéros", disabled=False, layout=Layout(width='80%', height='40px') ) g = widgets.Checkbox( value=False, description=r'La dernière ligne de $U$ est entièrement composée de zéros', disabled=False, layout=Layout(width='80%', height='40px') ) h = widgets.Checkbox( value=False, description=r'La première entrée de la première ligne de $L$ est égale à 1', disabled=False, layout=Layout(width='80%', height='40px') ) def correction(a, b, c, d, e, f, g, h): if not a and not b and not c and d and not e and not f and g and not h: display(Latex("C'est correct. En effet, $A$ n'est clairement pas inversible, car la dernière ligne est " "égale à la seconde moins la première, et il en va de même pour le vecteur de droite $b$. " "Par conséquent, la dernière ligne de $U$ est entièrement composée de zéros (réponse 7) et la " "dernière entrée du vecteur de droite $b$, après l'application de la méthode d'élimination de " "Gauss, est également égale à 0. Ainsi, la dernière équation du système linéaire résultant a " "tous les coefficients égaux à 0, ce qui donne lieu à une infinité de solutions " "(réponse 4).")) else: display(Latex("C'est faux.")) interact_manual(correction, a=a, b=b, c=c, d=d, e=e, f=f, g=g, h=h) return def Ex2Chapitre2_10(L, U, b, x, y): """Provides the correction to exercise 2 of notebook 2_10 :param L: lower triangular matrix from LU decomposition :type L: list[list] :param U: upper triangular matrix from LU decomposition :type U: list[list] :param b: right-hand side vector :type b: list[list] :param x: system solution :type x: list[list] :param y: temporary variable :type y: list[list] """ if type(L) is list: L = np.array(L) if type(U) is list: U = np.array(U) if type(x) is list: x = np.array(x) if type(y) is list: y = np.array(y) y_true = np.linalg.solve(L, b) x_true = np.linalg.solve(U, y) res_x = np.linalg.norm(x - x_true) / np.linalg.norm(x_true) <= 1e-4 res_y = np.linalg.norm(y - y_true) / np.linalg.norm(y_true) <= 1e-4 if res_x and res_y: display(Latex("C'est correct")) else: display(Latex("C'est faux")) return def Ex3Chapitre2_10(): """Provides the correction to exercise 3 of notebook 2_10 :return: :rtype: """ a = widgets.Checkbox( value=False, description=r"If L is such that all its diagonal elements equal 1, then the temporary variable y is a vector " r"of ones as well", disabled=False, layout=Layout(width='80%', height='40px') ) b = widgets.Checkbox( value=False, description=r"Matrix L is diagonal", disabled=False, layout=Layout(width='80%', height='40px') ) c = widgets.Checkbox( value=False, description=r"Matrix U is diagonal", disabled=False, layout=Layout(width='80%', height='40px') ) d = widgets.Checkbox( value=False, description=r"The second entry of the solution is always 2.5 times the fourth one", disabled=False, layout=Layout(width='80%', height='40px') ) e = widgets.Checkbox( value=False, description=r"The second entry of the solution is always 5 times the fourth one", disabled=False, layout=Layout(width='80%', height='40px') ) f = widgets.Checkbox( value=False, description=r"The sum of all the entries always equals 2.5", disabled=False, layout=Layout(width='80%', height='40px') ) g = widgets.Checkbox( value=False, description=r"The sum of all the entries but the second one always equals 0", disabled=False, layout=Layout(width='80%', height='40px') ) h = widgets.Checkbox( value=False, - description=r"The vector [1, 0 -1, 0] is one of the solutions to the linear system", + description=r"The vector $\hat{x} = (1, 0 -1, 0)$ is one of the solutions to the linear system", disabled=False, layout=Layout(width='80%', height='40px') ) def correction(a, b, c, d, e, f, g, h): if a and not b and not c and d and not e and not f and g and h: display(Latex("C'est correct. Indeed the set of all possible solutions can be written as " "$x = [1-4a, 2.5a, 3a-1, a]$. From this, it is clear that the second entry is 2.5 times the " "fourth one (answer 4), that the sum of all the entries but the second one equals $0$ " "(answer 7) and that $x^* = [1,0,-1,0]$ is a solution, in case $a$ is set to 0 (answer 8). " "Also, if L is computed so that it has ones on its diagonal, it is immediate to deduce that " "the temporary vector $y$ that solves the system $Ly=b$ is actually all made of ones.")) else: display(Latex("C'est faux.")) interact_manual(correction, a=a, b=b, c=c, d=d, e=e, f=f, g=g, h=h) return diff --git a/Chapitre 4 - Bases et dimension/Prototype 4.10.ipynb b/Chapitre 4 - Bases et dimension/Prototype 4.10.ipynb new file mode 100644 index 0000000..c4bd547 --- /dev/null +++ b/Chapitre 4 - Bases et dimension/Prototype 4.10.ipynb @@ -0,0 +1,277 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "jupyter": { + "source_hidden": true + } + }, + "outputs": [], + "source": [ + "%cd ..\n", + "import Librairie.AL_Fct as al\n", + "%cd \"Chapitre 4 - Bases et dimension\"\n", + "\n", + "import numpy as np\n", + "from IPython.display import display, Markdown, Latex\n", + "import plotly.graph_objs as go\n", + "import plotly\n", + "import ipywidgets as widgets\n", + "from ipywidgets import interact, interactive, fixed, interact_manual\n", + "from ipywidgets import Layout, HBox, VBox, Label\n", + "#import matplotlib\n", + "#import plotly.express as px" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Concept(s)-clé(s)\n", + "\n", + "\n", + "\n", + "### LEMME 5 :\n", + "\n", + "Soit $S$ un système de $m$ équations linéaires à $n$ inconnues, $A$ la matrice des coefficients de $S$ et $\\hat{A}$ sa matrice augmentée. Alors $S$ possède une solution si et seulement si le rang colonne de $A$ est égal au rang colonne de $\\hat{A}.$" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### EXERCICE 1.1\n", + "\n", + "Soit 𝑆 un système de 𝑚 équations linéaires à 𝑛 inconnues:\n", + "\n", + "$\\begin{equation}\n", + " \\left\\{\n", + " \\begin{aligned}\n", + " x_1 + 4x_2 + 3x_3 + 4x_4 = 1 \\\\ \n", + " 2x_1 + 6x_2 + 5x_3 + 8x_4 = 1 \\\\\n", + " x_1 + x_3 + 4x_4 = 1\n", + " \\end{aligned}\n", + " \\right.\n", + "\\end{equation}$\n", + "\n", + "Cette quation peut se repréenseter sous la forme $AX =b$.\n", + "Ecrivez A la matrice et le vecteur b dans la cellule suivante en respectant\n", + "\n", + "$[[ a, b], [c, d]] = \\begin{pmatrix} a & b \\\\ c & d \\end{pmatrix}$\n", + "\n", + "et b en suivant le format \n", + "\n", + "$[e, f] = \\begin{pmatrix} e \\\\ f \\end{pmatrix}$" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "jupyter": { + "source_hidden": true + } + }, + "outputs": [], + "source": [ + "def exercice1_1():\n", + " A_sol = [[1, 4, 3, 4],[2, 6, 5, 8],[1, 0, 1, 4]]\n", + " b_sol = [1, 1, 1]\n", + " if A == [] or b == []:\n", + " print(\"Au moins une des deux entrée est vide\")\n", + " elif not (len(A) == len(b)):\n", + " print(\"Les tailles de la matrice et du vecteur ne correspondent pas\")\n", + " else:\n", + " if A == A_sol:\n", + " if b == b_sol:\n", + " print(\"Correct !\")\n", + " else:\n", + " print(\"Le vecteur b est faux, votre reponse correspond au système suivant:\")\n", + " al.printSyst(A, b)\n", + " elif b == b_sol:\n", + " print(\"La Matrice A est fausse, votre reponse correspond au système suivant:\")\n", + " al.printSyst(A, b)\n", + " else:\n", + " print(\"Faux, votre reponse correspond au système suivant:\")\n", + " al.printSyst(A, b)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# n'oubliez pas d'executer la cellule\n", + "A = []\n", + "b = []\n", + "\n", + "exercice1_1() # ne pas toucher cette ligne" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### EXERCICE 1.2\n", + "Pour calculer le rang colonne de $A$ nous échelonnons sa matrice transposée. Si et seulement si le rang colonne de $A$ est égal au rang colonne de $\\hat{A}$.\n", + "À partir de cette matrice, donnez le rang colonne de $A$ et trouvez une base de l'espace colonne de $A$ ." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "jupyter": { + "source_hidden": true + } + }, + "outputs": [], + "source": [ + "A_sol = np.array([[1, 4, 3, 4],[2, 6, 5, 8],[1, 0, 1, 4]])\n", + "A_sol_t = A_sol.transpose()\n", + "M = al.echelonMat('E', A_sol_t)\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "jupyter": { + "source_hidden": true + } + }, + "outputs": [], + "source": [ + "def exercice1_2_1():\n", + " \n", + " text_rang = widgets.IntText()\n", + " box = VBox([Label('Rang colonne de A:'), text_rang])\n", + " button = widgets.Button(description='Vérifier')\n", + " out = widgets.Output()\n", + " \n", + " def callback(e):\n", + " out.clear_output()\n", + " with out:\n", + " if(text_rang.value == 2):\n", + " print('Correct !')\n", + " else: \n", + " print('False, try again or check the solution')\n", + " \n", + " button.on_click(callback)\n", + " display(box)\n", + " display(button)\n", + " display(out)\n", + "\n", + "exercice1_2_1()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "jupyter": { + "source_hidden": true + } + }, + "outputs": [], + "source": [ + "def exercice1_2_2():\n", + " \n", + " base_sol = [[1,2,1],[0,1,2]]\n", + " \n", + " if base_sol == []:\n", + " print(\"L'entrée est vide\")\n", + " else:\n", + " if base == base_sol:\n", + " print(\"Correct !\")\n", + " else:\n", + " print(\"Faux\")\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# [vect1,vect2,...] avec vect = [a, b, c] n'oubliez pas d'executer la cellule\n", + "base = [[1,2,1],[0,1,2]]\n", + "exercice1_2_2()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### EXERCICE 1.3 \n", + "Le système possède-t-il une solution ? (utilisez le lemme 5)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "jupyter": { + "source_hidden": true + } + }, + "outputs": [], + "source": [ + "def exercise_1_3():\n", + " \n", + " radio = widgets.RadioButtons(\n", + " options=['Yes', 'No'],\n", + " description='Answer:',\n", + " disabled=False\n", + " )\n", + "\n", + " button = widgets.Button(description='Vérifier')\n", + " out = widgets.Output()\n", + "\n", + " def callback(e):\n", + " out.clear_output()\n", + " with out:\n", + " if (radio.value == \"Yes\"):\n", + " print('Mauvaise réponse.')\n", + " else: \n", + " print('Correct !')\n", + " \n", + " button.on_click(callback)\n", + " display(radio)\n", + " display(button)\n", + " display(out)\n", + " \n", + "exercise_1_3()\n", + "\n", + "\n", + "\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.4" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/Chapitre 4 - Bases et dimension/Prototype 4.11.ipynb b/Chapitre 4 - Bases et dimension/Prototype 4.11.ipynb new file mode 100644 index 0000000..a5f80ca --- /dev/null +++ b/Chapitre 4 - Bases et dimension/Prototype 4.11.ipynb @@ -0,0 +1,534 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "from IPython.display import display, Markdown, Latex\n", + "import plotly.graph_objs as go\n", + "import plotly\n", + "import ipywidgets as widgets\n", + "from ipywidgets import interact, interactive, fixed, interact_manual, Layout\n", + "import matplotlib\n", + "import plotly.express as px\n", + "import sympy as sp" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Concept(s)-clé(s)\n", + "\n", + "### Définition 1 :\n", + "Soient $V$ un $\\mathbb{R}$-espace vectoriel de dimension finie $n$, $\\mathscr{B} =\\{v_1,\\ldots,v_n\\}$ une base ordoné de $V$ et $v \\in V$. Comme $\\mathscr{B}$ est une base de $V$, il existe des uniques scalaires $\\alpha_1,\\ldots,\\alpha_n \\in \\mathbb{R}$ tels que $v = \\alpha_1v_1 + \\ldots + \\alpha_nv_n$. On appelle $\\alpha_1,\\ldots,\\alpha_n$ les coordonnées de $v$ par rapport à la base $\\mathscr{B}$ et on écrit\n", + "\n", + "\n", + "$$[v]_{\\mathscr{B}} = \\begin{pmatrix} \\alpha_1 \\\\ \\alpha_2 \\\\ \\vdots \\\\ \\alpha_n \\end{pmatrix}.$$\n", + "\n", + "### Proposition 2 :\n", + "Soient $V$ un $\\mathbb{R}$-espace vectoriel de dimension finie $n$ et $\\mathscr{B} = (v_1,\\ldots,v_n)$ une base ordonnée de $V$. Alors les deux affirmations suivantes sont vérifiées.\n", + "\n", + "1. Pour tous $v_1,v_2 \\in V$, on a $[v_1 + v_2 ]_{\\mathscr{B}} = [v_1]_{\\mathscr{B}}+[v_2]_{\\mathscr{B}}.$\n", + "\n", + "2. Pour tout $v \\in V$ et tout $\\lambda \\in \\mathbb{R}$, on a $[\\lambda v]_{\\mathscr{B}} = \\lambda[v]_{\\mathscr{B}}$" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Exercice 1:\n", + "\n", + "Soit $\\mathbb{R}^2$ l'espace du plan. La base la plus évidnte de cet espace vectoriel est la base orthonormée $\\mathscr{B} = ((1,0),(0,1))$. Cette base est représentée dans le graphique suivant." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "#ici un graph pas distordu (graph 1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Quelle base de $\\mathbb{R}^2$ est représentée ci-dessous?" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "def exercice_1(base):\n", + " base_solution = [[1,2],[3,2]]\n", + " is_correct = all(item in base_solution for item in base)\n", + " if is_correct:\n", + " is_correct = all(item in base for item in base_solution)\n", + " \n", + " correct_text = \"C'est correct!\"\n", + " incorrect_text = \"C'est incorrect.\"\n", + " \n", + " display(correct_text if is_correct else incorrect_text)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "#ici un graph avec grille distordue (graph 2)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\"C'est incorrect.\"" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Entrez les vecteurs qui forment la base réprésentée ci-dessus\n", + "# Par exemple : [[1, 2], [3, 4]]\n", + "base = [[-2,1],[4,1]]\n", + "\n", + "exercice_1(base)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "jupyter": { + "source_hidden": true + } + }, + "outputs": [], + "source": [ + "def exercice_2aB1(vB1):\n", + " v = [5,6]\n", + " \n", + " if vB1==v:\n", + " is_correct = 1\n", + " else:\n", + " is_correct = 0\n", + " \n", + " correct_text = \"C'est correct!\"\n", + " incorrect_text = \"C'est incorrect.\"\n", + " \n", + " display(correct_text if is_correct else incorrect_text)\n", + "\n", + "def exercice_2aB2(vB2):\n", + " v = [2,1]\n", + " \n", + " if vB2==v:\n", + " is_correct = 1\n", + " else:\n", + " is_correct = 0\n", + " \n", + " correct_text = \"C'est correct!\"\n", + " incorrect_text = \"C'est incorrect.\"\n", + " \n", + " display(correct_text if is_correct else incorrect_text)\n", + "\n", + "def exercice_2bB1(uB1):\n", + " u = [8,4]\n", + " \n", + " if uB1==u:\n", + " is_correct = 1\n", + " else:\n", + " is_correct = 0\n", + " \n", + " correct_text = \"C'est correct!\"\n", + " incorrect_text = \"C'est incorrect.\"\n", + " \n", + " display(correct_text if is_correct else incorrect_text)\n", + "\n", + "def exercice_2bB2(uB2):\n", + " u = [-1,3]\n", + " \n", + " if uB2==u:\n", + " is_correct = 1\n", + " else:\n", + " is_correct = 0\n", + " \n", + " correct_text = \"C'est correct!\"\n", + " incorrect_text = \"C'est incorrect.\"\n", + " \n", + " display(correct_text if is_correct else incorrect_text)\n", + " \n", + "def exercice_2cB1(wB1):\n", + " w = [5,4]\n", + " \n", + " if wB1==w:\n", + " is_correct = 1\n", + " else:\n", + " is_correct = 0\n", + " \n", + " correct_text = \"C'est correct!\"\n", + " incorrect_text = \"C'est incorrect.\"\n", + " \n", + " display(correct_text if is_correct else incorrect_text)\n", + " \n", + "def exercice_2cB2(wB2):\n", + " w = [0.5,1.5]\n", + " \n", + " if wB2==w:\n", + " is_correct = 1\n", + " else:\n", + " is_correct = 0\n", + " \n", + " correct_text = \"C'est correct!\"\n", + " incorrect_text = \"C'est incorrect.\"\n", + " \n", + " display(correct_text if is_correct else incorrect_text)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Exercice 2\n", + "\n", + "a) Soit le vecteur $\\textbf{v}$ représenté dans le graph suivant, $\\mathscr{B}_1$ la base orthonormée de $\\mathbb{R}^2$ et $\\mathscr{B}_2 = ((1,2),(3,2))$. Quelles sont les coordonnées de de $\\textbf{v}$ dans $\\mathscr{B}_1$? " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#ici graph avec v desssus (graph 3)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\"C'est correct!\"" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Entrez les coordonnées du vecteur v dans la base B1\n", + "# Par exemple : [1,2]\n", + "vB1 = [5,6]\n", + "\n", + "exercice_2aB1(vB1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Et dans $\\mathscr{B}_2$?" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\"C'est correct!\"" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Entrez les coordonnées du vecteur v dans la base B2\n", + "# Par exemple : [1,2]\n", + "vB2 = [2,1]\n", + "\n", + "exercice_2aB2(vB2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "b) Avec les mêmes bases, quelles sont les coordonnées du vecteur $\\textbf{u}$ dans $\\mathscr{B}_1$?" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#ici graph avec u desssus (graph 4)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\"C'est correct!\"" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Entrez les coordonnées du vecteur u dans la base B1\n", + "# Par exemple : [1,2]\n", + "uB1 = [8,4]\n", + "\n", + "exercice_2bB1(uB1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Et dans $\\mathscr{B}_2$?" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\"C'est correct!\"" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Entrez les coordonnées du vecteur u dans la base B2\n", + "# Par exemple : [1,2]\n", + "uB2 = [-1,3]\n", + "\n", + "exercice_2bB2(uB2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "c) Toujours avec les mêmes bases, quelles sont les coordonnées du vecteur $\\textbf{w}$ dans $\\mathscr{B}_1$?" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#ici graph avec w desssus (graph 5)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\"C'est correct!\"" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Entrez les coordonnées du vecteur w dans la base B1\n", + "# Par exemple : [1,2]\n", + "wB1 = [5,4]\n", + "\n", + "exercice_2cB1(wB1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Et dans $\\mathscr{B}_2$?" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\"C'est correct!\"" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Entrez les coordonnées du vecteur w dans la base B2\n", + "# Par exemple : [1,2]\n", + "wB2 = [.5,1.5]\n", + "\n", + "exercice_2cB2(wB2)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "jupyter": { + "source_hidden": true + } + }, + "outputs": [], + "source": [ + "def exercice_3_B1(sB1):\n", + " s = [13,10]\n", + " \n", + " if sB1==s:\n", + " is_correct = 1\n", + " else:\n", + " is_correct = 0\n", + " \n", + " correct_text = \"C'est correct!\"\n", + " incorrect_text = \"C'est incorrect.\"\n", + " \n", + " display(correct_text if is_correct else incorrect_text)\n", + "\n", + "def exercice_3_B2(sB2):\n", + " s = [1,4]\n", + " \n", + " if sB2==s:\n", + " is_correct = 1\n", + " else:\n", + " is_correct = 0\n", + " \n", + " correct_text = \"C'est correct!\"\n", + " incorrect_text = \"C'est incorrect.\"\n", + " \n", + " display(correct_text if is_correct else incorrect_text)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Exercice 3\n", + "\n", + "Considérons maintenant le vecteur $\\textbf{s}$ tel que $\\textbf{s} = \\textbf{v}+\\textbf{u}$. A l'aide de la proposition 2 et de l'exerciceprécédent, déduire les coordonnées de $\\textbf{s}$ dans $\\mathscr{B}_1$." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\"C'est correct!\"" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Entrez les coordonnées du vecteur s dans la base B1\n", + "# Par exemple : [1,2]\n", + "sB1 = [13,10]\n", + "\n", + "exercice_3_B1(sB1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Et dans $\\mathscr{B}_2$?" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\"C'est correct!\"" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Entrez les coordonnées du vecteur s dans la base B2\n", + "# Par exemple : [1,2]\n", + "sB2 = [1,4]\n", + "\n", + "exercice_3_B2(sB2)" + ] + } + ], + "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.9" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/Chapitre 4 - Bases et dimension/Prototype 4.12.ipynb b/Chapitre 4 - Bases et dimension/Prototype 4.12.ipynb new file mode 100644 index 0000000..60bc4b1 --- /dev/null +++ b/Chapitre 4 - Bases et dimension/Prototype 4.12.ipynb @@ -0,0 +1,435 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 91, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "from IPython.display import display, Markdown, Latex\n", + "import plotly.graph_objs as go\n", + "import plotly\n", + "import ipywidgets as widgets\n", + "from ipywidgets import interact, interactive, fixed, interact_manual, Layout\n", + "import matplotlib\n", + "import plotly.express as px\n", + "import sympy as sp" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Concept(s)-clé(s)\n", + "\n", + "\n", + "\n", + "### MÉTHODE POUR TROUVER UNE BASE À PARTIR D'UN SYSTÈME DE GÉNÉRATEURS :\n", + "\n", + "Soient $V$ un $\\mathbb{R}$-espace vectoriel de dimension finie $n,$ $\\mathscr{B}=(v_1,\\ldots,v_n)$ une base de $V,$ $S\\subset V$ une partie finie et $W=\\mbox{Vect}(S).$ Pour trouver une base de $W$ et la compléter en une base de $V,$ on procède comme suit.\n", + "\n", + "\n", + "\n", + "1. Pour chaque $v\\in S,$ on écrit $[v]_{\\mathscr{B}} = \\begin{pmatrix} \\alpha_1 \\ \\alpha_2 \\ \\cdots \\ \\alpha_n \\end{pmatrix}^T.$\n", + "\n", + "2. On définit la matrice $A$ dont les lignes sont les vecteurs $[v]_{\\mathscr{B}}^T$ ($v\\in S$).\n", + "\n", + "3. On échelonne la matrice $A$ : les lignes non-nulles ainsi obtenues forment une base de l'espace ligne de cette matrice. De plus, les vecteurs de $W$ correspondants forment une base de $W.$\n", + "\n", + "4. On remplace les lignes nulles de la matrice échelonnée par des lignes non-nulles de manière à ce que celle-ci contienne $n$ pivots. Les vecteurs de $V$ associés aux lignes de cette nouvelle matrice forment une base de $V.$" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Exercice 1\n", + "\n", + "Soit $S = (v_1,v_2,v_3,v_4,v_5) \\in \\mathbb{R}^6$ et $W=Vect(S)$. Selon la méthode vue en cours, quelles sont les dimensions de la matrice $A$?" + ] + }, + { + "cell_type": "code", + "execution_count": 92, + "metadata": { + "jupyter": { + "source_hidden": true + } + }, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "55d262fd0d9b4bb2bd66bff949b93591", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "IntText(value=0, description='Nombre de lignes : \\n')" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "990af7f3e9704c648cb800181c78ec83", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "IntText(value=0, description='Nombre de colonne : \\n')" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "d89fc1bc22ab413b8cfae9f01ce53c62", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Button(description='Vérifier', style=ButtonStyle())" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "c009cef7b6aa448f9d94067df1acb58c", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Output()" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "def exercice_1():\n", + " nbr_ligne = widgets.IntText(\n", + " description='Nombre de lignes : \\n',\n", + " disabled=False\n", + " )\n", + " nbr_colonne = widgets.IntText(\n", + " description='Nombre de colonne : \\n',\n", + " disabled=False\n", + " )\n", + " \n", + " button = widgets.Button(description='Vérifier')\n", + " out = widgets.Output()\n", + " \n", + " def callback(e):\n", + " out.clear_output()\n", + " r_l = nbr_ligne.value\n", + " r_c = nbr_colonne.value\n", + " with out:\n", + " if r_l == 5 and r_c == 6:\n", + " display(Markdown(\"C'est correct!\"))\n", + " else:\n", + " display(Markdown(\"C'est incorrect.\"))\n", + " \n", + " button.on_click(callback)\n", + " \n", + " display(nbr_ligne)\n", + " display(nbr_colonne)\n", + " display(button)\n", + " display(out)\n", + "exercice_1()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Exercice 2\n", + "\n", + "Sachant que $v_2 = 2v_3+3v_5$, combien faut-il rajouter, au minimum, de lignes non-nulles à la matrice $A$, dans sa forme échelonnée, pour que les vecteurs associés aux lignes de celle-ci forment une base de $\\mathbb{R}^6$?" + ] + }, + { + "cell_type": "code", + "execution_count": 93, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "4076b26f75744445b3cf5896f179cedf", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "IntText(value=0, description='Réponse :')" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "b58405ced7a145488354c4aaf861e6b8", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Button(description='Vérifier', style=ButtonStyle())" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "a0ba4e3933dc45a58b89e6690f045109", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Output()" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "def exercice_2():\n", + " text = widgets.IntText(\n", + " description='Réponse :',\n", + " disabled=False\n", + " )\n", + " button = widgets.Button(description='Vérifier')\n", + " out = widgets.Output()\n", + " \n", + " def callback(e):\n", + " out.clear_output()\n", + " r = text.value\n", + " \n", + " with out:\n", + " if r == 2:\n", + " display(Markdown(\"C'est correct!\"))\n", + " else:\n", + " display(Markdown(\"C'est incorrect.\"))\n", + " \n", + " button.on_click(callback)\n", + " \n", + " display(text)\n", + " display(button)\n", + " display(out)\n", + "exercice_2()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Exercice 3\n", + "\n", + "Voici la matrice $A$ échelonnée, nommée $B$:\n", + "\n", + "$$B = \\begin{pmatrix} 1 & 4 & 0 & 2 & 0 & 1 \\\\ 0 & 0 & 0 & 0 & 0 & 0 \\\\ 0 & 1 & 1 & 2 & 1 & 0 \\\\ 0 & 0 & 1 & 3 & 3 & 2 \\\\ 0 & 0 & 0 & 0 & 0 & 0\\end{pmatrix}$$\n", + "\n", + "a) Combien de vecteurs doivent être ajoutés aux lignes non-nulles de $B$ pour que celles-co soient une base de $\\mathbb{R}^6$ ?" + ] + }, + { + "cell_type": "code", + "execution_count": 94, + "metadata": { + "jupyter": { + "source_hidden": true + } + }, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "ae4d71b36c1e47eb856deba820c5246c", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "IntText(value=0, description='Réponse :')" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "c740a93affe6485781db2b9791ff7988", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Button(description='Vérifier', style=ButtonStyle())" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "b421f8f2260e44388ecd9b0e667cbe74", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Output()" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "def exercice_3_a():\n", + " text = widgets.IntText(\n", + " description='Réponse :',\n", + " disabled=False\n", + " )\n", + " button = widgets.Button(description='Vérifier')\n", + " out = widgets.Output()\n", + " \n", + " def callback(e):\n", + " out.clear_output()\n", + " r = text.value\n", + " \n", + " with out:\n", + " if r == 3:\n", + " display(Markdown(\"C'est correct!\"))\n", + " else:\n", + " display(Markdown(\"C'est incorrect.\"))\n", + " \n", + " button.on_click(callback)\n", + " \n", + " display(text)\n", + " display(button)\n", + " display(out)\n", + "exercice_3_a()" + ] + }, + { + "cell_type": "code", + "execution_count": 95, + "metadata": {}, + "outputs": [], + "source": [ + "def exercice_3_b(base):\n", + " base = base + [[1,4,0,2,0,1],[0,1,1,2,1,0],[0,0,1,3,3,2]]\n", + " base = np.array(base)\n", + " out = widgets.Output()\n", + " display(out)\n", + "\n", + " with out:\n", + " out.clear_output()\n", + "\n", + " feedback = \"\"\n", + " is_correct = False\n", + " \n", + " s = base.shape\n", + " \n", + "\n", + " if len(base) == 0:\n", + " feedback = \"Les vecteurs nuls ne peuvent pas .\"\n", + " elif len(s) != 2 or s[1] != 6:\n", + " feedback = \"Le format des vecteurs n'est pas bon.\"\n", + " elif s[0] < 6:\n", + " feedback = \"L'ensemble entré ne contient pas assez de vecteurs pour engendrer toutes les solutions du système.\"\n", + " elif s[0] > 6:\n", + " feedback = \"L'ensemble entré contient trop de vecteurs pour être une famille libre.\"\n", + " else:\n", + " expected = np.array(sp.Matrix([[1,0,0,0,0,0],[0,1,0,0,0,0],[0,0,1,0,0,0],[0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 1, 0],[0, 0, 0, 0, 0, 1]]).rref()[0])\n", + " actual = np.array(sp.Matrix(base).rref()[0])\n", + " \n", + " if not np.array_equal(actual, expected):\n", + " feedback = \"L'ensemble entré n'engendre pas l'espace solution du système.\"\n", + " else:\n", + " is_correct = True\n", + " \n", + " correct_text = \"C'est correct!
\"\n", + " incorrect_text = \"C'est incorrect.
\"\n", + " \n", + " display(Markdown((correct_text if is_correct else incorrect_text) + feedback))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "b) Donner une collection de vecteurs qui complètent les lignes non-nulles de $B$ en une base de $\\mathbb{R}^6$." + ] + }, + { + "cell_type": "code", + "execution_count": 96, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "43e5ba33de834853a4c7de5910599ba0", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Output()" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Entrez les vecteurs qui complètent les lignes non-nulles de B en une base de R^6\n", + "# Par exemple : [[1, 2], [3, 4]]\n", + "vecteurs_manquants = [[0,0,0,1,0,0],[0,0,0,0,1,0],[0,0,0,0,0,1]]\n", + "\n", + "exercice_3_b(vecteurs_manquants)" + ] + }, + { + "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.9" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/Chapitre 4 - Bases et dimension/Prototype 4.9.ipynb b/Chapitre 4 - Bases et dimension/Prototype 4.9.ipynb new file mode 100644 index 0000000..22e4385 --- /dev/null +++ b/Chapitre 4 - Bases et dimension/Prototype 4.9.ipynb @@ -0,0 +1,314 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "jupyter": { + "source_hidden": true + } + }, + "outputs": [], + "source": [ + "%cd ..\n", + "import Librairie.AL_Fct as al\n", + "%cd \"Chapitre 4 - Bases et dimension\"\n", + "\n", + "import numpy as np\n", + "from IPython.display import display, Markdown, Latex\n", + "import plotly.graph_objs as go\n", + "import plotly\n", + "import ipywidgets as widgets\n", + "from ipywidgets import interact, interactive, fixed, interact_manual, Layout, HBox, VBox" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Concept(s)-clé(s)\n", + "\n", + "\n", + "\n", + "### DÉFINITION 1 :\n", + "\n", + "Soit $A\\in M_{m\\times n}(\\mathbb{R})$ une matrice de taille $m\\times n$ à coefficients réels.\n", + "\n", + "\n", + "\n", + "1. Le *rang ligne* de $A$ est la dimension de l'espace ligne de $A.$\n", + "\n", + "2. Le *rang colonne* de $A$ est la dimension de l'espace colonne de $A.$\n", + "\n", + "\n", + "\n", + "### REMARQUES 2 :\n", + "\n", + "\n", + "\n", + "1. Le rang ligne de $A$ est plus petit ou égal à $n,$ car c'est un sous-espace vectoriel de $\\mathbb{R}^n.$\n", + "\n", + "2. Le rang ligne de $A$ est plus petit ou égal à $m,$ car engendré par $m$ vecteurs.\n", + "\n", + "3. Le rang colonne de $A$ est plus petit ou égal à $m$ et $n,$ par le même raisonnement.\n", + "\n", + "4. Le rang colonne de $A$ est égal au rang ligne de $A^T.$\n", + "\n", + "5. Le rang ligne de $A$ est égal au rang colonne de $A^T.$\n", + "\n", + "\n", + "\n", + "### PROPOSITION 3 :\n", + "\n", + "Soient $A,B\\in M_{m\\times n}(\\mathbb{R})$ des matrices ligne équivalentes. Alors l'espace ligne de $A$ est égal à l'espace ligne de $B.$ Par conséquent, le rang ligne de $A$ est égal au rang ligne de $B.$\n", + "\n", + "### PROPOSITION 4 :\n", + "\n", + "Soit $A$ une matrice échelonnée. Alors le rang ligne de $A$ est égal au nombre de pivots. Aussi, une base de l'espace ligne de $A$ est donnée par les lignes contenant un pivots." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### EXERCICE 1\n", + "\n", + "Soit la matrice A :\n", + "\n", + "$$A = \\begin{pmatrix} 1 & 2 & 3 \\\\ 4 & 5 & 6 \\end{pmatrix}$$\n", + "\n", + "Sélectionnez les propositions correctes\n", + "(maintenez CTRL pour sélectionner plusieurs cellules à la fois)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "jupyter": { + "source_hidden": true + } + }, + "outputs": [], + "source": [ + "def exercise_1():\n", + " r1 = 'Le rang ligne de 𝐴 est plus petit ou égal à 2, car c\\'est un sous-espace vectoriel de ℝ2.'\n", + " r2 = 'Le rang ligne de 𝐴 est plus petit ou égal à 3, car c\\'est un sous-espace vectoriel de ℝ3.'\n", + " r3 = 'Le rang ligne de 𝐴 est plus petit ou égal à 3, car engendré par 3 vecteurs.'\n", + " r4 = 'Le rang ligne de 𝐴 est plus petit ou égal à 2, car engendré par 2 vecteurs.'\n", + " r5 = 'Le rang colonne de A est plus petit ou égal à 2.'\n", + "\n", + " select = widgets.SelectMultiple(\n", + " options=[(r1, 1), (r2, 2), (r3, 3), (r4, 4), (r5, 5)],\n", + " description='Sélection :',\n", + " disabled=False,\n", + " layout=Layout(width='auto', height='100px')\n", + " )\n", + "\n", + " button = widgets.Button(description='Vérifier')\n", + " out = widgets.Output()\n", + "\n", + " def callback(e):\n", + " out.clear_output()\n", + " with out:\n", + " if (1 in select.value or 3 in select.value):\n", + " print('Mauvaise réponse. \\nAttention à ne pas confondre les espaces des lignes et colonnes')\n", + " elif (2 not in select.value or 4 not in select.value or 5 not in select.value):\n", + " print('Il manque au moins une réponse.')\n", + " elif (2 in select.value and 4 in select.value and 5 in select.value):\n", + " print('Correct !')\n", + " \n", + " button.on_click(callback)\n", + "\n", + " display(select)\n", + " display(button)\n", + " display(out)\n", + " \n", + "exercise_1()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### EXERCICE 2\n", + "#### 2.1\n", + "Soit la matrice $A$ :\n", + "\n", + "$$A = \\begin{pmatrix} 1 & 2 & 3 \\\\ 0 & 1 & 2 \\end{pmatrix}$$\n", + "\n", + "Donnez le rang ligne de $A$." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "jupyter": { + "source_hidden": true + } + }, + "outputs": [], + "source": [ + "def exercice_2_1():\n", + " text = widgets.IntText(\n", + " description='Réponse :',\n", + " disabled=False\n", + " )\n", + " button = widgets.Button(description='Vérifier')\n", + " out = widgets.Output()\n", + " \n", + " def callback(e):\n", + " out.clear_output()\n", + " r = text.value\n", + " \n", + " with out:\n", + " if r == 2:\n", + " display(Markdown(\"Par la proposition 4 c'est correct!\"))\n", + " elif r > 2:\n", + " display(Markdown(\"Faux, c'est trop grand\"))\n", + " else:\n", + " display(Markdown(\"Faux, c'est trop petit\"))\n", + " \n", + " button.on_click(callback)\n", + " \n", + " display(text)\n", + " display(button)\n", + " display(out)\n", + "exercice_2_1()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### 2.2\n", + "Parmi les ensembles suivants, séléctionnez l'ensemble générant l'espace ligne de $A$\n", + "\n", + "$E_1 = \\begin{Bmatrix}\\begin{pmatrix} 1 \\\\ 2 \\\\ 3 \\end{pmatrix}, \\begin{pmatrix} 0 \\\\ 1 \\\\ 2 \\end{pmatrix}\\end{Bmatrix}$ $E_2 = \\begin{Bmatrix}\\begin{pmatrix} 1 \\\\ 2 \\\\ 3 \\end{pmatrix}, \\begin{pmatrix} 0 \\\\ 1 \\\\ 2 \\end{pmatrix}, \\begin{pmatrix} 0 \\\\ 0 \\\\ 1 \\end{pmatrix}\\end{Bmatrix}$ \n", + "$E_3 = \\begin{Bmatrix}\\begin{pmatrix} 1 \\\\ 0\\end{pmatrix}, \\begin{pmatrix} 2 \\\\ 1 \\end{pmatrix}, \\begin{pmatrix} 3 \\\\ 2 \\end{pmatrix}\\end{Bmatrix}$\n", + "$E_4 = \\begin{Bmatrix}\\begin{pmatrix} 1 \\\\ 0\\end{pmatrix}, \\begin{pmatrix} 2 \\\\ 1 \\end{pmatrix}\\end{Bmatrix}$" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "jupyter": { + "source_hidden": true + } + }, + "outputs": [], + "source": [ + "def exercise_2_2():\n", + " select = widgets.SelectMultiple(\n", + " options=['E1', 'E2', 'E3', 'E4'],\n", + " description='Sélection :',\n", + " disabled=False,\n", + " layout=Layout(width='auto', height='auto')\n", + " )\n", + "\n", + " button = widgets.Button(description='Vérifier')\n", + "\n", + " out = widgets.Output()\n", + "\n", + " def callback(e):\n", + " \n", + " out.clear_output()\n", + " with out:\n", + " if len(select.value) <= 0: # Empty\n", + " pass\n", + " elif len(select.value) > 1:\n", + " display(Markdown(\"Un seul de ces ensembles génère exactement l'espace ligne de A\"))\n", + " elif 'E1' not in select.value:\n", + " display(Markdown(\"Faux\"))\n", + " else:\n", + " display(Markdown(\"Correct !\"))\n", + " button.on_click(callback)\n", + " display(select)\n", + " display(button)\n", + " display(out)\n", + " \n", + "exercise_2_2()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### 2.3\n", + "Utilizez la remarque 2 ainsi que les propositions 3 et 4 pour trouver le rang colonne de $A$" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "jupyter": { + "source_hidden": true + } + }, + "outputs": [], + "source": [ + "\n", + "\n", + "def exercise_2_3():\n", + " text = widgets.IntText(description='Réponse :', disabled=False)\n", + "\n", + " button = widgets.Button(description='Vérifier')\n", + " button2 = widgets.Button(description='Solution', disabled=True)\n", + " box = HBox(children=[button,button2])\n", + " out = widgets.Output()\n", + "\n", + " def callback(e):\n", + " out.clear_output()\n", + " button2.disabled = False\n", + " with out:\n", + " if(text.value == 2):\n", + " print('Correct !')\n", + " else: \n", + " print('False, try again or check the solution')\n", + " \n", + " def solution(e):\n", + " out.clear_output()\n", + " with out:\n", + " A = np.array([[1, 2, 3], [0, 1, 2]])\n", + " A_t = A.transpose()\n", + " display(Markdown('Pour trouver le rang colonne de $A$, nous utilisons la remarque 2 et trouvous le rang ligne de la transposée de $A$.'))\n", + " display(Markdown('Par les propositions 3 et 4, nous échelonnons la matrice transposée et observont le nombre de lignes qui contiennent des pivots'))\n", + " M = al.echelonMat('E', A_t)\n", + " display(Markdown('Ainsi le rang colonne de $A$ est 2'))\n", + " \n", + " button.on_click(callback)\n", + " button2.on_click(solution)\n", + " \n", + " display(text)\n", + " display(box)\n", + " display(out)\n", + " \n", + "exercise_2_3()\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.4" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git "a/Chapitre 8 - Valeurs propres, vecteurs propres, diagonalisation/8.1 Valeurs propres et vecteurs propres, d\303\251finitions, exemples.ipynb" "b/Chapitre 8 - Valeurs propres, vecteurs propres, diagonalisation/8.1 Valeurs propres et vecteurs propres, d\303\251finitions, exemples.ipynb" index 397345f..0e55e33 100644 --- "a/Chapitre 8 - Valeurs propres, vecteurs propres, diagonalisation/8.1 Valeurs propres et vecteurs propres, d\303\251finitions, exemples.ipynb" +++ "b/Chapitre 8 - Valeurs propres, vecteurs propres, diagonalisation/8.1 Valeurs propres et vecteurs propres, d\303\251finitions, exemples.ipynb" @@ -1,202 +1,202 @@ { "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Concept(s)-clé(s) et théorie\n", "\n", "#### Définition: Valeur propre et vecteur propre d'une application linéaire\n", "\n", "Soient $V$ un $\\mathbb{R}$-espace vectoriel et $T: V \\rightarrow V$ une transformation linéaire. On dit que $\\lambda \\in \\mathbb{R}$ est une valeur propre de $T$ s'il existe $v \\in V$ non-nul tel que $T(v)=\\lambda v$. Aussi, si $\\lambda \\in \\mathbb{R}$ est une valeur propre de $T$, alors tout vecteur non-nul $v \\in V$ tel que $T(v)=\\lambda v$ s'appelle un vecteur propre de $T$ correspondant à la valeur propre $\\lambda$.\n", "\n", "#### Définition: Valeur propre et vecteur propre d'une matrice\n", "Soit $A \\in M_{n \\times n} \\ (\\mathbb{R})$ . On dit que $\\lambda \\in \\mathbb{R}$ est une valeur propre de $A$ s'il existe $X \\in M_{n \\times 1} (\\mathbb{R})$ non-nul tel que $A X=\\lambda X$. Aussi, si $\\lambda \\in \\mathbb{R}$ est une valeur propre de $A$, alors toute solution non-nulle de $A X=\\lambda X$ s'appelle un vecteur propre de $A$ correspondant à la valeur propre $\\lambda$." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import plotly\n", "import plotly.graph_objects as go\n", "import sympy as sp\n", "from IPython.display import display, Latex\n", "from Ch8_lib import *" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### **Exemple 1**\n", "\n", "Pour savoir si un vecteur $v \\in M_{n \\times 1} \\ (\\mathbb{R})$ est un vecteur propre de la matrice $A\\in M_{n \\times n} \\ (\\mathbb{R})$, il suffit de vérifier que les vecteurs $v$ et $b = A \\ v$ sont colinéaires. Il est possible de visualiser cela graphiquement pour des vecteurs de dimension $n=2$ où $n=3$." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Definition de la matrice A et du vecteur v (3D)\n", "# On utilise des numpy array pour les plots\n", "v = np.array([1, 1, 1])\n", "A = np.array([[1, 1, 1], [1, 1, 1], [1, 1, 1]])\n", "\n", "# Multiplication de v par A\n", "b = A@v\n", "\n", "# Plot\n", "vector_plot_3D(v, b)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Exercice 1\n", "Etant donné une matrice carrée $A \\in M_{n \\times n} \\ (\\mathbb{R})$ et un vecteur $v \\in M_{n \\times 1} \\ (\\mathbb{R})$. Déterminez si $v$ est un vecteur propre de la matrice $A$. Si tel est le cas, trouvez la valeur propre $\\lambda \\in \\mathbb{R}$ associée. \n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "# Les matrices ou/et vecteurs peuvent dépendre du paramètre x\n", + "# Ici, les matrices ou/et vecteurs peuvent dépendre du paramètre x\n", "x = sp.symbols('x')\n", "\n", "# a)\n", "A_1 = sp.Matrix([[1, 1, 1], [1, 1, 1], [1, 1, 1]])\n", "v_1 = sp.Matrix([1, 1, 1])\n", "\n", - "display(Latex(\" $A =\" + sp.latex(A_1) + \"\\hspace{20mm} v= \" + sp.latex(v_1) + \"$\"))" + "display(Latex(\" $A =\" + latexp(A_1) + \"\\hspace{20mm} v= \" + latexp(v_1) + \"$\"))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Affiche la solution pour A_1 et v_1\n", "CheckEigenVector(A_1, v_1)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# b)\n", "A_2 = sp.Matrix([[4*x, 8*x], [1, 2]])\n", "v_2 = sp.Matrix([2, -1])\n", "\n", - "display(Latex(\" $A =\" + sp.latex(A_2) + \"\\hspace{20mm} v= \" + sp.latex(v_2) + \"$\"))" + "display(Latex(\" $A =\" + latexp(A_2) + \"\\hspace{20mm} v= \" + latexp(v_2) + \"$\"))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Print the solution for A_2 and v_2\n", "CheckEigenVector(A_2, v_2)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# c)\n", "A_3 = sp.Matrix([[1, 2], [1, 2]])\n", "v_3 = sp.Matrix([0, 0])\n", "\n", - "display(Latex(\" $A =\" + sp.latex(A_3) + \"\\hspace{20mm} v= \" + sp.latex(v_3) + \"$\"))" + "display(Latex(\" $A =\" + latexp(A_3) + \"\\hspace{20mm} v= \" + latexp(v_3) + \"$\"))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Print the solution for A_3 and v_3\n", "CheckEigenVector(A_3, v_3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Exercice 2\n", "En utilisant la définition d'une valeur propre donnée plus haut, vérifiez si un nombre donné $\\lambda$ est une valeur propre de la matrice $A \\in M_{n \\times n} \\ (\\mathbb{R})$. Si oui trouvez un vecteur propre correspondant à $\\lambda$.\n", "\n", "##### Méthode: \n", "Poser $A v = \\lambda v \\Leftrightarrow (A - \\lambda I) v = 0 $ et étudier le nombre de solutions du système.\n", "\n", "- Si le système a une unique solution ($v$ = 0), alors $\\lambda$ n'est pas une valeur propre de la matrice A.\n", "- Si le système a une infinité de solutions, alors $\\lambda$ est une valeur propre de $A$.\n", "\n", "Si $\\lambda$ est bien une valeur propre de $A$, alors n'importe quelle solution non triviale $v$ du système $A v = \\lambda v$ est un vecteur propre associé à $\\lambda$." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# a)\n", "A = sp.Matrix([[2, 0], [1, 2]])\n", "l = 2\n", "\n", "# A remplir pour vérifier avec la fonction ch8_1_exo_2\n", "# Mettre vp = True si c'est une valeur propre de A. False sinon.\n", "vp = True \n", "# Entrez un vecteur propre associé à lambda si c'est une valeur propre, sinon laissez les 0\n", "v = sp.Matrix([0, 0])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ch8_1_exo_2(A, l, vp, v)" ] } ], "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.2" } }, "nbformat": 4, "nbformat_minor": 2 } diff --git "a/Chapitre 8 - Valeurs propres, vecteurs propres, diagonalisation/8.3 Polyn\303\264me caract\303\251ristique.ipynb" "b/Chapitre 8 - Valeurs propres, vecteurs propres, diagonalisation/8.3 Polyn\303\264me caract\303\251ristique.ipynb" index cf6d026..cfb1383 100644 --- "a/Chapitre 8 - Valeurs propres, vecteurs propres, diagonalisation/8.3 Polyn\303\264me caract\303\251ristique.ipynb" +++ "b/Chapitre 8 - Valeurs propres, vecteurs propres, diagonalisation/8.3 Polyn\303\264me caract\303\251ristique.ipynb" @@ -1,146 +1,146 @@ { "cells": [ { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import sympy as sp\n", "from IPython.display import display, Latex\n", "from Ch8_lib import *" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Définition 1:\n", "Soient $A\\in M_{n \\times n}(\\mathbb{R})$ et $t$ une indéterminée. Le polynôme caractéristique de $A$, noté $c_A(t)$, est le polynme défini par $$c_A(t)=\\det (A-tI)$$\n", "\n", "### Proposition 2:\n", "Soient $A,P\\in M_{n\\times n}(\\mathbb{R})$ et supposons que soit inversible. Alors \n", "$$c_A(t)=c_{PAP^{-1}}(t).$$\n", "\n", "### Définition 3:\n", "Soit $T:V \\to V$ une transformation linéaire d'un $\\mathbb{R}$-espace vectoriel de dimension finie $V$. On définit le polynôme caractéristique de $T$ par $c_T(t)=c_A(t),$ où $A=[T]_{\\mathscr{B}}$ pour une base ordonnée quelconque $\\mathscr{B}$ de $V$.\n", "\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "$\\lambda \\in \\mathbb{R}$ est une valeur propre de $A\\in M_{n \\times n}(\\mathbb{R})$ si et seulement si: $$ c_A(\\lambda) = \\det (A-\\lambda I) = 0$$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Exemple 1\n", "Méthode pour calculer les valeurs propres d'une matrice $3 \\times 3$.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Définition de la matrice (Par défaut, les coefficients sont fixés à 1)\n", "A = sp.Matrix([[1,1,1],[1,1,1],[1,1,1]])\n", "\n", "l = sp.symbols('\\lambda')\n", "I = sp.eye(3)\n", "\n", "# Calcul étape par étape du polynome caractéristique (degré 3 ici).\n", "Determinant_3x3(A-l*I, True, True, 3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "On a donc le polynome caractéristique de la matrice A, les valeurs propres sont les racines de ce polynôme.\n", "On résout $$\\det (A- \\lambda I) = 0$$" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Résolution de l'équation avec sympy\n", "eq = sp.Eq(sp.det(A-l*I),0)\n", "sol = sp.solve(eq, l)\n", "\n", "display(Latex(\"Les racines du polynôme caractéristiques (les valeurs propres de A) sont: $\" + \n", " sp.latex(sol) + \"$.\"))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Exercice 1\n", "Trouver les valeurs propres des matrices données ci-dessous en trouvant les racines du polynôme caractéristique.\n", "\n", "*Pour trouver les racines des polynômes caractéristiques de degré 3 ou 4, factorisez à l'aide de racines évidentes $\\in [-2, -1, 0, 1, 2]$*" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Trouver les valeurs propres des matrices suivantes\n", "A_1 = sp.Matrix([[-2, 4], [5, -1]])\n", "A_2 = sp.Matrix([[1, 2], [3, 1]])\n", "A_3 = sp.Matrix([[1, 0, 4], [1, 3, 1], [2, 4, -1]])\n", "A_4 = sp.Matrix([[4, 0, 1], [-2, 1, 0], [-2, 0, 1]])\n", "A_5 = sp.Matrix([[1, 2, 0, 0], [2, 1, 0, 0], [-4, 2, 2, -1], [-8, 5, 0, 1]])\n", "A_6 = sp.Matrix([[4, 0, 0, 0], [7, -11, 0, 0], [-0.5, 2.3, sp.sqrt(2), 0], [-8, 5, 2, 11]])\n", "\n", "# Matrice à afficher\n", "A = A_1\n", - "display(Latex(\"$\" + sp.latex(A) + \"$\"))" + "display(Latex(\"Trouvez les valeurs propres de la matrice $A =\" + latexp(A) + \"$\"))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "# Affiche la solution pour la matrice spécifiée comme argument de la fontion valeurs_propres\n", + "# Affiche la solution étape par étape pour la matrice spécifiée comme argument de la fontion valeurs_propres\n", "valeurs_propres(A_1)" ] } ], "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.2" } }, "nbformat": 4, "nbformat_minor": 2 } diff --git a/Chapitre 8 - Valeurs propres, vecteurs propres, diagonalisation/8.4 Espaces propres.ipynb b/Chapitre 8 - Valeurs propres, vecteurs propres, diagonalisation/8.4 Espaces propres.ipynb index fb107ce..50583a7 100644 --- a/Chapitre 8 - Valeurs propres, vecteurs propres, diagonalisation/8.4 Espaces propres.ipynb +++ b/Chapitre 8 - Valeurs propres, vecteurs propres, diagonalisation/8.4 Espaces propres.ipynb @@ -1,127 +1,163 @@ { "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "### Définition 1\n", "Soient $\\phi:V\t\\to V$ une transformation linéaire d'un espace vectoriel $V$ et $\\lambda \\in \\mathbb{R}$ une valeur propre de $\\phi.$ Alors l'espace propre de $\\phi$ associé à $\\lambda$ est le sous-ensemble de $V$ défini par $E_{\\lambda}=\\{v\\in V: \\phi(v)=\\lambda v\\}$.\n", "\n", "De manière similaire, si $\\lambda\\in \\mathbb{R}$ est une valeur propre de la matrice $A\\in M_{n \\times n}(\\mathbb{R}),$ alors l'espace propre de $A$ associé à $\\lambda$ est le sous-ensemble de $M_{n \\times 1}(\\mathbb{R})$ défini par $E_{\\lambda}=\\{X\\in M_{n \\times 1}(\\mathbb{R}) : AX=\\lambda X\\}$.\n", "\n", "### Proposition 2\n", "Le sous-ensemble $E_\\lambda$ est un sous-espace vectoriel." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import plotly\n", "import plotly.graph_objects as go\n", "import sympy as sp\n", "import sys, os \n", "sys.path.append('../Librairie')\n", "import AL_Fct as al\n", "from IPython.utils import io\n", "from IPython.display import display, Latex\n", "from Ch8_lib import *" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Exercice 1\n", + "**Trouvez les valeurs propres des matrices suivantes puis pour chacune des valeurs propres, trouvez une base de l'espace propre correspondant.**\n", + "\n", + "\n", + "La fonction `eigen_basis` détaille étape par étape comment obtenir une base de l'espace propre associé à une valeur propre donnée d'une matrice. Elle vérifie également que la base de l'espace propre rentrée est correcte.\n", + "Cette fonction prend 3 arguments: \n", + "* La matrice (définie comme `A = sp.Matrix([[1, 0], [0, 2]])` par exemple)\n", + "* La valeur propre pour laquelle on souhaite calculer l'espace propre (définie comme `l = 2` par exemple)\n", + "* Une base de l'espace propre à vérifier. La base doit être exprimée comme une liste de vecteurs de base: \n", + " * Exemples:\n", + " * `base = [[v11, v12, v13], [v21, v22, v23]]` si la base contient deux vecteurs de dimension 3\n", + " * `base = [[v11, v12]]` si la base n'a qu'un seul vecteur de dimension 2\n", + "\n", + "Pour appeler la fonction, on execute simplement:\n", + "`eigen_basis(A, l, base)`\n", + "\n", + "Si vous ne trouvez pas de base pour l'espace propre, vous pouvez simplement afficher la solution en exécutant `eigen_basis(A, l)`. \n" + ] + }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "#A_sp = sp.Matrix([[0, -4, -1], [0, -8, 8], [0, -4, -4]])\n", - "#display(A_sp.rref())\n", - "#A_np = np.array([[0, -4, -1], [0, -8, 8], [0, -4, -4]])\n", - "#b = np.zeros(3)\n", - "#display(al.echelonMat('ER', A))\n", - "#A = np.array([[4, -1, 6],[2, 1, 6], [2, -1, 8]])\n", - "\n", - "#A = np.random.randint(-5,5, (3,3))\n", - "#A = np.eye(3)\n", - "A = sp.Matrix([[3, -4, -1], [0, -5, 8], [0, -1, -4]])\n", - "A_sp = sp.Matrix(A)\n", + "A1 = sp.Matrix([[-1, 3], [-1, 3]])\n", + "A2 = sp.Matrix([[4, 4], [3, 0]])\n", "\n", - "eig = A_sp.eigenvects()\n", - "eig_list = np.array(eig[0][2]).astype(np.float64)\n", + "# Simplement pour lambda = 3 (les autres valeurs propores sont complexes)\n", + "A3 = sp.Matrix([[3, -4, -1], [0, -5, 8], [0, -1, -4]])\n", "\n", - "for sp_mat in eig_list:\n", - " sp_mat = np.array(sp_mat)\n", - " \n", - "basis, basic_idx, free_idx = eigen_basis_sp(A_sp, float(eig[0][0]), eig_list, disp=True)\n", - "\n" + "# Trouver les valeurs propres en utilisant les racines évidentes du polynôme caractéristique\n", + "A4 = sp.Matrix([[4, -1, 6],[2, 1, 6], [2, -1, 8]])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "A = np.array([[1, 1, 1],[1, 1, 1], [1, 1, 2]])\n", + "# Matrice (A1, A2, A3 ou A4)\n", + "A = A1\n", + "display(A)\n", "\n", - "A_sp = sp.Matrix(A)\n", + "# Rentrer une valeur propre que vous avez calculé\n", + "l = 0\n", "\n", - "plot3x3_eigspace(A_sp, plot_vector=False)\n" + "# Base que vous avez calculé associé à la valeur propre ci-dessus\n", + "base = [[1, 1], [1, 2]]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "A = sp.Matrix([[4, -1, 6],[2, 1, 6], [2, -1, 8]])\n", - "\n" + "# Solution étape par étape et vérification de la base calculée\n", + "eigen_basis(A1, l, base)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Visualisation des espaces propres\n", + "Les espaces propres des matrices $2\\times2$ et $3\\times3$ peuvent être représenté graphiquement.\n", + "\n", + "La fonction `plot_eigspace` permet de visualiser les espaces propres associer à chaque valeurs propres d'une matrice $2\\times2$ ou $3\\times3$. Pour utiliser cette function, il suffit de donner comme argument une matrice. Les valeurs propres et leur espace propre associé sont calculés par la fonction et ensuite affichés.\n", + "\n", + "Utilisez les matrices de l'**Exercice 1** afin de visualiser les espaces propres dont vous avez calculé les bases." ] }, { "cell_type": "code", "execution_count": null, - "metadata": { - "scrolled": true - }, + "metadata": {}, "outputs": [], "source": [ - "A = sp.Matrix([[1, 1], [-1, 3]])\n", + "A_sp = sp.Matrix([[1,0,0], [0,2,0], [0, 0, 2]])\n", + "plot_eigspace(A_sp)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Observations (MOOC 8.5)\n", + "* On voit que l'origine est toujours compris dans n'importe quel espace propre. Un espace propre étant un espace sous-vectoriel, il contient forcément le vecteur nul (l'origine).\n", + "\n", + "* Deux espaces propres associé à deux valeurs propres distinctes de la même matrice n'ont en commun que le vecteur nul (l'origine).\n", "\n", - "plot2x2_eigspace(A)" + "* Deux vecteurs propres associés à des valeurs propres distinctes sont linéairement indépendants." ] }, { "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.7.2" } }, "nbformat": 4, "nbformat_minor": 2 } diff --git "a/Chapitre 8 - Valeurs propres, vecteurs propres, diagonalisation/8.7 Multiplicit\303\251 alg\303\251brique, multiplicit\303\251 g\303\251om\303\251trique.ipynb" "b/Chapitre 8 - Valeurs propres, vecteurs propres, diagonalisation/8.7 Multiplicit\303\251 alg\303\251brique, multiplicit\303\251 g\303\251om\303\251trique.ipynb" new file mode 100644 index 0000000..8ad2b54 --- /dev/null +++ "b/Chapitre 8 - Valeurs propres, vecteurs propres, diagonalisation/8.7 Multiplicit\303\251 alg\303\251brique, multiplicit\303\251 g\303\251om\303\251trique.ipynb" @@ -0,0 +1,71 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Définition 1:\n", + "Soient $\\phi: V \\rightarrow V$ une transformation linéaire d'un $\\mathbb{R}$ -espace vectoriel $V$ de dimension finie $n \\in \\mathbb{N}$ et $\\lambda \\in \\mathbb{R}$ une valeur propre de $\\phi$. Comme toute valeur propre de $\\phi$ est racine de $c_{\\phi}(t),$ on peut factoriser\n", + "$$c_{\\phi}(t)=(t-\\lambda)^{m} p(t)$$\n", + "où $p(\\lambda) \\neq 0$ (i.e. $t-\\lambda$ ne divise pas $p(t)$). L'entier $m$ est appelée la multiplicité algébrique de $\\lambda$. Aussi, la dimension du sous-espace $E_{\\lambda}$ de $V$ est appelée la multiplicité géométrique de $\\lambda$.\n", + "\n", + "### Proposition 2:\n", + "\n", + "Soient $\\phi: V \\rightarrow V$ une transformation linéaire d'un $\\mathbb{R}$-espace vectoriel $V$ de dimension finie $n \\in \\mathbb{N}$ et $\\lambda \\in \\mathbb{R}$ une valeur propre de $\\phi$. Alors la multiplicité géométrique de $\\lambda$ est plus grande ou égale à 1. Aussi, celle-ci est toujours plus petite ou égale à la multiplicité algébrique de $\\lambda$." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from Ch8_lib import *\n", + "import sys, os\n", + "sys.path.append('../Librairie')\n", + "import AL_Fct as al\n", + "import numpy as np\n", + "import sympy as sp\n", + "from IPython.utils import io\n", + "from IPython.display import display, Latex\n", + "import plotly\n", + "import plotly.graph_objects as go" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Exercice 1: Calcul des multiplicités algébriques et géométriques." + ] + }, + { + "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.7.2" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/Chapitre 8 - Valeurs propres, vecteurs propres, diagonalisation/8.8 Crit\303\250re de diagonalisabilit\303\251.ipynb" "b/Chapitre 8 - Valeurs propres, vecteurs propres, diagonalisation/8.8 Crit\303\250re de diagonalisabilit\303\251.ipynb" new file mode 100644 index 0000000..b9c9152 --- /dev/null +++ "b/Chapitre 8 - Valeurs propres, vecteurs propres, diagonalisation/8.8 Crit\303\250re de diagonalisabilit\303\251.ipynb" @@ -0,0 +1,152 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Théorème\n", + "Soit $\\phi: V \\rightarrow V$ une transformation linéaire d'un $\\mathbb{R}$-espace vectoriel $V$ de dimension finie $n \\in \\mathbb{N}$. Alors $\\phi$ est diagonalisable si et seulement si il existe $a \\in \\mathbb{R}, \\lambda_{1}, \\ldots, \\lambda_{r} \\in \\mathbb{R}$ distincts et $m_{1}, \\ldots, m_{r} \\in \\mathbb{N}$ tels que\n", + "$$c_{\\phi}(t)=a\\left(t-\\lambda_{1}\\right)^{m_{1}} \\ldots\\left(t-\\lambda_{r}\\right)^{m_{r}}$$\n", + "et $m_{i}=\\operatorname{dim} E_{\\lambda_{i}}$ pour tout $1 \\leq i \\leq n$" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import sys, os\n", + "sys.path.append('../Librairie')\n", + "import AL_Fct as al\n", + "import numpy as np\n", + "import sympy as sp\n", + "from IPython.utils import io\n", + "from IPython.display import display, Latex, Markdown\n", + "import plotly\n", + "import plotly.graph_objects as go\n", + "from Ch8_lib import *" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Exercice 1\n", + "À l'aide de la représentation graphique des espaces propres associés aux différentes valeurs propres d'une matrice, determinez si cette dernière est diagonalisable. (Aucun long calcul requis).\n", + "\n", + "**Si besoin, la méthode à appliquer est donnée plus bas.**" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "A1 = sp.Matrix([[3, 4], [0, 3]])\n", + "A2 = sp.Matrix([[1, 3], [4,5]])\n", + "A3 = sp.Matrix([[5, 0, 0],[0, 1, 0], [0, 0, 1]])\n", + "A4 = sp.Matrix([[1, 0, -2],[2 ,1, 0], [0, 0, 3]])\n", + "\n", + "# Choisir matrice (A = A1 ou A = A2 ...)\n", + "A = A1\n", + "plot_eigspace(A)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Affiche la solution pour la matrice A = A1 ou A = A2 ...\n", + "A = A1\n", + "# Votre réponse a : La matrice A est-elle diagonlisable ? (True pour oui, False pour non)\n", + "my_answer = True\n", + "\n", + "ch8_8_ex_1(A, my_answer)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Méthode exercice 1\n", + "On sait que le polynôme caractéristique d'une matrice $A (n \\times n)$ est d'ordre $n$. \n", + "\n", + "Avec $c_A(t)=a(t-\\lambda_{1})^{m_{1}} \\ldots (t-\\lambda_{r})^{m_{r}}$, avec $a \\in \\mathbb{R}$, $r\\leq n$ et $\\lambda_{1}, \\ldots, \\lambda_{r} \\in \\mathbb{R}$ distincts, on peut en déduire que $\\sum_{i=1}^r m_i = n$\n", + "\n", + "Sachant également que $\\dim E_{\\lambda_i} \\leq m_i$, on a $m_i = \\dim E_{\\lambda_i} $ pour tout $ i = 1, .., r$ si et seulement si $\\sum_{i=1}^r \\dim E_{\\lambda_i} = n$ \n", + "\n", + "Le théorème donné plus haut indique qu'une matrice est diagonalisable si et seulement si $m_i = \\dim E_{\\lambda_i}$ pour tout $ i = 1, .., r$. \n", + "\n", + "On vient de montrer que c'est équivalent à $\\sum_{i=1}^r \\dim E_{\\lambda_i} = n$.\n", + "\n", + "Grâce à la représentation graphique des espaces propres, on connait la dimension de chaque espace propre (droite -> $\\dim E_{\\lambda_i} = 1$, plan -> $\\dim E_{\\lambda_i}=2$). Il suffit donc de vérifier que la somme des dimensions de tous les espaces propres est bien égal à $n$. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Exercice 2\n", + "Determinez si les matrices suivantes sont diagonalisables. Essayez d'utiliser la méthode la plus simple pour chaque cas.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "A1 = sp.Matrix([[1, 2], [3, 2]])\n", + "A2 = sp.Matrix([[5, -7], [0, 5]])\n", + "A3 = sp.Matrix([[3, 5, -10], [1, 7, 2], [-2, 2, 4]])\n", + "A4 = sp.Matrix([[3, 5, -10], [1, 7, 2], [-2, 2, 4]])\n", + "A5 = sp.Matrix([[1, 0, 0, 0],[11, -5, 0, 0],[-1, 2, 3, 0],[0, -2, 1, -3]])\n", + "A6 = sp.Matrix([[-1, 0, 0, 0],[11, -5, 0, 0],[-1, 2, -1, 0],[0, -2, 1, -1]])\n", + "\n", + "display(A1)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Affiche la solution étape par étape pour la matrice donné en argument de la fonction isDiagonalizable\n", + "isDiagonalizable(A1)\n" + ] + }, + { + "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.7.2" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/Chapitre 8 - Valeurs propres, vecteurs propres, diagonalisation/Ch8_lib.py b/Chapitre 8 - Valeurs propres, vecteurs propres, diagonalisation/Ch8_lib.py index e1d205b..74da8b0 100644 --- a/Chapitre 8 - Valeurs propres, vecteurs propres, diagonalisation/Ch8_lib.py +++ b/Chapitre 8 - Valeurs propres, vecteurs propres, diagonalisation/Ch8_lib.py @@ -1,653 +1,745 @@ import sys, os sys.path.append('../Librairie') import AL_Fct as al import numpy as np import sympy as sp from IPython.utils import io -from IPython.display import display, Latex +from IPython.display import display, Latex, Markdown import plotly import plotly.graph_objects as go def vector_plot_3D(v, b): """ Show 3D plot of a vector (v) and of b = A * v @param v: numpy array of shape (3,) @param b: numpy array of shape (3,) @return: """ fig = go.Figure() fig.add_trace(go.Scatter3d(x=[0, v[0]], y=[0, v[1]], z=[0, v[2]], line=dict(color='red', width=4), mode='lines+markers', name='$v$')) fig.add_trace(go.Scatter3d(x=[0, b[0]], y=[0, b[1]], z=[0, b[2]], line=dict(color='royalblue', width=4, dash='dash'), mode='lines+markers', name='$A \ v$')) fig.show() def CheckEigenVector(A, v): """ Check if v is an eigenvector of A, display step by step solution @param A: square sympy Matrix of shape (n,n) @param v: 1D sympy Matrix of shape (n,1) @return: """ # Check Dimensions if A.shape[0] != A.shape[1] or v.shape[0] != A.shape[1]: raise ValueError('Dimension problem, A should be square (n x n) and v (n x 1)') if v == sp.zeros(v.shape[0], 1): display(Latex("$v$ est le vecteur nul, il ne peut pas être un vecteur propre par définition.")) else: # Matrix Multiplication b = A * v # Print some explanation about the method - display(Latex("On voit que $ b = A v = " + sp.latex(b) + "$")) + display(Latex("On voit que $ b = A v = " + latexp(b) + "$")) display(Latex("On cherche alors un nombre $\lambda \in \mathbb{R}$ tel que $b = \lambda v" \ - + "\Leftrightarrow" + sp.latex(b) + " = \lambda" + sp.latex(v) + '$')) + + "\Leftrightarrow" + latexp(b) + " = \lambda" + latexp(v) + '$')) # Symbol for lambda l = sp.symbols('\lambda', real=True) # Check if there is a solution lambda of eq: A*v = lambda * v eq = sp.Eq(b, l * v) sol = sp.solve(eq, l) # If there is l st b = l*v if sol: display(Latex("Il existe bien une solution pour $\lambda$. Le vecteur $v$ est donc un vecteur \ propre de la matrice $A$.")) display(Latex("La valeur propre associée est $\lambda = " + sp.latex(sol[l]) + "$.")) # Otherwise else: display(Latex("L'equation $b = \lambda v$ n'a pas de solution.")) display(Latex("Le vecteur $v$ n'est donc pas un vecteur propre de la matrice $A$.")) def ch8_1_exo_2(A, l, vp, v): """ Display step by step @param A: Square sympy matrix @param l: eigenvalue (float or int) @param vp: Boolean, given answer to question is l an eigenvalue of A @param v: proposed eigenvector @return: """ # Check Dimensions if A.shape[0] != A.shape[1] or v.shape[0] != A.shape[1]: raise ValueError('Dimension problem, A should be square (n x n) and v (n x 1)') n = A.shape[0] eig = list(A.eigenvals().keys()) for i, w in enumerate(eig): eig[i] = float(w) eig = np.array(eig) if np.any(abs(l-eig) < 10**-10): if vp: display(Latex("$\lambda = " + str(l) + "$ est bien une valeur propre de la matrice $A$.")) else: display(Latex("Non, $\lambda = " + str(l) + "$ est bien une valeur propre de la matrice $A$.")) if v != sp.zeros(n, 1): # Check the eigen vector v z = sp.simplify(A * v - l * v) if z == sp.zeros(n, 1): display(Latex("$v$ est bien un vecteur propre de $A$ associé à $\lambda = " + str(l) + "$ car on a:")) - display(Latex("$$" + sp.latex(A) + sp.latex(v) + "= " + str(l) + "\cdot " + sp.latex(v) + "$$")) + display(Latex("$$" + latexp(A) + latexp(v) + "= " + str(l) + "\cdot " + latexp(v) + "$$")) else: display(Latex("$v$ n'est pas un vecteur propre de $A$ associé à $\lambda = " + str(l) + "$ car on a:")) - display(Latex("$$" + sp.latex(A) + sp.latex(v) + "\\neq \lambda" + sp.latex(v) + "$$")) + display(Latex("$$" + latexp(A) + latexp(v) + "\\neq \lambda" + latexp(v) + "$$")) else: display(Latex("$v$ est le vecteur nul et ne peut pas être par définition un vecteur propre.")) else: if vp: display(Latex("En effet, $\lambda$ n'est pas une valeur propre de $A$.")) else: display(Latex("Non, $\lambda = " + str(l) + "$ n'est pas une valeur propre de $A$.")) def red_matrix(A, i, j): """ Return reduced matrix (without row i and col j)""" row = [0, 1, 2] col = [0, 1, 2] row.remove(i - 1) col.remove(j - 1) return A[row, col] def pl_mi(i, j, first=False): """ Return '+', '-' depending on row and col index""" if (-1) ** (i + j) > 0: if first: return "" else: return "+" else: return "-" def brackets(expr): """Takes a sympy expression, determine if it needs parenthesis and returns a string containing latex of expr with or without the parenthesis.""" expr_latex = sp.latex(expr) if '+' in expr_latex or '-' in expr_latex: return "(" + expr_latex + ")" else: return expr_latex def Determinant_3x3(A, step_by_step=True, row=True, n=1): """ Step by step computation of the determinant of a 3x3 sympy matrix strating with given row/col number @param A: 3 by 3 sympy matrix @param step_by_step: Boolean, True: print step by step derivation of det, False: print only determinant @param row: True to compute determinant from row n, False to compute determinant from col n @param n: row or col number to compute the determinant from (int between 1 and 3) @return: display step by step solution for """ if A.shape != (3, 3): raise ValueError('Dimension of matrix A should be 3x3. The input A must be a sp.Matrix of shape (3,3).') if n < 1 or n > 3 or not isinstance(n, int): raise ValueError('n should be an integer between 1 and 3.') # Construc string for determinant of matrix A detA_s = sp.latex(A).replace('[', '|').replace(']', '|') # To print all the steps if step_by_step: # If we compute the determinant with row n if row: # Matrix with row i and col j removed (red_matrix(A, i, j)) A1 = red_matrix(A, n, 1) A2 = red_matrix(A, n, 2) A3 = red_matrix(A, n, 3) detA1_s = sp.latex(A1).replace('[', '|').replace(']', '|') detA2_s = sp.latex(A2).replace('[', '|').replace(']', '|') detA3_s = sp.latex(A3).replace('[', '|').replace(']', '|') line1 = "$" + detA_s + ' = ' + pl_mi(n, 1, True) + brackets(A[n - 1, 0]) + detA1_s + pl_mi(n, 2) + \ brackets(A[n - 1, 1]) + detA2_s + pl_mi(n, 3) + brackets(A[n - 1, 2]) + detA3_s + '$' line2 = '$' + detA_s + ' = ' + pl_mi(n, 1, True) + brackets(A[n - 1, 0]) + "\cdot (" + sp.latex(sp.det(A1)) \ + ")" + pl_mi(n, 2) + brackets(A[n - 1, 1]) + "\cdot (" + sp.latex(sp.det(A2)) + ")" + \ pl_mi(n, 3) + brackets(A[n - 1, 2]) + "\cdot (" + sp.latex(sp.det(A3)) + ')$' line3 = '$' + detA_s + ' = ' + sp.latex(sp.simplify(sp.det(A))) + '$' # If we compute the determinant with col n else: # Matrix with row i and col j removed (red_matrix(A, i, j)) A1 = red_matrix(A, 1, n) A2 = red_matrix(A, 2, n) A3 = red_matrix(A, 3, n) detA1_s = sp.latex(A1).replace('[', '|').replace(']', '|') detA2_s = sp.latex(A2).replace('[', '|').replace(']', '|') detA3_s = sp.latex(A3).replace('[', '|').replace(']', '|') line1 = "$" + detA_s + ' = ' + pl_mi(n, 1, True) + brackets(A[0, n - 1]) + detA1_s + pl_mi(n, 2) + \ brackets(A[1, n - 1]) + detA2_s + pl_mi(n, 3) + brackets(A[2, n - 1]) + detA3_s + '$' line2 = '$' + detA_s + ' = ' + pl_mi(n, 1, True) + brackets(A[0, n - 1]) + "\cdot (" + sp.latex(sp.det(A1))\ + ")" + pl_mi(n, 2) + brackets(A[1, n - 1]) + "\cdot (" + sp.latex(sp.det(A2)) + ")" + \ pl_mi(n, 3) + brackets(A[2, n - 1]) + "\cdot (" + sp.latex(sp.det(A3)) + ')$' line3 = '$' + detA_s + ' = ' + sp.latex(sp.simplify(sp.det(A))) + '$' # Display step by step computation of determinant display(Latex(line1)) display(Latex(line2)) display(Latex(line3)) # Only print the determinant without any step else: display(Latex("$" + detA_s + "=" + sp.latex(sp.det(A)) + "$")) def valeurs_propres(A): if A.shape[0] != A.shape[1]: raise ValueError("A should be a square matrix") l = sp.symbols('\lambda') n = A.shape[0] poly = sp.det(A - l * sp.eye(n)) poly_exp = sp.expand(poly) poly_factor = sp.factor(poly) det_str = sp.latex(poly_exp) + "=" + sp.latex(poly_factor) - display(Latex("On cherche les valeurs propres de la matrice $ A=" + sp.latex(A) + "$.")) + display(Latex("On cherche les valeurs propres de la matrice $ A=" + latexp(A) + "$.")) display(Latex("Le polynome caractéristique de $A$ est: $$\det(A- \lambda I)= " + det_str + "$$")) eq = sp.Eq(poly, 0) sol = sp.solve(eq, l) if len(sol) > 1: display(Latex("Les racines du polynôme caractéristique sont $" + sp.latex(sol) + "$.")) display(Latex("Ces racines sont les valeurs propres de la matrice $A$.")) else: display(Latex("L'unique racine du polynôme caractéristique est" + str(sol[0]))) def texVector(v): """ Return latex string for vertical vector Input: v, 1D np.array() """ n = v.shape[0] return al.texMatrix(v.reshape(n, 1)) def check_basis(sol, prop): """ Checks if prop basis is equivalent to sol basis @param sol: verified basis, 2D numpy array, first dim: vector indexes, second dim: idx of element in a basis vect @param prop: proposed basis @return: boolean """ prop = np.array(prop, dtype=np.float64) # number of vector in basis n = len(sol) # Check dimension of proposed eigenspace if n != len(prop): display(Latex("Le nomber de vecteur(s) propre(s) donné(s) est incorrecte. " + "La dimension de l'espace propre est égale au nombre de variable(s) libre(s).")) return False else: # Check if the sol vector can be written as linear combination of prop vector # Do least squares to solve overdetermined system and check if sol is exact A = np.transpose(prop) lin_comb_ok = np.zeros(n, dtype=bool) for i in range(n): x, _, _, _ = np.linalg.lstsq(A, sol[i], rcond=None) res = np.sum((A @ x - sol[i]) ** 2) lin_comb_ok[i] = res < 10 ** -13 return np.all(lin_comb_ok) -def eigen_basis_sp(A, l, prop_basis=None, disp=True): +def eigen_basis(A, l, prop_basis=None, disp=True, return_=False): """ Display step by step method for finding a basis of the eigenspace of A associated to eigenvalue l Eventually check if the proposed basis is correct. Display or not @param A: Square sympy Matrix with real coefficients @param l: real eigen value of A (float or int) @param prop_basis: Proposed basis: list of base vector (type list of list of floats) @param disp: boolean if display the solution. If false it displays nothing + @param return_: boolean if return something or nothing @return: basis: a correct basis for the eigen space (2D numpy array) basic_idx: list with indices of basic variables of A - l*I free_idx: list with indices of free variables of A - l*I """ if not A.is_Matrix: raise ValueError("A should be a sympy Matrix.") # Check if A is square n = A.shape[0] if n != A.shape[1]: raise ValueError('A should be a square matrix.') - - # Compute eigenvals in symbolic eig = A.eigenvals() eig = list(eig.keys()) # Deal with complex number (removal) complex_to_rm = [] for idx, el in enumerate(eig): if not el.is_real: complex_to_rm.append(idx) for index in sorted(complex_to_rm, reverse=True): del eig[index] eig = np.array(eig) # evaluate symbolic expression eig_eval = np.array([float(el) for el in eig]) # Check that entered eigenvalue is indeed an eig of A if np.all(abs(l - eig_eval) > 1e-10) and len(eig) > 0: display(Latex("$\lambda$ n'est pas une valeur propre de $A$.")) return None, None, None # Change value of entered eig to symbolic expression (for nice print) l = eig[np.argmin(np.abs(l - eig))] I = sp.eye(n) Mat = A - l * I b = np.zeros(n) if disp: - display(Latex("On a $ A = " + sp.latex(A) + "$.")) + display(Latex("On a $ A = " + latexp(A) + "$.")) display(Latex("On cherche une base de l'espace propre associé à $\lambda = " + str(l) + "$.")) # ER matrix e_Mat, basic_idx = Mat.rref() # Idx of basic and free varialbe basic_idx = list(basic_idx) basic_idx.sort() free_idx = [idx for idx in range(n) if idx not in basic_idx] free_idx.sort() n_free = len(free_idx) # String to print free vars free_str = "" for i in range(n): if i in free_idx: free_str += "x_" + str(i + 1) + " \ " # Display echelon matrix if disp: display(Latex("On échelonne la matrice du système $A -\lambda I = 0 \Rightarrow " + al.texMatrix(np.array(Mat), np.reshape(b, (n, 1))) + "$")) display(Latex("On obtient: $" + al.texMatrix(np.array(e_Mat[:, :n]), np.reshape(b, (n, 1))) + "$")) display(Latex("Variable(s) libre(s): $" + free_str + "$")) # Build a list of n_free basis vector: # first dim: which eigenvector (size of n_free) # second dim: which element of the eigenvector (size of n) basis = np.zeros((n_free, n)) for i in range(n_free): basis[i, free_idx[i]] = 1.0 for idx, j in enumerate(free_idx): for i in basic_idx: basis[idx, i] = - float(e_Mat[i, j]) # Show calculated basis basis_str = "" for idx, i in enumerate(free_idx): basis_str += "x_" + str(i + 1) + " \cdot" + texVector(basis[idx]) if idx < n_free - 1: basis_str += " + " if disp: display(Latex("On peut donc exprimer la base de l'espace propre comme: $" + basis_str + "$")) if prop_basis is not None and disp: correct_answer = check_basis(basis, prop_basis) if correct_answer: display(Latex("La base donnée est correcte car on peut retrouver la base calculée ci-dessus" \ " avec une combinaison linéaire de la base donnée. " "Aussi les deux bases ont bien le même nombre de vecteurs.")) else: display(Latex("La base donnée est incorrecte.")) - return basis, basic_idx, free_idx + if return_: + return basis, basic_idx, free_idx def generate_eigen_vector(basis, l, limit): + """ + Function to generate a random eigenvector associated to a eigenvalue given a basis of the eigenspace + The returned eigenvector is such that itself and its multiplication with the matrix will stay in range of limit + in order to have a nice plot + @param basis: basis of eigenspace associated to eigenvalue lambda + @param l: eigenvalue + @param limit: limit of the plot: norm that the engenvector or its multiplication with the matrix will not exceed + @return: eigen vector (numpy array) + """ n = len(basis) basis_mat = np.array(basis).T basis_mat = basis_mat.astype(np.float64) coeff = 2 * np.random.rand(n) - 1 vect = basis_mat @ coeff if abs(l) <= 1: vect = vect / np.linalg.norm(vect) * (limit - 1) else: vect = vect / np.linalg.norm(vect) * (limit - 1) / l return vect -def plot3x3_eigspace(A, xL=-10, xR=10, p=None, plot_vector=True): +def plot3x3_eigspace(A, xL=-10, xR=10, p=None, plot_vector=False): # To have integer numbers if p is None: p = xR - xL + 1 n = A.shape[0] # Check 3 by 3 if n != 3 or n != A.shape[1]: raise ValueError("A should be 3 by 3") w = A.eigenvals() w = list(w.keys()) # Deal with complex number (removal) complex_to_rm = [] for idx, el in enumerate(w): if not el.is_real: complex_to_rm.append(idx) for index in sorted(complex_to_rm, reverse=True): del w[index] display("Des valeurs propres sont complexes, on les ignore.") if len(w)==0: display("Toute les valeurs propres sont complexes.") return gr = 'rgb(102,255,102)' org = 'rgb(255,117,26)' # red = 'rgb(255,0,0)' blue = 'rgb(51, 214, 255)' colors = [blue, gr, org] s = np.linspace(xL, xR, p) t = np.linspace(xL, xR, p) tGrid, sGrid = np.meshgrid(s, t) data = [] A_np = np.array(A).astype(np.float64) for i, l in enumerate(w): l_eval = float(l) - basis, basic_idx, free_idx = eigen_basis_sp(A, l_eval, disp=False) + basis, basic_idx, free_idx = eigen_basis(A, l_eval, disp=False, return_=True) n_free = len(basis) if n_free != len(free_idx): raise ValueError("len(basis) and len(free_idx) should be equal.") gr = 'rgb(102,255,102)' colorscale = [[0.0, colors[i]], [0.1, colors[i]], [0.2, colors[i]], [0.3, colors[i]], [0.4, colors[i]], [0.5, colors[i]], [0.6, colors[i]], [0.7, colors[i]], [0.8, colors[i]], [0.9, colors[i]], [1.0, colors[i]]] X = [None] * 3 if n_free == 2: X[free_idx[0]] = tGrid X[free_idx[1]] = sGrid X[basic_idx[0]] = tGrid * basis[0][basic_idx[0]] + sGrid * basis[1][basic_idx[0]] plot_obj = go.Surface(x=X[0], y=X[1], z=X[2], showscale=False, showlegend=True, colorscale=colorscale, opacity=1, name="$ \lambda= " + sp.latex(l) + "$") elif n_free == 1: plot_obj = go.Scatter3d(x=t * basis[0][0], y=t * basis[0][1], z=t * basis[0][2], line=dict(colorscale=colorscale, width=4), mode='lines', name="$\lambda = " + sp.latex(l) + "$") elif n_free == 3: display(Latex("La dimension de l'espace propre de l'unique valeur propre est 3: tous les vecteurs" \ "$v \in \mathbb{R}^3 $ appartiennent à l'espace propre de la matrice $A$." \ "On ne peut donc pas reprensenter sous la forme d'un plan ou d'une droite.")) return else: print("error") return data.append(plot_obj) if (plot_vector): v1 = generate_eigen_vector(basis, l_eval, xR) v2 = A_np @ v1 data.append(go.Scatter3d(x=[0, v1[0]], y=[0, v1[1]], z=[0, v1[2]], line=dict(width=6), marker=dict(size=4), mode='lines+markers', name='$v_{' + sp.latex(l) + '}$')) data.append(go.Scatter3d(x=[0, v2[0]], y=[0, v2[1]], z=[0, v2[2]], line=dict(width=6, dash='dash'), marker=dict(size=4), mode='lines+markers', name="$A \ v_{" + sp.latex(l) + "}$")) layout = go.Layout( showlegend=True, # not there WHY???? --> LEGEND NOT YET IMPLEMENTED FOR SURFACE OBJECTS!! legend=dict(orientation="h"), autosize=True, width=800, height=800, scene=go.layout.Scene( xaxis=dict( gridcolor='rgb(255, 255, 255)', zerolinecolor='rgb(255, 255, 255)', showbackground=True, backgroundcolor='rgb(230, 230,230)', range=[xL, xR] ), yaxis=dict( gridcolor='rgb(255, 255, 255)', zerolinecolor='rgb(255, 255, 255)', showbackground=True, backgroundcolor='rgb(230, 230,230)', range=[xL, xR] ), zaxis=dict( gridcolor='rgb(255, 255, 255)', zerolinecolor='rgb(255, 255, 255)', showbackground=True, backgroundcolor='rgb(230, 230,230)', range=[xL, xR] ), aspectmode="cube", ) ) fig = go.Figure(data=data, layout=layout) plotly.offline.iplot(fig) return def plot2x2_eigspace(A, xL = -10, xR = 10, p=None): if p is None: p = xR - xL + 1 w = A.eigenvals() w = list(w.keys()) # Deal with complex number (removal) complex_to_rm = [] for idx, el in enumerate(w): if not el.is_real: complex_to_rm.append(idx) for index in sorted(complex_to_rm, reverse=True): del w[index] display("Une valeur propre est complexe, on l'ignore.") if len(w) == 0: display("Toute les valeurs propres sont complexes.") return data = [] for i, l in enumerate(w): l_eval = float(l) - basis, basic_idx, free_idx = eigen_basis_sp(A, l_eval, disp=False) + basis, basic_idx, free_idx = eigen_basis(A, l_eval, disp=False, return_=True) n_free = len(basis) if n_free != len(free_idx): raise ValueError("len(basis) and len(free_idx) should be equal.") if n_free == 2: - display(Latex("Tous les vecteurs du plan appartiennent à l'espace propre de A associé à $\lambda = " - +sp.latex(l) +"$. On ne peut donc pas le représenter.")) + display(Latex("Tous les vecteurs du plan appartiennent à l'espace propre de A associé à $\lambda = " \ + + sp.latex(l) + "$. On ne peut donc pas le représenter.")) return else: t = np.linspace(xL, xR, p) trace = go.Scatter(x=t*basis[0][0], y=t*basis[0][1], marker=dict(size=6), mode='lines+markers', name="$\lambda = " + sp.latex(l) + "$") data.append(trace) layout = go.Layout(showlegend=True, autosize=True) fig = go.Figure(data=data, layout=layout) plotly.offline.iplot(fig) return def plot_eigspace(A, xL=-10, xR=10, p=None): """ Plot the eigenspaces associated to all eigenvalues of A @param A: Sympy matrix of shape (2,2) or (3,3) @param xL: Left limit of plot @param xR: Right limit of plot @param p: Number of points to use """ n = A.shape[0] # Check 3 by 3 or 2 by 2 if (n != 2 and n!=3) or n != A.shape[1]: raise ValueError("A should be 2 by 2 or 3 by 3.") if not A.is_Matrix: raise ValueError("A should be a sympy Matrix.") if n==2: plot2x2_eigspace(A, xL, xR, p) else: plot3x3_eigspace(A, xL, xR, p) -# def create_eig_set(A, show_vector=True, tol=10 ** -13): -# w, _ = np.linalg.eig(A) -# w_imag = np.imag(w) -# if np.all(np.abs(w_imag) < 10 ** -13): -# w = np.real(w) -# else: -# raise ValueError("Complex eigenvalues detected") -# w_set = [w[0]] -# -# for i in range(1, 3): -# # If no very close element already in w_set, then add w[i] in w_set -# if np.all(np.abs(w_set - w[i]) > tol): -# w_set.append(w[i]) -# -# return w_set -# -# -# def create_eig_set_sp(A): -# A_sp = sp.Matrix(A) -# eig_dic = A_sp.eigenvals() -# return np.array(list(eig_dic.keys()), dtype=np.float64) -# + +def latexp(A): + """ + Function to output latex expression of a sympy matrix but with round parenthesis + @param A: sympy matrix + @return: latex string + """ + return sp.latex(A, mat_delim='(', mat_str='matrix') + + +def ch8_8_ex_1(A, prop_answer): + """ + Check if a matrix is diagonalisable. + @param A: sympy square matrix + @param prop_answer: boolean, answer given by the student + @return: + """ + if not A.is_Matrix: + raise ValueError("A should be a sympy Matrix.") + n = A.shape[0] + if n != A.shape[1]: + raise ValueError('A should be a square matrix.') + + eig = A.eigenvects() + dim_geom = 0 + + for x in eig: + dim_geom += len(x[2]) + answer = dim_geom == n + + if answer: + display(Latex("Oui la matrice $A = " + latexp(A) + "$ est diagonalisable.")) + else: + display(Latex("Non la matrice $A = " + latexp(A) + "$ n'est pas diagonalisable.")) + + if answer == prop_answer: + display(Latex("Votre réponse est correcte !")) + else: + display(Latex("Votre réponse est incorrecte.")) + + +def isDiagonalizable(A): + """ + Step by step method to determine if a given matrix is diagonalizable. This methods uses always (I think) + the easiest way to determine it. + @param A: sympy matrix + @return: nothing + """ + if not A.is_Matrix: + raise ValueError("A should be a sympy Matrix.") + + n = A.shape[0] + if n != A.shape[1]: + raise ValueError('A should be a square matrix.') + + display(Latex("On cherche à déterminer si la matrice $A=" + latexp(A) + "$ de taille $n \\times n$ avec $n = " + + str(n) + "$ est diagonalisable.")) + + if A.is_lower or A.is_upper: + display(Latex("Les valeurs propres sont simple à trouver, ce sont les éléments diagonaux.")) + else: + valeurs_propres(A) + + # Check if eigenvalue are all distincts + eig = A.eigenvects() + + if len(eig) == n: + display(Latex("On a $n$ valeurs propres distinctes. La matrice est donc diagonalisable.")) + return + else: + display(Latex("Les valeurs propres ne sont pas toutes distinctes. On va donc vérifier la multiplicité " + + "géométrique des valeurs propres ayant une multiplicité algébrique supérieur à 1.")) + + # Some list to have info about eigenvalues with algebraic mult > 1 + idx = [] + eigenvalues = [] + mult_al = [] + mult_geo = [] + + for i in range(len(eig)): + if eig[i][1] > 1: + idx.append(i) + eigenvalues.append(eig[i][0]) + mult_al.append(eig[i][1]) + mult_geo.append(len(eig[i][2])) + + display(Latex("L'ensemble des valeurs propres ayant une multiplicité algébrique supérieur à 1 est " + str( + eigenvalues) + ".")) + + for i, l in enumerate(eigenvalues): + display(Markdown("**On calcule la multiplicité géométrique pour $\lambda= " + sp.latex(l) + + "$ ayant une multiplicité algébrique de " + str(mult_al[i]) + ".**")) + + basis, basic, free = eigen_basis(A, l, prop_basis=None, disp=True, return_=True) + display(Markdown("**La multiplicité géométrique pour $\lambda= " + sp.latex(l) + "$ est de " + + str(len(free)) + ".**")) + if (len(free) < mult_al[i]): + display(Markdown("**La multiplicité géométrique est strictement inférieur à la multiplicité" + "algébrique + pour cette valeur propre. La matrice n'est donc pas diagonalisable.**")) + return + else: + display(Latex("On a bien multiplicité algébrique = multiplicité géométrique pour cette valeur propre.")) + + display(Markdown("**Toutes les valeurs propres ont une multiplicité algébrique et géométrique égales." + + " La matrice $A$ est donc bien diagonalisable !**")) \ No newline at end of file diff --git a/Librairie/AL_Fct.py b/Librairie/AL_Fct.py index c49af86..71c3a4d 100644 --- a/Librairie/AL_Fct.py +++ b/Librairie/AL_Fct.py @@ -1,1512 +1,1490 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Created on Wed Mar 13 16:42:29 2019 @author: jecker """ from __future__ import division import numpy as np from IPython.display import display, Latex, display_latex import plotly import plotly.graph_objs as go plotly.offline.init_notebook_mode(connected=True) from IPython.core.magic import register_cell_magic from IPython.display import HTML import ipywidgets as widgets import random from ipywidgets import interact_manual, Layout import sympy as sp @register_cell_magic def bgc(color): script = ( "var cell = this.closest('.jp-CodeCell');" "var editor = cell.querySelector('.jp-Editor');" "editor.style.background='{}';" "this.parentNode.removeChild(this)" ).format(color) display(HTML(''.format(script))) ############################################################################### ## PRINTS Equations, systems, matrix def printMonomial(coeff, index=None, include_zeros=False): """Prints the monomial coeff*x_{index} in optimal way :param coeff: value of the coefficient :type coeff: float :param index: index of the monomial. If None, only the numerical value of the coefficient is displayed :type index: int or NoneType :param include_zeros: if True, monomials of type 0x_n are printed. Defaults to False :type include_zeros: bool :return: string representative of the monomial :rtype: str """ if index is not None: coeff = abs(coeff) if coeff % 1: return str(round(coeff, 3)) + ('x_' + str(index) if index is not None else "") elif not coeff: if index is None: return str(0) else: return str(0) + 'x_' + str(index) if include_zeros else "" elif coeff == 1: return 'x_' + str(index) if index is not None else str(int(coeff)) elif coeff == -1: return 'x_' + str(index) if index is not None else str(int(coeff)) else: return str(int(coeff)) + ('x_' + str(index) if index is not None else "") def printPlusMinus(coeff, include_zeros=False): """Prints a plus or minus sign, depending on the sign of the coefficient :param coeff: value of the coefficient :type coeff: float :param include_zeros: if True, 0-coefficients are assigned a "+" sign :type include_zeros: bool :return: "+" if the coefficient is positive, "-" if it is negative, "" if it is 0 :rtype: str """ if coeff > 0: return "+" elif coeff < 0: return "-" else: return "+" if include_zeros else "" def strEq(n, coeff): """Method that provides the Latex string of a linear equation, given the number of unknowns and the values of the coefficients. If no coefficient value is provided, then a symbolic equation with `n` unknowns is plotted. In particular: * **SYMBOLIC EQUATION**: if the number of unknowns is either 1 or 2, then all the equation is displayed while, if the number of unknowns is higher than 2, only the first and last term of the equation are displayed * **NUMERICAL EQUATION**: whichever the number of unknowns, the whole equation is plotted. Numerical values of the coefficients are rounded to the third digit :param n: number of unknowns of the equation :type n: int :param coeff: coefficients of the linear equation. It must be [] if a symbolic equation is desired :type: list[float] :return: Latex string representing the equation :rtype: str """ Eq = '' if not len(coeff): if n is 1: Eq = Eq + 'a_1x_1 = b' elif n is 2: Eq = Eq + 'a_1x_1 + a_2x_2 = b' else: Eq = Eq + 'a_1x_1 + \ldots + ' + 'a_' + str(n) + 'x_' + str(n) + '= b' else: all_zeros = len(set(coeff[:-1])) == 1 and not coeff[0] # check if all lhs coefficients are 0 start_put_sign = all_zeros if n is 1: Eq += "-" if coeff[0] < 0 else "" Eq += printMonomial(coeff[0], index=1, include_zeros=all_zeros) + "=" + printMonomial(coeff[-1]) else: Eq += "-" if coeff[0] < 0 else "" Eq += printMonomial(coeff[0], index=1, include_zeros=all_zeros) start_put_sign = start_put_sign or coeff[0] is not 0 for i in range(1, n): Eq += printPlusMinus(coeff[i], include_zeros=all_zeros) if start_put_sign \ else "-" if coeff[i] < 0 else "" Eq += printMonomial(coeff[i], index=i+1, include_zeros=all_zeros) start_put_sign = start_put_sign or coeff[i] is not 0 Eq += "=" + printMonomial(coeff[-1]) return Eq def printEq(coeff, b, *args): """Method that prints the Latex string of a linear equation, given the values of the coefficients. If no coefficient value is provided, then a symbolic equation with `n` unknowns is plotted. In particular: * **SYMBOLIC EQUATION**: if the number of unknowns is either 1 or 2, then all the equation is displayed while, if the number of unknowns is higher than 2, only the first and last term of the equation are displayed * **NUMERICAL EQUATION**: whichever the number of unknowns, the whole equation is plotted. Numerical values of the coefficients are rounded to the third digit :param coeff: coefficients of the left-hand side of the linear equation :type: list[float] :param b: right-hand side coefficient of the linear equation :type b: float :param *args: optional; if passed, it contains the number of unknowns to be considered. If not passed, all the unknowns are considered, i.e. n equals the length of the coefficients list :type: *args: list """ if len(args) == 1: n = args[0] else: n = len(coeff) coeff = coeff + b texEq = '$' texEq = texEq + strEq(n, coeff) texEq = texEq + '$' display(Latex(texEq)) return def printSyst(A, b, *args): """Method that prints a linear system of `n` unknowns and `m` equations. If `A` and `b` are empty, then a symbolic system is printed; otherwise a system containing the values of the coefficients stored in `A` and `b`, approximated up to their third digit is printed. :param A: left-hand side matrix. It must be [] if a symbolic system is desired :type: list[list[float]] :param b: right-hand side vector. It must be [] if a symbolic system is desired :type b: list[float] :param args: optional; if not empty, it is a list of two integers representing the number of equations of the linear system (i.e. `m`) and the number of unknowns of the system (i.e. `n`) :type: list """ if (len(args) == 2) or (len(A) == len(b)): # ensures that MatCoeff has proper dimensions if len(args) == 2: m = args[0] n = args[1] else: m = len(A) n = len(A[0]) texSyst = '$\\begin{cases}' Eq_list = [] if len(A) and len(b): if type(b[0]) is list: b = np.array(b).astype(float) A = np.concatenate((A, b), axis=1) else: A = [A[i] + [b[i]] for i in range(0, m)] # becomes augmented matrix A = np.array(A) # just in case it's not for i in range(m): if not len(A) or not len(b): Eq_i = '' if n is 1: Eq_i = Eq_i + 'a_{' + str(i + 1) + '1}' + 'x_1 = b_' + str(i + 1) elif n is 2: Eq_i = Eq_i + 'a_{' + str(i + 1) + '1}' + 'x_1 + ' + 'a_{' + str(i + 1) + '2}' + 'x_2 = b_' + str( i + 1) else: Eq_i = Eq_i + 'a_{' + str(i + 1) + '1}' + 'x_1 + \ldots +' + 'a_{' + str(i + 1) + str( n) + '}' + 'x_' + str(n) + '= b_' + str(i + 1) else: Eq_i = strEq(n, A[i, :]) # attention A is (A|b) Eq_list.append(Eq_i) texSyst = texSyst + Eq_list[i] + '\\\\' texSyst = texSyst + '\\end{cases}$' display(Latex(texSyst)) else: print("La matrice des coefficients n'a pas les bonnes dimensions") return def texMatrix(*args): """Method which produces the Latex string corresponding to the input matrix. .. note:: if two inputs are passed, they represent A and b respectively; as a result the augmented matrix A|B is plotted. Otherwise, if the input is unique, just the matrix A is plotted :param args: input arguments; they could be either a matrix and a vector or a single matrix :type args: list[list] or list[numpy.ndarray] :return: Latex string representing the input matrix or the input matrix augmented by the input vector :rtype: str """ if len(args) == 2: # matrice augmentée if not type(args[0]) is np.ndarray: A = np.array(args[0]).astype(float) else: A = args[0].astype(float) if len(A.shape) <= 1: raise ValueError("If two input arguments are passed, the first one must be either a matrix or a column " "vector! Row vectors or empty vectors are not accepted.") m = A.shape[1] if not type(args[1]) is np.array: b = np.array(args[1]).astype(float) else: b = args[1].astype(float) if len(b.shape) <= 1: raise ValueError("If two input arguments are passed, the second one must be either a matrix or a column " "vector! Row vectors or empty vectors are not accepted.") try: assert A.shape[0] == b.shape[0] except AssertionError: raise ValueError(f"If two input arguments are passed, they must both be either matrices or column vectors, " f"with the same number of rows. In this case, instead, the first input argument has " f"{A.shape[0]} rows, while the second one has {b.shape[0]}") A = np.concatenate((A, b), axis=1) - texApre = '\\left[\\begin{array}{' + texApre = '\\left(\\begin{array}{' texA = '' for i in np.asarray(A): texALigne = '' texALigne = texALigne + str(round(i[0], 4) if i[0] % 1 else int(i[0])) if texA == '': texApre = texApre + 'c' for j in i[1:m]: if texA == '': texApre = texApre + 'c' texALigne = texALigne + ' & ' + str(round(j, 4) if j % 1 else int(j)) if texA == '': texApre = texApre + '| c' for j in i[m:]: if texA == '': texApre = texApre + 'c' texALigne = texALigne + ' & ' + str(round(j, 4) if j % 1 else int(j)) texALigne = texALigne + ' \\\\' texA = texA + texALigne - texA = texApre + '} ' + texA[:-2] + ' \\end{array}\\right]' + texA = texApre + '} ' + texA[:-2] + ' \\end{array}\\right)' elif len(args) == 1: # matrice des coefficients if not type(args[0]) is np.ndarray: A = np.array(args[0]).astype(float) else: A = args[0].astype(float) - texApre = '\\left[\\begin{array}{' - texApost = ' \\end{array}\\right]' + texApre = '\\left(\\begin{array}{' + texApost = ' \\end{array}\\right)' texA = '' if len(A.shape) == 0 or A.shape[0] == 0: return texApre + '}' + texA + texApost elif len(A.shape) == 1: A = np.expand_dims(A, 0) for i in np.asarray(A): texALigne = '' texALigne = texALigne + str(round(i[0], 4) if i[0] % 1 else int(i[0])) if texA == '': texApre = texApre + 'c' for j in i[1:]: if texA == '': texApre = texApre + 'c' texALigne = texALigne + ' & ' + str(round(j, 4) if j % 1 else int(j)) texALigne = texALigne + ' \\\\' texA = texA + texALigne texA = texApre + '} ' + texA[:-2] + texApost else: print("Ce n'est pas une matrice des coefficients ni une matrice augmentée") texA = '' return texA def printA(*args, name=None): """Method which prints the input matrix. .. note:: if two inputs are passed, they represent A and b respectively; as a result the augmented matrix A|B is plotted. Otherwise, if the input is unique, just the matrix A is plotted :param args: input arguments; they could be either a matrix and a vector or a single matrix :type args: list[numpy.ndarray] or list[list] :param name: if not None, it is the name of the matrix; what is printed is then {name} = {value}. If None, only the matrix value is displayed. Defaults to None :type name: str or NoneType """ if name is not None and type(name) is str: texA = '$' + name + ' = ' + texMatrix(*args) + '$' else: texA = '$' + texMatrix(*args) + '$' display(Latex(texA)) return def printEquMatrices(*args): """Method which prints the list of input matrices. .. note:: if two inputs are passed, they represent the list of coefficient matrices A and the list of rhs b respectively; as a result the augmented matrices A|B are plotted. Otherwise, if the input is unique, just the matrices A are plotted :param args: input arguments; they could be either a list of matrices and a list of vectors or a single list of matrices :type args: list """ # list of matrices is M=[M1, M2, ..., Mn] where Mi=(Mi|b) if len(args) == 2: listOfMatrices = args[0] listOfRhS = args[1] texEqu = '$' + texMatrix(listOfMatrices[0], listOfRhS[0]) for i in range(1, len(listOfMatrices)): texEqu = texEqu + '\\quad \\sim \\quad' + texMatrix(listOfMatrices[i], listOfRhS[i]) texEqu = texEqu + '$' display(Latex(texEqu)) else: listOfMatrices = args[0] texEqu = '$' + texMatrix(listOfMatrices[0]) for i in range(1, len(listOfMatrices)): texEqu = texEqu + '\\quad \\sim \\quad' + texMatrix(listOfMatrices[i]) texEqu = texEqu + '$' display(Latex(texEqu)) return def printLUMatrices(LList, UList): """Method which prints the list of L and U matrices, constructed during an interactive LU decomposition routine :param LList: list of lower triangular matrices :type LList: list[numpy.ndarray] :param UList: list of upper triangular matrices :type UList: list[numpy.ndarray] """ try: assert len(LList) == len(UList) except AssertionError: print("The lists of lower and upper traingular matrices must have the same length!") raise ValueError texEqu = '\\begin{align*}' for i in range(len(LList)): texEqu += 'L &= ' + texMatrix(LList[i]) + '\\qquad & U &= ' + texMatrix(UList[i]) if i < len(LList) - 1: texEqu += ' \\\\ ' texEqu += '\\end{align*}' display(Latex(texEqu)) return # %% Functions to enter something def EnterInt(n=None): """Function to allow the user to enter a non-negative integer :param n: first integer, passed to the function. If null or negative or None, an integer is requested to the user. Defaults to None :type n: int or NoneType :return: positive integer :rtype: int """ while type(n) is not int or (type(n) is int and n <= 0): try: n = int(n) if n <= 0: print("Le nombre ne peut pas être négatif o zero!") print("Entrez à nouveau: ") n = input() except: if n is not None: print("Ce n'est pas un entier!") print("Entrez à nouveau:") n = input() else: print("Entrez un entier positif") n = input() return n def EnterListReal(n): """Function which allows the user to enter a list of `n` real numbers :param n: number of real numbers in the desired list :type n: int :return: list of `n` real numbers :rtype: list[float] """ if n < 0: print(f"Impossible de générer une liste de {n} nombres réels") elif n == 0: return [] else: print(f"Entrez une liste de {n} nombres réels") coeff = None while type(coeff) is not list: try: coeff = input() coeff = [float(eval(x)) for x in coeff.split(',')] if len(coeff) != n: print("Vous n'avez pas entré le bon nombre de réels!") print("Entrez à nouveau : ") coeff = input() except: print("Ce n'est pas le bon format!") print("Entrez à nouveau") coeff = input() return coeff def SolOfEq(sol, coeff, i): """Method that verifies if `sol` is a solution to the linear equation `i`with coefficients `coeff` :param sol: candidate solution vector :type sol: list :param coeff: coefficients of the linear equation :type coeff: list :param i: index of the equation :type i: int :return: True if `sol` is a solution, False otherwise :rtype: bool """ try: assert len(sol) == len(coeff)-1 except AssertionError: print(f"La suite entrée n'est pas une solution de l'équation {i}; Les dimensions ne correspondent pas") return False A = np.array(coeff[:-1]) isSol = abs(np.dot(A, sol) - coeff[-1]) < 1e-8 if isSol: print(f"La suite entrée est une solution de l'équation {i}") else: print(f"La suite entrée n'est pas une solution de l'équation {i}") return isSol def SolOfSyst(solution, A, b): """Method that verifies if `solution` is a solution to the linear system with left-hand side matrix `A` and right-hand side vector `b` :param solution: candidate solution vector :type solution: list :param A: left-hand side matrix of the linear system :type A: list[list[float]] or numpy.ndarray :param b: right-hand side vector of the linear system :type b: list[float] or numpy.ndarray :return: True if `sol` is a solution, False otherwise :rtype: bool """ try: assert len(solution) == (len(A[0]) if type(A) is list else A.shape[1]) except AssertionError: print(f"La suite entrée n'est pas une solution du système; Les dimensions ne correspondent pas") return False A = [A[i] + [b[i]] for i in range(0, len(A))] A = np.array(A) isSol = [SolOfEq(solution, A[i, :], i+1) for i in range(len(A))] if all(isSol): print("C'est une solution du système") return True else: print("Ce n'est pas une solution du système") return False # PLOTS WITH PLOTLY # def drawLine(p, d): """Method which allows to plot lines, points and arrows in the 2D-place or 3D-space, using plotly library :param p: point :type p: list[list[float]] :param d: direction vector. If made of all zeros, just the reference point is plotted; if different from 0 a line passing through `p` and with direction `d` is plotted :type d: list[list[float]] :return: generated plot """ blue = 'rgb(51, 214, 255)' colors = [blue] colorscale = [[0.0, colors[0]], [0.1, colors[0]], [0.2, colors[0]], [0.3, colors[0]], [0.4, colors[0]], [0.5, colors[0]], [0.6, colors[0]], [0.7, colors[0]], [0.8, colors[0]], [0.9, colors[0]], [1.0, colors[0]]] vec = 0.9 * np.array(d) if len(p) == 2: data = [] t = np.linspace(-5, 5, 51) s = np.linspace(0, 1, 10) if all(dd == [0] for dd in d): vector = go.Scatter(x=p[0] + s*0, y=p[1] + s*0, marker=dict(symbol=6, size=12, color=colors[0]), name ='Point') else: trace = go.Scatter(x=p[0] + t * d[0], y=p[1] + t * d[1], name='Droite') peak = go.Scatter(x=d[0], y=d[1], marker=dict(symbol=6, size=12, color=colors[0]), showlegend=False) vector = go.Scatter(x=p[0] + s * d[0], y=p[1] + s * d[1], mode='lines', line=dict(width=5, color=colors[0]), name='Vecteur directeur') zero = go.Scatter(x=t*0, y=t*0, name='Origine', marker=dict(symbol=6, size=12, color=colors[0]), showlegend=False) data.append(vector) data.append(zero) if not all(dd == [0] for dd in d): data.append(trace) data.append(peak) fig = go.FigureWidget(data=data) plotly.offline.iplot(fig) elif len(p) == 3: data = [ { 'type': 'cone', 'x': [1], 'y': vec[1], 'z': vec[2], 'u': d[0], 'v': d[1], 'w': d[2], "sizemode": "absolute", 'colorscale': colorscale, 'sizeref': 1, "showscale": False, 'hoverinfo': 'none' } ] t = np.linspace(-5, 5, 51) s = np.linspace(0, 1, 10) zero = go.Scatter3d(x=t*0, y=t*0, z=t*0, name='Origine', marker=dict(size=3), showlegend=False) if all(dd == [0] for dd in d): vector = go.Scatter3d(x=p[0] + s*0, y=p[1] + s*0, z=p[2] + s*0, marker=dict(size=5), name='Point') else: trace = go.Scatter3d(x=p[0] + t * d[0], y=p[1] + t * d[1], z=p[2] + t * d[2], mode='lines', name='Droite') vector = go.Scatter3d(x=p[0] + s * d[0], y=p[1] + s * d[1], z=p[2] + s * d[2], mode='lines', line=dict(width=5,color=colors[0], dash='solid'), name='Vecteur directeur', hoverinfo='none') data.append(zero) data.append(vector) if not all(dd == [0] for dd in d): data.append(trace) layout = { 'scene': { 'camera': { 'eye': {'x': -0.76, 'y': 1.8, 'z': 0.92} } } } fig = go.FigureWidget(data=data, layout=layout) plotly.offline.iplot(fig) return fig def Plot2DSys(xL, xR, p, A, b): """Function for the graphical visualization of a 2D system of equations, plotting the straight lines characterizing the different equations appearing in the system :param xL: left limit of the plot in both coordinates :type xL: int or float :param xR: right limit of the plot in both coordinates :type xR: int or float :param p: number of points used to draw the straight lines :type p: int :param A: matrix of the linear system :type A: list[list[float]] or numpy.ndarray :param b: right-hand side vector of the linear system :type b: list[float] or numpy.ndarray """ A = [A[i] + [b[i]] for i in range(0, len(A))] A = np.array(A) t = np.linspace(xL, xR, p) data = [] for i in range(1, len(A) + 1): if (abs(A[i - 1, 1])) > abs(A[i - 1, 0]): # p0=[0,A[i-1,2]/A[i-1,1]] # p1=[1,(A[i-1,2]-A[i-1,0])/A[i-1,1]] trace = go.Scatter(x=t, y=(A[i-1, 2] - A[i-1, 0] * t) / A[i-1, 1], name='Droite %d' % i) else: trace = go.Scatter(x=(A[i-1, 2] - A[i-1, 1] * t) / A[i-1, 0], y=t, name='Droite %d' % i) data.append(trace) fig = go.Figure(data=data) plotly.offline.iplot(fig) return def Plot3DSys(xL, xR, p, A, b): """Function for the graphical visualization of a 3D system of equations, plotting the straight lines characterizing the different equations appearing in the system :param xL: left limit of the plot in all coordinates :type xL: int or float :param xR: right limit of the plot in all coordinates :type xR: int or float :param p: number of points used to draw the straight lines :type p: int :param A: matrix of the linear system :type A: list[list[float]] or numpy.ndarray :param b: right-hand side vector of the linear system :type b: list[float] or numpy.ndarray """ A = np.array(A) b = np.array(b) gr = 'rgb(102,255,102)' org = 'rgb(255,117,26)' # red = 'rgb(255,0,0)' blue = 'rgb(51, 214, 255)' colors = [blue, gr, org] s = np.linspace(xL, xR, p) t = np.linspace(xL, xR, p) tGrid, sGrid = np.meshgrid(s, t) data = [] for i in range(len(A)): colorscale = [[0.0, colors[i]], [0.1, colors[i]], [0.2, colors[i]], [0.3, colors[i]], [0.4, colors[i]], [0.5, colors[i]], [0.6, colors[i]], [0.7, colors[i]], [0.8, colors[i]], [0.9, colors[i]], [1.0, colors[i]]] j = i + 1 arg = np.argmax(np.abs(A[i,:])) # All the coefficient of equation are 0: b==0 -> every combinations are solution, b!=0 -> No solution if A[i, arg]==0: if b[i] == 0: print("No constraints on equation", j, "of the system.") else: print("No solution for equation", j, "of the system.") # A least a coefficient is different from 0, plot the one with largest coeff in mag else: if arg==2: # z en fonction de x,y x = sGrid y = tGrid surface = go.Surface(x=x, y=y, z=(b[i] - A[i, 0] * x - A[i, 1] * y) / A[i, 2], showscale=False, showlegend=True, colorscale=colorscale, opacity=1, name='Plan %d' % j) elif arg==1: # y en fonction de x,z x = sGrid z = tGrid surface = go.Surface(x=x, y=(b[i]-A[i, 0]*x - A[i, 2]*z)/A[i, 1], z=z, showscale=False, showlegend=True, colorscale=colorscale, opacity=1, name='Plan %d' % j) elif arg==0: # x en fonction de y,z y = sGrid z = tGrid surface = go.Surface(x=(b[i] - A[i, 1] * y - A[i,2] * z)/A[i, 0], y=y, z=z, showscale=False, showlegend=True, colorscale=colorscale, opacity=1, name='Plan %d' % j) data.append(surface) layout = go.Layout( showlegend=True, # not there WHY???? --> LEGEND NOT YET IMPLEMENTED FOR SURFACE OBJECTS!! legend=dict(orientation="h"), autosize=True, width=800, height=800, scene=go.layout.Scene( xaxis=dict( gridcolor='rgb(255, 255, 255)', zerolinecolor='rgb(255, 255, 255)', showbackground=True, backgroundcolor='rgb(230, 230,230)' ), yaxis=dict( gridcolor='rgb(255, 255, 255)', zerolinecolor='rgb(255, 255, 255)', showbackground=True, backgroundcolor='rgb(230, 230,230)' ), zaxis=dict( gridcolor='rgb(255, 255, 255)', zerolinecolor='rgb(255, 255, 255)', showbackground=True, backgroundcolor='rgb(230, 230,230)' ) ) ) fig = go.Figure(data=data, layout=layout) plotly.offline.iplot(fig) return def isDiag(M): """Method which checks if a matrix is diagonal :param M: input matrix :type M: list[list[float]] or numpy.ndarray :return: True if M is diagonal else False :rtype: bool """ if not type(M) is np.ndarray: M = np.array(M) i, j = M.shape try: assert i == j except AssertionError: print("A non-squared matrix cannot be diagonal!") return False test = M.reshape(-1)[:-1].reshape(i - 1, j + 1) return ~np.any(test[:, 1:]) def isSym(M): """Method which checks if a matrix is symmetric :param M: input matrix :type M: list[list[float]] or numpy.ndarray :return: True if M is symmetric else False :rtype: bool """ if not type(M) is np.ndarray: M = np.array(M) i, j = M.shape try: assert i == j except AssertionError: print("A non-squared matrix cannot be symmetric!") return False return ~np.any(M - np.transpose(M)) # ECHELONNAGE # def echZero(indice, M): """Method which sets to zero the entries of matrix M that correspond to a True value in the boolean vector indice :param indice: vector of booleans; if an element is True, it means that the element with the corresponding index in matrix M must be set to 0 :type indice: list[bool] :param M: matrix to be processed :type: numpy.ndarray :return: processed matrix M, where the given entries have been properly set to 0 :rtype: numpy.ndarray """ Mat = M[np.logical_not(indice), :].ravel() Mat = np.concatenate([Mat, M[indice, :].ravel()]) Mat = Mat.reshape(len(M), len(M[0, :])) return Mat def Eij(M, i, j, get_E_inv=False): """Method to swap line `i` and line `j` of matrix `M` :param M: matrix to be processed :type M: numpy.ndarray :param i: first line index :type i: int :param j: second line index :type j: int :param get_E_inv: if True, the inverse matrix of the applied elementary operation is returned. Defaults to False :type get_E_inv: bool :return: processed matrix, with line `i` and `j` having been swapped :rtype: numpy.ndarray """ M = np.array(M) M[[i, j], :] = M[[j, i], :] if get_E_inv: L = np.eye(M.shape[0], M.shape[0]).astype(float) L[[i, j]] = L[[j, i]] if get_E_inv: return M, L else: return M def Ealpha(M, i, alpha, get_E_inv=False): """Method to multiply line `i` of matrix `M` by the scalar coefficient `alpha` :param M: matrix to be processed :type M: numpy.ndarray :param i: reference line index :type i: int :param alpha: scalar coefficient :type alpha: float :param get_E_inv: if True, the inverse matrix of the applied elementary operation is returned. Defaults to False :type get_E_inv: bool :return: processed matrix, with line `i` multiplied by the scalar `alpha` :rtype: numpy.ndarray """ M = np.array(M) M[i, :] = alpha * M[i, :] if get_E_inv: L = np.eye(M.shape[0], M.shape[0]).astype(float) L[i ,i] = 1 / alpha if get_E_inv: return M, L else: return M def Eijalpha(M, i, j, alpha, get_E_inv=False): """Method to add to line `i` of matrix `M` line `j` of the same matrix, multiplied by the scalar coefficient `alpha` :param M: matrix to be processed :type M: numpy.ndarray :param i: line to be modified :type i: int :param j: line whose multiple has tobe added to line `i` :type j: int :param alpha: scalar coefficient :type alpha: float :param get_E_inv: if True, the inverse matrix of the applied elementary operation is returned. Defaults to False :type get_E_inv: bool :return: processed matrix, with line `i` being summed up with line `j` multiplied by `alpha` :rtype: numpy.ndarray """ M = np.array(M) M[i, :] = M[i, :] + alpha * M[j, :] if get_E_inv: L = np.eye(M.shape[0], M.shape[0]).astype(float) L[i, j] = -alpha if get_E_inv: return M, L else: return M def echelonMat(ech, *args): """Method to perform Gauss elimination on either the matrix of the coefficients (if `len(args)==1`) or on the augmented matrix (if `len(args)==2`); the elimination can be either in standard form (if `ech=='E` or in reduced form (if `ech=='ER'`). :param ech: :type ech: :param args: :type args: :return: :rtype: """ if len(args) == 2: # matrice augmentée A = np.array(args[0]).astype(float) m = A.shape[0] n = A.shape[1] b = np.array(args[1]) - b = np.reshape(b, (n, 1)) + b = np.reshape(b, (m, 1)) A = np.concatenate((A, b), axis=1) else: # matrice coeff A = np.array(args[0]).astype(float) m = A.shape[0] n = A.shape[1] - if ech == 'E': # Echelonnée + if ech in {'E', 'ER'}: # Echelonnée + Mat = np.array(A) Mat = Mat.astype(float) # in case the array in int instead of float. numPivot = 0 for i in range(len(Mat)): j = i - while all(abs(Mat[j:, i]) < 1e-15) and j != len(Mat[0, :]) - 1: # if column (or rest of) is 0, take next - j += 1 + goOn = True + if all(abs(Mat[j:, i]) < 1e-15) and j != len(Mat[0, :]) - 1: # if column (or rest of) is 0, take next + goOn = False if j == len(Mat[0, :]) - 1: - if len(Mat[0, :]) > j: - Mat[i + 1:len(Mat), :] = 0 + Mat[i+1:len(Mat), :] = 0 break - if abs(Mat[i, j]) < 1e-15: - Mat[i, j] = 0 - zero = abs(Mat[i:, j]) < 1e-15 - M = echZero(zero, Mat[i:, :]) - Mat[i:, :] = M - Mat = Ealpha(Mat, i, 1 / Mat[i, j]) # usually Mat[i,j]!=0 - for k in range(i + 1, len(A)): - Mat = Eijalpha(Mat, k, i, -Mat[k, j]) - # Mat[k,:]=[0 if abs(Mat[k,l])<1e-15 else Mat[k,l] for l in range(len(MatCoeff[0,:]))] - numPivot += 1 - Mat[abs(Mat) < 1e-15] = 0 + if goOn: + if abs(Mat[i, j]) < 1e-15: + Mat[i, j] = 0 + zero = abs(Mat[i:, j]) < 1e-15 + M = echZero(zero, Mat[i:, :]) + Mat[i:, :] = M + Mat = Ealpha(Mat, i, 1 / Mat[i, j]) # usually Mat[i,j]!=0 + for k in range(i + 1, len(A)): + Mat = Eijalpha(Mat, k, i, -Mat[k, j]) + # Mat[k,:]=[0 if abs(Mat[k,l])<1e-15 else Mat[k,l] for l in range(len(MatCoeff[0,:]))] + numPivot += 1 + Mat[abs(Mat) < 1e-15] = 0 print("La matrice est sous la forme échelonnée") if len(args) == 2: printEquMatrices([A[:, :n], Mat[:, :n]], [A[:, n:], Mat[:, n:]]) else: printEquMatrices([A, Mat]) - elif ech == 'ER': # Echelonnée réduite - Mat = np.array(A) - Mat = Mat.astype(float) # in case the array in int instead of float. - numPivot = 0 - for i in range(len(Mat)): - j = i - while all(abs(Mat[j:, i]) < 1e-15) and j != len( - Mat[0, :]) - 1: # if column (or rest of) is zero, take next column - j += 1 - if j == len(Mat[0, :]) - 1: - # ADD ZERO LINES BELOW!!!!!! - if len(Mat[0, :]) > j: - Mat[i + 1:len(Mat), :] = 0 - break - if abs(Mat[i, j]) < 1e-15: - Mat[i, j] = 0 - zero = abs(Mat[i:, j]) < 1e-15 - M = echZero(zero, Mat[i:, :]) - Mat[i:, :] = M - Mat = Ealpha(Mat, i, 1 / Mat[i, j]) # normalement Mat[i,j]!=0 - for k in range(i + 1, len(A)): - Mat = Eijalpha(Mat, k, i, -Mat[k, j]) - # Mat[k,:]=[0 if abs(Mat[k,l])<1e-15 else Mat[k,l] for l in range(len(MatCoeff[0,:]))] - numPivot += 1 - Mat[abs(Mat) < 1e-15] = 0 - - print("La matrice est sous la forme échelonnée") - if len(args) == 2: - printEquMatrices([A[:, :n], Mat[:, :n]], [A[:, n:], Mat[:, n:]]) - else: - printEquMatrices([np.asmatrix(A), np.asmatrix(Mat)]) + if ech == 'ER': # Echelonnée réduite Mat = np.array(Mat) - i = (len(Mat) - 1) + i = len(Mat) - 1 while i >= 1: - while all( - abs(Mat[i, :len(Mat[0]) - 1]) < 1e-15) and i != 0: # if ligne (or rest of) is zero, take next ligne - i -= 1 - # we have a lign with one non-nul element j = i # we can start at pos ij at least the pivot is there - if abs(Mat[i, j]) < 1e-15: # if element Aij=0 take next one --> find pivot - j += 1 - # Aij!=0 and Aij==1 if echelonMat worked - for k in range(i): # put zeros above pivot (which is 1 now) - Mat = Eijalpha(Mat, k, i, -Mat[k, j]) + goOn = True + if all(abs(Mat[i, :len(Mat[0]) - 1]) < 1e-15) and i != 0: # if row (or rest of) is zero, take next + goOn = False + if goOn: + # we have a row with one non-nul element + if abs(Mat[i, j]) < 1e-15: # if element Aij=0 take next one --> find pivot + j += 1 + # Aij!=0 and Aij==1 if echelonMat worked + for k in range(i): # put zeros above pivot (which is 1 now) + Mat = Eijalpha(Mat, k, i, -Mat[k, j]) i -= 1 print("La matrice est sous la forme échelonnée réduite") if len(args) == 2: printEquMatrices([A[:, :n], Mat[:, :n]], [A[:, n:], Mat[:, n:]]) else: printEquMatrices([A, Mat]) + if (Mat[:min(m,n), :min(m,n)] == np.eye(min(m,n))).all(): + print("La matrice peut être réduite à la matrice d'identité") + else: + print("La matrice ne peut pas être réduite à la matrice d'identité") + else: print(f"Méthode d'échelonnage non reconnue {ech}. Méthodes disponibles: 'E' (pour la forme échelonnée standard)" f", 'ER' (pour la forme échelonnée réduite))") return np.asmatrix(Mat) def randomA(): """Method which generates a random matrix with rows and columns within 1 and 10 and integer entries between -100 and 100 :return: generated random matrix :rtype: numpy.ndarray """ n = random.randint(1, 10) m = random.randint(1, 10) A = [[random.randint(-100, 100) for i in range(n)] for j in range(m)] printA(A) return np.array(A) def dimensionA(A): """Method which allows the user to enter the matrix dimensions and verifies whether they are correct or not :param A: reference matrix :type A: numpy.ndarray """ m = widgets.IntText( value=1, step=1, description='m:', disabled=False ) n = widgets.IntText( value=1, step=1, description='n:', disabled=False ) display(m) display(n) def f(): if m.value == A.shape[0] and n.value == A.shape[1]: print('Correct!') else: print('Incorrect, entrez de nouvelles valeurs') interact_manual(f) return def manualEch(*args): """Method which allows the user to perform the Gauss elimination method on the given input matrix, eventually extended by the right-hand side vector. :param args: :type args: :return: :rtype: """ if len(args) == 2: # matrice augmentée A = np.array(args[0]).astype(float) m = A.shape[0] b = args[1] if type(b[0]) is list: b = np.array(b).astype(float) A = np.concatenate((A, b), axis=1) else: b = [b[i] for i in range(m)] A = [A[i] + [b[i]] for i in range(m)] else: A = np.array(args[0]).astype(float) m = A.shape[0] j = widgets.BoundedIntText( value=1, min=1, max=m, step=1, description='Ligne j:', disabled=False ) i = widgets.BoundedIntText( value=1, min=1, max=m, step=1, description='Ligne i:', disabled=False ) r = widgets.RadioButtons( options=['Eij', 'Ei(alpha)', 'Eij(alpha)', 'Revert'], description='Opération:', disabled=False ) alpha = widgets.Text( value='1', description='Coeff. alpha:', disabled=False ) print("Régler les paramètres et évaluer la cellule suivante") print("Répéter cela jusqu'à obtenir une forme échelonnée réduite") display(r) display(i) display(j) display(alpha) return i, j, r, alpha def echelonnage(i, j, r, alpha, A, m=None, *args): """Method which performs the Gauss elimination method step described by `r.value` with parameters `ì`, `j` and `alpha` on matrix `A` :param i: first reference line :type i: ipywidgets.Text :param j: second reference line :type j: ipywidgets.Text :param r: RadioButton describing the elementary matricial operation to be performed :type r: ipywidgets.radioButton :param alpha: scalar coefficient :type alpha: ipywidgets.Text :param A: starting matrix :type A: numpy.ndarray :param m: starting augmented matrix. If None, it equals A. Defaults to None. :type m: numpy.ndarray or NoneType :param args: either the list of matrices or both the list of matrices and rhs having bee built during the application of the methos :type args: list[numpy.ndarray] or tuple(list[numpy.ndarray], list[numpy.ndarray]) :return: processed matrix :rtype: numpy.ndarray """ if m is None: m = A.copy() m = np.array(m).astype(float) if alpha.value == 0 and r.value in {'Ei(alpha)', 'Eij(alpha)'}: print('Le coefficient alpha doit être non-nul!') if r.value == 'Eij': m = Eij(m, i.value-1, j.value-1) if r.value == 'Ei(alpha)': m = Ealpha(m, i.value-1, eval(alpha.value)) if r.value == 'Eij(alpha)': m = Eijalpha(m, i.value-1, j.value-1, eval(alpha.value)) if len(args) == 2: A = np.asmatrix(A) MatriceList = args[0] RhSList = args[1] if r.value != 'Revert': MatriceList.append(m[:, :A.shape[1]]) RhSList.append(m[:, A.shape[1]:]) else: if len(MatriceList) > 1 and len(RhSList) > 1: MatriceList.pop() RhSList.pop() mat = MatriceList[-1] rhs = RhSList[-1] m = np.concatenate((mat,rhs), axis=1) else: print("Impossible de revenir sur l'opération!") printEquMatrices(MatriceList, RhSList) elif len(args) == 1: MatriceList = args[0] if r.value != 'Revert': MatriceList.append(m) else: if len(MatriceList) > 1: MatriceList.pop() m = MatriceList[-1] else: print("Impossible de revenir sur l'opération!") printEquMatrices(MatriceList) else: print("La liste des matrices ou des matrices et des vecteurs connus doit être donnée en entrée de la fonction!") raise ValueError return m def LU_interactive(i, j, r, alpha, *args): """Method which performs the Gauss elimination method step described by `r.value` with parameters `ì`, `j` and `alpha` on matrix `A` :param i: first reference line :type i: ipywidgets.Text :param j: second reference line :type j: ipywidgets.Text :param r: RadioButton describing the elementary matricial operation to be performed :type r: ipywidgets.radioButton :param alpha: scalar coefficient :type alpha: ipywidgets.Text :param A: starting matrix :type A: numpy.ndarray :param m: starting augmented matrix. If None, it equals A. Defaults to None. :type m: numpy.ndarray or NoneType :param args: either the list of matrices or both the list of matrices and rhs having bee built during the application of the method :type args: list[numpy.ndarray] or tuple(list[numpy.ndarray], list[numpy.ndarray]) :return: processed matrix :rtype: numpy.ndarray """ if len(args) == 2: U = np.array(args[1][-1]).astype(float) else: print("La liste des matrices diagonales inférieures et supérieures déjà calculées doit être donnée en entrée de" " la fonction") raise ValueError if alpha.value == 0 and r.value in {'Ei(alpha)', 'Eij(alpha)'}: print('Le coefficient alpha doit être non-nul!') is_valid_operation = True if r.value == 'Eij': print("Exchanging two lines is not a valid operation, if LU decomposition WITHOUT pivoting has to be computed") is_valid_operation = False if r.value == 'Ei(alpha)': U, L = Ealpha(U, i.value-1, eval(alpha.value), get_E_inv=True) if r.value == 'Eij(alpha)': U, L = Eijalpha(U, i.value-1, j.value-1, eval(alpha.value), get_E_inv=True) if is_valid_operation: LList = args[0] UList = args[1] if r.value != 'Revert': UList.append(U) LList.append(np.dot(LList[-1], L)) else: if len(UList) > 1 and len(LList) > 1: UList.pop() U = UList[-1] LList.pop() L = LList[-1] else: print("Impossible de revenir sur l'opération!") printLUMatrices(LList, UList) else: L = args[0][-1] U = args[1][-1] return L, U def LU_no_pivoting(A, ptol=1e-5): """Method that computes the LU decomposition of a matrix, without using pivoting. If the matrix cannot be decomposed, the method raises a ValueError. :param A: matrix to be decomposed :type A: list[list] or numpy.ndarray :param ptol: tolerance on the pivot values; if a pivot with value smaller (in absolute value) than ptol is found, a ValueError is raised. Defaults to 1e-5 :type ptol: float :return: lower triangular matrix L and upper triangular matrix U such that A = LU, if they exist :rtype: tuple(numpy.ndarray, numpy.ndarray) or NoneType """ A = np.array(A).astype(float) m, n = A.shape n_op = 0 try: assert m <= n except AssertionError: raise ValueError("La décomposition LU n'est pas implémentée pour les matrices rectangulaires " "ayant plus de lignes que de colonnes") for i in range(m): if (A[i+1:, :] == 0).all(): break pivot = A[i, i] if abs(pivot) <= ptol: print("Pivot avec la valeur 0 rencontré. Cette matrice n'admet pas de décomposition LU (sans pivoting)") return None, None for k in range(i+1, m): lam = A[k, i] / pivot n_op += 1 A[k, i+1:n] = A[k, i+1:n] - lam * A[i, i+1:n] n_op += 2*(n-i-1) A[k, i] = lam L = np.eye(m) + np.tril(A, -1)[:m, :m] U = np.triu(A) n_op += m**2 print(f"Nombre d'opérations élémentaires: {n_op}") return L, U def manualOp(*args): """Method which allows the user to perform elementary operations on the given input matrix, eventually extended by the right-hand side vector. :param args: :type args: :return: :rtype: """ if len(args) == 2: # matrice augmentée A = np.array(args[0]).astype(float) M = A.shape[0] b = args[1] if type(b[0]) is list: b = np.array(b).astype(float) A = np.concatenate((A, b), axis=1) else: b = [b[i] for i in range(M)] A = [A[i] + [b[i]] for i in range(M)] else: A = np.array(args[0]).astype(float) M = A.shape[0] A = np.array(A) # just in case it's not i = widgets.BoundedIntText( value=1, min=1, max=M, step=1, description='Ligne i:', disabled=False ) j = widgets.BoundedIntText( value=1, min=1, max=M, step=1, description='Ligne j:', disabled=False ) r = widgets.RadioButtons( options=['Eij', 'Ei(alpha)', 'Eij(alpha)'], description='Opération:', disabled=False ) alpha = widgets.Text( value='1', description='Coeff. alpha:', disabled=False ) print("Régler les paramètres et cliquer sur RUN INTERACT pour effectuer votre opération") def f(r, i, j, alpha): m = A MatriceList = [A[:, :len(A[0])-1]] RhSList = [A[:, len(A[0])-1:]] if alpha == 0 and r != 'Eij': print('Le coefficient alpha doit être non-nul!') if r == 'Eij': m = Eij(m, i-1, j-1) if r == 'Ei(alpha)': m = Ealpha(m, i-1, eval(alpha)) if r == 'Eij(alpha)': m = Eijalpha(m, i-1, j-1, eval(alpha)) MatriceList.append(m[:, :len(A[0])-1]) RhSList.append(m[:, len(A[0])-1:]) printEquMatricesAug(MatriceList, RhSList) return interact_manual(f, r=r, i=i, j=j, alpha=alpha) return ######################################## OBSOLETE #################################################################### def printEquMatricesAug(listOfMatrices, listOfRhS): # list of matrices is M=[M1, M2, ..., Mn] where Mi=(Mi|b) texEqu = '$' + texMatrix(listOfMatrices[0], listOfRhS[0]) for i in range(1, len(listOfMatrices)): texEqu = texEqu + '\\quad \\sim \\quad' + texMatrix(listOfMatrices[i], listOfRhS[i]) texEqu = texEqu + '$' display(Latex(texEqu)) def echelonMatCoeff(A): # take echelonMAt but without b. b = [0 for _ in range(len(A))] Mat = [A[i] + [b[i]] for i in range(len(A))] Mat = np.array(Mat) Mat = Mat.astype(float) # in case the array in int instead of float. numPivot = 0 for i in range(len(Mat)): j = i while all(abs(Mat[j:, i]) < 1e-15) and j != len( Mat[0, :]) - 1: # if column (or rest of) is zero, take next column j += 1 if j == len(Mat[0, :]) - 1: # ADD ZERO LINES BELOW!!!!!! if len(Mat[0, :]) > j: Mat[i + 1:len(Mat), :] = 0 print("La matrice est sous la forme échelonnée") printEquMatrices(np.asmatrix(A), np.asmatrix(Mat[:, :len(A[0])])) break if abs(Mat[i, j]) < 1e-15: Mat[i, j] = 0 zero = abs(Mat[i:, j]) < 1e-15 M = echZero(zero, Mat[i:, :]) Mat[i:, :] = M Mat = Ealpha(Mat, i, 1 / Mat[i, j]) # normalement Mat[i,j]!=0 for k in range(i + 1, len(A)): Mat = Eijalpha(Mat, k, i, -Mat[k, j]) # Mat[k,:]=[0 if abs(Mat[k,l])<1e-15 else Mat[k,l] for l in range(len(MatCoeff[0,:]))] numPivot += 1 Mat[abs(Mat) < 1e-15] = 0 # printA(np.asmatrix(Mat[:, :len(A[0])])) return np.asmatrix(Mat) def echelonRedMat(A, b): Mat = echelonMat('ER', A, b) Mat = np.array(Mat) MatAugm = np.concatenate((A, b), axis=1) # MatAugm = [A[i]+[b[i]] for i in range(0,len(A))] i = (len(Mat) - 1) while i >= 1: while all(abs(Mat[i, :len(Mat[0]) - 1]) < 1e-15) and i != 0: # if ligne (or rest of) is zero, take next ligne i -= 1 # we have a lign with one non-nul element j = i # we can start at pos ij at least the pivot is there if abs(Mat[i, j]) < 1e-15: # if element Aij=0 take next one --> find pivot j += 1 # Aij!=0 and Aij==1 if echelonMat worked for k in range(i): # put zeros above pivot (which is 1 now) Mat = Eijalpha(Mat, k, i, -Mat[k, j]) i -= 1 printA(Mat) print("La matrice est sous la forme échelonnée réduite") printEquMatrices(MatAugm, Mat) return np.asmatrix(Mat) def printEquMatricesOLD(listOfMatrices): # list of matrices is M=[M1, M2, ..., Mn] texEqu = '$' + texMatrix(listOfMatrices[0]) for i in range(1, len(listOfMatrices)): texEqu = texEqu + '\\quad \\sim \\quad' + texMatrix(listOfMatrices[i]) texEqu = texEqu + '$' display(Latex(texEqu)) return def texMatrixAug(A, b): # return tex expression of one matrix (A|b) where b can also be a matrix m = len(A[0]) A = np.concatenate((A, b), axis=1) texApre = '\\left(\\begin{array}{' texA = '' for i in np.asarray(A): texALigne = '' texALigne = texALigne + str(round(i[0], 3) if i[0] % 1 else int(i[0])) if texA == '': texApre = texApre + 'c' for j in i[1:m]: if texA == '': texApre = texApre + 'c' texALigne = texALigne + ' & ' + str(round(j, 3) if j % 1 else int(j)) if texA == '': texApre = texApre + '| c' for j in i[m:]: if texA == '': texApre = texApre + 'c' texALigne = texALigne + ' & ' + str(round(j, 3) if j % 1 else int(j)) texALigne = texALigne + ' \\\\' texA = texA + texALigne texA = texApre + '} ' + texA[:-2] + ' \\end{array}\\right)' return texA def printAAug(A, b): # Print matrix (A|b) texA = '$' + texMatrixAug(A, b) + '$' display(Latex(texA)) return def printEquMatricesOLD(*args): # M=[M1, M2, ..., Mn] n>1 VERIFIED OK texEqu = '$' + texMatrix(args[0]) for i in range(1, len(args)): texEqu = texEqu + '\\quad \\sim \\quad' + texMatrix(args[i]) texEqu = texEqu + '$' display(Latex(texEqu)) return def Ex1Chapitre1_5_6(): style = {'description_width': 'initial'} e=widgets.Textarea( value='', placeholder='Utilisez des lettres majuscules', description='Matrices échelonnées:', layout=Layout(width='60%', height='50px'), style=style, disabled=False ) er=widgets.Textarea( value='', placeholder='Utilisez des lettres majuscules', description='Matrices échelonnées-réduites:', layout=Layout(width='60%', height='50px'), style=style, disabled=False ) r=widgets.Textarea( value='', placeholder='Utilisez des lettres majuscules', description='Aucun des deux:', layout=Layout(width='60%', height='50px'), style=style, disabled=False ) display(e) display(er) display(r) return e,er,r \ No newline at end of file diff --git a/ToDo.md b/ToDo.md index 41a1e8b..bc656e5 100644 --- a/ToDo.md +++ b/ToDo.md @@ -1,8 +1,11 @@ ## Known problems to be fixed - [ ] *Plot3DSys* function has issues when the matrix has a rows made of all zeros - [x] Exercise 4 in Notebook 1.2 displays a *RuntimeWarningError* due to a division by 0, if the "sliding" parameter *h* is set to 0 - [x] *printA* library method fails if it is given a row vector (i.e. a list of int/float) as input -- [ ] *ipywidgets* have troubles being displayed on **Noto** +- [x] *ipywidgets* have troubles being displayed on **Noto** +- [x] *echelonMat* function does not work on matrices having a column + made of all zeros +