R1.07 - Outils fondamentaux
TP 1 - Introduction à numPy

A. Ridard

Avant de parler des tableaux, parlons un peu des listes

Construction d'une liste en extension :

In [ ]:
lst1 = [0,2,4,6]
lst1

Construction d'une liste en compréhension :

In [ ]:
lst2 = [2*i+1 for i in range(4)]
lst2

Index et slicing :

In [ ]:
lst2[0]
In [ ]:
lst2[-1]
In [ ]:
lst2[1:3]

Et plein d'autres choses à découvrir...

Passons aux tableaux

Nous devons importer le module numpy qui propose des tableaux multi-dimensionnels mais aussi des fonctions mathématiques :

In [ ]:
import numpy as np # on préfixera toutes les fonctions de numpy avec np

Tableaux de dimension 1

Construction à partir d'une liste :

In [ ]:
tab1 = np.array(lst1)
tab1

Il s'agit d'un tableau numpy

In [ ]:
type(tab1)

à une dimension possédant 4 éléments

In [ ]:
tab1.shape

tous de même type (entier 32 bits ici)

In [ ]:
tab1.dtype

Attention au typage dynamique !

In [ ]:
tab2 = tab1/2
tab2

La division par 2 fournit des flottants (avez-vous remarqué le point ?) malgré la parité des dividendes

In [ ]:
tab2.dtype

