EBougnol, JJ Fleck,
MHeckmann & M Kostyra,
Kléber, PCSI& - I. Applications directes du cours 1/8
Intégration et tirage aléatoire
Partie I
Applications directes du cours
1 Intégration
Implémentez les fonctions
integration_rectangle(f,a,b,n)
et
integration_trapeze(f,a,b,n)
qui
intègrent la fonction
f
entre
a
et
b
sur
n
points d’échantillonnage par, respectivement, la méthode des
rectangles et celle des trapèzes. Elle doit renvoyer la valeur de cette intégrale.
1def integration_rectangle(f,a,b,n=100):
2’’’Fonction permettant d’intégrer la fonction f sur l’intervalle [a,b]
3par méthode des rectangles en découpant en n sous-intervalles.’’’
4if a== b: return 0.0 # Cas particulier permettant d’utiliser n=0
5estimation = 0.0 # L’approximation de l’intégrale
6h=(b-a)/n# La longueur des clôtures
7x=a# On se place à gauche de la clôture
8for iin range(n): # On passe par toutes les clôtures
9estimation += h*f(x) # On rajoute la contribution
10 x+= h# Et on met x à jour
11 return estimation
12
13 def integration_trapeze(f,a,b,n=100):
14 ’’’Fonction permettant d’intégrer la fonction f sur l’intervalle [a,b]
15 par méthode des trapèzes en découpant en n sous-intervalles.’’’
16 if a== b: return 0.0 # Cas particulier permettant d’utiliser n=0
17 estimation = 0.0 # L’approximation de l’intégrale
18 h=(b-a)/n# La longueur des clôtures
19 x=a# On se place à gauche de la clôture
20 for iin range(n): # On passe par toutes les clôtures
21 # On rajoute l’aire du trapèze correspondant
22 estimation += h*(f(x)+f(x+h))/2
23 x+= h# Et on met x à jour
24 return estimation
2 Recherche d’un zéro d’une fonction par dichotomie
Implémentez la fonction zero_dichotomie(f,a,b) qui cherche1un zéro de la fonction fentre aet b.
1def zero_dichotomie(f,a,b,epsilon=1e-6):
2’’’Recherche du zéro d’une fonction par dichotomie. Pour être sûr de
3marcher correctement, il ne doit y avoir qu’un seul zéro dans l’intervalle
4considéré. Néanmoins, si on a un peu de chance, il est possible que
5l’algorithme trouve au moins un zéro.’’’
6m=(a+b)/2.0
7fa,fb,fm =f(a),f(b),f(m) # On regarde f(a), f(b) et f(milieu)
1par dichotomie...
EBougnol, JJ Fleck,
MHeckmann & M Kostyra,
Kléber, PCSI& - II. Applications 2/8
8while abs(fm) >epsilon: # Tant que |f(milieu)| > epsilon choisi
9if fa*fm < 0:# Si f(a) et f(milieu) sont de signes différents
10 b=m# On bouge b vers le milieu
11 elif fb*fm < 0:# Si f(b) et f(milieu) sont de signes différents
12 a=m# On bouge a vers le milieu
13 else:# Sinon, c’est qu’il y a un problème...
14 s=’’’f(a) et f(b) sont de même signe,
15 nombre pair ou nul de zéro sur l’intervalle,
16 je préfère m’arrêter’’’
17 raise ValueError(s)
18 m=(a+b)/2.0 # On n’oublie pas de redéfinir m !
19 fa,fb,fm =f(a),f(b),f(m) # On regarde les nouveaux f(a), f(b) et f(milieu)
20 # Renvoie de la valeur de milieu en fin de boucle
21 # (c’est qu’il est assez proche de 0)
22 return m
Remarquez que si jamais vous préférez utiliser comme condition de boucle
while abs(b-a) >epsilon
,
le résultat est exactement le même, mais il est absolument nécessaire de traiter les cas où
f(a)
,
f(b)
ou
f(m)
puissent être exactement nuls (d’autant que les tests se font sur des intervalles simples et que l’on peut
tomber exactement sur la bonne valeur). Ici ce n’est pas le cas, car si on tombe sur
m
tel que
f
(
m
) = 0,
alors automatiquement la condition abs(fm) >epsilon sera fausse et on sort de la boucle while.
Partie II
Applications
1 Distribution triangulaire
1def triangle(x):
2’’’La fonction triangle a été choisie de sorte qu’elle soit déjà
3normalisée (l’intégrale de 2 à 4 vaut 1).’’’
4if x< 2:return 0
5elif x< 3:return x-2
6elif x< 4:return 1-(x-3)
7else:return 0
1import random # Pour les tirages aléatoires
2import matplotlib.pyplot as plt # Pour les graphiques
3
4def tirage_triangle(n=10000):
5’’’Tirages aléatoires à base de fonction triangulaire.’’’
6xmin,xmax,nb_points=2,4,100 # Initialisations
7# Préparation de la primitive
8F=lambda x: integration_trapeze(triangle,xmin,x,nb_points)
9evenements =[]
10 for iin range(n): # Boucle sur les évènements
11 if i%100 == 0:print(i) # On affiche du feedback car le calcul est long...
12 nb =random.random() # Tirage aléatoire
13 G=lambda x: F(x) -nb # Pour tromper la dichotomie et bien chercher un zéro
14 evenements.append(zero_dichotomie(G,xmin,xmax))
EBougnol, JJ Fleck,
MHeckmann & M Kostyra,
Kléber, PCSI& - II. Applications 3/8
15 plt.hist(evenements,bins=60,range=(0,6))
16 plt.savefig(’tirage_triangle.png’)
17 plt.clf()
18
19 import numpy as np
20 import scipy.interpolate
21
22 def tirage_triangle2(n=10000):
23 ’’’Tirages aléatoires à base de fonction triangulaire en utilisant une
24 fonction d’interpolation pour la recherche de l’antécédent.
25 ’Achement plus rapide !’’’
26 # Préparation de la fonction réciproque de la primitive
27 xmin,xmax,nb_points = 2,4,500
28 X=np.linspace(xmin,xmax,nb_points)
29 FX=[integration_trapeze(triangle,xmin,X[i],i) for iin range(nb_points)]
30 # La fonction réciproque est donnée directement par interpolation
31 antecedent =lambda x: float(scipy.interpolate.interp1d(FX,X)(x))
32 # Boucle sur les évènements
33 evenements =[]
34 for iin range(n):
35 if i%100 == 0:print(i) # On affiche du feedback car le calcul est long...
36 nb =random.random() # Tirage aléatoire
37 evenements.append(antecedent(nb))
38 plt.hist(evenements,bins=60,range=(0,6))
39 plt.savefig(’tirage_triangle2.png’)
40 plt.clf()
41
42 import time # Pour mesurer la différence de temps des deux méthodes
43 t1 =time.clock() # Début du chrono
44 tirage_triangle() # Tirage simple
45 t2 =time.clock() # Temps intermédiaire
46 tirage_triangle2()# Tirage rapide
47 t3 =time.clock() # Fin du chrono
La première fonction met un temps de 66.0 s à s’exécuter alors que la seconde ne prend que 4.5 s...
Et voici les résultats:
EBougnol, JJ Fleck,
MHeckmann & M Kostyra,
Kléber, PCSI& - II. Applications 4/8
2 Distribution gaussienne
1def moyenne_et_variance(liste):
2’’’Calcul de la moyenne <u> = Sum u / N et de la variance <(u-<u>)^2>
3d’une liste de nombres en une seule passe. Renvoie un doublet
4(moyenne,variance).’’’
5somme,somme_carres = 0.0,0.0 # Initialisation des mémoires
6for uin liste: # Itérer sur tous les éléments
7somme += u# Stocker la somme
8somme_carres += u**2 # et la somme des carrés
9N=len(liste) # Nombre d’éléments de la liste
10 moyenne =somme /N# Calcul de la moyenne: somme/N
11 # Pour le calcul de la variance: On utilise le fait que
12 # <(u-<u>)^2> = <(u^2 - 2*u*<u> + <u>^2)>
13 # = <u^2> - 2*<u>*<u> + <u>^2
14 # = <u^2> - <u>^2
15 variance =somme_carres /N-moyenne**2
16 return moyenne,variance
17
18 # Définition de la Gaussienne et normalisation
19 gauss =lambda x: np.exp(-(x-10)**2/(2*3**2))
20
21 xmin,xmax,nb_points = 0,20,500
22
23 # Attention à bien calculer la normalisation "à part" pour éviter tout
24 # recalcul lors de l’appel à gauss_normalisee(x) !
25 gnormalisation =integration_trapeze(gauss,xmin,xmax,nb_points)
26 gauss_normalisee =lambda x: gauss(x)/gnormalisation
27
28 import scipy.integrate
29
30 def tirage_gauss(n,n2=False):
31 ’’’Tirage d’une distribution de n notes suivant une gaussienne. On va
32 utiliser l’interpolation pour aller plus vite ainsi que cumtrapz pour
33 l’échantillonnage de la primitive. Pour représenter facilement un
34 sous-ensemble des notes tirées, on introduit le valeur n2 qui doit être <n
35 pour que cela fonctionne.’’’
36 # Préparation de la primitive
37 X=np.linspace(xmin,xmax,nb_points)
38 FX=scipy.integrate.cumtrapz([gauss_normalisee(x) for xin X],X,initial=0)
39 # La fonction réciproque est donnée directement par interpolation
40 antecedent =lambda x: float(scipy.interpolate.interp1d(FX,X)(x))
41 # Boucle sur les évènements
42 evenements =[]
43 for iin range(n):
44 nb =random.random() # Tirage aléatoire
45 evenements.append(antecedent(nb)) # Recherche de l’antécédent
46 print("Vérification moyenne et variance pour n={}:".format(n))
47 print(moyenne_et_variance(evenements))
EBougnol, JJ Fleck,
MHeckmann & M Kostyra,
Kléber, PCSI& - II. Applications 5/8
48 plt.hist(evenements,bins=20,range=(0,20))
49 if n2: # Si on veut regarder un sous-ensemble en plus
50 plt.hist(evenements[:n2],bins=20,range=(0,20))
51 plt.savefig(’gauss_{}.png’.format(n)) # On adapte le nom du fichier
52 plt.clf()
53
54 tirage_gauss(132,44)# Pour les tirages des classes
55 tirage_gauss(10000)# Parce qu’on n’a pas peur !
Les figures obtenues sont les suivantes
On reconnaît mieux la gaussienne avec 10000 tirages qu’avec seulement une centaine, ce que confirme
d’ailleurs le calcul de la moyenne et de la variance qui devrait normalement tendre vers le couple (10,9)
(car 32= 9)
Vérification moyenne et variance pour n=132:
(10.078461617938686, 7.63343211923916)
Vérification moyenne et variance pour n=10000:
(10.010888067713651, 8.941670809613967)
3 IMF: Initial Mass Function
Lors de la naissance d’un amas stellaire, la distribution des masses
m
des étoiles (exprimées en masses
solaires M
) suit ce que l’on appelle l’IMF (pour « Initial Mass Function ») dont les astronomes pensent
qu’elle est universelle, c’est-à-dire que quel que soit le coin de l’Univers observé, c’est cette distribution qui
semble prévaloir. Celle-ci peut se modéliser
2
de manière simple comme un raccordement par continuité de
trois lois de puissance
f(m)
mαsi m < 1 M
mβsi 1 M<m<10 M
mγsi m > 10 M
où l’on prend généralement α= 1,30,β= 2,35 et γ= 4,0.
1def imf(m):
2’’’Définition de l’IMF non normalisée. On se débrouille déjà pour avoir
3quelque-chose de continu en m=1 et m=10.’’’
4alpha,beta,gamma = 1.3,2.35,4.0
2Kroupa, P. 2002, Science, 295, 82
1 / 8 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 !