Created
June 11, 2013 16:06
-
-
Save olberger/5758183 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"metadata": { | |
"name": "NumPy - Alg\u00e8bre lin\u00e9aire" | |
}, | |
"nbformat": 3, | |
"nbformat_minor": 0, | |
"worksheets": [ | |
{ | |
"cells": [ | |
{ | |
"cell_type": "heading", | |
"level": 1, | |
"metadata": {}, | |
"source": [ | |
"Alg\u00e8bre lin\u00e9aire avec NumPy." | |
] | |
}, | |
{ | |
"cell_type": "heading", | |
"level": 4, | |
"metadata": {}, | |
"source": [ | |
"On commence par importer tout ce qui est contenu dans le NumPy, et par d\u00e9finir une matrice m inversible." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"from numpy import *" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 1 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"m = array( [[1, 2, 3],\n", | |
" [2, 3, 4],\n", | |
" [3, 4, 6]] )" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 2 | |
}, | |
{ | |
"cell_type": "heading", | |
"level": 4, | |
"metadata": {}, | |
"source": [ | |
"Les op\u00e9rations classiques li\u00e9es \u00e0 la r\u00e9solution de syst\u00e8mes lin\u00e9aires et \u00e0 la r\u00e9duction d'endomorphimes sont quant \u00e0 elles disponibles dans la biblioth\u00e8qe linalg." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"linalg.det(m) # d\u00e9terminant" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 3, | |
"text": [ | |
"-1.0000000000000004" | |
] | |
} | |
], | |
"prompt_number": 3 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"minv = linalg.inv(m) # inverse\n", | |
"print minv" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"[[-2. 0. 1.]\n", | |
" [ 0. 3. -2.]\n", | |
" [ 1. -2. 1.]]\n" | |
] | |
} | |
], | |
"prompt_number": 4 | |
}, | |
{ | |
"cell_type": "heading", | |
"level": 4, | |
"metadata": {}, | |
"source": [ | |
"On peut v\u00e9rifier que minv est bien l'inverse (num\u00e9rique) de m." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"print dot(minv, m) # M^{-1} . M = I" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"[[ 1.00000000e+00 -1.33226763e-15 -1.77635684e-15]\n", | |
" [ 0.00000000e+00 1.00000000e+00 0.00000000e+00]\n", | |
" [ 0.00000000e+00 4.44089210e-16 1.00000000e+00]]\n" | |
] | |
} | |
], | |
"prompt_number": 5 | |
}, | |
{ | |
"cell_type": "heading", | |
"level": 4, | |
"metadata": {}, | |
"source": [ | |
"Pour r\u00e9soudre une syst\u00e8me lin\u00e9aire, on utilise la fonction linalg.solve(). Notez que la matrice doit \u00eatre carr\u00e9e et inversible." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"b = array([2, 2, 3])\n", | |
"x = linalg.solve(m, b) # r\u00e9solution de syst\u00e8me\n", | |
"print x" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"[-1. 0. 1.]\n" | |
] | |
} | |
], | |
"prompt_number": 6 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"print dot(m, x) # on v\u00e9rifie que la solution est correcte" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"[ 2. 2. 3.]\n" | |
] | |
} | |
], | |
"prompt_number": 7 | |
}, | |
{ | |
"cell_type": "heading", | |
"level": 4, | |
"metadata": {}, | |
"source": [ | |
"On peut aussi calculer les valeurs propres d'une matrice, et les vecteurs propres associ\u00e9s." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"valp, vecp = linalg.eig(m) # valeurs et vecteurs propres\n", | |
"print \"Valeurs propres de m :\", valp\n", | |
"print \"Vecteurs propres associ\u00e9s :\"\n", | |
"print vecp" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"Valeurs propres de m : [ 10.18669767 -0.42027581 0.23357814]\n", | |
"Vecteurs propres associ\u00e9s :\n", | |
"[[ 0.36530658 0.92694664 0.08556306]\n", | |
" [ 0.52826911 -0.13074871 -0.83894966]\n", | |
" [ 0.7664743 -0.35167415 0.53744064]]\n" | |
] | |
} | |
], | |
"prompt_number": 8 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"print dot(m, vecp[:,0]) # m * 1er vecteur propre\n", | |
"print valp[0] * vecp[:,0] # 1ere valeur propre * 1er vecteur propre" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"[ 3.72126769 5.38131768 7.80784197]\n", | |
"[ 3.72126769 5.38131768 7.80784197]\n" | |
] | |
} | |
], | |
"prompt_number": 9 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"P = vecp\n", | |
"D = diag(valp)\n", | |
"Pinv = linalg.inv(P)\n", | |
"print dot(P, dot(D, Pinv)) # principe de diagonalisation : m = P . D . Pinv" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"[[ 1. 2. 3.]\n", | |
" [ 2. 3. 4.]\n", | |
" [ 3. 4. 6.]]\n" | |
] | |
} | |
], | |
"prompt_number": 10 | |
}, | |
{ | |
"cell_type": "heading", | |
"level": 1, | |
"metadata": {}, | |
"source": [ | |
"Illustration d'un probl\u00e8me d'instabilit\u00e9 num\u00e9rique." | |
] | |
}, | |
{ | |
"cell_type": "heading", | |
"level": 4, | |
"metadata": {}, | |
"source": [ | |
"On consid\u00e8re le syst\u00e8me lin\u00e9aire A.x = b d\u00e9fini comme suit." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"A = array( [[10., 7., 8., 7.],\n", | |
" [7., 5., 6., 5.],\n", | |
" [8., 6., 10., 9.],\n", | |
" [7., 5., 9., 10.]] )\n", | |
"b = array( [32, 23, 33, 31 ] )\n", | |
"print \"A = \", A\n", | |
"print \"b = \", b.T" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"A = [[ 10. 7. 8. 7.]\n", | |
" [ 7. 5. 6. 5.]\n", | |
" [ 8. 6. 10. 9.]\n", | |
" [ 7. 5. 9. 10.]]\n", | |
"b = [32 23 33 31]\n" | |
] | |
} | |
], | |
"prompt_number": 11 | |
}, | |
{ | |
"cell_type": "heading", | |
"level": 4, | |
"metadata": {}, | |
"source": [ | |
"Cherchons une solution x \u00e0 ce probl\u00e8me." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"x = linalg.solve(A, b)\n", | |
"print x" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"[ 1. 1. 1. 1.]\n" | |
] | |
} | |
], | |
"prompt_number": 12 | |
}, | |
{ | |
"cell_type": "heading", | |
"level": 4, | |
"metadata": {}, | |
"source": [ | |
"Nous trouvons bien la solution attendue." | |
] | |
}, | |
{ | |
"cell_type": "heading", | |
"level": 4, | |
"metadata": {}, | |
"source": [ | |
"Appliquons maintenant une l\u00e9g\u00e8re pertubation aux coefficients de A, puis essayons de r\u00e9soudre le nouveau syst\u00e8me lin\u00e9aire ainsi obtenu." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"E = array( [[0., 0., 0.1, 0.2],\n", | |
" [0.08, 0.04, 0., 0.],\n", | |
" [0., -0.02, -0.02, 0.],\n", | |
" [-0.01, -0.01, 0., -0.02]] )\n", | |
"A2 = A + E\n", | |
"x2 = linalg.solve(A2, b)\n", | |
"print x2" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"[ -5.79224365 12.01880932 -1.56555429 2.56552237]\n" | |
] | |
} | |
], | |
"prompt_number": 13 | |
}, | |
{ | |
"cell_type": "heading", | |
"level": 4, | |
"metadata": {}, | |
"source": [ | |
"On constate qu'une petite pertubation sur les coefficients de A provoque un changement assez important sur le r\u00e9sultat du syst\u00e8me lin\u00e9aire." | |
] | |
}, | |
{ | |
"cell_type": "heading", | |
"level": 4, | |
"metadata": {}, | |
"source": [ | |
"On peut quantifier le changement sur la matrice en calculant la norme 2 de E = A - A2." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"def matrix_norm2(M): # calcule la norme 2 de la matrice M\n", | |
" valp, _ = linalg.eig( dot(M.conj(), M) )\n", | |
" return sqrt( max(valp) )\n", | |
"\n", | |
"matrix_norm2(E)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 14, | |
"text": [ | |
"(0.050463861837858059+0j)" | |
] | |
} | |
], | |
"prompt_number": 14 | |
}, | |
{ | |
"cell_type": "heading", | |
"level": 4, | |
"metadata": {}, | |
"source": [ | |
"De m\u00eame, on peut quantifier le changement au niveau de la solution du syst\u00e8me, en calculant la norme 2 de x-x2." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"def vect_norm2(v): # calcule la norme 2 du vecteur v\n", | |
" return sqrt( sum(v**2) )\n", | |
"\n", | |
"vect_norm2( x-x2 )" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 15, | |
"text": [ | |
"13.288403278162946" | |
] | |
} | |
], | |
"prompt_number": 15 | |
}, | |
{ | |
"cell_type": "heading", | |
"level": 4, | |
"metadata": {}, | |
"source": [ | |
"Pour justifier l'\u00e9cart important entre les vecteurs x et x2, il faut regarder le conditionnement de la matrice A. En effet, en d\u00e9finissant cond_2(A) = |||A|||_2 . |||A^{-1}|||_2, on peut montrer que :\n", | |
" || x - x2 ||_2 <= cond_2(A) . ||| A - A2 |||_2.\n", | |
"Ainsi, plus le conditionnement de A est \u00e9lev\u00e9, et plus on a un risque d'instabilit\u00e9 num\u00e9rique." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"cond = matrix_norm2(A) * matrix_norm2( linalg.inv(A) )\n", | |
"cond" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 16, | |
"text": [ | |
"2984.0927016755245" | |
] | |
} | |
], | |
"prompt_number": 16 | |
}, | |
{ | |
"cell_type": "heading", | |
"level": 4, | |
"metadata": {}, | |
"source": [ | |
"On constate que le condition de A est tr\u00e8s \u00e9lev\u00e9. On en d\u00e9duit une borne sur || x - x2 ||_2 qui est tr\u00e8s \u00e9lev\u00e9e, qui laisse largement place \u00e0 une instabilit\u00e9 num\u00e9rique." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"cond * matrix_norm2(E)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 17, | |
"text": [ | |
"(150.58884180871425+0j)" | |
] | |
} | |
], | |
"prompt_number": 17 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [] | |
} | |
], | |
"metadata": {} | |
} | |
] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment