Vous êtes sur la page 1sur 16

Ingénierie numérique et simulation Numpy, Scipy et Matplotlib

Introduction à Numpy, Scipy et Matplotlib

Python dispose de nombreux modules de calcul scientifique permettant d'aborder efficacement un


problème scientifique. C'est un langage très riche et des outils interactifs permettent de le transformer
en un environnement de travail complet et facile d'utilisation pour l'informatique scientifique.
Il existe de nombreux modules scientifiques sous python, Parmi ces modules nous nous intéressons
particulièrement à 1:
 numpy : Puissant outil pour créer, manipuler, et appliquer de nombreuses opérations sur des
tableaux de nombres (matrices). Stable et bien documenté :
http://docs.scipy.org/doc/numpy/reference/ (en anglais).
 scipy : Fonctions mathématiques puissantes s'appliquant aux tableaux générés par numpy.
C'est la boîte à outil numérique pour les tableaux numpy. Elle contient des opérations
spécifiques (algèbre linéaire, statistiques,...) de manipulation de tableaux numpy.
Documentation à :
http://docs.scipy.org/doc/scipy/reference/ (en anglais).
 matplotlib : Permet le tracé de graphes de fonctions. Documentation à :
http://matplotlib.org/users/pyplot_tutorial.html (en anglais)

1. Les tableaux numpy :


Le module numpy est la boîte à outils indispensable pour faire du calcul scientifique avec Python.
Pour modéliser les vecteurs, matrices, et plus généralement les tableaux à n dimensions, numpy
fournit le type ndarray.
Il y a des différences majeures avec les listes (resp. les listes de listes) qui pourraient elles aussi nous
servir à représenter des vecteurs (resp. des matrices) :
 Les tableaux numpy sont homogènes, c’est-à-dire constitués d’éléments du même type (On
trouvera donc des tableaux d’entiers, des tableaux de flottants, des tableaux de chaînes de
caractères, etc).
 La taille des tableaux numpy est fixée à la création. On ne peut donc augmenter ou diminuer
la taille d’un tableau comme le ferait pour une liste (à moins de créer un tout nouveau
tableau, bien sûr).

1.1. Importation du module numpy :

1
Ces modules fournissent un ensemble d’objets ainsi qu’un groupes de fonctions permettant de manipuler
nombre d’objets de façon simple et très performantes dans le cadre du calcul scientifique.

1/16
Ingénierie numérique et simulation Numpy, Scipy et Matplotlib

Traditionnellement, on charge la totalité du module numpy, mais en le renommant en np, de la


manière suivante :
>>> import numpy as np

Les fonctions de numpy sont alors accessibles par leur nom qualifié « np.nom_de_la_fonction ».
Important : dans toute la suite, on supposera que le module numpy a été importé de cette manière.
Quand on évoquera la fonction « array » par exemple, on pensera toujours à l’utiliser avec la syntaxe
« np.array »

1.2. Création de tableaux avec array :


L’opérateur np.array prend en argument une liste et renvoie un tableau numpy ayant les mêmes
éléments. En cas de liste de listes, l’opérateur s’applique récursivement à chaque sous–liste : la valeur
de retour est donc un tableau de tableaux.
On peut définir un tableau à partir d’une liste et préciser de manière optionnelle le type des éléments.
Exemple 1.1 :
>>> t1=np.array([1,2,3]) # tableau 1D (entiers)
>>> t1
array([1, 2, 3])
>>> t2=np.array([1,2,3],float) # tableau 1D (réels)
>>> t2
array([ 1., 2., 3.])
>>> t3=np.array([1,2,3],complex) # tableau 1D (complexes)
>>> t3
array([ 1.+0.j, 2.+0.j, 3.+0.j])
>>> t4=np.array([[1,2,3],[3,8,9]]) # tableau 2D
>>> t4
array([[1, 2, 3],
[3, 8, 9]])

Ces tableaux admettent quelques attributs: par exemple, les fonctions size et shape qui renvoient le
nombre d’éléments et la taille du tableau.
Exemple 1.2 :
>>> B = np.array( [[1,2,3] , [1,4,9]] );
>>> np.size(B)
6

2/16
Ingénierie numérique et simulation Numpy, Scipy et Matplotlib

>>> np.shape(B)
(2,3)

1.3. Tableaux spécifiques :


 Matrices zeros et ones :
Les méthodes zeros et ones permettent de créer des tableaux contenants des 0 ou des 1.
Attention pour créer des tableaux 2d et plus, les dimensions doivent être données sous la forme d'un
seul argument tuple (contenant ces dimensions).
Exemple 1.3:
>>> np.zeros(5) # tableau 1d de 0
array([ 0., 0., 0., 0., 0.])
>>> np.ones((2,4)) # tableau 2d de taille 2 x 4 contenant des 1
array([[ 1., 1., 1., 1.],
[ 1., 1., 1., 1.]])
[0, 0, 0, 0, 0]])

Remarques :
 arange(a,b,inc) permet de créer un tableau 1d et fonctionne comme la fonction
range(a,b,inc) sauf que les arguments peuvent être des flottants :
>>> np.arange(0,1,0.1)
array([ 0. , 0.1 , 0.2 , 0.3 , 0.4 , 0.5 , 0.6 , 0.7 , 0.8 , 0.9])
 La méthode reshape permet de modifier la taille d’un tableau sous la contrainte que le
nombre total d’éléments doit rester constant. On pourra ainsi passer (dans les deux sens) d’un
vecteur de taille n à une matrice de taille (p; q) ou à une matrice de taille (r; s) à condition
que n = pq = rs.
>>> np.arange(0,1,0.1).reshape(2,5)
array([[ 0. , 0.1 , 0.2 , 0.3 , 0.4] ,
[0.5 , 0.6 , 0.7 , 0.8 , 0.9]])

 Identité, matrices diagonales ou triangulaires


La fonction identity fabrique la matrice identité d’ordre n (donné comme 1er argument)
Exemple 1.5 :

>>> np.identity(4)
array([[ 1., 0., 0., 0.],
[ 0., 1., 0., 0.],
[ 0., 0., 1., 0.],

3/16
Ingénierie numérique et simulation Numpy, Scipy et Matplotlib

[ 0., 0., 0., 1.]])


La fonction eye permet de fabriquer la matrice identité ou plus généralement une matrice dont tous
les coefficients sont nuls sauf ceux d’une certaine « parallèle » à la diagonale et qui valent 1.
Exemple 1.5 :
>>> np.eye(3) # matrice identité 3 x 3 equivalent à np.eye(3,3)
array([[ 1., 0., 0.],
[ 0., 1., 0.],
[ 0., 0., 1.]])
>>> np.eye(3, 2, dtype=int)
array([[ 1 , 0],
[ 0 , 1],
[ 0 , 0]])

La fonction diag, si elle est appliquée à un vecteur (ou à une liste, ou à un tuple) renvoie la matrice
diagonale formée sur les coefficients de ce vecteur
Exemple 1.6 :
>>> np.diag(np.ones(3))
array([[ 1., 0., 0.],
[ 0., 1., 0.],
[ 0., 0., 1.]])

Exemple 1.7 :
>>> A = np.array([[1,2,3],[4,5,6],[7,8,9]]) # un tableau 2d
>>> A
array( [ [ 1 , 2 , 3 ],
[ 4 , 5 , 6 ],
[ 7 , 8 , 9 ] ])
>>> np.diag(A) # extraction de la diagonale principale
array([1, 5, 9])

1.4. Accès aux éléments d’un tableau numpy:


 Tableau à une dimension :
Pour les tableaux à une dimension (vecteur), la syntaxe est la même que pour les listes.
Exemple 1.8 :
On choisit ici de former le vecteur v, de longueur p = 16, tel que v[k] = 10*k pour k allant de 0 à 15.

4/16
Ingénierie numérique et simulation Numpy, Scipy et Matplotlib

>>> v = np.array(range(0,160,10))
>>> v
array([ 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150])
>>> v[0] # le 1er élément
0
>>> v[-1] # le dernier élément
150
>>> v[4 :11] # de v[4] à v[10]
array([40, 50, 60, 70,80, 90, 100])
>>> v[ 11 : 4 : -1 ] # de v[11] à v[5], donc |4-11| = 7 éléments
array([110, 100, 90, 80, 70, 60, 50])
>>> v[ : 6 : -1 ] # de v[15] à v[7], donc |6-15| = 9 éléments
array([150, 140, 130, 120, 110, 100, 90, 80, 70])
>>> v[ 6 : : -1 ] # de v[6] à v[0], donc 7 éléments
array([60, 50, 40, 30, 20, 10, 0])

 Tableau à deux dimensions (matrices):


Pour une matrice numpy m, il est possible d’accéder directement à l’élément de ligne i et de colonne
j avec la syntaxe m[i, j] (alors qu’avec une matrice python “classique” il faudrait écrire m[i][j]).
Exemple 1.9 :
>>> m = np.array( [ [ 10*i + j for j in range(8) ] for i in range(5) ] )
>>> m
array([ [ 0, 1, 2, 3, 4, 5, 6, 7],
[10, 11, 12, 13, 14, 15, 16, 17],
[20, 21, 22, 23, 24, 25, 26, 27],
[30, 31, 32, 33, 34, 35, 36, 37],
[40, 41, 42, 43, 44, 45, 46, 47] ])
>>> m[3,5] # element en position (3,5)
35
>>> m[3] # vecteur-ligne en position 3
array([30, 31, 32, 33, 34, 35, 36, 37])
>>> m[ : , 5] # vecteur-colonne en position 5
array([ 5, 15, 25, 35, 45])
>>> m[1 : 4 , 2 : 6] # lignes 1 à 3, colonnes 2 à 5
array( [[12, 13, 14, 15],
[22, 23, 24, 25],
[32, 33, 34, 35]] )

5/16
Ingénierie numérique et simulation Numpy, Scipy et Matplotlib

Remarques:
Comme les listes, les matrices sont des objets mutables.
>>> A=np.array([[ 1, 1],[-1, 0]])
>>> B=A
>>> A[1,1]=2
>>> A
array([[ 1, 1],
[-1, 2]])
>>> B
array([[ 1, 1],
[-1, 2]])
Pour éliminer ce problème, il faut faire une copie de la matrice A :
>>> A=np.array([[ 1, 1],[-1, 0]])
>>> B=np.array(A,copy=True)
>>> A[1,1]=2
>>> A
array([[ 1, 1],
[-1, 2]])
>>> B
array([[ 1, 1],
[-1, 0]])

1.5. Opérations sur les tableaux numpy :


Au contraire des listes, il est possible d’effectuer les opérations arithmétiques (addition, soustraction,
multiplication, division) sur les tableaux numpy.
Toutes ces opérations agissent case par case, entre tableaux de même format. Sur le plan syntaxique,
elle sont classiquement notées à l’aide des opérateurs +, -, * et /.
Attention :
L’addition des tableaux numpy est la même que l’addition usuelle, la multiplication * de matrices
numpy n’a rien à voir avec la multiplication usuelle. Il en est de même pour la division.
En effet, si a et b sont des matrices numpy, a * b se contente de calculer la matrice des coefficients
a[i, j] * b[i, j] au lieu de la matrice des coefficients ∑ k a[i, k]b[k, j]. De même a/b se contente de
calculer la matrice des coefficients a[i, j]/b[i, j].
De manière similaire, a ** 2 se contente d´élever chaque coefficient au carré au lieu de calculer a2 au
sens matriciel.
Exemple 1.10 :

6/16
Ingénierie numérique et simulation Numpy, Scipy et Matplotlib

>>> t = array( [ [1,2,3] , [4,5,6] ] )


>>> s = array( [ [0,0,7] , [6,6,6] ] )
>>> t
array( [ [1,2,3] ,
[4,5,6] ] )
>>> s
array( [ [0,0,7] ,
[6,6,6] ] )
>>> s+t
array([[ 1, 2, 10],
[10, 11, 12]])

>>> s-t
array([[-1, -2, 4],
[ 2, 1, 0]])
>>> s*t
array([[ 0, 0, 21],
[24, 30, 36]])
>>> s**2
array([[ 0, 0, 49],
[36, 36, 36]])

1.6. Quelques outils d’algèbre linéaire :


 Produit matriciel
