PSI_Mat2_2015_26¶
- Thème : construction de matrices, calculs de valeurs propres, simulations probabilistes, tracé de courbes, et diagonalisations.
Documentation¶
Correction d’un exercice de maths avec Python, issu des annales pour les oraux du concours Centrale-Supélec.
- Sujet : PSI 3, http://www.concours-centrale-supelec.fr/CentraleSupelec/MultiY/C2015/PSI-Mat2-2015-26.pdf
- Dates : séances de révisions, vendredi 10 et samedi 11 juin (2016).
- Auteur : Lilian Besson, pour le cours d’informatique pour tous en prépa MP au Lycée Lakanal (http://perso.crans.org/besson/infoMP/),
- Licence : MIT Licence (http://lbesson.mit-license.org).
-
PSI_Mat2_2015_26.
q0
()[source]¶ Préliminaires :
- Comme pour tous ces exercices, on commence par importer les modules requis, ici numpy, numpy.linalg et matplotlib :
>>> import numpy as np >>> import numpy.linalg as LA # Convention recommandée >>> import matplotlib.pyplot as plt
- On aura aussi besoin de faire des tirages aléatoires, on peut utiliser au choix soit
numpy.random
soitrandom
. Je préfère le plus simple,random
:
>>> import random
-
PSI_Mat2_2015_26.
q1
()[source]¶ Question 1.
- On écrit d’abord une fonction qui créé cette matrice \(M(a, b)\),
- Puis une fonction qui calcule ses deux valeurs propres complexes \(\lambda_1, \lambda_2\) (de façon approchée),
- Et enfin, on renvoit ecart(a, b) = abs(lambda1 - lambda2).
-
PSI_Mat2_2015_26.
M
(a, b)[source]¶ Renvoie la matrice \(M(a, b)\) définie dans l’énoncé :
\[\begin{split}M(a, b) := [[3a - 2b, - 6a + 6b + 3], [a - b, - 2a + 3b + 1]] = \begin{bmatrix} 3a - 2b & - 6a + 6b + 3 \\ a - b & - 2a + 3b + 1 \end{bmatrix}\end{split}\]Exemple :
>>> print(M(1, 3)) [[-3 15] [-2 8]]
-
PSI_Mat2_2015_26.
lam12
(a, b)[source]¶ Calcule et renvoie \(\lambda_1, \lambda_2 = \mathrm{Sp}(M(a, b))\).
Exemple :
>>> lam12(1, 3) (2.0000000000000009, 2.9999999999999991) >>> [round(l) for l in lam12(1, 3)] [2.0, 3.0]
-
PSI_Mat2_2015_26.
ecart
(a, b)[source]¶ Calcule et renvoie \(|\lambda_1 - \lambda_2|\), approchée à \(10^{-2}\) près.
Exemple :
>>> ecart(1, 3) 1.0
-
PSI_Mat2_2015_26.
q2_a
()[source]¶ Question 2.a.
- On va d’abord écrire une fonction
geom()
qui effectue un tirage selon une loi géométrique (de paramètrep
), - Ensuite, la fonction
hasard()
est immédiate à écrire.
Note
hasard(p) / 500
est une valeur approchée de la probabilité queecart(A, B)
soit non-nul, soit que \(M(A, B)\) soit diagonalisable.- On va d’abord écrire une fonction
-
PSI_Mat2_2015_26.
geom
(p)[source]¶ Effectue un tirage selon une loi géométrique de paramètre
p
.Par définition, en utilisant
random.random()
, on effectue ce tirage avec ce code :n = 0 # Si 0 < p < 1, on est sûr que cette boucle termine (mais ça peut prendre du temps !) while random.random() > p: # L'expérience de probabilité p a échoué, on compte +1 n += 1 # On renvoie le nombre d'échec avant le succès return n
Pour plus de détails, cf. cette page Wikipédia si besoin.
Note
Cette fonction est au programme, il faut la connaître !
Voir aussi
On aurait aussi pu utiliser
numpy.random.geometric()
, qui fonctionne directement :>>> np.random.seed(0) # On enlève l'aléatoire, pour que l'exemple soit le même à chaque fois >>> p = 0.3 # Valeur arbitraire de p = 0.3 >>> a = np.random.geometric(p) >>> b = np.random.geometric(p) >>> ecart(a, b) 0.0
-
PSI_Mat2_2015_26.
hasard
(p, N=500)[source]¶ Fonction assez élémentaire : pour
N = 500
fois, on tirea
etb
grâce àgeom()
, et on compte +1 siecart()
a donnéecart(a, b) >= 1e-1
.Voir aussi
En utilisant
numpy.random.geometric()
, on peut générerN = 500
tirages en une seule ligne :>>> np.random.seed(0) # On enlève l'aléatoire, pour que l'exemple soit le même à chaque fois >>> p = 0.3 # Valeur arbitraire de p = 0.3 >>> N = 500 >>> a = np.random.geometric(p, N) >>> b = np.random.geometric(p, N) >>> # Cette sum( ecart(a[i], b[i]) >= 1e-1 ...) compte le nombre de ecart(a, b) qui sont >= 1e-1 >>> nb = sum(ecart(a[i], b[i]) >= 1e-1 for i in range(N)) >>> nb # 434 sur 500 434
-
PSI_Mat2_2015_26.
q2_b
(N=500)[source]¶ Question 2.b.
- On va d’abord créer la liste des valeurs de
p
\(= \frac{1}{100}, \dots, \frac{99}{100}\), - Puis pour chaque
p
, on calculehasard(p) / 500
grâce àhasard()
, qu’on stocke dans une liste de valeurs, - Enfin, on ouvre une fenêtre
matplotlib
et on affiche (avecmatplotlib.pyplot.plot()
) ces valeurs.
Attention
La fonction
hasard()
est, comme nom l’indique, aléatoire ! Donc chaque exécution de cette fonction sera différente, et donc chaque graphique sera différent !Cela devrait donner une figure comme ça :
- On va d’abord créer la liste des valeurs de
-
PSI_Mat2_2015_26.
q2_c
(N=500)[source]¶ Question 2.c.
On a juste à ajouter trois lignes dans la fonction précédente Q2.b, en calculant les valeurs de \(\frac{2 - 2 p + p^2}{2 - p}\) pour
p = np.linspace(1e-2, 1 - 1e-2, 400)
(par exemple, pour400
valeurs).On est très content d’observer que cette formule colle très bien aux valeurs numériques simulées en Q2.b. (et donc, ça donne une très bonne indication pour la dernière question Q3.c).
Cela devrait donner une figure comme ça :
Note
J’ai fait
N = 5000
simulations plutôt queN = 500
pour mieux voir que la formule colle aux valeurs aléatoires.
-
PSI_Mat2_2015_26.
q3
()[source]¶ Question 3.
On définit la matrice \(M'(a, b)\) suivante :
\[\begin{split}M'(a, b) := [[a+1, 1], [0, b]] = \begin{bmatrix} a + 1 & 1 \\ 0 & b \end{bmatrix}\end{split}\]
-
PSI_Mat2_2015_26.
q3_a
()[source]¶ Question 3.a.
C’est une pure question de maths, à faire sur papier.
Pour des matrices \(2 \times 2\), si elles sont diagonalisables, il suffit de vérifier qu’elles ont même polynôme caractéristique (et qu’il soit scindé à racines simples), soit mêmes traces et mêmes déterminant :
- Trace :
\[\begin{split}\mathrm{tr}(M(a, b)) &= (3a - 2b) + (-2a + 3b + 1) = a + b + 1. \\ \mathrm{tr}(M'(a, b)) &= (a + 1) + (b) = a + b + 1.\end{split}\]- Déterminant :
\[\begin{split}\mathrm{det}(M(a, b)) &= (3a - 2b) \times (-2a + 3b + 1) - (a - b) \times (-6a + 6b + 3) = b (a + 1). \\ \mathrm{det}(M'(a, b)) &= (a + 1) \times b - 0 \times 1 = b (a + 1).\end{split}\]Note
Vous pouvez vérifier le calcul de \(\mathrm{det}(M(a, b))\) vous-même, ou par exemple sur ce site (SymPyGamma.com).
- Si elles ne sont pas diagonalisables, en fait ça implique que \(a + 1 = b\), et donc en regardant la forme simplifiée de \(M(a, b)\) dans ce cas, on arrive assez vite à montrer qu’elle est semblable à \(M'(a, b)\).
-
PSI_Mat2_2015_26.
q3_b
()[source]¶ Question 3.b.
Une matrice réelle \(2 \times 2\) est diagonalisable ssi elle admet deux valeurs propres distinctes.
Donc la matrice \(M'(a, b)\) est diagonalisable ssi \(a + 1 \neq b\).
-
PSI_Mat2_2015_26.
q3_c
()[source]¶ Question 3.c.
D’après Q3.a et Q3.b, \(M(a, b)\) est diagonalisable ssi \(M'(a, b)\) l’est (elles sont semblables) ssi \(a + 1 \neq b\).
Calculons donc la probabilité que \(A + 1 \neq B\) (on rappelle que les deux variables aléatoires \(A\) et \(B\) suivent \(\mathcal{G}(p)\) une loi géométrique de paramètre \(p\)).
\[\begin{split}\mathbb{P}(A + 1 \neq B) &= \sum_{k=0}^{+\infty} \mathbb{P}(A + 1 \neq k, B = k) \\ &= \sum_{k=0}^{+\infty} \mathbb{P}(A \neq k - 1) \mathbb{P}(B = k) \;\;\text{car}\;A,B \;\text{indépendants}\\ &= \mathbb{P}(B = 0) + \sum_{k=1}^{+\infty} (1 - \mathbb{P}(A = k - 1)) ((1-p)^{k} p) \;\;\text{car}\;B \thicksim \mathcal{G}(p) \\ &= p + p \sum_{k=1}^{+\infty} (1 - ((1-p)^{k-1} p)) (1-p)^{k} \;\;\text{car}\;A \thicksim \mathcal{G}(p) \\ &= p + p \sum_{k=1}^{+\infty} (1-p)^{k} - p^2 \sum_{k=0}^{+\infty} (1-p)^{2k-1} \;\;\text{et}\;0 < (1-p) < 1 \\ &= p + p \frac{(1-p)}{1 - (1-p)} - p^2 \frac{1}{(1-p)} \frac{(1-p)^2}{1 - (1-p)^2} \\ &= p + (1-p) - \frac{p^2}{1-p} \frac{(1-p)^2}{2p-p^2} \\ &= 1 - \frac{p^2(1-p)^2}{p(2-p)(1-p)} \\ &= 1 - \frac{p(1-p)}{(2-p)} \\ &= \frac{(2-p) - p(1-p)}{2-p} \\ &= \frac{2-2p+p^2}{2-p}\end{split}\]On retrouve bien la formule donnée par l’énoncé en Q3.c. OUF !
Sortie du script¶
$ python PSI_Mat2_2015_26.py
Test automatique de toutes les doctests ecrites dans la documentation (docstring) de chaque fonction :
Trying:
print(M(1, 3))
Expecting:
[[-3 15]
[-2 8]]
ok
Trying:
ecart(1, 3)
Expecting:
1.0
ok
Trying:
np.random.seed(0) # On enlève l'aléatoire, pour que l'exemple soit le même à chaque fois
Expecting nothing
ok
Trying:
p = 0.3 # Valeur arbitraire de p = 0.3
Expecting nothing
ok
Trying:
a = np.random.geometric(p)
Expecting nothing
ok
Trying:
b = np.random.geometric(p)
Expecting nothing
ok
Trying:
ecart(a, b)
Expecting:
0.0
ok
Trying:
np.random.seed(0) # On enlève l'aléatoire, pour que l'exemple soit le même à chaque fois
Expecting nothing
ok
Trying:
p = 0.3 # Valeur arbitraire de p = 0.3
Expecting nothing
ok
Trying:
N = 500
Expecting nothing
ok
Trying:
a = np.random.geometric(p, N)
Expecting nothing
ok
Trying:
b = np.random.geometric(p, N)
Expecting nothing
ok
Trying:
nb = sum(ecart(a[i], b[i]) >= 1e-1 for i in range(N))
Expecting nothing
ok
Trying:
nb # 434 sur 500
Expecting:
434
ok
Trying:
lam12(1, 3)
Expecting:
(2.0000000000000009, 2.9999999999999991)
ok
Trying:
[round(l) for l in lam12(1, 3)]
Expecting:
[2.0, 3.0]
ok
Trying:
import numpy as np
Expecting nothing
ok
Trying:
import numpy.linalg as LA # Convention recommandée
Expecting nothing
ok
Trying:
import matplotlib.pyplot as plt
Expecting nothing
ok
Trying:
import random
Expecting nothing
ok
10 items had no tests:
__main__
__main__.q1
__main__.q2
__main__.q2_a
__main__.q2_b
__main__.q2_c
__main__.q3
__main__.q3_a
__main__.q3_b
__main__.q3_c
6 items passed all tests:
1 tests in __main__.M
1 tests in __main__.ecart
5 tests in __main__.geom
7 tests in __main__.hasard
2 tests in __main__.lam12
4 tests in __main__.q0
20 tests in 16 items.
20 passed and 0 failed.
Test passed.
Plus de details sur ces doctests peut etre trouve dans la documentation de Python:
https://docs.python.org/3/library/doctest.html (en anglais)
Le fichier Python se trouve ici : PSI_Mat2_2015_26.py
.