TP 3 : Matrice de population
Contents
TP 3 : Matrice de population#
Rappels sur les matrices#
Définition#
Une matrice est représentée en Python par une liste de listes (ou : un tableau de tableaux), chaque sous-liste correspondant à une ligne de la matrice.
Par exemple, la matrice
est représentée par :
M = [[1, 0, 3], [2, 2, 1]]
Ainsi, la première sous-liste [1, 0, 3]
correspond à la première ligne de la matrice et [2, 2, 1]
correspond à la deuxième ligne.
Accéder et modifier un élément#
On accède à l’élément sur la ligne i
, colonne j
de la matrice avec M[i][j]
. Par exemple :
M[0][2] # élément ligne 0, colonne 2
3
Remarque : Les lignes et colonnes commencent à \(0\) (au lieu de \(1\) en mathématiques).
On peut modifier l’élément ligne i
, colonne j
avec M[i][j] = ...
. Par exemple :
M[1][0] = 42
M # M a bien été modifiée
[[1, 0, 3], [42, 2, 1]]
Taille d’une matrice#
Le nombre de lignes de la matrice est le nombre de sous-listes, qui peut être obtenue avec len(M)
:
len(M) # nombre de lignes de M
2
Le nombre de colonnes est égal au nombre d’éléments sur une ligne, c’est-à-dire la taille d’une sous-liste. On eut l’obtenir avec len(M[0])
(nombre d’éléments sur la première ligne de M
) :
len(M[0]) # la 1ère ligne contient 3 éléments, donc il y a 3 colonnes
3
Création d’une matrice de taille \(n \times p\)#
Pour créer une matrice de taille \(n \times p\) remplie de \(0\), on a deux possibilités :
Utiliser
np.zeros((n, p))
du modulenumpy
(import numpy as np
). Ceci donne un tableau (np.darray
), qui ressemble beaucoup aux listes avec quelques petites différences (pas deappend
, opérations terme à terme…).Définir une liste contenant \(n\) listes de \(p\) zéros ;
M = []
for i in range(3):
L = [] # la ième ligne
for j in range(5):
L.append(0)
M.append(L)
M # matrice 3x5 remplie de 0
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
Parcourir une matrice#
Pour parcourir une matrice, on utilise deux indices (un pour la ligne, un pour la colonne), dans deux boucles for
. Par exemple, mettons des \(2\) partout dans \(M\) :
for i in range(3): # i est le numéro de ligne
for j in range(5): # j est le numéro de colonne
M[i][j] = 2
M
[[2, 2, 2, 2, 2], [2, 2, 2, 2, 2], [2, 2, 2, 2, 2]]
Exercices sur les matrices#
Exercice
Écrire une fonction somme(M)
renvoyant la somme des éléments d’une matrice M
.
Solution
def somme(M):
s = 0
for i in range(len(M)):
for j in range(len(M[0])):
s += M[i][j]
return s
M = [[1, 2], [3, 4]]
somme(M) # 10
10
Exercice
Écrire une fonction nulle
déterminat si une matrice est nulle (ne contient que des \(0\)). nulle(M)
doit renvoyer True
si M
est nulle, False
sinon.
Solution
def nulle(M):
for i in range(len(M)):
for j in range(len(M[0])):
if M[i][j] != 0:
return False
return True
print(nulle([[1, 2], [3, 4]]))
nulle([[0, 0], [0, 0]])
False
True
Exercice
Écrire une fonction identite(n)
renvoyant la matrice identité de taille \(n\).
Solution
def identite(n):
I = []
for i in range(n):
L = []
for j in range(n):
L.append(0)
L[i] = 1
I.append(L)
return I
identite(3)
[[1, 0, 0], [0, 1, 0], [0, 0, 1]]
Exercice
Écrire une fonction transpose(M)
renvoyant la transposée d’une matrice M
.
Solution
def transpose(M):
tM = []
for i in range(len(M[0])):
L = [] # la ième ligne
for j in range(len(M)):
L.append(0)
tM.append(L)
for i in range(len(M)):
for j in range(len(M[0])):
tM[i][j] = M[j][i]
return tM
transpose([[1, 2], [3, 4]])
array([[1., 3.],
[2., 4.]])
Exercice
Écrire une fonction produit(A, B)
renvoyant le produit matriciel de A
et B
. On rappelle que \(AB = (c_{i, j})\) où \(c_{i, j} = \sum_{k = 0}^p a_{i, k} b_{k, j}\), où \(p\) est le nombre de colonnes de \(A\) (qui doit être égal au nombre de lignes de \(B\), ce qu’on suppose être le cas).
On pourra compléter le code suivant :
def produit(A, B):
n = ... # nombre de lignes de A
p = ... # nombre de colonnes de A
q = ... # nombre de colonnes de B
# définir une matrice C de taille n*q remplie de 0
for i in range(n):
for j in range(q):
# ici on va calculer C[i][j] (c'est-à-dire une somme)
for k in range(p):
C[i][j] += ...
return C
Solution
import numpy as np
def produit(A, B):
n = len(A) # nombre de lignes de A
p = len(A[0]) # nombre de colonnes de A
q = len(B[0]) # nombre de colonnes de B
C = [[0]*q for _ in range(n)]
for i in range(n):
for j in range(q):
for k in range(p):
C[i][j] += A[i][k]*B[k][j]
return C
produit([[1, 2], [3, 4]], [[5, 6], [7, 8]])
[[19, 22], [43, 50]]
Matrice de population#
On souhaite étudier l’évolution d’une population de rongeurs à des stades d’âges différents. On ne s’intéresse qu’à la population d’individus femelles. On suppose qu’aucun rongeur vit au plus \(3\) ans et on note \(a_n\), \(b_n\), \(c_n\) le nombre de femelles âgées de \(0\), \(1\), \(2\) ans à l’année \(n\) (initialement \(n = 0\)).
Chaque femelle donne en moyenne naissance à \(6\) femelles lors de sa 2ème année et \(10\) femelles lors de sa \(3\)ème année.
Cependant, seul un rongeur sur deux survit au dela de sa première année et seul 40% de ceux qui survivent la deuxième
année survivront jusqu’à la troisième année.
Exercice
(Sans programmation) Exprimer \(a_{n+1}\), \(b_{n+1}\), \(c_{n+1}\) en fonction de \(a_{n}\), \(b_{n}\), \(c_{n}\).
Solution
On définit maintenant le vecteur \(X_n = \begin{pmatrix} a_n\\ b_n\\ c_n \end{pmatrix}\), que l’on représentera sous forme de liste en Python.
Exercice
On prend initalement \(a_0 = 10\), \(b_0 = 0\), \(c_0 = 0\). Définir \(X_0\) en Python, sous forme d’une matrice colonne.
Solution
X0 = [[10], [0], [0]]
Exercice
Définir (sur papier puis en Python) une matrice \(A\) telle que \(X_{n + 1} = AX_n\).
Solution
Solution
A = [[0, 6, 10], [0.5, 0, 0], [0, 0.4, 0]]
\(A\) est appelée une matrice de Leslie.
On remarque que, par récurrence évidente : \(X_n = A^n X_0\).
Exercice
Écrire une fonction puissance(A, n)
renvoyant \(A^n\).
Solution
def puissance(A, n):
An = identite(len(A))
for k in range(n):
An = produit(An, A)
return An
puissance(A, 3)
[[2.0, 18.0, 30.0], [1.5, 2.0, 0.0], [0.0, 1.2000000000000002, 2.0]]
Exercice
Écrire une fonction population(n)
renvoyant \(X_n\).
Solution
def population(n):
return produit(puissance(A, n), X0)
population(10)
[4590.0, 1120.0, 234.00000000000003]
Exercice
Que vaut \(X_1\), \(X_2\), \(X_3\), \(X_4\) ?
Solution
for i in range(1, 10):
print(population(i))
Exercice
Utiliser la fonction suivante pour afficher les \(n\) premières valeurs de \(a_k\), \(b_k\), \(c_k\). On appelera par exemple plot_population(10)
.
import matplotlib.pyplot as plt
def plot_population(n):
x = list(range(n))
y = [population(i) for i in x]
a, b, c = zip(*y)
plt.plot(x, a, label="$a_n$")
plt.plot(x, b, label="$b_n$")
plt.plot(x, c, label="$c_n$")
plt.legend()
plt.show()
Solution
plot_population(10)
<Figure size 640x480 with 1 Axes>
Exercice
Utiliser la fonction suivante pour afficher le taux d’accroissement, c’est-à-dire \(\frac{a_{n+1}}{a_n}\), par exemple. On pourra appeler plot_accroissement(20)
, par exemple.
import matplotlib.pyplot as plt
def plot_accroissement(n):
x = list(range(n))
x_ = list(range(1, n - 1))
y = [population(i) for i in x]
X = list(zip(*y))
X_ = [[]]*3
for i in range(3):
X_[i] = [0 if X[i][j] == 0 else X[i][j+1]/X[i][j] for j in x_]
plt.plot(x_, X_[0], label=r"$\frac{a_{n+1}}{a_n}$")
plt.plot(x_, X_[1], label=r"$\frac{b_{n+1}}{b_n}$")
plt.plot(x_, X_[2], label=r"$\frac{c_{n+1}}{c_n}$")
plt.legend()
plt.show()
Solution
plot_accroissement(20)
<Figure size 640x480 with 1 Axes>
Exercice
D’après le théorème de Perron-Frobenius, le taux d’accroissement est censé tendre, quand \(n \longrightarrow \infty\), vers la plus grande valeur propre de \(A\).
Calculer les valeurs propres de \(A\) (si vous avez déjà vu la définition de valeur propre en mathématiques…).
Vérifier avec
np.linalg.eig(A)
, qui renvoie deux tableaux, le premier contenant les valeurs propres et le deuxième les vecteurs propres.