Syntaxe de l’appel : np.dot (matrice A, matrice B)
Valeur de retour : le produit matriciel A.B
Attention : l’opérateur * effectue une multiplication terme à terme des éléments des deux matrices,
¸ça n’a rien à voir avec un produit matriciel
Exemple 1.11 :
>>>A=np.array([[1,2],[3,4]])
>>>np. dot (A, np.eye(2)) # syntaxe correcte du produit matriciel
array([[ 1., 2.],
[ 3., 4.]])
>>> A * np.eye(2) # Faux (produit terme a terme)
array([[ 1., 0.],
[ 0., 4.]])

7/16
Ingénierie numérique et simulation Numpy, Scipy et Matplotlib

 Déterminant d’une matrice


Syntaxe de l’appel : np.linalg.det (matrice A)
Valeur de retour : le déterminant de A, de type float

Exemple 1.12 :
>>> np.linalg.det ( [ [1 , 2] , [3 , 4] ] )
-2.0000000000000004

 Rang d’une matrice :


Syntaxe d’appel : np.rank(matrice A)
Valeur de retour : le rang de la matrice A (entier)
>>> A=np.arange(15).reshape(3,5)
>>> A
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
>>> np.rank(A)
2

 Inverse d’une matrice carrée:


Syntaxe d’appel : np.linalg.inv(matrice A)
Valeur de retour : A-1 (provoque une erreur si A n’est pas inversible).
>>> A=np.array( [ 2 , 4 , 6 , 8 ] , float ).reshape( 2 , 2 )
>>> np.linalg.inv( A )
array([[-1. , 0.5 ],
[ 0.75, -0.25]])
Attention : Comme d’habitude avec les logiciels de calcul scientifique, il faut d’abord savoir si la
matrice est inversible pour l’inverser, ou encore rester critique vis à vis du résultat retourné.
 Résolution d’un système de Cramer :
Syntaxe de l’appel : np.linalg.solve (matrice A, vecteur B)
Valeur de retour : le vecteur X solution de AX = B
Exemple 1.13 :
Résolution du système : x + 2y = 2
3x + 4y = 8
>>> a=np.array([ [ 1 , 2 ] , [ 3 , 4 ] ])
>>> b=np.array([ 2 , 8 ])

8/16
Ingénierie numérique et simulation Numpy, Scipy et Matplotlib

>>> np.linalg.solve( a , b )
array([ 4., -1.])

 Puissance d’une matrice :


Syntaxe de l’appel : np.linalg.matrix_power (matrice A, entier n)
Valeur de retour : An
Exemple 1.14 :
>>> A=np.array( [ [ 1 , 2 ] , [ 3 , 4 ] ] )
>>> np. linalg.matrix_power (A, -2)
array( [ [ 5.5 , -2.5 ],
[ -3.75 , 1.75 ] ])

 Transposé d’une matrice


Syntaxe de l’appel : np.transpose (matrice A)
Valeur de retour : tA
Exemple 1.15 :
>>> A=np.array( [ [ 1 , 2 ] , [ 3 , 4 ] ] )
>>>A
array( [ [ 1 , 2 ] ,
[3, 4]])
>>>np.transpose (A)
array( [ [ 1 , 3 ] ,
[2,4]])

2. Les graphiques avec matplotlib :

9/16
Ingénierie numérique et simulation Numpy, Scipy et Matplotlib

Le module matplotlib est chargé de tracer les courbes. Dans toute la suite on supposera qu’on a
effectué :
>>> import matplotlib.pyplot as plt

Les instructions :
>>> plt.plot ([x0, . . . , xn], [y0, . . . , yn])
>>> plt.show () # provoque l’affichage

permettent de tracer une ligne brisée reliant les points de coordonnées (xk, yk). Les listes de
coordonnées peuvent aussi être données sous forme de tableaux numpy.
Quoi Comment
Tracer une ligne brisée plt.plot([x0,...,xn] , [y0...,yn])
Mettre des titres/noms aux axes plt.title(’Titre de la figure’)
plt.xlabel(’Nom de l’axe des x’)
plt.ylabel(’Nom de l’axe des y’)
Visualiser le résultat plt.show( )
Effacer la fenêtre graphique courante plt.clf( )
Sauver la figure plt.save(’courbe.bmp’)
(sous différents formats !) plt.savefig(’courbe.pdf’)

