Académique Documents
Professionnel Documents
Culture Documents
introduction à C++ et
résolution de problèmes de physique par ordinateur
Corrigé 5
Université de Genève
Section de Physique
Références :
http://dpnc.unige.ch/~bravar/C++2015/L5 :
pour les notes du cours, les exercices et les corrigés
5.1 Problèmes d’intégration numérique
1. Intégrale d’un fonction quelconque
On cherche ici à intégrer une fonction. On utilise une fonction C++ pour définir la fonction
à intégrer. On a choisi un polynôme du second degré avec les coefficients fixés. Les bornes
de l’intervalle d’intégration, ainsi que le nombre de divisions de l’intervalle sont entrés par
l’utilisateur. On utilise la méthode du trapèze et la méthode de Simpson pour l’intégration.
Integrale.cpp
1 #include <i o s t r e a m >
2 #include <cmath>
3
4 using namespace s t d ;
5
6 // d e c l a r a t i o n de l a f o n c t i o n a i n t e g r e r
7 double f o n c ( double ) ;
8
9 int main ( ) {
10 // s a i s i d e s p a r a m e t r e s
11 double min , max ;
12 c o u t << ” En trez un i n t e r v a l d ’ i n t e g r a t i o n : ” << e n d l ;
13 c o u t << ”min = ” ; c i n >> min ;
14 c o u t << ”max = ” ; c i n >> max ;
15 int d i v ;
16 c o u t << ” En trez un nombre de suos−d i v i s i o n s : ” << e n d l ;
17 c o u t << ”N = ” ; c i n >> d i v ;
18 double d e l t a x = (max−min ) / d i v ;
19
20 double i n t T r a p e z e = 0 . ;
21 double i n t S i m p s o n = 0 . ;
22 f o r ( int i =0; i<=d i v ; i ++) {
23 // methode du t r a p e z e
24 i n t T r a p e z e += ( f o n c ( min+i ∗ d e l t a x ) +
25 f o n c ( min+( i +1)∗ d e l t a x ) ) ;
26 // methode de Simpson
27 i n t S i m p s o n += ( f o n c ( min+d e l t a x ∗ i ) +
28 4 . ∗ f o n c ( min+( i +0.5) ∗ d e l t a x ) +
29 f o n c ( min+( i +1)∗ d e l t a x ) ) ;
30 }
31 i n t T r a p e z e ∗= d e l t a x / 2 . ;
32 i n t S i m p s o n ∗= d e l t a x / 6 . ;
33 c o u t << ” I n t e g r a l e avec l a methode du t r a p e z e : ” << i n t T r a p e z e << e n d l ;
34 c o u t << ” I n t e g r a l e avec l a methode de Simpson : ” << i n t S i m p s o n << e n d l ;
35
36 return 0 ;
37 }
38
39 // d e f i n i t i o n de l a f o n c t i o n a i n t e g r e r
40 double f o n c ( double x ) {
41 // dans c e t example nous avons c h o i s i un polynome de 2eme d e g r e e ;
42 double a , b , c ;
43 a = 10.;
44 b = −3.;
45 c = 7.;
46
47 double y = a ∗ ( x∗x ) + b∗x + c ;
48
49 return y ;
50 }
2
2. Intégrale des fonctions sinus et cosinus sur l’intervalle [0 − π]
Le programme ci-dessous calcule l’intégrale des fonctions sin(x) et cos(x) à l’aide des
méthodes du trapèze et de Simpson respectivement.
Les bornes de l’intervalle d’intégration sont fixées [0 − π], mais le nombre de division de
l’intervalle est rentré par l’utilisateur.
IntSinus.cpp
1 #include <i o s t r e a m >
2 #include <cmath>
3
4 using namespace s t d ;
5
6 int main ( ) {
7 c o u t << ” I n t e g r a t i o n de s i n ( x ) e t c o s ( x ) s u r [0− Pi ] ” << e n d l ;
8
9 const int N = 1 0 0 0 0 0 ;
10 double d e l t a x = M PI/N;
11
12 // i n t e g r a l du s i n u s e t du c o s i n u s a v e c l a methode du r e c t a n g l e ( a gauche )
13 double i n t S i n R = 0 . , intCosR = 0 . ;
14 f o r ( int i =0; i <N; i ++) {
15 i n t S i n R += s i n ( d e l t a x ∗ i ) ;
16 intCosR += c o s ( d e l t a x ∗ i ) ;
17 }
18 i n t S i n R ∗= d e l t a x ;
19 intCosR ∗= d e l t a x ;
20 c o u t << ” I n t e g r a l e de s i n ( x ) avec l a methode du r e c t a n g l e : ”
21 << i n t S i n R << e n d l ;
22 c o u t << ” I n t e g r a l e de c o s ( x ) avec l a methode du r e c t a n g l e : ”
23 << intCosR << e n d l ;
24
25 // i n t e g r a l du s i n u s e t du c o s i n u s a v e c l a methode du t r a p e z e
26 double i n t S i n T = 0 . , intCosT = 0 . ;
27 f o r ( int i =0; i<=N; i ++) {
28 i n t S i n T += s i n ( d e l t a x ∗ i ) + s i n ( d e l t a x ∗ ( i +1) ) ;
29 intCosT += c o s ( d e l t a x ∗ i ) + c o s ( d e l t a x ∗ ( i +1) ) ;
30 }
31 i n t S i n T ∗= d e l t a x / 2 . ;
32 intCosT ∗= d e l t a x / 2 . ;
33 c o u t << ” I n t e g r a l e de s i n ( x ) avec l a methode du t r a p e z e : ”
34 << i n t S i n T << e n d l ;
35 c o u t << ” I n t e g r a l e de c o s ( x ) avec l a methode du t r a p e z e : ”
36 << intCosT << e n d l ;
37
38 // i n t e g r a l du s i n u s e t du c o s i n u s a v e c l a methode de Simpson
39 double i n t S i n S =0. , i n t C o s S = 0 . ;
40 f o r ( int i =0; i<=N; i ++) {
41 i n t S i n S += s i n ( d e l t a x ∗ i ) + 4∗ s i n ( d e l t a x ∗ ( i +0.5) ) + s i n ( d e l t a x ∗ ( i +1) ) ;
42 i n t C o s S += c o s ( d e l t a x ∗ i ) + 4∗ c o s ( d e l t a x ∗ ( i +0.5) ) + c o s ( d e l t a x ∗ ( i +1) ) ;
43 }
44 i n t S i n S ∗= d e l t a x / 6 . ;
45 i n t C o s S ∗= d e l t a x / 6 . ;
46 c o u t << ” I n t e g r a l e de s i n ( x ) avec l a methode de Simpson : ”
47 << i n t S i n S << e n d l ;
48 c o u t << ” I n t e g r a l e de c o s ( x ) avec l a methode de Simpson : ”
49 << i n t C o s S << e n d l ;
50
51 return 0 ;
52 }
3
Pour un même nombre des divisions, l’on peut constater que les valeurs obtenues avec
la méthode de Simpson sont plus proches des valeurs exactes des intégrales (i.e. 2 pour
l’intégrale du sinus et 0 pour l’intégrale du cosinus). En outre, plus N augmente, plus on
se rapproche des valeurs exactes (on augmente la précision du calcul).
4
Maintenant nous avons besoin d’une expression numérique pour la dérivée seconde f 00 (x0 ).
On approxime la fonction f (x) en x0 − ∆x
2
et x0 + ∆x
2
avec l’expansion en série de Taylor :
2 3
∆x ∆x 1 00 ∆x 1 ∆x
f (x0 − ) = f (x0 ) − f 0 (x0 ) + f (x0 ) − f 000 (x0 ) + ... (8)
2 2 2 2 6 2
2 3
∆x ∆x 1 00 ∆x 1 ∆x
f (x0 + ) = f (x0 ) + f 0 (x0 ) + f (x0 ) + f 000 (x0 ) + ... (9)
2 2 2 2 6 2
Après substitution de f 00 (x0 ) dans l’intgrale précédente avec l’expression donnée ci-dessus,
on arrive à (∆x3 × O(∆x2 ) = O(∆x5 ) :
x0 + ∆x
1 f (x0 − ∆x ) − 2f (x0 ) + f (x0 + ∆x ) 3
Z
2 2∆x
2
f (x)dx = f (x0 )∆x + 2
2
+ O(∆x5 )
x0 − ∆x
2
6 ∆x /4 8
1 ∆x ∆x
= f (x0 )∆x + f (x0 − ) − 2f (x0 ) + f (x0 + ) ∆x + O(∆x5 )
6 2 2
1 ∆x ∆x
= f (x0 − ) + 4f (x0 ) + f (x0 + ) ∆x + O(∆x5 ) (11)
6 2 2
En conclusion, ignorant les termes d’ordre supérieurs à ∆x4 , l’intégrale de f (x) sur l’in-
tervalle x0 − 2 , x0 + ∆x
∆x
2
est donnée par
Z x0 + ∆x
2 1 ∆x ∆x
f (x)dx = f (x0 − ) + 4f (x0 ) + f (x0 + ) ∆x (12)
x0 − ∆x
2
6 2 2
avec ∆x = (b−a)
N
, où N est le nombre de divisions de l’intervalle [a, b] et xi = a+ ∆x
2
+i×∆x.
A noter les coefficients de f : le point au milieu pèse 4 fois plus que les points aux
extrémités.
4. Volume de rotation Rb
Comme pour une aire, dans le cas d’un volume de révolution, nous avons V = a dV où
dV = πf 2 (x)dx est le volume élémentaire (c. à d. un cylindre de rayon f (x) et d’épaisseur
dx) lors de la rotation autour de l’axe des x de la surface limitée par l’axe x, la courbe
y = f (x) et les droites x = a et x = b. Soit :
Z b
V = πf 2 (x)dx (14)
a
5
1 // volume de r o t a t a t i o n
2 #include <i o s t r e a m >
3 #include <cmath>
4 #include <iomanip>
5
6 using namespace s t d ;
7
8 // p r o t o t y p e de l a f o n c t i o n
9 double f o n c ( double x ) ;
10
11 int main ( ) {
12 // d e f i n i t i o n de l ’ i n t e r v a l l e d ’ i n t g r a t i o n
13 double xmin , xmax ;
14 xmin = 0 . 0 ;
15 xmax = 1 . 0 ;
16
17 int d i v ;
18 c o u t << ” En trez l e nombre de d i v i s i o n s : ” ;
19 c i n >> d i v ;
20 double d e l t a x = ( xmax−xmin ) / d i v ;
21
22 double i n t T r a p e z e = 0 . ;
23 double i n t R e c t a n g l e = 0 . ;
24 f o r ( int i =0; i <d i v ; i ++) {
25 i n t R e c t a n g l e += f o n c ( xmin + i ∗ d e l t a x + d e l t a x / 2 . ) ∗ d e l t a x ;
26 i n t T r a p e z e += ( f o n c ( xmin+d e l t a x ∗ i ) + f o n c ( xmin+d e l t a x+d e l t a x ∗ i ) ) ∗
27 deltax / 2 . ;
28 }
29 c o u t << ”Le volume de r e v o l u t i o n ( meth . r e c t a n g l e ) e s t : ”
30 << s e t p r e c i s i o n ( 8 ) << i n t R e c t a n g l e << e n d l ;
31 c o u t << ”Le volume de r e v o l u t i o n ( meth . t r a p e z e ) e s t : ”
32 << s e t p r e c i s i o n ( 8 ) << i n t T r a p e z e << e n d l ;
33
34 return 0 ;
35 }
36
37 // d e f i n i t i o n de l a f o n c t i o n
38 double f o n c ( double x ) {
39 double y ;
40 y = s i n ( x ) + x∗x + 2 . ;
41
42 double v o l = M PI ∗ y∗y ;
43 return v o l ;
44 }
Ensuite, en utilisant cette fois uniquement la methode de Simpson (que l’on sait plus
précise), on cherche à effectuer le calcul de cette distance avec une précision de 1% sur
le résultat. Dans la mesure ou l’on ne connait pas la valeur exacte de cette distance, on
considère la précision de 1% atteinte lorsque le résultat de l’itération ne diffère pas plus
6
de 1% du resultat de l’itération précédente. Comme on l’a vu, le résultat de l’intégrale
dépend du nombre de divisions utilisé dans le calcul. Pour un grand nombre de divisions,
une précision de 1% sera atteinte rapidement.
Dans le programme ci-dessous, on commence l’intégration avec seulement 3 divisions de
l’intervalle [t1 , t2 ].
Vitesse.cpp
1 #include <i o s t r e a m >
2 #include <cmath>
3
4 using namespace s t d ;
5
6 // d e c l a r a t i o n de l a f o n c t i o n v i t e s s e v ( t ) = 3∗ t / s q r t (1 + 3∗ t ∗ t )
7 double f o n c ( double t ) ;
8
9 int main ( ) {
10 c o u t << ” C a l c u l de l a d i s t a n c e par i n t e g r a t i o n de l a v i t e s s e ” << e n d l ;
11 // s a i s i d e s p a r a m e t r e s
12 c o u t << ” En trez un temps d ’ i n t e g r a t i o n : ” ;
13 double time ; c i n >> time ;
14 c o u t << ” En trez un nombre de s o u s d i v i s i o n s : ” ;
15 int d i v ; c i n >> d i v ;
16 double d e l t a t = time / d i v ;
17
18 double i n t T r a p e z e = 0 . ;
19 double i n t S i m p s o n = 0 . ;
20 f o r ( int i =0; i <d i v ; i ++) {
21 i n t T r a p e z e += ( f o n c ( d e l t a t ∗ i ) + f o n c ( d e l t a t ∗ ( i +1) ) ) ;
22 i n t S i m p s o n +=
23 ( f o n c ( d e l t a t ∗ i ) + 4 . ∗ f o n c ( d e l t a t ∗ ( i +0.5) ) + f o n c ( d e l t a t ∗ ( i +1) ) ) ;
24 }
25 i n t T r a p e z e ∗= d e l t a t / 2 . ;
26 i n t S i m p s o n ∗= d e l t a t / 6 . ;
27
28 double d i s t a n c e T = i n t T r a p e z e ;
29 double d i s t a n c e S = i n t S i m p s o n ;
30 c o u t << ” I n t e g r a l e de l a v i t e s s e avec l a methode du t r a p e z e : ”
31 << d i s t a n c e T << ” m e t r e s ” << e n d l ;
32 c o u t << ” I n t e g r a l e de l a v i t e s s e avec l a methode de Simpson : ”
33 << d i s t a n c e S << ” m e t r e s ” << e n d l ;
34
35 // C a l c u l de l ’ i n t e g r a l e a v e c 1% de p r e c i s i o n a v e c l a methode de Simpson :
36 // on d e f i n i t l a p r e c i s i o n a 1% comme e t a n t l ’ i t e r a t i o n au−d e l a de
37 // l a q u e l l e l e r e s u l t a t ne d i f f e r e pas p l u s d ’1% du r e s u l t a t de
38 // l ’ i t e r a t i o n p r e c e d e n t e
39 double d i s t O l d = 0 . 1 ;
40 while ( ( f a b s ( d i s t a n c e S −d i s t O l d ) / d i s t O l d ) > 0 . 0 0 1 ) {
41 d i v +=1;
42 d e l t a t = time / d i v ;
43 distOld = distanceS ;
44 distanceS = 0 . ;
45
46 f o r ( int i =0; i <d i v ; i ++)
47 d i s t a n c e S +=
48 ( f o n c ( d e l t a t ∗ i ) + 4 . ∗ f o n c ( d e l t a t ∗ ( i +0.5) ) + f o n c ( d e l t a t ∗ ( i +1) ) ) ;
49 d i s t a n c e S ∗= d e l t a t / 6 . ;
50
51 c o u t << ”N = ” << d i v << ” , d i s t a n c e = ” << d i s t a n c e S
52 << ” , p r e c i s i o n = ” << f a b s ( d i s t a n c e S −d i s t O l d ) / d i s t O l d << e n d l ;
53 } // f i n de l a b o u c l e w h i l e
7
54
55 c o u t << ” P r e c i s i o n de 0.1% a t t e i n t e pour ” << d i v
56 << ” s o u s d i v i s i o n s ” << e n d l ;
57
58 return 0 ;
59 }
60
61 // d e f i n i t i o n de l a f o n c t i o n v i t e s s e v ( t ) = 3∗ t / s q r t (1 + 3∗ t ∗ t )
62 double f o n c ( double t ) {
63 double v i t e s s e ;
64 v i t e s s e = 3 . ∗ t / s q r t ( 1 + 3∗ t ∗ t ) ;
65
66 return v i t e s s e ;
67 }
6. Frottement
On considère ici le cas unidimensionnel. La loi de Newton nous donne :
ẍ C
=− (15)
ẋ m
L’intégration de t0 à t donne donc :
C
ẋ(t) = ẋ(t0 )e− m (t−t0 ) (16)
√
Le temps théorique pour lequel la vitesse atteinte vaut ẋ(0)/ 2 est donc :
m √
t= ln( 2) (17)
C
On n’utilisera pas ici la solution de l’équation différentielle, mais on intégrera l’équation
du mouvement pour obtenir la vitesse. Pour intégrer l’équation du mouvement on utilise
l’algorithme suivant :
à partir d’un temps initial t0 = 0. L’utilisateur entre un premier choix pour le temps
d’intégration. En fonction de la différence avec le rapport demandé le programme effectue
l’intégrale par pas
√ de 0.001 s et affiche le temps pour lequel la valeur de l’intégrale passe
en-dessus de 1/ 2.
Frottement.cpp
1 #include <i o s t r e a m >
2 #include <cmath>
3
4 using namespace s t d ;
5
6 int main ( ) {
7 // on c h o i s i t d e s v a l e u r s pour a v o i r un e f f e t de l ’ o r d r e de 1%
8 const double C = 1 . ; // c o e f f i c i e n t de f r o t t e m e n t
9 const double M = 1 0 0 . ; // masse
10 // v i t e s s e i n i t i a l e : en r e a l i t e l e r e s u l t a t ne depend pas de v0 !
11 double v0 = 1 0 0 . ;
12
13 double dt ;
14 c o u t << ” En trez un pas d ’ i n t e g r a t i o n ( ˜ 0 . 0 1 s e c . ) : ” ;
15 c i n >> dt ;
16
8
17 double v i t e s s e = v0 ;
18 double time = 0 . ;
19 while ( v i t e s s e > v0 / s q r t ( 2 . ) ) {
20 v i t e s s e = v i t e s s e ∗ ( 1 . − C/M∗ dt ) ;
21 time += dt ;
22 }
23
24 c o u t << ”La v i t e s s e demandee e s t a t t e i n t e a p r e s ”
25 << time << ” s e c o n d e s . ” << e n d l ;
26 c o u t << ”Le temps t h e o r i q u e e s t = ” << M/C∗ l o g ( s q r t ( 2 . ) )
27 << ” s e c o n d e s . ” << e n d l ;
28
29 return 0 ;
30 }
7. Champ gravitationnel
On calcule le champ gravitationnel de la Terre en un point quelconque P en tenant
compte du fait que la Terre n’est pas parfaitement sphérique. Pour cela on considère
une ellipsoı̈de. Le champ dans le point P est calculé en sommant les contributions des
sous-volumes utilisés pour diviser le volume complet (discrétisation de l’intégrale). Le
programme utilise deux fonctions : la première fonction (verifierVolume) vérifie si un
point se trouve ou non dans le volume de l’ellipsoı̈de, la deuxième fonction (fieldComp)
calcule les composantes du champ dû à un sous-volume particulier.
Vous pouvez tester le programme par exemple, en rentrant les dimensions d’une sphère
parfaite, ou en rentrant les coordonnées d’un point sur un plan de symétrie.
ChampG.cpp
1 // c a l c u l du champ g r a v i t a t i o n n e l g e n e r e par un e l l i p s o i d e dans l e p o i n t X
2 #include <i o s t r e a m >
3 #include <cmath>
4
5 using namespace s t d ;
6
7 bool v e r i f i e r V o l u m e ( double x [ ] , double a [ ] ) ;
8 void fieldComp ( double xsub [ ] , double xp [ ] , double f [ ] ) ;
9
10 // c o n s t a n t e g l o b a l e
11 const double GN = 6 . 6 7 3 e −11; //mˆ3 kgˆ−1 sˆ−2
12
13 int main ( ) {
14 // s a i s i d e s p a r a m e t r e s
15 double a [ 3 ] ;
16 c o u t << ”Champ g r a v i t a t i o n n e l g e n e r e par un e l l i p s o i d dans l e p o i n t X”
17 << e n d l << e n d l ;
18 c o u t << ” En trez l e s d i m e n s i o n s de l ’ e l l i p s o i d e ( a x e s en m e t r e s ) : ”
19 << e n d l ;
20 c o u t << ” a = ” ; c i n >> a [ 0 ] ;
21 c o u t << ”b = ” ; c i n >> a [ 1 ] ;
22 c o u t << ” c = ” ; c i n >> a [ 2 ] ;
23
24 double M = 10 e20 ;
25 c o u t << ” En trez l e masse de l ’ o b j e t ( ˜ 1 0 e20 kg ) : ” << e n d l ;
26 c i n >> M;
27
28 double xp [ 3 ] ;
29 c o u t << ” En trez l e s c o o r d o n n e e s du p o i n t X ( en m e t r e s ) : ” << e n d l ;
30 c o u t << ” ( l e p o i n t X peut e t r e s i t u e a l ’ i n t e r i e u r de l ’ e l l i p s o i d e ) ”
31 << e n d l ;
9
32 c o u t << ”x = ” ; c i n >> xp [ 0 ] ;
33 c o u t << ”y = ” ; c i n >> xp [ 1 ] ;
34 c o u t << ” z = ” ; c i n >> xp [ 2 ] ;
35
36 int d i v ;
37 c o u t << ” En trez l e nombre de d i v i s i o n s de l ’ axe majeur ( a ) : ” << e n d l ;
38 c o u t << ”N = ” ; c i n >> d i v ;
39 double dx [ 3 ] ;
40 f o r ( int i =0; i <3; i ++)
41 dx [ i ] = a [ i ] / d i v ;
42
43 // b o u c l e s u r l e s ” sous−volumes ” de l ’ e l l i p s o i d e :
44 // s i l e c e n t r e d ’ un sous−volume e s t dans l ’ e l l i p s o i d e
45 // on a d d i t i o n n e sa c o n t r i b u t i o n au champ t o t a l
46 double xsub [ 3 ] ;
47 int sousVolumes = 0 ;
48 double f [ 3 ] ;
49 double f i e l d [ 3 ] = { 0 . } ;
50 bool i n s i d e ;
51 // on commence par l e c o t e n e g a t i f d e s a x e s
52 f o r ( int i x =0; ix <(2∗ d i v ) ; i x++) { // axe x
53 f o r ( int i y =0; iy <(2∗ d i v ) ; i y++) { // axe y
54 f o r ( int i z =0; i z <(2∗ d i v ) ; i z ++) { // axe z
55 // c a l c u l e de l a p o s i t i o n du suos−volume en 3 dim
56 f o r ( int i =0; i <3; i ++)
57 xsub [ i ] = −a [ i ] + dx [ i ] / 2 . + i x ∗dx [ i ] ;
58
59 // on v e r i f i e que l e p o i n t e s t dans l e volume c o n s i d e r e
60 i n s i d e = v e r i f i e r V o l u m e ( xsub , a ) ;
61 if ( inside ) {
62 sousVolumes += 1 ;
63 // c o n t r i b u t i o n de ce s ous vo lum e au champ g r a v i t a t i o n n e l :
64 // on c o n s i d e r e GN = 1 e t m = 1 : F = G∗m/( r ∗ r ) = 1/( r ∗ r )
65 // i l f a u t maintenant d e t e r m i n e r l e s composantes du v e c t e u r
66 // pour p o u v o i r sommer t o u t e s l e s c o n t r i b u t i o n s
67 fieldComp ( xsub , xp , f ) ;
68 f o r ( int i =0; i <3; i ++)
69 f i e l d [ i ] += f [ i ] ;
70 }
71 }
72 }
73 }
74
75 c o u t << sousVolumes << ” sous−volumes s o n t d e f i n i s . ” << e n d l ;
76 // on n o r m a l i s e l e champ a l a masse de l ’ o b j e t ;
77 //M / # sous−volumes = masse sous−volume
78 double f f = 0 . ;
79 f o r ( int i =0; i <3; i ++) {
80 f i e l d [ i ] ∗= −GN∗M/ sousVolumes ;
81 f f += pow ( f i e l d [ i ] , 2 ) ;
82 }
83 f f = sqrt ( f f ) ;
84
85 cout << ” Estimation du champ : | F | = ” << f f << ” m/ s 2 . ” << e n d l ;
86 cout << ” Fx = ” << field [0] << e n d l ;
87 cout << ” Fy = ” << field [1] << e n d l ;
88 cout << ” Fz = ” << field [2] << e n d l ;
89
90 return 0 ;
91 }
10
92
93 bool v e r i f i e r V o l u m e ( double x [ ] , double a [ ] ) {
94 bool i n s i d e = f a l s e ;
95
96 // e q u a t i o n de l ’ e l l i p s o i d e
97 i f ( ( pow ( x [ 0 ] / a [ 0 ] , 2 ) + pow ( x [ 1 ] / a [ 1 ] , 2 ) + pow ( x [ 2 ] / a [ 2 ] , 2 ) ) <= 1 . )
98 i n s i d e = true ;
99
100 return i n s i d e ;
101 }
102
103 // c a l c u l du champ g r a v i t a t i o n n e l en X
104 void fieldComp ( double x [ ] , double p [ ] , double f [ ] ) {
105 // c a l c u l de l a d i s t a n c e e n t r e l e c e n t r e du sous−volume
106 // e t l e p o i n t X
107 double d i s t = 0 . ;
108 f o r ( int i =0; i <3; i ++)
109 d i s t += pow ( p [ i ]−x [ i ] , 2 ) ;
110 dist = sqrt ( dist ) ;
111
112 // composantes de G non n o r m a l i s e e s
113 f o r ( int i =0; i <3; i ++)
114 f [ i ] = ( p [ i ]−x [ i ] ) / pow ( d i s t , 3 ) ;
115
116 return ;
117 }
8. Moment d’inertie
Le programme calcule le moment d’inertie pour une sphère à densité non-uniforme et de
rayon R. L’axe de rotation de la sphère étant z, on définit le moment d’inertie par rapport
à l’axe de rotations tel quel :
Z Z Z Z Z
2 2
Iz = a dm = a ρ(r)dV = (x2 + y 2 ) ρ0 e−r/R dx dy dz (19)
(x2 +y 2 +z 2 )<R2
p
où a2 = x2 + y 2 est la distance par rapport à l’axe d’inertie et r = x2 + y 2 + z 2 est la
distance au centre de la sphère.
Comme la valeur de l’expression à intégrer est la même si on échange x → −x, y → −y,
ou z → −z, on peut calculer l’intégrale pour la partie de la sphère où x > 0, y > 0, et
z > 0, qui représente 1/8 du volume total (le résultat est le même que pour les autres
éléments x < 0, y > 0, et z > 0 ; x > 0, y < 0, et z > 0 ; etc.)
Z R Z R Z R
Iz = 8 × (x2 + y 2 ) ρ0 e−r/R dx dy dz (20)
0 0 0
N N
XXX N √ 2 2 2
≈ 8× (x2i + yj2 ) ρ0 e− (xi +yj +zk )/R (∆x)3 (21)
i=0 j=0 k=0
11
R rayon de la sphere
ρ densite centrale de la sphere
Nombre de sub-divisions des axes de la sphere = N
S=I0
YES NO
YES
S= S+Ii NO
S= I total
La somme commence avec le cube de centre (∆x/2, ∆y/2, ∆z/2), la densité du cube et
la distance de son centre à l’axe de rotation sont calculées. A chaque changement de
cube nous ajoutons R/N à une coordonée, en commmençant avec celle de l’axe z, jusqu’à
la valeur limite R, ensuite la valeur de z revient à ∆x/2 et nous ajoutons R/N à la
coordonnée y, etc. Voir aussi le diagramme de flux montré dans la figure 1.
MomentdInerite.cpp
1 //moment d ’ i n e r i t e d ’ une s p h e r e
2 #include <i o s t r e a m >
3 #include <cmath>
4 #include <iomanip>
5
6 using namespace s t d ;
7
8 // f o n c t i o n d e n s i t e
9 double d e n s i t e ( double r , double R, double rho0 ) ;
10 // d i s t a n c e du c e n t r e de l a s p h e r e
11 double r ( const double p o i n t [ ] ) ;
12 // d i s t a n c e a l ’ axe de r o t a t i o n au c a r r e
13 double perp2 ( const double p o i n t [ ] ) ;
14
15 int main ( ) {
16 // s a i s i d e s p a r a m e t r e s
17 double rho0 ;
18 c o u t << ” Q u e l l e e s t l a d e n s i t e de l a s p h e r e au c e n t r e ( en kg /mˆ 3 ) ? ” ;
12
19 c i n >> rho0 ;
20 double R; // rayon de l a s p h r e
21 c o u t << ” e t l e rayon de l a s p h e r e ( en m) ? ” ;
22 c i n >> R;
23 int d i v ; // d i v i s i o n s de l ’ axe x
24 c o u t << ”En combien de p a r t i e v o u l e z vous d i v i s e r l e rayon de l a s p h e r e ?
”;
25 c i n >> d i v ;
26
27 double dx = R/ d i v ;
28 double dV = pow ( dx , 3 ) ; // sous−volume
29
30 double m I n e r t i e = 0 . ;
31 int i t e r = 0 ; //# i t e r a t i o n s
32 double p o i n t [ 3 ] ; // p o i n t a l ’ i n t e r i e u r de l a s p h e r e
33 // on c a l c u l e l e moment d ’ i n e r t i e d ’ un o c t a n t de l a s p h e r e
34 p o i n t [ 0 ] = dx / 2 . ;
35 f o r ( int i =0; i <d i v ; i ++) {
36 p o i n t [ 1 ] = dx / 2 . ;
37 f o r ( int j =0; j <d i v ; j ++) {
38 p o i n t [ 2 ] = dx / 2 . ;
39 f o r ( int k=0; k<d i v ; k++) {
40 // d ’ abord i l f a u t v e r i f i e r s i l e p o i n t e s t a l ’ i n t e r i e u r
41 i f ( r ( p o i n t )>R) break ;
42 m I n e r t i e += d e n s i t e ( r ( p o i n t ) ,R, rho0 ) ∗ dV ∗ perp2 ( p o i n t ) ;
43 p o i n t [ 2 ] += dx ;
44 i t e r ++;
45 }
46 p o i n t [ 1 ] += dx ;
47 }
48 p o i n t [ 0 ] += dx ;
49 }
50
51 c o u t << ”Moment d ’ i n e r t i e de l ’ o c t a n t c a l c u l e : ” << setw ( 1 0 ) << m I n e r t i e
52 << ” kg mˆ2 ” << e n d l
53 << ” e t nombre d ’ i t e r a t i o n s computees : ” << i t e r << e n d l ;
54
55 c o u t << ”Le moment d ’ i n e r t i e e s t e g a l a ”
56 << setw ( 1 5 ) << s e t p r e c i s i o n ( 1 0 ) << s c i e n t i f i c << 8 . ∗ m I n e r t i e
57 << ” kg mˆ2 ” << e n d l ;
58
59 return 0 ;
60 }
61
62 // f o n c t i o n d e n s i t e
63 double d e n s i t e ( double r , double R, double rho0 ) {
64 return rho0 ∗ exp(− r /R) ;
65 }
66
67 // d i s t a n c e du c e n t r e de l a s p h e r e
68 double r ( const double p o i n t [ ] ) {
69 return s q r t ( pow ( p o i n t [ 0 ] , 2 ) + pow ( p o i n t [ 1 ] , 2 ) + pow ( p o i n t [ 2 ] , 2 ) ) ;
70 }
71
72 // d i s t a n c e a l ’ axe de r o t a t i o n au c a r r e
73 double perp2 ( const double p o i n t [ ] ) {
74 return pow ( p o i n t [ 0 ] , 2 ) + pow ( p o i n t [ 1 ] , 2 ) ;
75 }
13
Figure 2 – Diagramme de flux pour le calcule du champ électrique.
9. Champ électrique
On cherche à calculer le champ électrique E produit par un anneau de rayon R et de charge
Q en tout point quelconque X. Pour ce faire on considère un système de coordonnées
cartesiennes dont l’origine est le centre de l’anneau, et l’on divise l’anneau en segments de
longueur I = R∆Φ avec ∆Φ = 2π/n (modélisation du problème). Le rayon de l’anneau,
la charge et le nombre de divisions sont fournis par l’utilisateur.
En utilisant le principe de superposition, on calcule le champ généré au point X par
chaque segment et l’on additionne ensuite les contributions des différents segments pour
obtenir le champs E total. Voir aussi le diagramme de flux montré dans la figure 2.
ChampElect.cpp
1 //champ e l e c t r i q u e dans un p o i n t q u e l c o n q u e
2 #include <i o s t r e a m >
3 #include <cmath>
4
5 using namespace s t d ;
6
7 void fieldComp ( double x , double y , double z ,
8 double xp , double yp , double zp ,
9 double q , double &ex , double &ey , double &e z ) ;
10 double d i s t a n c e T o P o i n t ( double x , double y , double z ,
11 double xp , double yp , double zp ) ;
12
13 // c o n s t a n t e d i e l e c t r i q u e
14 const double e p s 0 =8.854 e −12;
15
16 int main ( ) {
17 double R;
14
18 c o u t << ” En trez l e rayon de l ’ anneau ( en m) : ” ;
19 c o u t << ”R = ” ; c i n >> R;
20 double Q;
21 c o u t << ” En trez l e c h a r g e de l ’ anneau ( en C) : ” ;
22 c o u t << ”Q = ” ; c i n >> Q;
23 int d i v ;
24 c o u t << ” En trez l e nombre N de d i v i s i o n s de l ’ anneau : ” ;
25 c i n >> d i v ;
26
27 double xp , yp , zp ;
28 c o u t << ” En trez l e s c o o r d o n n e e s du p o i n t X ( en m) : ” << e n d l ;
29 c o u t << ”x = ” ; c i n >> xp ;
30 c o u t << ”y = ” ; c i n >> yp ;
31 c o u t << ” z = ” ; c i n >> zp ;
32
33 /∗ On imagine l ’ anneau dans l e p l a n xy , u n i d i m e n s i o n n e l
34 1) l ’ anneau e s t d i v i s e en N segments
35 2) on ” b o u c l e ” s u r l e s segments de l ’ anneau
36 3) on c a l c u l e l e champ g e n e r e par chaque segment
37 4) on a d d i t i o n n e l e s c o n t r i b u t i o n s au champ t o t a l . ∗/
38 double d e l t a P h i = 2 . ∗ M PI/ d i v ;
39 // c h a r g e du segment ( q e t Q s o n t 2 v a r i a b l e s d i f f e r e n t e s ! )
40 double q = Q/ d i v ;
41
42 double xseg , yseg , z s e g ;
43 double p h i ;
44 double d i s t a n c e = 0 . ;
45 double ex , ey , e z ;
46 double f i e l d X =0. , f i e l d Y =0. , f i e l d Z = 0 . ;
47 // b o u c l e s u r l ’ anneau
48 f o r ( int i s e g =0; i s e g <d i v ; i s e g ++) {
49 phi = deltaPhi /2. + i s e g ∗ deltaPhi ;
50 x s e g = R∗ c o s ( p h i ) ;
51 y s e g = R∗ s i n ( p h i ) ;
52 zseg = 0 . ;
53
54 // c a l c u l d e s composantes du v e c t e u r E
55 fieldComp ( xseg , yseg , z s e g , xp , yp , zp , q , ex , ey , e z ) ;
56
57 // e t on a d d i t i o n l e champ g e n e r e par chaque segment
58 f i e l d X += ex ;
59 f i e l d Y += ey ;
60 f i e l d Z += e z ;
61 }
62
63 double fieldXYZ = s q r t ( pow ( f i e l d X , 2 )+pow ( f i e l d Y , 2 )+pow ( f i e l d Z , 2 ) ) ;
64 c o u t << ” E s t i m a t i o n du champ : | E | = ” << fieldXYZ << ” V/m” << e n d l ;
65 c o u t << ” Ex = ” << f i e l d X << ” V/m” << e n d l ;
66 c o u t << ” Ey = ” << f i e l d Y << ” V/m” << e n d l ;
67 c o u t << ” Ez = ” << f i e l d Z << ” V/m” << e n d l ;
68
69 return 0 ;
70 }
71
72 // c a l c u l du champ e l e c t r i q u e en X
73 void fieldComp ( double x , double y , double z ,
74 double xp , double yp , double zp ,
75 double q , double &ex , double &ey , double &e z ) {
76
77 // c a l c u l de l a d i s t a n c e e n t r e l e c e n t r e du segment e t l e p o i n t X
15
78 double d i s t = d i s t a n c e T o P o i n t ( x , y , z , xp , yp , zp ) ;
79
80 //champ e l e c t r i q u e | E | en X
81 double e = 1 . / ( 4 . ∗ M PI∗ e p s 0 ) ∗ q / ( d i s t ∗ d i s t ) ;
82
83 // composantes de E
84 ex = e ∗ ( xp−x ) / d i s t ;
85 ey = e ∗ ( yp−y ) / d i s t ;
86 e z = e ∗ ( zp−z ) / d i s t ;
87 }
88
89 // d i s t a n c e e n t r e deux p o i n t s
90 double d i s t a n c e T o P o i n t ( double x1 , double y1 , double z1 ,
91 double x2 , double y2 , double z2 ) {
92 double d i s t a n c e ;
93 double d i f f x = x2−x1 ;
94 double d i f f y = y2−y1 ;
95 double d i f f z = z2−z1 ;
96 d i s t a n c e = s q r t ( pow ( d i f f x , 2 ) + pow ( d i f f y , 2 ) + pow ( d i f f z , 2 ) ) ;
97
98 return d i s t a n c e ;
99 }
16
17 c o u t << ”N = ” ; c i n >> N;
18
19 // s e s i e du c u o r a n t
20 c o u t << ” En trez l e c o u r a n t en A: ” << e n d l ;
21 c o u t << ” I = ” ; c i n >> I ;
22
23 // s e s i e de l a p o s i t i o n a q u e l l e c a l c u l e r l e champ
24 double px , py , pz ; // c o o r d o n n e e s du p o i n t c h o i s i
25 c o u t << ” En trez l a p o s i t i o n ou c a l c u l e r l e champ magnetique : ” << e n d l ;
26 c o u t << ”x = ” ; c i n >> px ;
27 c o u t << ”y = ” ; c i n >> py ;
28 c o u t << ” z = ” ; c i n >> pz ;
29
30 // on v e r i f i e que l e p o i n t ne s e s i t u e pas s u r l ’ anneau
31 // ( pas v r a i m e n t n e c e s s a i r e )
32 i f ( pz == 0 ) {
33 i f ( ( px∗px + py∗py ) == R∗R) {
34 c o u t << ”Le p o i n t e s t s u r l ’ anneau , e n t r e z d ’ a u t r e s v a l e u r s : ”
35 << e n d l ;
36 c o u t << ”x = ” ; c i n >> px ;
37 c o u t << ”y = ” ; c i n >> py ;
38 c o u t << ” z = ” ; c i n >> pz ;
39
40 while ( ( px∗px + py∗py ) == R∗R) {
41 c o u t << ”Le p o i n t e s t t o u j o u r s s u r l ’ anneau , ”
42 << ” e n t r e z d ’ a u t r e s v a l e u r s : ” << e n d l ;
43 c o u t << ”x = ” ; c i n >> px ;
44 c o u t << ”y = ” ; c i n >> py ;
45 c o u t << ” z = ” ; c i n >> pz ;
46 }
47 }
48 }
49
50 // l e champ t o t a l e s t c a l c u l e a v e c une b o u c l e s u r l e s segments de l ’ anneau
51 // on i n i t i a l i s e l e s composantes a z e r o en−d e h o r s de l a b o u c l e p r i n c i p a l e
52 double dBx , dBy , dBz ; //champ g e n e r e par l e segment
53 double Bx , By , Bz ; //champ t o t a l
54 Bx = 0 . ; By = 0 . ; Bz = 0 . ;
55
56 double rx , ry , r z ; // v e c t e u r du segment au p o i n t c h o i s i
57 double norme ; //norme du v e c t e u r
58
59 double theta ; // coordonnee p o l a i r e du segment de l ’ anneau
60 double dtheta ;
61 dtheta = 2 . ∗ M PI/N; // i n c r e m e n t a t i o n de l ’ a n g l e
62 double dlx , dly , d l z ; // composante du segment
63
64 // b o u c l e s u r l e s segments de l ’ anneau
65 f o r ( int i =0; i <N; i ++) {
66 // a n g l e p o l a i r e du segment ( commence a z e r o )
67 theta = i ∗ dtheta ;
68
69 // c a l c u l d e s composantes du segment
70 d l x = R∗ ( c o s ( t h e t a+d t h e t a ) − c o s ( t h e t a ) ) ;
71 d l y = R∗ ( s i n ( t h e t a+d t h e t a ) − s i n ( t h e t a ) ) ;
72 dlz = 0 . ;
73
74 // c a l c u l d e s composantes du v e c t e u r r r e l i a n t l e segment e t l e p o i n t
75 rx = px − R∗ c o s ( t h e t a ) ;
76 ry = py − R∗ s i n ( t h e t a ) ;
17
77 r z = pz ;
78
79 //norme du v e c t e u r
80 norme = s q r t ( rx ∗ rx + ry ∗ ry + r z ∗ r z ) ;
81
82 // c a l c u l d e s composantes du champ ma gn eti qu e g e n e r e par l e segment
83 // l e s composantes s o n t donnees par l e p r o d u i t v e c t o r i e l d l x r
84 dBx = (mu0 / ( 4 . ∗ M PI ) ) ∗ I ∗ ( d l y ∗ rz−d l z ∗ ry ) /pow ( norme , 3 ) ;
85 dBy = (mu0 / ( 4 . ∗ M PI ) ) ∗ I ∗ ( d l z ∗ rx−d l x ∗ r z ) /pow ( norme , 3 ) ;
86 dBz = (mu0 / ( 4 . ∗ M PI ) ) ∗ I ∗ ( d l x ∗ ry−d l y ∗ rx ) /pow ( norme , 3 ) ;
87
88 // pour chaque i t e r a t i o n on a d d i t i o n l e champ g e n e r e p e r l e segment
89 // au champ m agn et iqu e t o t a l
90 Bx += dBx ;
91 By += dBy ;
92 Bz += dBz ;
93 }
94
95 cout << ”Le champ B [ T ] au p o i n t c h o i s i vaut : ” << e n d l ;
96 cout << ”B = ” << s q r t (Bx∗Bx + By∗By + Bz∗Bz ) << e n d l ;
97 cout << ”Bx = ” << Bx << e n d l ;
98 cout << ”By = ” << By << e n d l ;
99 cout << ”Bz = ” << Bz << e n d l ;
100
101 return 0 ;
102 }
18
26 c o u t << ” difference finie a droite : ”
27 << ( c o s ( x+h )−c o s ( x ) ) /h << e n d l ;
28 c o u t << ” d i f f e r e n c e f i n i e a gauche : ”
29 << ( c o s ( x )−c o s ( x−h ) ) /h << e n d l ;
30 c o u t << ” difference finie centrale : ”
31 << ( c o s ( x+h )−c o s ( x−h ) ) / ( 2 . ∗ h ) << e n d l ;
32
33 return 0 ;
34 }
2. Dérivée
Le programme calcule les dérivées première et seconde d’un polynôme arbitraire du second
degré. Le programme demande à l’utilisateur d’entrer le point x auquel calculer les dérivées
et la largeur de l’incrément h. Dans le calcul numérique de la dérivée seconde on retrouve
h2 au dénominateur. Il faut aussi faire attention à la précision finie de l’ordinateur dans
le choix de h.
Prob2 diff.cpp
1 #include <i o s t r e a m >
2 #include <cmath>
3
4 using namespace s t d ;
5
6 // p r o t o t y p e de l a f o n c t i o n
7 double f o n c ( double ) ;
8
9 int main ( ) {
10 double x ;
11 c o u t << ” En trez une v a l e u r a l a q u e l l e c a l c u l e r l e s d e r i v e e s : ” << e n d l ;
12 c o u t << ”x = ” ; c i n >> x ;
13 double h ;
14 c o u t << ” En trez une v a l e u r de h : ” << e n d l ;
15 c o u t << ”h = ” ; c i n >> h ;
16
17 double d e r i v e e 1 , d e r i v e e 2 ;
18 d e r i v e e 1 = ( f o n c ( x+h ) − f o n c ( x−h ) ) / ( 2 . ∗ h ) ;
19 d e r i v e e 2 = ( f o n c ( x+h ) − 2 . ∗ f o n c ( x ) + f o n c ( x−h ) ) / ( h∗h ) ;
20
21 c o u t << ”Au p r e m i e r o r d r e en h l a d e r i v e e p r e m i e r e vaut : ” << e n d l ;
22 c o u t << ” f ’ ( x ) = ” << d e r i v e e 1 << e n d l ;
23 c o u t << ”La d e r i v e e s e c o n d e vaut ( a t t e n t i o n a h ! ) : ” << e n d l ;
24 c o u t << ” f ’ ’ ( x ) = ” << d e r i v e e 2 << e n d l ;
25
26 return 0 ;
27 }
28
29 // d e f i n i t i o n de l a f o n c t i o n
30 // dans c e t example nous avons c h o i s i un polynome de 2eme d e g r e e ;
31 double f o n c ( double x ) {
32 double a , b , c ;
33 a = 10.;
34 b = −3.;
35 c = 7.;
36
37 double y = a ∗ ( x∗x ) + b∗x + c ;
38
39 return y ;
40 }
19
3. Activité d’une source de cobalt
L’activité d’une source radioactive de cobalt 60 (60
27 Co) est donnée par la loi de Poisson :
dN −1 N (t)
A=− = −N0 e−t/τ = (25)
dt τ τ
avec τ = t1/2 /ln(2) (t1/2 est le temps de demi vie). Le nombre initial d’atomes de cobalt est
N0 = M0 /A0 ×NA ou M0 est la masse initiale de l’échantillon, A0 est la masse du Cobalt en
Kg/mole et NA est le nombre d’Avogadro, c’est-à-dire le nombre d’atomes dans une mole.
Dans le programme nous avons résolu l’équation différentielle de manière numérique, et
nous faisons la comparaison avec le résultat exact et la differentiation numérique.
La figure 3 montre le nombre d’atomes (en moles) en fonction du temps pour une masse
initiale de 500 Kg sur 50 années (clairement une fonction exponentielle).
Cobalt60.cpp
1 #include <i o s t r e a m >
2 #include <cmath>
3 #include <iomanip>
4
5 using namespace s t d ;
6
7 int main ( ) {
8 const double nAvogadro = 6 . 0 2 2 1 4 1 e23 ;
9 const double secParAn = 3 6 5 . ∗ 2 4 . ∗ 3 6 0 0 . ;
10 double tau = 5 . 2 7 1 / l o g ( 2 . ) ; // temps de demi−v i e du Co−60 ( 5 . 2 7 1 ans )
11
12 c o u t << ” ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗\ n” ;
13 c o u t << ”Programme pour l e c a l c u l de l ’ a c t i v i t e d ’ une s o u r c e de Co60\n” ;
14 const double A0=59.9338222 e −3;
15 c o u t << ”La masse du Cobalt e s t A0 = ” << A0 << ” kg p e r mole . \ n” ;
16 c o u t << ” ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗\ n” ;
17
18 // s a i s i d e s p a r a m e t r e s
19 double M0;
20 c o u t << ” Q u e l l e e s t l a masse i n i t i a l e de l a s o u r c e ( en kg ) ? ” ;
21 c i n >> M0;
22 double t 0 ;
23 c o u t << ” Apres combien d ’ ans v o u l e z vous c o n n a i t r e l ’ a c t i v i t e de l a
source ? ” ;
24 c i n >> t 0 ;
25 int n ;
26 c o u t << ”Combien d ’ i t e r a t i o n s v o u l e z −vous f a i r e pour c e c a l c u l ? ” ;
27 c i n >> n ;
28
29 double S = M0/A0 ; // nombre i n i t i a l d ’ atomes / nAvogadro
30 double dt = t 0 /n ;
31 c o u t << ” v a l e u r e x a c t e ” << exp(− t 0 / tau ) / tau ∗M0/A0∗ nAvogadro << e n d l ;
32 c o u t << ” v a l e u r approx ”
33 << ( exp ((− t 0+dt ) / tau )−exp ((− t0−dt ) / tau ) ) / ( 2 . ∗ dt ) ∗M0/A0∗ nAvogadro
34 << ” ( c a l c u l i n c o r r e c t ! ) ” << e n d l ;
35 // f a u x p a r c e que s i on c o n n a i t exp(− t 0+d t )
36 // on c o n n a i t a u s s i l a v a l e u r e x a c t e !
37 f o r ( int i =0; i < n ; i ++)
38 S = S ∗(1.0 − dt / tau ) ;
39
40 double a c t i v i t e = S/ tau ∗ nAvogadro ;
41 c o u t << ” F r a c t i o n remanente ”<< S/M0∗A0<<e n d l ;
42 c o u t << ”L ’ a c t i v i t e de l a s o u r c e a p r e s ” << t 0 << ” ans e s t de ”
43 << a c t i v i t e << ” d e s i n t e g r a t i o n s par an” << e n d l ;
20
masse (kg)
temps (ans)
4. Erreur d’arrondi
Le programme calcule la derivée de la fonction f (x) = x2 avec la formule de la différence
finie centrale :
f 0 (x)exacte = 2x
0 f (x + h) − f (x − h) (x + h)2 − (x − h)2 4xh
fapprox (x) = = = = 2x
2h 2h 2h
Dans ce cas, l’approximation est exacte. L’erreur sera purement une erreur d’arrondi,
c’est-à-dire une erreur de précision dans le calcul de l’approximation : dans chaque ap-
proximation l’approximation l’ordinateur peut rater la valeur exacte. Dans le cas où h = x
, ou aussi pour h = 1 et x entier, l’ordinateur peut trouver la valeur exacte parce qu’il
exécutera d’abord la somme x + h et le reste x − h. Dans la figure 4 nous voyons que pour
x = 1 l’approximation est moins bonne avec h plus petit. Mais pour x = 0.001, l’erreur
d’arrondi diminue jusqu’à h = x et augmente ensuite. Le résultat trouvé dépend aussi de
l’ordinateur utilisé.
DiffFinieCentrale.cpp
1 #include <i o s t r e a m >
2 #include <cmath>
3 #include <iomanip>
4
5 using namespace s t d ;
21
6
7 double d i f f F i n i e C e n t r a l ( double x0 , double h ) ;
8
9 int main ( ) {
10 const int STEPMAX = 2 1 ;
11
12 double h , dfNum , d f C a l c ;
13 double d e l t a ;
14 double x0 ;
15 c o u t << ” E s t i m a t i o n de l a d e r i v e e de f ( x )=x ˆ3 avec l a d i f f e r e c e f i n i e
c e n t r a l e ” << e n d l ;
16 c o u t << ” e n t r e z l a v a l e u r de x ou e s t i m e r f ’ ( x ) : ” ;
17 c i n >> x0 ;
18
19 c o u t << e n d l ;
20 c o u t << ” h ; l o g ( dfNum − dfAna ) ; dfNum”
21 << e n d l << e n d l ;
22 f o r ( int s t e p =0; s t e p <STEPMAX; s t e p++) {
23 h = pow (10. , − s t e p ) ;
24
25 dfNum = d i f f F i n i e C e n t r a l ( x0 , h ) ; // d e r i v e e numerique
26 d f C a l c = 3 . ∗ x0 ; // d e r i v e e a n a l y t i q u e
27
28 i f ( f a b s ( dfNum−d f C a l c ) !=0)
29 d e l t a = l o g 1 0 ( f a b s ( dfNum−d f C a l c ) ) ;
30 else
31 d e l t a = −9999.99; // une v a l e u r j a m a i s a t t e i n t par l e l o g a r i t h m e
32
33 c o u t << s e t p r e c i s i o n ( 2 0 ) << f i x e d << h << ” ”
34 << d e l t a << ” ” << dfNum <<e n d l ;
35 }
36 c o u t << e n d l ;
37
38 return 0 ;
39 }
40
41 double d i f f F i n i e C e n t r a l ( double x0 , double h ) {
42 double d f = ( pow ( x0+h , 3 )−pow ( x0−h , 3 ) ) / ( 2 . ∗ h ) ;
43 return d f ;
44 }
Dans le programme nous avons défini une fonction pour le calcul de la dérivée numérique,
et une variable qui prend la valeur exacte de la derivée. Ensuite nous évaluons la différence
entre l’approximation et la derivée exacte. Pour éviter une erreur d’exéxecution quand
le programme essaie de prendre le logarithme de 0, nous avons mis une condition : si la
valeur trouvée par l’approximation est égale à la valeur exacte calculée, on utilise une
valeur qui n’est jamais atteinte, que nous utilisons seulement pour faire le graphique.
Dans la figure 5 on montre le même calcul pour f (x) = x3 , avec :
f 0 (x)exacte = 3x2
0 f (x + h) − f (x − h) (x + h)3 − (x − h)3 2h(3x2 + h2 )
fapprox (x) = = = = 3x2 + h2
2h 2h 2h
mais on voit que la valeur -30 n’est jamais atteinte, parce qu’on n’a jamais h = 0, et
pour h trop petit les erreurs d’arrondi dans les opérations de puissance et de reste dans
le calcul approché sont grandes.
22
0
-5
-5
-10
-10
-15
-15
-20
-20
-25 -25
-30 -30
-20 -15 -10 -5 0 -20 -15 -10 -5 0
Figure 4 – Graphique de l’erreur (en puissance de 10) trouvée lors du calcul de l’approximation
de la derivée de f (x) = x2 , en fonction du logarithme du paramètre h utilisé. A gauche on
montre le graphique pour x = 1, à droite pour x = 0.001.
0
0
-2
-2
-4
-6
-4
-8
-6
-10
-8 -12
-14
-10
-16
-20 -15 -10 -5 0 -20 -15 -10 -5 0
Figure 5 – Graphique de l’erreur (en puissances de 10) trouvée lors du calcul de l’approxima-
tion de la derivée de f (x) = x3 , en fonction du logarithme du paramètre h utilisé. A gauche on
montre le graphique pour x = 1, à droite pour x = 0.001.
23