#! /usr/bin/env python3
# -*- coding: utf-8; mode: python -*-
r""" Correction d'un exercice de maths avec Python, issu des annales pour les oraux du concours Centrale-Supélec.
- *Sujet :* PSI 1, http://www.concours-centrale-supelec.fr/CentraleSupelec/MultiY/C2015/PSI-Mat2-2015-24.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).
-----------------------------------------------------------------------------
"""
from __future__ import print_function, division # Python 2 compatibility
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import quad
# %% Question 0.
[docs]def q0():
r""" Préliminaires :
- Comme pour tous ces exercices, on commence par **importer** les modules requis, ici `numpy <https://docs.scipy.org/doc/numpy/>`_ et `matplotlib <http://matplotlib.org/users/beginner.html>`_ :
>>> import numpy as np
>>> import matplotlib.pyplot as plt
- En question 4 on a besoin de :py:func:`scipy.integrate.quad`, on l'importe ici :
>>> from scipy.integrate import quad
"""
pass
# %% Question 1.
[docs]def q1():
r""" Question 1.
On nous demandait de tracer, pour :math:`n = 2 \dots 7`,
ces courbes :math:`\mathcal{C}_n = \{ (x_n(t), y_n(t)), t \in [0, 2\pi] \}`, définies par :
.. math::
x_n(t) &= 4 \cos(t) - \cos(nt) \\
y_n(t) &= 4 \sin(t) - \sin(nt)
Cela suggère d'utiliser une boucle ``for n in range(2, 7+1)`` et les fonctions généralisées :py:func:`numpy.cos` et :py:func:`numpy.sin` : ::
N = 300 # Nb points
t = np.arange(0, 2*np.pi, N) # t = 0 .. 2*pi avec 300 points
plt.hold(True) # Mettre tous les dessins sur la même figure
for n in range(2, 7 + 1): # Rappel: range(a, b) = [a, a+1, .., a+b-1] borne b non incluse !
x = 4 * np.cos(t) - np.cos(n * t)
y = 4 * np.sin(t) - np.sin(n * t)
plt.plot(x, y, label=("n = %d" % n)) # et pas (t, x) ou (t, y)
plt.legend() # Afficher la légende, décrite avec les label=... plus haut
plt.title("Cn pour n = 2..7") # On met un joli titre
plt.show() # On montre la figure !
Cela donne une figure comme celle ci-dessous :
.. image:: PSI_Mat2_2015_24__figure1.png
"""
N = 300 # Nb points
t = np.linspace(0, 2 * np.pi, N) # t = 0 .. 2*pi avec 300 points
# Attention, np.arange ne fait pas du tout pareil !
plt.figure() # Nouvelle figure
plt.hold(True) # Mettre tous les dessins sur la même figure
plt.grid(True) # Activer les quadrillages
for n in range(2, 7 + 1): # Rappel: range(a, b) = [a, a+1, .., a+b-1] borne b non incluse !
x = 4 * np.cos(t) - np.cos(n * t)
y = 4 * np.sin(t) - np.sin(n * t)
plt.plot(x, y, label=(r"$n = %d$" % n)) # et pas (t, x) ou (t, y)
plt.legend() # Afficher la légende, décrite avec les label=... plus haut
plt.title(r"$C_n$ pour $n = 2 ... 7$") # On met un joli titre
plt.savefig("PSI_Mat2_2015_24__figure1.png", dpi=180) # On la sauvegarde
plt.show() # On montre la figure !
# %% Question 2.
[docs]def q2():
r""" Question 2.
À l'aide de la figure, on observe les symétries suivantes :
- symétrie par rapport à l'axe :math:`x`, car :math:`t \mapsto 4 \sin(t)` et :math:`t \mapsto - \sin(n t)` sont symétriques par rapport à :math:`\pi`,
- pour :math:`n` impaire (vert, cyan, doré sur notre figure 1), symétrie par rapport à l'axe :math:`y`, car :math:`t \mapsto 4 \cos(t)` et :math:`t \mapsto - \cos(n t)` sont symétriques par rapport à :math:`\pi` si :math:`n` est impaire (mais :math:`t \mapsto - \cos(n t)` ne l'est pas si :math:`n` est pair).
"""
pass
# %% Question 3.
[docs]def q3():
r""" Question 3.
À l'aide de la figure, on observe que seule la courbe rouge (:math:`n = 4`) admet des points non-réguliers, et qu'elle en a trois, correspondant à :math:`t = 0, 2\pi/3, 4\pi/3`.
Il faudrait aussi prouver la même chose, faites le sur papier (c'est un bon exercice).
Si besoin, cf. `le chapitre 24.3.3 de ce cours de MPSI (§24.3.3 p692) <http://mp.cpgedupuydelome.fr/pdf/monCoursSpe2003.pdf#page=692>`_.
Les deux fonctions :math:`t \mapsto x_n(t)` et :math:`t \mapsto y_n(t)` sont de classes :math:`\mathcal{C}^{\infty}`, mais pour étudier les points non-réguliers (aussi appelés singuliers), il faut trouver les points où le vecteur vitesse :math:`v(t) = [x_n'(t), y_n'(t)]` s'annule.
On calcule d'abord le vecteur vitesse :
.. math::
v(t) = [x_n'(t), y_n'(t)] = [ -4 \sin(t) + n \sin(nt), +4 \cos(t) - n \cos(nt)].
On cherche à avoir :math:`n'(t) = 0`, soit :math:`4 \sin(t) = n \sin(n t)` et :math:`4 \cos(t) = n \cos(n t)`.
En prenant la somme des carrés des deux côtés, on obtient d'abord que :math:`n'(t) = 0 \implies 4^2 = n^2 \implies n = 4` :
c'est déjà pas mal, on vient de prouver que seule la courbe :math:`n = 4` peut avoir des points non-réguliers.
Désormais, pour :math:`n = 4`, :math:`n'(t) = 0` *ssi* :math:`\sin(t) = \sin(4 t)` et :math:`\cos(t) = \cos(4 t)`.
On remarque déjà que les trois points observés, :math:`t = 0, 2\pi/3, 4\pi/3`, fonctionnent, mais on doit montrer que ce sont les seuls.
Si :math:`\sin(t) = \sin(4 t)` et :math:`\cos(t) = \cos(4 t)`, alors en utilisant l'identité d'Euler, cela implique que :math:`\mathrm{e}^{it} = \mathrm{e}^{4it}` qui implique que :math:`\mathrm{e}^{3it} = 1`, et donc :math:`3t = 0 \;\mathrm{mod}\; 2\pi`, or :math:`t \in [0, 2\pi]`, donc cela implique que :math:`t \in \{0, 2\pi/3, 4\pi/3\}`.
Et voilà.
"""
pass
# %% Question 4.
[docs]def l(n):
r""" Calcule la longueur :math:`l_n` de façon approchée via la fonction :py:func:`scipy.integrate.quad` (``quad(f, a, b)``),
appliquée à :py:func:`dOM_sur_dt` définie **dans le corps de la fontion** ``def l(n): ...``.
En effet, :py:func:`dOM_sur_dt` **doit** dépendre de ``n``, mais :py:func:`scipy.integrate.quad` a besoin d'une fonction qui n'accepte qu'un seul paramètre : si ``f`` est :math:`t \mapsto f(t)`, alors ``quad(f, a, b)`` :math:`\simeq \int_{a}^{b} f(t) \; \mathrm{d}t`.
.. note::
En fait, :py:func:`scipy.integrate.quad` accepte une fonction du genre :math:`g : (t, n) \mapsto g(t, n)` si on l'appelle comme ``quad(g, 0, 1, args=(8))`` (qui sera une approximation de :math:`\int_{a = 0}^{b = 1} g(t, n = 8) \; \mathrm{d}t)`.
"""
def dOM_sur_dt(t):
""" Fonction exacte pour calculer || d OM / dt || = sqrt(x'(t) + y'(t))."""
return np.sqrt((- 4 * np.sin(t) + n * np.sin(n * t))**2 + (4 * np.cos(t) - n * np.cos(n * t))**2)
# Maintenant on l'utilise avec scipy.integrate.quad
return quad(dOM_sur_dt, 0, 2 * np.pi)[0]
[docs]def q4():
r""" Question 4.
Il faut se souvenir de la formule donnant la longueur d'un arc paramétré.
Encore une fois, si besoin, cf. `le chapitre 24.1 de ce cours de MPSI (§24.1 p680) <http://mp.cpgedupuydelome.fr/pdf/monCoursSpe2003.pdf#page=680>`_.
La formule a connaître est :
.. math::
l_n = \int_{t = 0}^{t = 2\pi} \left\| \frac{\overrightarrow{OM}(t)}{\mathrm{d} t} \right\|_2 \mathrm{d} t.
1. On définit une fonction `dOM_sur_dt(t)` qui calcule :math:`\left\| \frac{\overrightarrow{OM}(t)}{\mathrm{d} t} \right\|_2 = \sqrt{x_n'(t)^2 + y_n'(t)^2}` (note : c'est une fonction *exacte*),
2. On utilise ensuite la fonction :py:func:`scipy.integrate.quad` pour calculer l'intégrale de façon *numérique*,
3. On met tout ça dans une fonction :math:`l(n)` qui donnera la longueur de la courbe en fonction de n,
4. On calcule la liste des valeurs de :math:`l(n)` par une liste en compréhension, avec :math:`n = 1 .. 20`,
5. On affiche ces valeurs (avec :py:func:`matplotlib.pyplot.plot`).
Cela donne une figure comme celle ci-dessous :
.. image:: PSI_Mat2_2015_24__figure2.png
"""
# Valeurs M_n = (n, l_n) demandées
valeurs_n = [n for n in range(1, 20 + 1)]
valeurs_M = [l(n) for n in range(1, 20 + 1)]
# print("valeurs_M =", valeurs_M)
asymptote = [2 * np.pi * n for n in range(1, 20 + 1)]
# print("asymptote =", asymptote)
# On crée la figure
plt.figure()
plt.grid(True)
plt.hold(True)
plt.title(r"$M_n = (n, l_n)$ pour $n = 1 ... 20$") # On met un joli titre
plt.plot(valeurs_n, valeurs_M, 'r*-', label=r'$n \mapsto l_n$', lw=2, ms=5) # Trait rouge, continu avec des *
plt.plot(valeurs_n, asymptote, 'b:', label=r'Asymptote : $n \mapsto 2 \pi n$', lw=2) # Trait bleu, discontinu avec des - - -
plt.legend(loc='upper left') # On affiche la légende
plt.savefig("PSI_Mat2_2015_24__figure2.png", dpi=180) # On la sauvegarde
plt.show()
return valeurs_n, valeurs_M
# %% Question 5.
[docs]def q5():
r""" Question 5.
On s'inspire de la figure précédente pour deviner une forme que peut avoir :math:`l_n` pour :math:`n \to +\infty`.
Son comportement semble parfaitement linéaire...
En lisant la figure précédente, on trouve :math:`l_n \simeq 2 \pi \times n`.
On calcule :
.. math::
&\left\| \frac{\overrightarrow{OM}(t)}{\mathrm{d} t} \right\|_2 \\
&= \sqrt{x_n'(t)^2 + y_n'(t)^2} \\
&= \sqrt{(- 4 \sin(t) + n \sin(n t))^2 + (4 \cos(t) - n \cos(n t))^2}
Donc pour :math:`n \to +\infty`,
:math:`- 4 \sin(t) + n \sin(n t) = \mathcal{O}(n \sin(n t))`,
:math:`4 \cos(t) - n \cos(n t) = \mathcal{O}(- n \cos(n t))`,
puisque :math:`- 4 \sin(t), 4 \cos(t) \in [-4, 4]` sont bornés.
Donc pour :math:`n \to +\infty` :
.. math::
\sqrt{((- 4 \sin(t) + n \sin(n t))^2 + (4 \cos(t) - n \cos(n t))^2} \\
\simeq \sqrt{n^2 \sin^2(n t) + n^2 \cos^2(n t)} \\
= n \sqrt{\sin^2(n t) + \cos^2(n t)} \\
= n.
Ainsi, :math:`\int_{0}^{2\pi} \lim_{n\to\infty} \left\| \frac{\overrightarrow{OM}(t)}{\mathrm{d} t} \right\|_2 \mathrm{d}t = \int_{0}^{2\pi} n \mathrm{d}t = 2 \pi n`.
Reste à justifier comment on peut inverser l'intégrale et la limite.
On se souvient du théorème de convergence dominée, et sur papier on ferait proprement un calcul justifiant qu'on a une borne uniforme qui convient (comme :math:`|4 \cos(t) - n \cos(nt)| \leq 4 + n` et :math:`|- 4 \sin(t) + n \sin(nt)| \leq 4 + n` c'est assez rapide).
**Conclusion :** :math:`l_n \simeq_{n \to \infty} 2 \pi n`.
.. note::
Au tableau et sur papier, vous devriez justifier mieux, surtout les :math:`\simeq` et :math:`\mathcal{O}`. (J'ai juste la flemme.)
"""
pass
# %% Fin de la correction.
if __name__ == '__main__':
from doctest import testmod
print("Test automatique de toutes les doctests ecrites dans la documentation (docstring) de chaque fonction :")
testmod(verbose=True)
# testmod()
print("\nPlus de details sur ces doctests peut etre trouve dans la documentation de Python:\nhttps://docs.python.org/3/library/doctest.html (en anglais)")
# Fin de PSI_mat2_2015_24.py