Exemple 2.1 : la courbe de la fonction sinus


import matplotlib.pyplot as plt
import numpy as np
x=np.linspace(-5,5,100)
plt.plot(x,np.sin(x)) # on utilise la fonction sinus de numpy
plt.ylabel("fonction sinus")
plt.xlabel("l’axe des abcisses")
plt.show()

Nous obtenons ceci :

10/16
Ingénierie numérique et simulation Numpy, Scipy et Matplotlib

Remarques :
1. linspace(a,b,n) permet de créer un tableau 1d dont les n composantes sont uniformément
réparties entre a et b :
>>> np.linspace( 0 , 1 , 5 ) # vecteur à 5 composantes équiréparties entre 0 et 1
array([ 0. , 0.25 , 0.5 , 0.75 , 1. ])
2. numpy permet de “vectoriser”, i.e. appliquer une fonction à un vecteur/matrice et éviter les
boucles. Comme nous avons choisi d’utiliser numpy à travers import numpy as np, il faut
choisir les fonctions usuelles définies dans numpy. Par exemple :
>>> from math import sin
>>> a=np.arange( 4, dtype=float)
>>> a
array([ 0., 1., 2., 3.])
>>> sin(a)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: only length-1 arrays can be converted to Python scalars
>>> np.sin(a)
array([ 0. , 0.84147098 , 0.90929743 , 0.14112001 ])

Exemple 2.2 : la courbe de la fonction t sur ,


t et sin(5)
On commence par créer le tableau des abscisses (x); ensuite, on crée le tableau des ordonnées (y) en
appliquant la fonction f préalablement définie à chaque élément de x. Pour cela, on va appliquer
directement f à un tableau, ce qui produit le tableau des images.
def f(t) : # définition de la fonction
return np.sin(5*t) * np.exp(t)

11/16
Ingénierie numérique et simulation Numpy, Scipy et Matplotlib

x = np.linspace(-np.pi, np.pi, 100) # création des tableau abscisses et ordonnées


y = f(x)

plt.plot(x, y)
plt.grid() # décoration : pour créer une grille
plt.title('Le graphe de $f$') # Le titre
plt.xlabel('$x$') # le nom de l'axe horizontal
plt.ylabel('$y=f(x)$')
plt.axhline(color='black') #equivalent a linewidth=1, color='k')
plt.axvline(color='black')
plt.savefig('courbe1.pdf') # pour sauver (en pdf ou autre)
plt.show() # l’affichage se fait après la sauvegarde !

Nous obtenons ceci :

3. Le module scipy :
Le module scipy est la boîte à outils numérique (librairie de calcul scientifique) pour les tableaux
numpy. On trouve dans scipy les opérations de manipulation / traitement de données numériques
classiques, mais spécifiques à un type d’application (algèbre linéaire, statistiques, etc.).

3.1. Intégration numérique


scipy dispose de plusieurs méthodes d'intégration de fonctions.

12/16
Ingénierie numérique et simulation Numpy, Scipy et Matplotlib

1. La méthode quad(f,a,b) pour intégrer f sur l'intervalle [a; b] :


>>> from scipy import integrate
>>>f = lambda x: x**2
>>> integrate.quad( f , 0 , 1 )
(0.33333333333333337, 3.700743415417189e-15)