Les opérations se font avec le plus grand type (une belle relation d'ordre)

In [ ]:
tab1+tab2

Avez-vous remarqué que les opérations sur les tableaux se font terme à terme ? D'où l'efficacité de ce type...

In [ ]:
2+tab1
In [ ]:
2*tab1
In [ ]:
tab1*tab2
In [ ]:
tab1**2
In [ ]:
np.cos(tab1)

Tableaux de dimension 2

Construction à partir d'une liste (de listes) :

In [ ]:
lst3 = [lst1,lst2]
tab1 = np.array(lst3)
print(lst3)
tab1

Il s'agit d'un tableau numpy à deux dimensions avec :

  • 2 éléments sur la première dimension (nombre de lignes)
  • 4 éléments sur la deuxième dimension (nombre de colonnes)
In [ ]:
tab1.shape

Attention à l'indexation double !

In [ ]:
lst3[0][2]
In [ ]:
tab1[0][2]
In [ ]:
tab1[0,2]
In [ ]:
lst3[0,2]

Construction en compréhension :

In [ ]:
def maFct(i,j):
    return(i+j)
tab2 = np.fromfunction(maFct,(4,4))
tab2

Construction à partir d'un tableau de dimension 1 :

In [ ]:
tab3 = tab2[:,0:2] # on prend une partie de tab2 pour en faire un tableau 2D avec 4 lignes et 2 colonnes
print('tab3 : \n',tab3,'\n') # on notera la différence d'affichage selon que l'on utilise ou pas la fonction print
tab4 = tab3.flatten() # on "applatit" tab3 pour en faire un tableau 1D avec 8 éléments
print('tab4 : \n',tab4,'\n')
tab5 = tab4.reshape(2,4) # on redimensionne tab4 pour en faire un tableau 2D avec 2 lignes et 4 colonnes
print('tab5 : \n',tab5,'\n')

numpy propose aussi des tableaux prédéfinis...

In [ ]:
I = np.eye(4)
print('I : \n',I,'\n')

J = np.ones((4,4))
print('J : \n',J,'\n')

N = np.zeros((4,4))
print('N : \n',N,'\n')

... que l'on peut modifier, notamment avec des boucles :

In [ ]:
tab6 = np.zeros((4,4))
for i in range(4):
    for j in range(4):
        tab6[i,j]=(j+1)**i
print('tab6 : \n',tab6,'\n')

tab7 = np.zeros((4,4))
for i in range(4):
    for j in range(4):
        tab7[i,j]=j*j + i/(j+1)
print('tab7 : \n',tab7)

La plupart des "traitements matriciels" sont disponibles sur les tableaux

In [ ]:
np.transpose(tab5)

Certains nécessitent le sous module linalg

In [ ]:
from numpy import linalg
In [ ]:
print('Le déterminant : ',linalg.det(tab6),'\n')
print('La matrice inverse : \n',linalg.inv(tab6))
In [ ]:
print('Le déterminant : ',linalg.det(tab7),'\n')
print('La matrice inverse : \n',linalg.inv(tab7))

Ne pas confondre la multiplication terme à terme et la multiplication matricielle !!!

In [ ]:
print('Un produit terme à terme :\n',tab1*tab5,'\n')
print('Un produit matriciel :\n',np.dot(tab1,tab3))
np.dot(tab1,tab5) # produit matriciel non valide

Pour la multiplication matricielle, on pourra aussi utiliser le raccourci @

In [ ]:
tab1 @ tab3

Matrices

Pour les "traitements matriciels", il existe aussi le type matrix

In [ ]:
mat1 = np.matrix(lst3) # on peut construire une matrice à partir d'une liste (de listes)
mat1

Il s'agit bien d'une matrice

In [ ]:
type(mat1)

Le symbole * prend alors le sens de produit matriciel !!!

In [ ]:
mat3 = np.matrix(tab3) # on peut évidemment construire une matrice à partir d'un tableau
print('Un produit matriciel :\n',mat1*mat3)

Attention, numpy et scipy ("extension" de numpy) sont des modules de calcul numérique (approché) alors que sympy est un module de calcul formel (exact avec éventuellement des variables/paramètres non valués). L'utilisation de numpy nécessite donc un certain esprit critique !!!

In [ ]:
from sympy import *
init_session()
In [ ]:
mat6 = Matrix(tab6)
mat6
In [ ]:
mat7 = Matrix(tab7)
mat7
In [ ]:
mat6.det()
In [ ]:
mat6.inv()
In [ ]:
mat7.det() # à comparer avec le résultat obtenu précédemment !
In [ ]:
mat7.inv() # à comparer avec le résultat obtenu précédemment !

Exercice 5 du TD2

L'objectif est de (re)faire cet exercice avec numpy et sympy.

On considère les matrices $ A=\left(\begin{array}{cccc} 1 & 2 & -1 & 3 \\ 3 & 0 & 1 & -4 \\ 5 & 4 & -1 & 2 \end{array}\right) $ et $ B=\left(\begin{array}{ccc} 1 & 2 & 1 \\ 3 & 4 & 1 \\ 5 & 6 & 1 \\ 7 & 8 & 1 \end{array}\right) $.

Calculer $C=AB$.

In [ ]:
 

Calculer $\det(C-I)$ où $I$ désigne la matrice identité d'ordre 3.

In [ ]:
 

En déduire que $C-I$ est inversible et déterminer son inverse.

In [ ]:
 

Exercice 3 du TD3

L'objectif est de (re)faire cet exercice avec numpy et sympy.

On considère $f$ l'application linéaire de $\mathbb R^3$ dans $\mathbb R^3$ associée à $A= \left(\begin{array}{ccc} 9 & -6 & 10 \\ -5 & 2 & -5 \\ -12 & 6 & -13 \end{array}\right) $ et les vecteurs $u,v,w\in\mathbb R^3$ définis par : $$u=(2,-1,-2),\ v=(1,0,-1),\ w=(-2,1,3)$$

Montrer que la famille $\big(u,v,w\big)$ est une base de $\mathbb R^3$.

In [ ]:
 

On notera $\mathcal B$ la base canonique de $\mathbb R^3$ et $\mathcal B'=\big(u,v,w\big)$.

Déterminer $P$ la matrice de passage de $\mathcal B$ à $\mathcal B'$ (attention à l'ordre), puis la matrice de passage de $\mathcal B'$ à $\mathcal B$.

In [ ]:
 

En déduire les coordonnées de $(1,2,3)$ dans la base $\mathcal B'$.

In [ ]:
 

A partir du diagramme de décomposition de $f$, déterminer $D=\mathcal M\big(f,\mathcal B'\big)$.

In [ ]: