TP sur les calculs numériques - Mathématiques en PCSI 834 à

Gaudino, casier 5 version 3.2
Lycée Masséna TP Méthodes numériques P.C.S.I.834
On rappelle que l’affichage d’un graphe se fait essentiellement avec la commande plot sous la forme :
plot(listes des abscisses, listes des ordonnées)
Plus précisément : pour tracer le graphe de sinus entre 0 et 10
from math import * #on charge le module math
import numpy as np #et tous les modules pour l'affichage
import matplotlib as mp #et oui
import matplotlib.pyplot as plt #tout ça
x = np.linspace(0.,10.) #fabrication automatique des abscisses entre 0 et 10
y = [sin(t) for t in x] #les ordonnées du graphe, par compréhension par exemple
plt.plot(x,y,'r-') #le graphe, avec les options : rouge (r) et trait plein (-)
#on aura besoin aujourd'hui de mettre o à la place de - : affichage de gros points
plt.axhline(color='k') #l'axe x. k pour black...
plt.axvline(color='k') #l'axe y. k pour black...
plt.show() #le show affiche le tout (sans cela, rien n'est affiché)
#comment, c'est déjà fini ?
La commande pour effacer un graphe est (avec les conventions d’alias employées) plt.clf().
I. Résumé sur l’utilisation des fonctions numériques de Python
import numpy # Ces deux là amènent aussi un certain
import scipy # nombre de fonctions mathématiques.
import scipy.integrate # Intégration de fonctions, résolution d'équations différentielles.
import scipy.optimize # Zéros des fonctions.
import matplotlib.pyplot # Pour la génération de graphiques.
import random # Pour faire des probabilités
II. Mesurer un temps d’éxécution
Pour mesurer un temps d’éxécution, on chargera également le module time. L’instruction time.clock() renvoie à
peu près le temps CPU (en secondes). Ce qui nous intéresse est l’écart entre deux temps, on tapera donc :
import time
t0 = time.clock()
#instructions à chronométrer
duree = time.clock() - t0
III. Suite récurrente double
1. Programmer le calcul du terme nde la suite récurrente double donnée par :
u0=u1= 1 et nN, un+2 =un+1 +un
On pourra remarquer que ces termes sont des entiers. Comparer avec la formule trouvée en appliquant les
formules vues en cours pour les valeurs jusqu’à n= 100.
2. Programmer le calcul du terme nde la suite récurrente double donnée par :
u0= 1, u1= 1 2 et nN, un+2 = 2un+1 +un
Comparer avec la formule trouvée en appliquant les formules vues en cours pour les valeurs jusqu’à n= 100.
On doit trouver une grosse différence de comportement. L’expliquer en réfléchissant aux valeurs numériques des
constantes à déterminer dans ces calculs.
1
IV. Dérivée numérique
Il est fréquent de ne pas pouvoir calculer directement f0(x), mais de la remplacer par une valeur approchée, comme
f(x+h)f(x)
h,f(x)f(xh)
h,f(x+h)f(xh)
2h.
1. `
A l’aide de Python, comparer les valeurs des trois méthodes, pour f:x7→ x3en x= 1, pour h= 10k, avec k
de 1 à 20.
2. On doit constater deux phénomènes :
(a) Les dernières valeurs sont fantaisistes. Comprendre pourquoi.
(b) La précision semble s’accroître, puis décroître contre toute attente, avec un optimum vers 108. Votre prof
de TD vous l’expliquera.
V. Résolution de f(x) = 0
On considère la fonction f:[0,4] R
x7−cos(x/3) 1/2.fsemble strictement décroissante, et admettre un unique
zéro : π.
V.1. Méthode de Dichotomie
1. Retrouver les formules des points anet bn. Ici, a= 0 et b= 4.
2. Programmer la méthode de dichotomie. Les arguments seront f,a,b, et la précision attendue. La sortie sera un
tuple qui donne la valeur approchée par défaut et le nombre d’étape.
3. Calculer une valeur approchée à 105près. Contrôler le temps d’execution, et le nombre d’étapes données (19
normalement).
4. Comparer la rapidité d’exécution avec celle de la fonction scipy.optimize.bisect. Attention à bien chronomé-
trer les calculs, et pas aussi leurs affichages ! Penser à la précision de cette fonction. On doit constater un ordre
de grandeur semblable.
5. Modifier la méthode de manière à faire afficher sur un même graphe la fonction et les points.
V.2. Méthode de Newton
1. Retrouver la formule de récurrence un+1 =g(un). Exprimer en particulier gen fonction de fet f0.
2. Programmer la méthode de Newton. Les arguments seront f, sa dérivée calculée à la main, b, et la précision
attendue (au sens de l’écart entre deux valeurs consécutives). La sortie sera un tuple qui donne la valeur approchée
et le nombre d’étape.
3. Calculer une valeur approchée à 105près à partir de 4. Contrôler le temps d’exécution, et le nombre d’étapes
données (le temps d’exécution est similaire, mais regardez la précision !).
4. Tenter de calculer une valeur approchée à partir de 0,5. Cela illustre le manque d’étude mathématique de la
méthode.
5. Comparer la rapidité d’exécution avec celle de la fonction scipy.optimize.newton. La méthode de Newton de
Python nécessite de lui fournir la dérivée (sinon, Python applique la méthode des sécantes : lire l’aide qu’affiche
Spyder !).
6. Modifier la méthode de manière à faire afficher sur un même graphe la fonction et les points. On doit très bien
voir la rapidité de convergence.
7. Pour ceux qui sont en avance : programmer la méthode des sécantes.
VI. Résolution d’équations différentielles
VI.1. Méthode d’Euler
1. Programmer la méthode d’Euler (par exemple l’affichage du graphe) pour le problème :
y0=yet y(0) = 1
2. Afficher sur un même graphe ce résultat et la fonction exp.
2
VI.2. Limites de la méthode
1. Programmer la méthode d’Euler pour le problème :
y0= 1 + y2et y(0) = 0
Prendre un pas assez modeste (genre 0.1) et un nombre de points faible (genre 20) pour éviter un dépassement
de capacité.
2. Afficher sur un même graphe ce résultat et la fonction tan. On programmera au-delà de π
2, pour bien voir le
problème.
VI.3. Comparaison avec les techniques intégrées de Python
Le module scipy.integrate permet directement de réaliser de tels calculs, sans précision sur la méthode employée
(l’intérêt intellectuel de ce paragraphe est donc < ε, et ce pour tout ε > 0, mais c’est au programme).
odeint s’utilise de la manière suivante : elle prend trois arguments au moins sous la forme
4 = scipy.integrate.odeint(1,2,3)
où les chiffres signifient :
1 est la fonction du second membre, qui dépend des deux paramètres yet tdans cet ordre (et ce même si t
n’apparait pas). Utiliser la notation lambda est pratique. Quelques exemples :
(a) y0=y2: 1 est lambda y,t : y**2
(b) y0(t)=2ty(t) + 1 : 1 est lambda y,t : 2*t*y +1
(c) ty0(t)ln(t)y(t) = cos(t) : 1 est lambda y,t : cos(t)/t + log(t)*y/t
2 est l’ordonnée initiale du problème de Cauchy (y0seulement : on parle d’une équation de degré 1).
3 est la liste des abscisses des points en lesquels on approxime. Le mieux est de l’obtenir avec un linspace du
module numpy (qui servira aussi pour le graphe). L’abscisse initiale t0(0 pour nous) est sa première valeur.
4 (la sortie) est la liste des ordonnées des points (prêts pour un graphe donc, si on le mixe avec la liste des abscisses).
Résoudre les deux exemples de problèmes de Cauchy de degré 1 avec la fonction odeint, partie du module scipy.integrate.
Afficher le graphe de la solution.
VI.4. Cas d’une équation de degré 2
1. Programmer la méthode d’Euler pour le problème : y00 + 4y= 0 et y(0) = 1 et y0(0) = 0. Il est
volontairement un peu différent de celui vu en cours. Il vaut mieux refaire à la main les calculs de vectorialisation
(l’apparition de la matrice).
2. Afficher sur un même graphe ce résultat et la fonction solution (à calculer à la main).
3. Faire de même avec le problème : y00 + 5y0+ 4y= 0 et y(0) = 2 et y0(0) = 5.
VI.5. Système proies-prédateurs
On considère le système différentiel non linéaire du premier ordre suivant :
x0(t) = ax(t)bx(t)y(t)
y0(t) = cx(t)y(t)dy(t)
Ce système modélise l’évolution d’une population de proies et de prédateurs qui interagissent. Dans ce système
x(t) est l’effectif des proies au temps t,
y(t) est l’effectif des prédateurs au temps t,
aest le taux de reproduction des proies en l’absence de prédateurs,
best le taux de mortalité des proies due aux prédateurs,
cest le taux de reproduction des prédateurs en fonction des proies mangées,
dest le taux de mortalité des prédateurs en l’absence de proies.
Par exemple, cela permet d’étudier la co-évolution d’une population de renards et lapins, ou de requins et sardines 1.
1. ´
Ecrire une fonction Python simul(x0,y0,tmax,n,a,b,c,d): qui calcule par la méthode d’Euler une approxi-
mation sur [0, tmax] de la solution de ce système vérifiant la condition initiale (x(0), y(0)) = (x0, y0). Plus
précisément :
1. Historiquement, il s’agissait de poissons dans le port (ou la lagune) de Venise.
3
x0 et y0 sont les populations initiales au temps t= 0 respectivement des proies et des prédateurs,
tmax est le temps sur lequel on fait l’approximation (et donc tmax =nh),
nest le nombre de points calculés dans la méthode d’Euler,
a,b,c,d sont les paramètres du système.
La fonction simul renverra un triplet formé de la liste des tk, de la liste des approximations xkde x(tk) et de la
liste des approximations ykde y(tk), pour 0 kn.
2. Tracer la courbe représentant l’évolution des proies, ainsi que celle des prédateurs. On prendra les valeurs
numériques : a= 0.6 ; b= 0.8 ; c= 0.3 ; d= 0.6 ; x0= 5 et y0= 1 sur 50 ans avec 5000 points.
3. Tracer la courbe reliant les points (xk, yk), pour 0 kn. Cette courbe représente l’évolution des populations
sur un même graphe (mais on n’y a plus le temps). La bonne manière de la comprendre est de visualiser une
animation : la courbe se dessine au fur et à mesure de l’écoulement des années.
On doit constater qu’elle boucle (à peu près) : le système est globalement stable.
4. Essayer de comprendre intuitivement pourquoi le système est stable. Il faudra réfléchir aux effets de l’augmen-
tation (ou de la diminution) des valeurs de x(t) et y(t).
5. ´
Etudions quelques évolutions numériques, pour comprendre l’écologie de la situation.
(a) Les autres paramètres étant fixes, augmenter progressivement b. Le résultat est-il conforme à l’intuition
(normalement, oui) ? On devrait remarquer quelque-chose vers b= 2,8.
(b) Les autres paramètres étant fixes, augmenter progressivement le nombre initial de prédateurs. Le résultat
est-il conforme à l’intuition (normalement, oui) ?
(c) On effectue un prélèvement (une chasse ou une pêche) des deux espèces, indistinctement sur les proies et
sur les prédateurs. Mathématiquement, cela revient à retrancher εx(t) à la première équation, et εy(t) à la
deuxième équation, et donc à modifier légèrement certaines valeurs de a,b. . . Afficher sur un même graphe,
avec deux couleurs différentes, la courbe avec et sans prélèvement.
Constater 2que cette action fait augmenter le nombre de proies et diminuer les prédateurs (essayer avec
des εdu genre 0,1).
VII. Calcul approché d’intégrales
VII.1. `
A la main (au cerveau, devrait-on dire)
Le but de la séquence est de faire une concurrence déloyale à Bouvart et Ratinet : nous allons dresser une (toute
petite) table de logarithmes 3. On veut donc intégrer la fonction x7→ 1
xde 1 à une autre valeur. Prenons par exemple
la valeur 2, pour calculer ln(2).
On fera cette série de questions pour les trois méthodes : rectangles à gauche, trapèzes, Simpson.
kJ0, n 1Kak=a+kba
n
Rn(f) = ba
n
n1
X
k=0
f(ak)
Tn(f) = ba
n
n1
X
k=0
f(ak) + f(ak+1)
2
σn(f) = ba
6n
n1
X
k=0 4fak+ak+1
2+f(ak) + f(ak+1)
1. Programmer le calcul approché de Z2
1
dt
t. Le seul argument sera le nombre d’étape n. Les calculs que nous
faisons aujourd’hui étant très limités, on ne demande pas d’optimiser le code (sauf à la dernière question).
2. Comparer la précision avec celle attendue : calculer à la main (ou avec Python) le nnécessaire pour avoir 3
décimales justes (utiliser les estimations d’erreurs vues en cours), et vérifier avec la valeur de ln(2) que connait
Python.
3. Comparer les ndes diverses méthodes.
2. Ce n’est pas une preuve, évidemment. La vrai preuve est (bizarement) très simple.
3. Sauf que la méthode choisie est vraiment élémentaire. Heureusement que les auteurs avaient des techniques beaucoup plus intelligentes
(les calculs étaient faits à la main !).
4
4. Optimiser le code pour la méthode des trapèzes : on essaiera de limiter au maximum le nombre de calcul, au
détriment au besoin de la complexité en mémoire. En particulier, on commencera par stocker dans une liste les
valeurs de la fonction que nous utiliserons effectivement (les 1
xen les points de la subdivision). Comparer les
temps d’éxécution (on doit trouver un facteur 2).
VII.2. Comparaison avec les techniques intégrées de Python
La méthode d’intégration de scipy où Python utilise une boite noire répugnante la méthode qu’il préfère est
scipy.integrate.quad (il faut se plonger dans l’aide pour savoir ce qu’il fait réellement). Elle renvoie un nombre
complexe (dont la partie imaginaire doit être dans ce cas très petite donc).
La méthode des trapèzes est obtenue dans Python grâce à l’extension scipy, plus précisément grâce à scipy.integrate.trapz.
Celle de Simpson est obtenue par scipy.integrate.simps (étonnant, non ?).
Cela s’utilise ainsi : scipy.integrate.trapz(y,x) xest la liste des abscisses (données par un linspace par
exemple) et yest la liste des ordonnées correspondantes.
Comparons donc les performances de notre méthode des trapèzes optimisée (avec n= 100 pour avoir un compte rond),
et celle de scipy : si les programmeurs Python ont dépassé le stade Bac+1, ils devraient faire mieux que nous :
1. Programmer la liste des abcisses avec 100 points ;
2. programmer la liste des ordonnées correspondantes ;
3. et faire calculer l’intégrale par ces deux manières, en mesurant le temps d’éxécution.
VII.3. Méthodes de Monte-Carlo
Une méthode de calcul approché basée sur les probabilités : on importera le module random de Python. On utilisera
la fonction random() qui donne un nombre réel compris entre 0 et 1, en suivant une loi uniforme.
On se donne une fonction f: [a, b]R. On se donne npoints (x1, ..., xn) choisis de manière aléatoire dans [a, b]
(en suivant une loi uniforme). Alors ba
n
n
X
i=1
f(xi) est une approximation de Zb
a
f, avec un intervalle de confiance (à
95%) de largeur α/n.
1. Écrire une fonction qui prend en argument f,a,b,net rend l’approximation de l’intégrale par la méthode de
Monte-Carlo en npoints. Tester sur différentes fonctions et plusieurs valeurs de n.
2. Adapter la méthode pour obtenir une approximation de π. On considère pour cela le carré C= [0,1] ×[0,1] qui
contient le quart de disque D centré en 0 et de rayon 1. On choisit de manière aléatoire un point dans C et on
teste son appartenance à D. Si on note Nle nombre total de points et NDle nombre de points dans le quart
de disque, le rapport ND/N donne une approximation de π/4 avec un intervalle de confiance à 95% de largeur
α/n.
Programmer la méthode. Tester la qualité de l’approximation.
5
1 / 5 100%
La catégorie de ce document est-elle correcte?
Merci pour votre participation!

Faire une suggestion

Avez-vous trouvé des erreurs dans linterface ou les textes ? Ou savez-vous comment améliorer linterface utilisateur de StudyLib ? Nhésitez pas à envoyer vos suggestions. Cest très important pour nous !