Université de Rouen L2 IBIOM Année 2009-2010 Mathématiques I, Python pour tous! TP Noté . Durée 1h30 Les documents Python, fiches de TD, fiches de TP sont autorisés. Il est interdit d’utiliser tout logiciel de communication (navigateur, irc, mail, etc) pendant l’épreuve. Les programmes/manipulations sont à inclure dans un fichier texte ou Python, les commentaires peuvent y être inclus ou rendus sur feuille. Le nom du fichier sera nom_tpnote.{txt,py} où nom est votre nom. À la fin de l’épreuve, envoyez le par courrier électronique à [email protected]. Avant de partir assurez-vous que le fichier a bien été reçu ! Exercice 1. Soit la matrice de taille 8 1 1 1 1 B = 1 1 1 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 1 1 1 1 . 1 1 1 1 Faire trois constructions différentes de cette matrice, dont une avec boucle(s) et une autre sans boucle et sans entrer tous les coefficients un à un. >>> >>> >>> >>> >>> >>> >>> ... ... ... ... >>> >>> >>> >>> >>> >>> import numpy as np b=np . ones ( ( 7 , 1 ) ) a=np . concatenate ( ( b , np . zeros ( ( 7 , 6 ) ) , b ) , a x i s =1) b=np . concatenate ( ( a , np . ones ( ( 1 , 8 ) ) ) ) b # Ok ! b=np . zeros ( ( 8 , 8 ) ) for i in range ( 7 ) : b[ i ,0]=1 b[ i ,7]=1 b [ 7 , i ]=1 b # Ok ! b=np . zeros ( ( 8 , 8 ) ) b[: ,0]=1 b[: ,7]=1 b[7 ,:]=1 b # Ok e t de t r o i s ! Exercice 2. Nous allons étudier expérimentalement l’effet d’une petite variation sur les coefficients du second membre sur la solution du système linéaire. Le but est qu’il faut toujours garder un œil critique sur les calculs numériques. Pour cela nous aurons besoin du calcul des normes 2 (voir documentation). Si b est un vecteur de Rn , ∥b∥2 ou la norme euclidienne de b est la généralisation au cas de la dimension n de la distance euclidienne (plan ou espace) √ ∥b∥2 = b 12 + b 22 + · · · + b n2 , où b 1 , . . . , b n sont les composantes du vecteur b dans la base canonique. Pour les curieux la norme 2 d’une matrice A carrée de taille n, notée ∥A∥2 , est le plus petit réel vérifiant pour tout x dans Rn ∥Ax∥2 ≤ ∥A∥2 ∥x∥2 . Dans les deux cas, Numpy calcule cette quantité via les commandes np.linalg.norm(b,2) et np.linalg.norm(A,2). Soient A (différente du TP réel) et b définis par 8 6 4 1 4 5 A= 8 4 1 1 4 3 1 1 1 6 19 11 b= 14 . 14 (a) Calculer la solution de ce système linéaire (à l’aide de Python bien sûr). (b) On perturbe ! Calculer la solution y du système perturbé Ay = b + ∆b où 0.01 0.05 ∆b = 0.07 0.05 On pose ∆x = y −x. Calculer le coefficient d’amplification d’erreur ∥∆x∥2 ∥b∥2 . Qu’observez-vous ? ∥x∥2 ∥∆b∥2 >>> a=np . array ( [ [ 8 . , 6 . , 4 , 1 ] , [ 1 , 4 , 5 , 1 ] , [ 8 , 4 ,1 , 1 ] , [ 1 , 4 , 3 , 6 ] ] ) >>> b=np . array ( [ 1 9 . , 11 , 14 , 1 4 ] ) >>> x=np . l i n a l g . solve ( a , b) >>> x array ( [ 1 . , 1 . , 1 . , 1 . ] ) >>> db=np . array ( [ 0 . 0 1 , 0 . 0 5 , 0 . 0 7 , 0 . 0 5 ] ) >>> y=np . l i n a l g . solve ( a , b+db) >>> y array ([ −2.34 , 9.745 , −4.85 , −1.34 ] ) >>> np . l i n a l g . norm( y−x , 2 ) / np . l i n a l g . norm( x , 2 ) * np . l i n a l g . norm( b , 2 ) / np . l i n a l g . norm( db , 2 ) 1667.9726140587538 # c o e f f i c i e n t d ’ amplification de l ’ erreur important Exercice 3. Gradient à pas fixe Soient la matrice A et le vecteur F définis par 2 1 1 2 A= 0 1 0 0 0 1 2 1 0 0 , 1 1 −1 F = 1 2 7 (a) Générer la matrice A et le vecteur F . (b) Résoudre (à l’aide de Python) le système linéaire AX = F . (c) On définit une suite de vecteur de R4 par 1 1 X0 = 1 , X n+1 = X n − .5(AX n − F ) pour n ≥ 0. 1 -i- Écrire une fonction en Python grafix(n) qui calcule X n . Calculer en particulier X 10 , X 50 , X 100 et X 2000 . (si vous n’avez pas réussi à écrire la fonction grafix faîtes au moins ces calculs à l’aide de boucle) -ii- Comparer les valeurs obtenues pour n grand avec la solution du système linéaire calculée en à la question (b). -iii- Quel est (expérimentalement) le comportement de la suite X n ? (d) On définit une suite de vecteur de R4 par 1 1 X0 = 1 , X n+1 = X n − 5(AX n − F ) pour n ≥ 0 1 -i- Écrire une fonction en Python grafix2(n) qui calcule X n . Calculer en particulier X 10 , X 50 , X 100 . -ii- Le comportement est-il le même qu’à la question précédente ? Quelle est la différence ? >>> import numpy as np >>> a=np . array ( [ [ 2 , 1 . , 0 , 0 ] , [ 1 , 2 , 1 , 0 ] , [ 0 , 1 , 2 , 1 ] , [ 0 , 0 , 1 , 2 ] ] ) >>> f =np . array ( [ 1 , − 1 , 1 , 7 ] ) >>> x=np . l i n a l g . solve ( a , f ) >>> x array ( [ 0 . 4 , 0 . 2 , −1.8 , 4 . 4 ] ) >>> def graphix (n ) : ... import numpy as np ... z=np . copy ( x0 ) ... f o r i in range (n ) : ... z=z −.5 * (np . dot ( a , z)− f ) ... return z >>> graphix ( 1 0 ) array ( [ 0.5703125 , 0.08691406 , −1.52441406 , 4.33007812]) >>> graphix ( 5 0 ) array ( [ 0.40003545 , 0.19997646 , −1.79994265 , 4.39998545]) >>> graphix (100) array ( [ 0 . 4 , 0 . 2 , −1.8 , 4 . 4 ] ) >>> graphix (2000) array ( [ 0 . 4 , 0 . 2 , −1.8 , 4 . 4 ] ) # expérimentalement : convergence vers l a solution # valeurs t r è s proches , à l a précision de l a machine près # de l a solution exacte , par exemple , f a i s o n s l a d i f f é r e n c e >>> graphix (2000) −x array ( [ 2.77555756e−16, −5.27355937e−16, 6.66133815e−16, −8.88178420e −16]) >>> graphix (100) −x array ( [ 8.86035634e−10, −5.88368826e−10, 1.43363565e−09, −3.63632680e −10]) # maintenant g r a f i x 2 (n) >>> def graphix2 (n ) : ... import numpy as np ... z=np . copy ( x0 ) ... f o r i in range (n ) : ... z=z −5 * (np . dot ( a , z)− f ) ... return z ... >>> graphix2 ( 1 0 ) array ( [ 9.55172743e+11 , 1.47898278e+12 , 1.39649941e+12 , 8.21711843e +11]) >>> graphix2 ( 5 0 ) array ( [ 1.81355484e+61 , 2.93439324e+61 , 2.93439308e+61 , 1.81355458e +61]) >>> graphix2 (100) array ( [ 7.86773509e+122 , 1.27302628e+123 , 1.27302628e+123 , 7.86773509e +122]) >>> # expérimentalement : ça diverge !