{ "nbformat_minor": 0, "nbformat": 4, "cells": [ { "source": [ "$$\n", "\\def\\CC{\\bf C}\n", "\\def\\QQ{\\bf Q}\n", "\\def\\RR{\\bf R}\n", "\\def\\ZZ{\\bf Z}\n", "\\def\\NN{\\bf N}\n", "$$\n", "# Alg\u00e8bre lin\u00e9aire" ], "cell_type": "markdown", "metadata": {} }, { "execution_count": null, "cell_type": "code", "source": [ "from __future__ import division, print_function # Python 3\n", "from sympy import init_printing\n", "init_printing(use_latex='mathjax',use_unicode=False) # Affichage des r\u00e9sultats" ], "outputs": [], "metadata": {} }, { "source": [ "Cette section concerne l'alg\u00e8bre lin\u00e9aire et les matrices. On trouvera d'autres exemples dans le tutoriel de Sympy sur le m\u00eame sujet: \n", "\n", "## D\u00e9finir une matrice\n", "\n", "En SymPy, on peut cr\u00e9er une matrice avec la fonction `Matrix` :" ], "cell_type": "markdown", "metadata": {} }, { "execution_count": null, "cell_type": "code", "source": [ "from sympy import Matrix" ], "outputs": [], "metadata": {} }, { "source": [ "Il suffit d'\u00e9crire les entr\u00e9es lignes par lignes avec la syntaxe suivante:" ], "cell_type": "markdown", "metadata": {} }, { "execution_count": null, "cell_type": "code", "source": [ "Matrix([[2, 5, 6], [4, 7, 10], [1, 0, 3]])" ], "outputs": [ { "execution_count": 1, "output_type": "execute_result", "data": { "text/plain": [ "[2 5 6 ]\n", "[ ]\n", "[4 7 10]\n", "[ ]\n", "[1 0 3 ]" ] }, "metadata": {} } ], "metadata": {} }, { "source": [ "Une autre fa\u00e7on \u00e9quivalente est de sp\u00e9cifier le nombre de lignes, le nombre de colonnes et puis la liste des entr\u00e9es:" ], "cell_type": "markdown", "metadata": {} }, { "execution_count": null, "cell_type": "code", "source": [ "Matrix(2, 3, [1, 2, 3, 4, 5, 6])" ], "outputs": [ { "execution_count": 1, "output_type": "execute_result", "data": { "text/plain": [ "[1 2 3]\n", "[ ]\n", "[4 5 6]" ] }, "metadata": {} } ], "metadata": {} }, { "source": [ "Par d\u00e9faut, si on ne sp\u00e9cifie pas les dimensions de la matrice, un vecteur colonne est retourn\u00e9:" ], "cell_type": "markdown", "metadata": {} }, { "execution_count": null, "cell_type": "code", "source": [ "Matrix([1,2,3,4])" ], "outputs": [ { "execution_count": 1, "output_type": "execute_result", "data": { "text/plain": [ "[1]\n", "[ ]\n", "[2]\n", "[ ]\n", "[3]\n", "[ ]\n", "[4]" ] }, "metadata": {} } ], "metadata": {} }, { "source": [ "## Op\u00e9rations de base\n", "\n", "Les op\u00e9rations de l'alg\u00e8bre des matrices (addition, multiplication, multiplication par un scalaire) sont d\u00e9finies naturellement:" ], "cell_type": "markdown", "metadata": {} }, { "execution_count": null, "cell_type": "code", "source": [ "M = Matrix([[5, 2], [-1, 7]])\n", "N = Matrix([[0, 4], [0, 5]])\n", "M + N" ], "outputs": [ { "execution_count": 1, "output_type": "execute_result", "data": { "text/plain": [ "[5 6 ]\n", "[ ]\n", "[-1 12]" ] }, "metadata": {} } ], "metadata": {} }, { "execution_count": null, "cell_type": "code", "source": [ "M * N" ], "outputs": [ { "execution_count": 1, "output_type": "execute_result", "data": { "text/plain": [ "[0 30]\n", "[ ]\n", "[0 31]" ] }, "metadata": {} } ], "metadata": {} }, { "execution_count": null, "cell_type": "code", "source": [ "4 * M" ], "outputs": [ { "execution_count": 1, "output_type": "execute_result", "data": { "text/plain": [ "[20 8 ]\n", "[ ]\n", "[-4 28]" ] }, "metadata": {} } ], "metadata": {} }, { "execution_count": null, "cell_type": "code", "source": [ "M ** 5" ], "outputs": [ { "execution_count": 1, "output_type": "execute_result", "data": { "text/plain": [ "[-475 12242]\n", "[ ]\n", "[-6121 11767]" ] }, "metadata": {} } ], "metadata": {} }, { "source": [ "De m\u00eame, on peut calculer l'inverse d'une matrice si elle est inversible:" ], "cell_type": "markdown", "metadata": {} }, { "execution_count": null, "cell_type": "code", "source": [ "M**-1" ], "outputs": [ { "execution_count": 1, "output_type": "execute_result", "data": { "text/plain": [ "[7/37 -2/37]\n", "[ ]\n", "[1/37 5/37 ]" ] }, "metadata": {} } ], "metadata": {} }, { "execution_count": null, "cell_type": "code", "source": [ "N**-1" ], "outputs": [ { "execution_count": 1, "output_type": "execute_result", "data": { "text/plain": [ "Traceback (most recent call last):\n", "...\n", "ValueError: Matrix det == 0; not invertible." ] }, "metadata": {} } ], "metadata": {} }, { "source": [ "La transposition d'une matrice se fait avec `.transpose()` :" ], "cell_type": "markdown", "metadata": {} }, { "execution_count": null, "cell_type": "code", "source": [ "from sympy import I\n", "M = Matrix(( (1,2+I,5), (3,4,0) ))\n", "M" ], "outputs": [ { "execution_count": 1, "output_type": "execute_result", "data": { "text/plain": [ "[1 2 + I 5]\n", "[ ]\n", "[3 4 0]" ] }, "metadata": {} } ], "metadata": {} }, { "execution_count": null, "cell_type": "code", "source": [ "M.transpose()" ], "outputs": [ { "execution_count": 1, "output_type": "execute_result", "data": { "text/plain": [ "[ 1 3]\n", "[ ]\n", "[2 + I 4]\n", "[ ]\n", "[ 5 0]" ] }, "metadata": {} } ], "metadata": {} }, { "source": [ "## Acc\u00e9der aux coefficients" ], "cell_type": "markdown", "metadata": {} }, { "execution_count": null, "cell_type": "code", "source": [ "from sympy import I\n", "M = Matrix(( (1,2+I,5), (3,4,0) ))\n", "M" ], "outputs": [ { "execution_count": 1, "output_type": "execute_result", "data": { "text/plain": [ "[1 2 + I 5]\n", "[ ]\n", "[3 4 0]" ] }, "metadata": {} } ], "metadata": {} }, { "source": [ "On acc\u00e8de \u00e0 l'\u00e9l\u00e9ment en position `(i,j)` en \u00e9crivant `M[i,j]` :" ], "cell_type": "markdown", "metadata": {} }, { "execution_count": null, "cell_type": "code", "source": [ "M[0,1]" ], "outputs": [ { "execution_count": 1, "output_type": "execute_result", "data": { "text/plain": [ "2 + I" ] }, "metadata": {} } ], "metadata": {} }, { "execution_count": null, "cell_type": "code", "source": [ "M[1,1]" ], "outputs": [ { "execution_count": 1, "output_type": "execute_result", "data": { "text/plain": [ "4" ] }, "metadata": {} } ], "metadata": {} }, { "source": [ "**Attention**: Les indices des positions commencent \u00e0 z\u00e9ro!!\n", "\n", "On acc\u00e8de aux lignes et au colonnes d'une matrices avec les m\u00e9thodes `row` et `col` :" ], "cell_type": "markdown", "metadata": {} }, { "execution_count": null, "cell_type": "code", "source": [ "M.row(1)" ], "outputs": [ { "execution_count": 1, "output_type": "execute_result", "data": { "text/plain": [ "[3 4 0]" ] }, "metadata": {} } ], "metadata": {} }, { "execution_count": null, "cell_type": "code", "source": [ "M.col(0)" ], "outputs": [ { "execution_count": 1, "output_type": "execute_result", "data": { "text/plain": [ "[1]\n", "[ ]\n", "[3]" ] }, "metadata": {} } ], "metadata": {} }, { "source": [ "## Construction de matrices particuli\u00e8res\n", "\n", "Les fonctions `zeros` et `ones` permettent de cr\u00e9er des matrices de z\u00e9ros et de uns:" ], "cell_type": "markdown", "metadata": {} }, { "execution_count": null, "cell_type": "code", "source": [ "from sympy import ones,zeros\n", "ones(2)" ], "outputs": [ { "execution_count": 1, "output_type": "execute_result", "data": { "text/plain": [ "[1, 1]\n", "[1, 1]" ] }, "metadata": {} } ], "metadata": {} }, { "execution_count": null, "cell_type": "code", "source": [ "zeros((2, 4))" ], "outputs": [ { "execution_count": 1, "output_type": "execute_result", "data": { "text/plain": [ "[0, 0, 0, 0]\n", "[0, 0, 0, 0]" ] }, "metadata": {} } ], "metadata": {} }, { "source": [ "La fonction `eye` de sympy permet de cr\u00e9er une matrice identit\u00e9:" ], "cell_type": "markdown", "metadata": {} }, { "execution_count": null, "cell_type": "code", "source": [ "from sympy import eye\n", "eye(3)" ], "outputs": [ { "execution_count": 1, "output_type": "execute_result", "data": { "text/plain": [ "[1, 0, 0]\n", "[0, 1, 0]\n", "[0, 0, 1]" ] }, "metadata": {} } ], "metadata": {} }, { "source": [ "La fonction `diag` permet de cr\u00e9er une matrice diagonale:" ], "cell_type": "markdown", "metadata": {} }, { "execution_count": null, "cell_type": "code", "source": [ "from sympy import diag\n", "diag(1,2,3)" ], "outputs": [ { "execution_count": 1, "output_type": "execute_result", "data": { "text/plain": [ "[1 0 0]\n", "[ ]\n", "[0 2 0]\n", "[ ]\n", "[0 0 3]" ] }, "metadata": {} } ], "metadata": {} }, { "source": [ "Les \u00e9l\u00e9ments de la diagonales peuvent \u00eatre eux-m\u00eames des matrices:" ], "cell_type": "markdown", "metadata": {} }, { "execution_count": null, "cell_type": "code", "source": [ "diag(1, 2, Matrix([[7,8],[2,3]]))" ], "outputs": [ { "execution_count": 1, "output_type": "execute_result", "data": { "text/plain": [ "[1 0 0 0]\n", "[ ]\n", "[0 2 0 0]\n", "[ ]\n", "[0 0 7 8]\n", "[ ]\n", "[0 0 2 3]" ] }, "metadata": {} } ], "metadata": {} }, { "source": [ "## Matrice \u00e9chelonn\u00e9e r\u00e9duite\n", "\n", "On calcule la forme \u00e9chelonn\u00e9e r\u00e9duite d'une matrice avec la m\u00e9thode `rref` (abbr\u00e9viation de *reduced row echelon form* en anglais):" ], "cell_type": "markdown", "metadata": {} }, { "execution_count": null, "cell_type": "code", "source": [ "M = Matrix([[1, 2, 0, 3], [2, 6, 5, 1], [-1, -4, -5, 2]])\n", "M.rref()" ], "outputs": [ { "execution_count": 1, "output_type": "execute_result", "data": { "text/plain": [ "([1 0 -5 8 ], [0, 1])\n", " [ ]\n", " [0 1 5/2 -5/2]\n", " [ ]\n", " [0 0 0 0 ]" ] }, "metadata": {} } ], "metadata": {} }, { "source": [ "## Noyau\n", "\n", "On calcule le noyau d'une matrice avec `nullspace` :" ], "cell_type": "markdown", "metadata": {} }, { "execution_count": null, "cell_type": "code", "source": [ "M = Matrix([[1, 2, 0, 3], [2, 6, 5, 1], [-1, -4, -5, 2]])\n", "M.nullspace()" ], "outputs": [ { "execution_count": 1, "output_type": "execute_result", "data": { "text/plain": [ "[[ 5 ], [-8 ]]\n", " [ ] [ ]\n", " [-5/2] [5/2]\n", " [ ] [ ]\n", " [ 1 ] [ 0 ]\n", " [ ] [ ]\n", " [ 0 ] [ 1 ]" ] }, "metadata": {} } ], "metadata": {} }, { "source": [ "## D\u00e9terminant\n", "\n", "On calcule le d\u00e9terminant avec la m\u00e9thode `det` :" ], "cell_type": "markdown", "metadata": {} }, { "execution_count": null, "cell_type": "code", "source": [ "M = Matrix([[2, 5, 6], [4, 7, 10], [1, 0, 3]])\n", "M.det()" ], "outputs": [ { "execution_count": 1, "output_type": "execute_result", "data": { "text/plain": [ "-10" ] }, "metadata": {} } ], "metadata": {} }, { "source": [ "## Polyn\u00f4me caract\u00e9ristique\n", "\n", "La m\u00e9thode `charpoly` permet de calculer le polyn\u00f4me caract\u00e9ristique d'une matrice carr\u00e9e:" ], "cell_type": "markdown", "metadata": {} }, { "execution_count": null, "cell_type": "code", "source": [ "M = Matrix([[3, -2, 4, -2], [5, 3, -3, -2], [5, -2, 2, -2], [5, -2, -3, 3]])\n", "from sympy.abc import x\n", "M.charpoly(x)" ], "outputs": [ { "execution_count": 1, "output_type": "execute_result", "data": { "text/plain": [ "PurePoly(x**4 - 11*x**3 + 29*x**2 + 35*x - 150, x, domain='ZZ')" ] }, "metadata": {} } ], "metadata": {} }, { "source": [ "On ajoute `.as_expr()` pour obtenir l'expression symbolique du polyn\u00f4me caract\u00e9ristique:" ], "cell_type": "markdown", "metadata": {} }, { "execution_count": null, "cell_type": "code", "source": [ "M.charpoly(x).as_expr()" ], "outputs": [ { "execution_count": 1, "output_type": "execute_result", "data": { "text/plain": [ " 4 3 2\n", "x - 11*x + 29*x + 35*x - 150" ] }, "metadata": {} } ], "metadata": {} }, { "execution_count": null, "cell_type": "code", "source": [ "from sympy import factor\n", "factor(_)" ], "outputs": [ { "execution_count": 1, "output_type": "execute_result", "data": { "text/plain": [ " 2\n", "(x - 5) *(x - 3)*(x + 2)" ] }, "metadata": {} } ], "metadata": {} }, { "source": [ "## Valeurs propres et vecteurs propres\n", "\n", "Continuons avec la m\u00eame matrice `M` d\u00e9finie pr\u00e9c\u00e9demment:" ], "cell_type": "markdown", "metadata": {} }, { "execution_count": null, "cell_type": "code", "source": [ " M" ], "outputs": [ { "execution_count": 1, "output_type": "execute_result", "data": { "text/plain": [ "[3 -2 4 -2]\n", "[ ]\n", "[5 3 -3 -2]\n", "[ ]\n", "[5 -2 2 -2]\n", "[ ]\n", "[5 -2 -3 3 ]" ] }, "metadata": {} } ], "metadata": {} }, { "source": [ "Soient les vecteurs colonnes `w` et `v` suivants:" ], "cell_type": "markdown", "metadata": {} }, { "execution_count": null, "cell_type": "code", "source": [ "w = Matrix((1,2,3,4))\n", "v = Matrix((1,1,1,0))\n", "w" ], "outputs": [ { "execution_count": 1, "output_type": "execute_result", "data": { "text/plain": [ "[1]\n", "[ ]\n", "[2]\n", "[ ]\n", "[3]\n", "[ ]\n", "[4]" ] }, "metadata": {} } ], "metadata": {} }, { "execution_count": null, "cell_type": "code", "source": [ "v" ], "outputs": [ { "execution_count": 1, "output_type": "execute_result", "data": { "text/plain": [ "[1]\n", "[ ]\n", "[1]\n", "[ ]\n", "[1]\n", "[ ]\n", "[0]" ] }, "metadata": {} } ], "metadata": {} }, { "source": [ "En g\u00e9n\u00e9ral, l'image par `M` d'un vecteur n'a rien \u00e0 voir avec ce vecteur. Par exemple, l'image par `M` de `w` n'a rien \u00e0 voir avec `w` :" ], "cell_type": "markdown", "metadata": {} }, { "execution_count": null, "cell_type": "code", "source": [ "M * w" ], "outputs": [ { "execution_count": 1, "output_type": "execute_result", "data": { "text/plain": [ "[3 ]\n", "[ ]\n", "[-6]\n", "[ ]\n", "[-1]\n", "[ ]\n", "[4 ]" ] }, "metadata": {} } ], "metadata": {} }, { "source": [ "Dans certains cas particuliers, l'image par `M` d'un vecteur retourne un multiple scalaire de ce vecteur. C'est ce qui se produit pour le vecteur `v` :" ], "cell_type": "markdown", "metadata": {} }, { "execution_count": null, "cell_type": "code", "source": [ "M * v" ], "outputs": [ { "execution_count": 1, "output_type": "execute_result", "data": { "text/plain": [ "[5]\n", "[ ]\n", "[5]\n", "[ ]\n", "[5]\n", "[ ]\n", "[0]" ] }, "metadata": {} } ], "metadata": {} }, { "source": [ "Le r\u00e9sultat pr\u00e9c\u00e9dent est \u00e9gal \u00e0 5 fois le vecteur `v` :" ], "cell_type": "markdown", "metadata": {} }, { "execution_count": null, "cell_type": "code", "source": [ "5 * v" ], "outputs": [ { "execution_count": 1, "output_type": "execute_result", "data": { "text/plain": [ "[5]\n", "[ ]\n", "[5]\n", "[ ]\n", "[5]\n", "[ ]\n", "[0]" ] }, "metadata": {} } ], "metadata": {} }, { "source": [ "Un vecteur $v$ qui satisfait l'\u00e9quation $Mv = \\lambda v$ pour un certain nombre r\u00e9el (ou complexe) $\\lambda$ est appel\u00e9 *vecteur propre*. Le nombre $\\lambda$ qui satisfait l'\u00e9quation est appel\u00e9 *valeur propre*. Il se trouve que les valeurs propres d'une matrice sont les racines de son polyn\u00f4me caract\u00e9ristique. Le calcul des valeurs et vecteurs propres d'une matrice est utile dans presque tous les domaines des math\u00e9matiques.\n", "\n", "En sympy, on calcule les valeurs propres d'une matrice avec la m\u00e9thode `eigenvals`. Le r\u00e9sultat est un dictionnaire qui associe \u00e0 chaque valeur propre sa multiplicit\u00e9 alg\u00e9brique (comme pour le calcul des racines):" ], "cell_type": "markdown", "metadata": {} }, { "execution_count": null, "cell_type": "code", "source": [ "M.eigenvals()" ], "outputs": [ { "execution_count": 1, "output_type": "execute_result", "data": { "text/plain": [ "{-2: 1, 3: 1, 5: 2}" ] }, "metadata": {} } ], "metadata": {} }, { "source": [ "Et on calcule les vecteurs propres d'une matrice avec la m\u00e9thode `eigenvects` :" ], "cell_type": "markdown", "metadata": {} }, { "execution_count": null, "cell_type": "code", "source": [ "M.eigenvects()" ], "outputs": [ { "execution_count": 1, "output_type": "execute_result", "data": { "text/plain": [ "[(-2, 1, [[0]]), (3, 1, [[1]]), (5, 2, [[1], [0 ]])]\n", " [ ] [ ] [ ] [ ]\n", " [1] [1] [1] [-1]\n", " [ ] [ ] [ ] [ ]\n", " [1] [1] [1] [0 ]\n", " [ ] [ ] [ ] [ ]\n", " [1] [1] [0] [1 ]" ] }, "metadata": {} } ], "metadata": {} }, { "source": [ "Le calcul pr\u00e9c\u00e9dent montre bien que le vecteur colonne `v = [1, 1, 1, 0]^T` est bien un vecteur propre de la matrice `M` associ\u00e9 \u00e0 la valeur propre `5` comme on l'avait vu plus t\u00f4t. Il permet aussi de r\u00e9aliser qu'un autre vecteur colonne lin\u00e9airement ind\u00e9pendant de `v` est aussi un vecteur propre associ\u00e9 \u00e0 la valeur propre `5`. Finalement, il y a deux autres vecteurs propres associ\u00e9s aux valeurs propres `-2` et `3`." ], "cell_type": "markdown", "metadata": {} } ], "metadata": { "kernelspec": { "display_name": "python2", "name": "python2" } } }