Elle retourne un couple constitué de la valeur approchée de l'intégrale (1er élément) et d'une
estimation de l'erreur commise. Pour accéder indépendamment à ces 2 valeurs :
>>> res = integrate.quad(f,0,1)
>>> res[0] # Résultat obtenu
0.33333333333333337
>>> res[1] # Estimation de l'erreur
3.700743415417189e-15
Remarque :
D'autres méthodes, par exemple pour le calcul d'intégrales doubles ou multiples sont disponibles
dans scipy. (voir : http://docs.scipy.org/doc/scipy/reference/integrate.html)

3.2. Intégration des équations différentielles avec odeint :


La bibliothèque scipy.integrate contient la fonction odeint, qui résout numériquement des
équations différentielles. On commence donc par la charger :
>>>from scipy.integrate import odeint

Le principe d’utilisation de odeint (pour intégrer numériquement des équations différentielles) est le
suivant : pour avoir une estimation numérique de la solution du problème : y '(t) f y(t),t  sur un
intervalle [t0 , tf]. Il faut définir :
 La variable ‘t’ est de la forme t=[ t0,t1,..., tf].
 La condition initiale est alors : y(t0) = y0.
La valeur renvoyée est un tableau contenant une estimation de la solution aux différents temps.
Une fois définies, on peut utiliser odeint:
>>>yt = odeint(f, y0, t)

Exemple 3.1 :
Prenons l'exemple de l'intégration sur [-1; 1] de l'équation différentielle : y’ = t avec y(-1) = 1/2.
dont l'unique solution est y(t) = t2/ 2
.

>>> t = np.linspace(-1,1,100)
>>> f = lambda y, t : t

13/16
Ingénierie numérique et simulation Numpy, Scipy et Matplotlib

>>> y0 = 1/2.
>>> y = odeint(f, y0, t)
>>> plt.plot(t,y)
>>> plt.grid()
>>> plt.show()

Nous obtenons le tracé suivant :

Il correspond bien au résultat attendu : y(t) = t2/ 2 sur l’intervalle [-1; 1]


Exemple 3.2 :

Prenons l'exemple de l'intégration sur [0; 4] de l'équation différentielle : y ' y  avec y(0) = 1.

# La solution du premier système devrait donner exp(-t/tau)


def f(y,t):
tau = 1.0
return - y / tau

>>> y0 = 1 # condition initiale


>>> t = np.arange(4) # Points temporels pour les calculs
>>> odeint( f , y0 , t )
array([[ 1. ],
[ 0.36787947],
[ 0.13533528],
[ 0.04978706]])
>>> np.exp(-t) # Vérification
array [1.0, 0.36787944117144233 , 0.1353352832366127 , 0.049787068367863944]

14/16
Ingénierie numérique et simulation Numpy, Scipy et Matplotlib

4. Trouver de l’aide :
Plusieurs méthodes existent pour trouver de la documentation sur les fonctions cherchées:
 Sur internet: http://numpy.org et http://scipy.org peuvent être de bons points de départ.
Voir aussi http://docs.scipy.org
 Via help(): Comme d’habitude, toutes les aides internes aux fonctions et objets manipulés
sont disponibles via la commande help( ), par exemple help(np.linalg.inv) .
 Via np.info(): a le même comportement que help(), par exemple np.info(np.linalg.det)
 Via np.source(): Permet de regarder le code source d’une fonction donnée. Particulièrement
utile pour comparer et comprendre l’implémentation des différents algorithmes.
Par exemple :
>>> import numpy as np
>>> np.source(np.linalg.inv)
In file: C:\pyzo2013b\Lib\pyzo-packages\numpy\linalg\linalg.py
def inv(a):
"""
Compute the (multiplicative) inverse of a matrix.

Given a square matrix `a`, return the matrix `ainv` satisfying


``dot(a, ainv) = dot(ainv, a) = eye(a.shape[0])``.

Parameters
----------
a : (M, M) array_like
Matrix to be inverted.

Returns
-------
ainv : (M, M) ndarray or matrix
(Multiplicative) inverse of the matrix `a`.

Raises
------
LinAlgError
If `a` is singular or not square.

Examples

15/16
Ingénierie numérique et simulation Numpy, Scipy et Matplotlib

--------
>>> from numpy import linalg as LA
>>> a = np.array([[1., 2.], [3., 4.]])
>>> ainv = LA.inv(a)
>>> np.allclose(np.dot(a, ainv), np.eye(2))
True
>>> np.allclose(np.dot(ainv, a), np.eye(2))
True

If a is a matrix object, then the return value is a matrix as well:

>>> ainv = LA.inv(np.matrix(a))


>>> ainv
matrix([[-2. , 1. ],
[ 1.5, -0.5]])

"""
a, wrap = _makearray(a)
return wrap(solve(a, identity(a.shape[0], dtype=a.dtype)))

16/16

Vous aimerez peut-être aussi