Professional Documents
Culture Documents
et de Chimie Industrielles
de la Ville de Paris
Mthodes Numriques
Didier Cassereau
Tlphone : 01.40.79.44.69
E-mail : didier.cassereau@espci.fr
Chapter 1
Introduction
1.1
Gnralits
Dans le domaine du calcul numrique, la premire chose faire est doublier dfinitivement la vision un
peu trop nave comme quoi tout se passe bien, et en particulier conformment aux bases mathmatiques
classiques. En effet, tout problme trait numriquement doit imprativement tenir compte des erreurs
qui peuvent intervenir dans le processus.
On peut distinguer deux types derreurs numriques :
les erreurs darrondis rsultant du codage des valeurs relles sur un nombre fini de bits (32, 64 bits,
voire plus encore suivant les compilateurs)
les erreurs algorithmiques.
A titre dexemple : la mthode du pivot de Gauss pour rsoudre un systme linaire de N quations N
inconnues est parfaitement rigoureuse du point de vue mathmatique (sous rserve que le systme soit
inversible), mais elle reste soumise aux erreurs darrondis. En revanche, lintgration dune fonction par
la mthode des trapzes induit une erreur supplmentaire due lalgorithme utilis (ici, approximation
dune fonction localement linaire).
1.2
Ces erreurs proviennent du codage des valeurs relles sur un nombre fini de bits significatifs. Il en rsulte
donc que les rels susceptibles dtre cods numriquement sont eux-mmes en nombre fini, alors que les
rels mathmatiques sont en nombre infini. Compte tenu des mthodes de codages (norme I.E.E.E.) les
rels ne sont dtermins quavec une prcision limite lintrieur dun domaine de valeurs galement
limit. Le domaine de valeurs limit nest gnralement pas lorigine de srieux problmes, sauf
manipuler des donnes trs grandes ou trs petites. Le problme majeur provient de la prcision limite
(typiquement 7 8 chiffres significatifs pour des rels simple prcision, 15 16 en double prcision).
Consquence immdiate de cette prcision limite : laddition nest plus associative et le rsultat dpend
de lordre dans lequel sont faits les calculs.
Exemple :
1.3
a = 1020 , b = 1020 , c = 1
(a + b) + c = 1
a + (b + c) = 0
La propagation derreur
Chapitre 1 : Introduction
progressent. Do limportance fondamentale de minimiser les erreurs chaque tape et rduire le nombre
de calculs si possible (en plus, rduire le nombre de calculs ncessaires permet de gagner du temps
lexcution, ce qui est trs apprciable).
1.4
1.5
Un des problmes majeurs de lanalyse numrique est lerreur numrique, associe la manipulation de
donnes dordres de grandeurs trs diffrents. Une question se pose alors : comment peut-on dfinir un
grand nombre ? ou inversement un nombre ngligeable ?
De faon trs nave, on pourrait rpondre que 1015 est un grand nombre, et que 1015 est plutt petit
! En fait, on peut trs vite se convaincre quune telle rponse nest pas satisfaisante, et que lon doit en
ralit tenir compte de lchelle dobservation des grandeurs considres. A titre dexemple :
pour le calcul de lnergie dun atome, lordre de grandeur caractristique est leV=1019 J ; cette
chelle, on doit considrer 1015 comme un trs grand nombre,
en revanche, pour le calcul du nombre de molcules dans un litre deau, lordre de grandeur caractristique est de 1023 (quelques moles), de sorte que 1015 est quantit parfaitement ngligeable.
Ceci est une difficult trs importante de lanalyse numrique : il nest a priori pas possible de rpondre de
faon unique cette question simple. Or de nombreux algorithmes utilisent les notions de grands/petits
nombres, par exemple pour dfinir des critres de convergence ou de divergence.
Exemple concret : calcul du rayon de Bohr de latome dhydrogne.
4
Chapitre 1 : Introduction
Le rayon de Bohr est dfini comme la valeur a0 minimisant la fonction nergie E(r) dfinie par
E(r) =
e2
~2
+
40 r 2mr2
Si lon calcule cette fonction nergie en J (ordre de grandeur des valeurs obtenues : 1019 ), un logiciel
tel que Matlab ne trouve pas le minimum correct, sauf si on lui prcise explicitement la constante de
convergence de lalgorithme utiliser.
En revanche tout se passe trs bien si cette nergie est calcule en eV, ce qui donne des valeurs caractristiques de lordre de lunit.
Cet exemple simple illustre le problme des ordres de grandeurs. De faon gnrale, il est de loin
prfrable, suivant le problme pos, dabandonner le systme uSI et de lui substituer un autre systme
dunits plus adapt aux grandeurs calcules. Une approche de ce type permet dliminer les trs grandes
ou petites valeurs, et de ne manipuler que des valeurs numriques de lordre de lunit. La conversion des
rsultats finaux en uSI peut se faire alors facilement partir dune simple tude du problme physique
tudi.
Une telle dmarche, trs simple mettre en oeuvre, permet dliminer beaucoup de problmes de prcision.
Chapter 2
2.1
Les systmes linaires sont relativement simples dun point de vue mathmatique, prcisment en raison
de la linarit des quations. On peut mettre en oeuvre deux types de mthodes numriques :
les mthodes directes, qui consistent manipuler directement les quations pour les rsoudre,
les mthodes itratives, qui consistent obtenir la solution par convergence dun processus itratif.
2.1.1
Cette mthode est la plus simple et la plus classique, elle correspond exactement ce que lon fait " la
main" :
de la premire quation, on exprime la premire inconnue x1 en fonction des autres inconnues, puis
on substitue cette expression dans les autres quations du systmes, faisant apparatre ainsi un
sous-systme dans lequel x1 nintervient pas,
on itre le mme schma jusqu ce que la matrice du systme devienne triangulaire suprieure
(toute la partie infrieure de la matrice - sous la diagonale - est remplie de zros),
une fois la triangularisation termine, on calcule xn , puis xn1 , et ainsi de suite jusqu x1 ; les
diffrentes solutions sont ainsi calcules de proche en proche.
Le principe de triangularisation permet
a11 a12
a21 a22
..
.
an1
a1n
x1
b1
a2n
x2 b2
.. .. = ..
..
.
. . .
ann
xn
..
.. ..
..
.
.
. .
0
0
0 ann
xn
bn
b01
b02
..
.
b0n
II)
10k x1 + x2
x1 + x2
= 0.5
=1
Utilisant des rels double prcision, on obtient alors les solutions suivantes :
k = 10
k = 12
Systme I
x1 = 0.5
x2 = 0.5
x1 = 0.5
x2 = 0.5
Systme II
x1 = 0.5
x2 = 0.5
x1 = 0.499989
x2 = 0.5
k = 14
k = 16
Systme I
x1 = 0.5
x2 = 0.5
x1 = 0.5
x2 = 0.5
Systme II
x1 = 0.499600
x2 = 0.5
x1 = 1.110223
x2 = 0.5
On constate donc que la rsolution du systme II donne des rsultats errons ds que k devient suffisamment grand, alors que la rsolution du systme I reste parfaitement stable.
Le programme ci-dessous illustre une implmentation de cette mthode de rsolution ; il est constitu
des blocs suivants :
les quatre premires fonctions alloc_vecteur, free_vecteur, alloc_matrice et free_matrice sont
des fonctions gnrales permettant de grer dynamiquement le stockage des matrices et vecteurs ;
ces fonctions sont utilises ici, mais ne font pas partie de lalgorithme du pivot de Gauss,
8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# include
# include
# include
# include
return pivot ;
}
/*
* Fonction de permutation de 2 lignes de la matrice
*/
void
permute_lignes ( double ** A ,
double * b ,
int n ,
int ligne1 ,
int ligne2 )
{
double x ;
int colonne ;
for ( colonne = 0; colonne < n ; colonne ++) {
x = A [ ligne1 ][ colonne ];
A [ ligne1 ][ colonne ] = A [ ligne2 ][ colonne ];
10
A [ ligne2 ][ colonne ] = x ;
}
x = b [ ligne1 ];
b [ ligne1 ] = b [ ligne2 ];
b [ ligne2 ] = x ;
}
/*
* Cette fonction cherche la solution du systme ax = b
* a est la matrice (n , n ) , b le second membre ( n ) et x la solution
* trouve ( n ) , n est la dimension du systme .
* La mthode de Gauss modifie a et b . Pour viter ce problme , on
* duplique a dans A , b dans B , et on utilise A et B pour la mthode
* du pivot de Gauss . On ne modifie donc ni a ni b .
* Valeur retourne : 0 en cas d erreur
*
1 en cas de succs
*/
int
gauss ( double ** a ,
double * b ,
double * x ,
int n )
{
int err , pivot , indpivot , ligne , colonne ;
double ** A , * B , coef ;
A = alloc_matrice ( n ) ;
if ( A == NULL )
return 0;
B = alloc_vecteur ( n ) ;
if ( B == NULL ) {
free_matrice (A , n ) ;
return 0;
}
// allocation matrice A
// copie de a dans A
// et de b dans B
err = 1;
for ( pivot = 0; pivot < n - 1; pivot ++) {
indpivot = trouve_pivot (A , n , pivot , pivot ) ;
if ( indpivot == -1) {
err = 0;
break ;
}
if ( pivot != indpivot )
permute_lignes (A , B , n , pivot , indpivot ) ;
// code d erreur
// allocation vecteur B
// permutation lignes
11
}
}
// err = 1 : on n a pas rencontr d erreur
// calcul des solutions , en remontant de la dernire jusqu la premire
if ( err == 1) {
for ( ligne = n - 1; ligne >= 0; ligne - -) {
coef = B [ ligne ];
for ( colonne = 1 + ligne ; colonne < n ; colonne ++)
coef -= A [ ligne ][ colonne ] * x [ colonne ];
x [ ligne ] = coef / A [ ligne ][ ligne ];
}
}
free_matrice (A , n ) ;
free_vecteur ( B ) ;
// dsallocation de A
// dsallocation de B
return err ;
}
/*
* Cette fonction calcule ( et affiche ) la diffrence Ax - b ( contrle )
*/
void
controle ( double ** a ,
double * b ,
double * x ,
int n )
{
double d ;
int i , j ;
printf ( " Vecteur Ax - b :\ n " ) ;
for ( i = 0; i < n ; i ++) {
d = -b [ i ];
for ( j = 0; j < n ; j ++)
d += a [ i ][ j ] * x [ j ];
printf ( " %9.2 e " , d ) ;
}
printf ( " \ n " ) ;
}
/*
* Cette fonction renvoie un nombre alatoire entre - range et + range
*/
double
frandom ( double range )
{
return range * (1.0 - 2.0 * ( double ) random () / RAND_MAX ) ;
}
/*
* Exemple d appel de la fonction gauss
* 1. on alloue dynamiquement a et b ( x = b + n )
* 2. la matrice a est alatoire entre -1 et +1 , idem pour b
* 3. on affiche a et b
* 4. on calcule la solution x par la fonction gauss
* 5. on affiche x , puis la diffrence ( ax - b )
* 6. on dsalloue a et b
*/
int
12
main ( void )
{
double ** a , * b , * x ;
int i , j , err , n ;
printf ( " Dimension de la matrice : " ) ;
scanf ( " % d " , & n ) ;
a = alloc_matrice ( n ) ;
if ( a == NULL ) {
printf ( " erreur d allocation de la matrice \ n " ) ;
return 0;
}
b = alloc_vecteur (2 * n ) ;
if ( b == NULL ) {
printf ( " erreur d allocation du vecteur second membre \ n " ) ;
free_matrice (a , n ) ;
return 0;
}
x = b + n;
for ( i = 0; i < n ; i ++) {
for ( j = 0; j < n ; j ++)
a [ i ][ j ] = frandom (1.0) ;
b [ i ] = frandom (1.0) ;
}
printf ( " Matrice a :\ n " ) ;
for ( i = 0; i < n ; i ++) {
for ( j = 0; j < n ; j ++)
printf ( " %9.6 f " , a [ i ][ j ]) ;
printf ( " \ n " ) ;
}
printf ( " Vecteur b :\ n " ) ;
for ( i = 0; i < n ; i ++)
printf ( " %9.6 f " , b [ i ]) ;
printf ( " \ n " ) ;
err = gauss (a , b , x , n ) ;
printf ( " Retour de la fonction gauss : % d \ n " , err ) ;
printf ( " Solution x :\ n " ) ;
for ( i = 0; i < n ; i ++)
printf ( " %9.6 f " ,x [ i ]) ;
printf ( " \ n " ) ;
controle (a , b , x , n ) ;
free_matrice (a , n ) ;
free_vecteur ( b ) ;
return 0;
}
13
-0.250954
-0.213538
-0.570849
-0.401769
4.16 e -17
On vrifie ainsi que la rsolution du systme fonctionne bien, la diffrence Ax b tant de lordre de
1016 .
2.1.2
Si la matrice A peut scrire sous la forme A = LU , o L et U sont des matrices triangulaires infrieure
et suprieure respectivement, alors le systme Ax = b peut se dcomposer en deux sous-systmes Ly = b
et U x = y.
Les matrices L et U tant triangulaires, la rsolution de chacun de ces deux sous-systmes est immdiate
:
Ly = b : on calcule y1 , y2 , ... yn (forward substitution),
U x = y : on calcule xn , xn1 , ... x1 (backward substitution).
Reste calculer cette dcomposition. On suppose les matrices dfinies par leurs coefficients
L = (ij ) , U = (ij ) , A = (aij )
ij = 0 si i < j
ij = 0 si i > j
Par dfinition du produit matriciel A = LU , on a
aij =
n
X
ik kj ,
i, j
k=1
si i < j
si i = j
si i > j
Cela nous conduit donc n2 quations, (n2 + n)/2 inconnues ij et (n2 + n)/2 inconnues ij . Il en
rsulte que lon a n inconnues de trop par rapport au nombre dquations. On va donc imposer n valeurs
particulires et ensuite dterminer les autres valeurs manquantes.
On se ramne ainsi un systme linaire de n quations n inconnues. Cela peut donner limpression
de ne pas beaucoup avancer puisque cest prcisment le problme que lon cherche rsoudre avec la
matrice A. En fait, lintrt de cette mthode est que la dtermination des coefficients ij et ij peut
se faire de faon immdiate, sans manipuler le systme dquations. Il sagit l de lalgorithme de Crout
qui consiste ragencer les quations dans un ordre adquat. Cette mthode peut tre dcrite par le
diagramme suivant :
ii = 1, i,
boucle sur j variant de 1 n
pour i variant de 1 j, calcul de ij par la formule ij = aij
i1
X
k=1
14
ik kj
aij
i1
X
!
ik kj
/jj
k=1
On peut vrifier que cette mthode nutilise tout instant que des valeurs ij et ij prcdemment
calcules, ce qui signifie que cette dcomposition est parfaitement rsolue numriquement.
Remarque : les mthodes de dcomposition LU peuvent galement mettre en oeuvre un choix de pivot
par permutation de colonnes de la matrice A ; cela rend la programmation plus dlicate, mais lalgorithme
gagne en stabilit numrique.
On peut modifier le programme prcdent en dfinissant les fonctions suivantes :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
/*
* Cette fonction initialise tous les lments de la matrice A 0
*/
void
zero_matrice ( double ** A ,
int n )
{
int i , j ;
for ( i = 0; i < n ; i ++) {
for ( j = 0; j < n ; j ++)
A [ i ][ j ] = 0.0;
}
}
/*
* Cette fonction calcule la dcomposition A = LU suivant
* l algorithme de Crout
*/
void
crout ( double ** A ,
double ** L ,
double ** U ,
int n )
{
int i , j ,k ;
zero_matrice (L , n ) ;
zero_matrice (U , n ) ;
for ( i = 0; i < n ; i ++)
L [ i ][ i ] = 1.0;
for ( j = 0; j < n ; j ++) {
for ( i = 0; i <= j ; i ++) {
U [ i ][ j ] = A [ i ][ j ];
for ( k = 0; k < i ; k ++)
U [ i ][ j ] -= L [ i ][ k ] * U [ k ][ j ];
}
for ( i = j + 1; i < n ; i ++) {
L [ i ][ j ] = A [ i ][ j ];
for ( k = 0; k < j ; k ++)
L [ i ][ j ] -= L [ i ][ k ] * U [ k ][ j ];
L [ i ][ j ] /= U [ j ][ j ];
}
}
}
/*
* Cette fonction rsoud le systme Ly =b , L tant triangulaire
15
2.1.3
La mthode itrative de Jacobi est fonde sur une recherche de point fixe, cest--dire que lon transforme
le systme initial Ax = b en lexprimant de la faon quivalente x = Bx + c.
Pour la mise en uvre de cette mthode, il est ncessaire de revenir quelques notions mathmatiques
simples.
A partir de la norme dun vecteur, on peut introduire la norme dune matrice par la dfinition
kAk = max
x6=0
16
kAxk
kxk
Uij =
aij
0
si i < j
si i j
Dij = aii ij
La mthode de Jacobi consiste choisir K = D, sous rserve que les coefficients diagonaux de la matrice
soient tous non nuls. On en dduit alors litration
xn+1 = I D1 A xn + D1 b = D1 [(A D) xn b]
que lon peut rcrire
xi,n+1
1 X
=
aij xj,n bi
aii
j6=i
17
2.1.4
La mthode itrative de Gauss-Seidel est similaire la prcdente, elle consiste simplement en un choix
diffrent de la matrice K.
De mme que dans litration de Jacobi, on suppose que les termes diagonaux de la matrice A sont tous
non nuls, et on choisit K = L + D. On en dduit alors litration suivante :
1
xn+1 = xn (L + D)
X
1 X
aij xj,n+1 +
aij xj,n bi
=
aii j<i
j>i
A condition de calculer les composantes xi,n+1 pour i croissant, cette expression dtermine parfaitement
le vecteur xn+1 .
Les itrations de Jacobi et Gauss-Seidel sont similaires par le principe. La principale diffrence rside
dans le fait que Jacobi utilise uniquement litration n pour calculer litration n + 1, alors que GaussSeidel utilise la fois litration n et les rsultats antrieurs de litration n + 1. Par consquent, on peut
intuitivement prvoir les comportements suivants :
en cas de convergence, Gauss-Seidel convergera plus rapidement que Jacobi,
en cas de divergence, Gauss-Seidel divergera plus rapidement aussi !
2.1.5
Afin dviter que les calculs sternisent, il est ncessaire de prvoir plusieurs critres darrt. On peut
citer les critres les plus frquemment utiliss :
kxn+1 xn k < : convergence absolue,
kxn+1 xn k < kxn k : convergence relative,
n < N : nombre maximal ditrations.
Les fonctions crites ci-dessous permettent la mise en oeuvre de ces deux mthodes itratives. A
lexcution, on peut par exemple tester le comportement de ces itrations avec des matrices coefficients alatoires. En pratique, on observe que la convergence ne sobtient que pour des matrices
diagonale dominante.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*
* Cette fonction renvoie la norme d un vecteur
*/
double
module ( double * x ,
int n )
{
double m = 0.0;
int i ;
for ( i = 0; i < n ; i ++)
m += x [ i ] * x [ i ];
return sqrt ( m ) ;
}
/*
* Cette fonction calcule z =x - y
*/
18
void
diff ( double * x ,
double * y ,
double * z ,
int n )
{
int i ;
for ( i = 0; i < n ; i ++)
z [ i ] = x [ i ] - y [ i ];
}
/*
* Cette fonction copie x dans y
*/
void
dup ( double * x ,
double * y ,
int n )
{
int i ;
for ( i = 0; i < n ; i ++)
y [ i ] = x [ i ];
}
/*
* Cette fonction implmente l itration de Jacobi
* a est la matrice , b le second membre , xn le vecteur solution de
* l itration courante , xnp le vecteur solution de la prochaine itration
* ( vecteur calcul par cette fonction )
*/
void
IterationJacobi ( double ** a ,
double * b ,
double * xn ,
double * xnp ,
int n )
{
int i , j ;
for ( i = 0; i < n ; i ++) {
xnp [ i ] = b [ i ];
for ( j = 0; j < n ; j ++) {
if ( i != j )
xnp [ i ] -= a [ i ][ j ] * xn [ j ];
}
xnp [ i ] /= a [ i ][ i ];
}
}
/*
* Cette fonction implmente l itration de Gauss - Seidel
* a est la matrice , b le second membre , xn le vecteur solution de
* l itration courante , xnp le vecteur solution de la prochaine itration
* ( vecteur calcul par cette fonction )
*/
void
I t e r a t i o n GaussSeidel ( double ** a ,
double * b ,
19
double * xn ,
double * xnp ,
int n )
{
int i , j ;
for ( i = 0; i < n ; i ++) {
xnp [ i ] = b [ i ];
for ( j = 0; j < i ; j ++)
xnp [ i ] -= a [ i ][ j ] * xnp [ j ];
for ( j = i + 1; j < n ; j ++)
xnp [ i ] -= a [ i ][ j ] * xn [ j ];
xnp [ i ] /= a [ i ][ i ];
}
}
/*
* Cette fonction gre la boucle ( Jacobi ou Gauss - Seidel )
*/
void Iteration ( double ** a ,
double * b ,
int n ,
double eps ,
void fIteration ( double ** , double * , double * , double * , int ) )
{
double m , * xn , * xnp , * ecart ;
int i , c = 0;
xn = alloc_vecteur (3 * n ) ;
if ( xn == NULL ) {
printf ( " erreur d allocation mmoire \ n " ) ;
return ;
}
xnp = xn + n ;
ecart = xnp + n ;
for ( i = 0; i < n ; i ++)
xn [ i ] = 0.0;
do {
c ++;
fIteration (a , b , xn , xnp , n ) ;
diff ( xn , xnp , ecart , n ) ;
dup ( xnp , xn , n ) ;
m = module ( ecart , n ) ;
if ( m < eps ||
1.0 / m < eps ||
c > 100)
break ;
} while (1) ;
// fonction d itration
// calcul de xnp - xn
// copie de xnp dans xn
// convergence
// divergence !
// trop d itrations
20
2.2
Le cas des systmes non linaires est beaucoup plus dlicat car les non-linarits sont gnratrices
dinstabilits numriques fortes.
Considrons lexemple relativement simple du systme suivant de deux quations deux inconnues :
(
2
f1 (x, y) = x2 y 2 1 = 0
2
f2 (x, y) = x2 2 2y 2 = 0
Lquation f1 (x, y) = 0 correspond une ligne courbe dans le plan xy ; de mme pour lquation
f2 (x, y) = 0. Le problme qui se pose alors consiste rechercher les intersections de ces lignes courbes.
En outre, ces lignes courbes peuvent dans certains cas dgnrer en simples points, ou encore en zones
continues deux dimensions (un demi-plan par exemple). Le cas particulier des fonctions ci-dessus est
illustr par le diagramme suivant :
Les quations f1 (x, y) = 0 et f2 (x, y) = 0
dfinissent des coniques dans le plan xy.
La rsolution du systme revient chercher
toutes les intersections entre ces coniques ;
dans le cas prsent, on constate aisment que
lon a 8 solutions distinctes possibles.
Si on gnralise un systme de n quations n inconnues, les lignes courbes prcdentes sont gnralement remplaces par des hyper-courbes de dimension n1, ce qui rend le problme encore plus complexe.
En fait, pour ces diverses raisons, il ny a pas de mthode miracle et universelle. On a imprativement
besoin de connatre et dintroduire dans le modle numrique des informations complmentaires sur le
systme rsoudre. Parmi les informations utiles, on trouve les points suivants :
le nombre de solutions distinctes ? en particulier peut-on attendre une solution unique ?
la position approximative de ces solutions.
Toute autre information a priori sur le systme est gnralement bienvenue, sous rserve de modifier en
consquence limplmentation des mthodes numriques de rsolution.
Sous rserve que lon parvienne cerner le problme pos, on peut simplifier le problme et gnraliser
la mthode de Newton-Raphson n dimensions.
Typiquement, le problme pos est du type
f1 (x1 , x2 , , xn ) = 0
f2 (x1 , x2 , , xn ) = 0
~ = (x1 , x2 , , xn )
notation vectorielle : X
..
fn (x1 , x2 , , xn ) = 0
21
n
X
fi ~
~
X xj = fi X
x
j
j=1
On obtient alors un systme linaire de n quations n inconnues qui sont les composantes du vecteur
~ Il ne reste alors plus qu rsoudre ce systme par les mthodes classiques adaptes ce genre de
X.
problme.
La mthode de Newton-Raphson utilise donc lorganigramme suivant :
Le programme ci-dessous donne un exemple de programmation de cette mthode ; seules les nouvelles
fonctions sont indiques ici.
1
2
3
4
5
6
7
8
9
10
11
12
13
/*
* Cette fonction calcule x - > x + dx
*/
void
add ( double * x ,
double * dx ,
int n )
{
int i ;
for ( i = 0; i < n ; i ++)
x [ i ] += dx [ i ];
22
}
/*
* Une fonction du systme rsoudre recevra 2 paramtres :
* - 1 pointeur double * , correspondant aux composantes x1 , x2 , ...
* - 1 entier correspondant au nombre d quations / inconnues
* Elle renverra un double correspondant la valeur de la fonction
*/
typedef double (* FONCTION ) ( double * , int ) ;
/*
* Le gradient d une fonction du systme rsoudre recevra 3 paramtres :
* - 1 pointeur double * , correspondant aux composantes x1 , x2 , ...
* - 1 pointeur double * , contenant en retour les composantes du gradient
*
en ce point
* - 1 entier correspondant au nombre d quations / inconnues
* Elle ne renverra rien
*/
typedef void (* GRADIENT ) ( double * , double * , int ) ;
# define EPS 1.0 e -12
/*
* Fonction de rsolution d un systme d quations non linaires
* - tabf : tableau des fonctions f1 , f2 ...
* - tabg : tableau des gradients correspondants
* - x0
: estimation initiale de la solution
* - n
: nombre d quations
* La fonction affiche l tat de la solution chaque itration , puis la
* solution finalement trouve et les valeurs des diffrentes fonctions
* en ce point .
* La fonction renvoie 1 si tout s est bien pass , 0 en cas de problme
*/
int
newton ( FONCTION * tabf ,
GRADIENT * tabg ,
double * x0 ,
int n )
{
int ok , c , i , j ;
double ** a , * b , * x , * gx , * dx , m ;
// On commence par quelques allocations mmoire
a = alloc_matrice ( n ) ;
if ( a == NULL ) {
printf ( " erreur d allocation mmoire ( matrice a ) \ n " ) ;
return 0;
}
b = alloc_vecteur (4 * n ) ;
if ( b == NULL ) {
printf ( " erreur d allocation mmoire ( vecteur b ) \ n " ) ;
free_matrice (a , n ) ;
return 0;
}
x = b + n;
dx = x + n ;
gx = dx + n ;
// x contient l estimation courante de la solution , dx le terme correctif
dup ( x0 , x , n ) ;
c = 0;
do {
23
c ++;
for ( i = 0; i < n ; i ++) {
tabg [ i ]( x , gx , n ) ;
for ( j = 0; j < n ; j ++)
a [ i ][ j ] = gx [ j ];
b [ i ] = - tabf [ i ]( x , n ) ;
}
ok = gauss (a , b , dx , n ) ;
if (! ok ) {
break ;
}
m = module ( dx , n ) ;
printf ( " itration %d , gauss %d ,
if ( m < EPS ) {
break ;
}
if ( c > 100) {
ok = 0;
break ;
}
add (x , dx , n ) ;
} while (1) ;
if ( ok ) {
// si ok =1 , tout s est bien pass , on
printf ( " x = " ) ;
// affiche les rsultats
for ( i = 0; i < n ; i ++)
printf ( " % g " , x [ i ]) ;
printf ( " \ n " ) ;
for ( i = 0; i < n ; i ++)
printf ( " f % d ( x ) = % e \ n " , i + 1 , tabf [ i ]( x , n ) ) ;
}
else {
printf ( " erreur dans newton \ n " ) ;
}
free_matrice (a , n ) ;
free_vecteur ( b ) ;
}
/*
* Fonction de calcul de x ^2
*/
double
sqr ( double x )
{
return x * x ;
}
/*
* Premire quation du systme : p [0] -> x et p [1] -> y
*/
double
f1 ( double * p ,
int n )
{
return sqr ( p [0]) - sqr ( sqr ( p [1]) - 1.0) ;
}
/*
* Gradient de la premire quation du systme : p [0] -> x et p [1] -> y
* gp [0] -> df1 / dx et gp [1] -> df1 / dy
24
*/
void
gf1 ( double * p ,
double * gp ,
int n )
{
gp [0] = 2.0 * p [0];
gp [1] = 4.0 * p [1] * (1.0 - sqr ( p [1]) ) ;
}
/*
* Seconde quation du systme : p [0] -> x et p [1] -> y
*/
double
f2 ( double * p ,
int n )
{
return sqr ( sqr ( p [0]) - 2.0) - 2 .0 * sqr ( p [1]) ;
}
/*
* Gradient
* gp [0] ->
*/
void
gf2 ( double
double
int n )
* p,
* gp ,
{
gp [0] = 4.0 * p [0] * ( sqr ( p [0]) - 2.0) ;
gp [1] = -4.0 * p [1];
}
/*
* Exemple d implmentation de la mthode de Newton
*/
# define N 2
int
main ( void )
{
FONCTION tabf [ N ];
GRADIENT tabg [ N ];
double x0 [ N ];
int i ;
for ( i = 0; i < N ; i ++) {
printf ( " Entrer la valeur de x0 [% d ] = " , i ) ;
scanf ( " % le " , x0 + i ) ;
}
tabf [0] = f1 ;
tabf [1] = f2 ;
tabg [0] = gf1 ;
tabg [1] = gf2 ;
newton ( tabf , tabg , x0 , N ) ;
return 0;
}
25
26
Chapter 3
27
Ce cas reste relativement ais, mais est toutefois moins favorable que le prcdent : la fonction varie doucement, sannule mais ne change
pas de signe.
28
Ces quelques exemples montrent quil est difficile de dfinir un algorithme numrique universel, et quil
est indispensable de connatre a priori certaines informations relatives la fonction et son/ses zro(s).
Cest alors en fonction de cette connaissance a priori que lon cherchera la mthode numrique la plus
adapte.
3.1
Cette mthode est trs simple mettre en oeuvre, mais elle est limite au cas dune fonction qui change
de signe de part et dautre de son zro.
La mthode est dcrite par les tapes suivantes :
on recherche dans un premier temps a et b > a tels que f (a)f (b) < 0 ; cette premire tape consiste
donc encadrer la solution cherche,
on choisit un point c entre a et b, puis on calcule f (c),
si f (a)f (c) < 0 la solution est entre a et c, sinon elle est entre c et b,
on remplace donc lintervalle [a, b] par [a, c] ou [c, b] suivant le cas et on itre le processus jusqu
convergence.
A chaque nouvelle itration, on rduit la longueur de lintervalle encadrant la solution cherche ; la
convergence est donc a priori garantie. Dautre part, la convergence sera dautant plus rapide que la
longueur du sous-intervalle [a, c] ou [c, b] est plus faible. Ne sachant a priori pas lequel de ces 2 intervalles
sera considrer litration suivante, on peut minimiser le pire des cas en choisissant c = (a + b)/2.
Dans ce cas, chaque nouvelle itration permet de diviser par 2 la longueur de lintervalle encadrant la
solution cherche. Si on note l0 la longueur initiale de lintervalle, on aura aprs n itrations ln = l0 /2n .
On peut considrer dans ce cas que litration converge si la condition ln < est satisfaite, soit encore
l0
n > log2
29
A titre dexemple : on suppose que la solution recherche est localise l0 = 10 prs et on veut trouver
la solution avec une prcision de 1012 , il faudra pour cela 44 itrations, ce qui est relativement peu.
Cette mthode est illustre par le diagramme suivant :
Mthode de la bisection/dichotomie :
a et b encadrent la solution, f (a)f (b) <
0,
c = (a + b)/2,
on remplace [a, b] par [a, c] ou [c, b] suivant le signe de f (a)f (c),
on itre jusqu assurer la convergence
du processus.
Le programme ci-dessous donne un exemple de programmation de cette mthode. Les paramtres passs
la fonction sont les valeurs initiales de a et b encadrant la solution cherche, la prcision souhaite, ainsi
que la fonction traiter. En retour, la fonction dichotomie retourne la valeur de la solution trouve.
On pourrait modifier le programme ci-dessous en contrlant :
que les paramtres initiaux a et b sont bien tels que a < b,
que la condition f (a)f (b) < 0 est bien satisfaite.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
30
else {
/* [a , b ] --> [c , b ] */
a = c;
fa = fc ;
}
e = b - a;
/* nouvelle longueur */
em = eps * ( fabs ( a ) + fabs ( b ) ) ;
}
return c ;
}
/*
* exemple de fonction dont on recherche le zro
*/
double
func ( double x )
{
return cos ( x + 3.0 * M_PI / 8.0) ;
}
/*
* programme principal
*/
int
main ( void )
{
double res ;
res = dichotomie ( -1.0 , +1.0 , 1.0 E -10 , func ) ;
printf ( " Solution : % f \ n " , res ) ;
printf ( " Valeur de la fonction : %.10 e \ n " , func ( res ) ) ;
return 0;
}
En modifiant le programme ci-dessus pour afficher ltat des diffrentes variables au fur et mesure du
calcul, on obtient la srie daffichages suivante :
iter = 1 ,
iter = 2 ,
iter = 3 ,
iter = 4 ,
iter = 5 ,
iter = 6 ,
iter = 7 ,
iter = 8 ,
iter = 9 ,
iter =10 ,
iter =11 ,
iter =12 ,
iter =13 ,
iter =14 ,
iter =15 ,
iter =16 ,
iter =17 ,
iter =18 ,
iter =19 ,
iter =20 ,
iter =21 ,
iter =22 ,
iter =23 ,
a =0.0000000000 ,
a =0.0000000000 ,
a =0.2500000000 ,
a =0.3750000000 ,
a =0.3750000000 ,
a =0.3750000000 ,
a =0.3906250000 ,
a =0.3906250000 ,
a =0.3906250000 ,
a =0.3925781250 ,
a =0.3925781250 ,
a =0.3925781250 ,
a =0.3925781250 ,
a =0.3925781250 ,
a =0.3926391602 ,
a =0.3926696777 ,
a =0.3926849365 ,
a =0.3926925659 ,
a =0.3926963806 ,
a =0.3926982880 ,
a =0.3926982880 ,
a =0.3926987648 ,
a =0.3926990032 ,
b =1.0000000000 ,
b =0.5000000000 ,
b =0.5000000000 ,
b =0.5000000000 ,
b =0.4375000000 ,
b =0.4062500000 ,
b =0.4062500000 ,
b =0.3984375000 ,
b =0.3945312500 ,
b =0.3945312500 ,
b =0.3935546875 ,
b =0.3930664062 ,
b =0.3928222656 ,
b =0.3927001953 ,
b =0.3927001953 ,
b =0.3927001953 ,
b =0.3927001953 ,
b =0.3927001953 ,
b =0.3927001953 ,
b =0.3927001953 ,
b =0.3926992416 ,
b =0.3926992416 ,
b =0.3926992416 ,
31
c =0.0000000000
c =0.5000000000
c =0.2500000000
c =0.3750000000
c =0.4375000000
c =0.4062500000
c =0.3906250000
c =0.3984375000
c =0.3945312500
c =0.3925781250
c =0.3935546875
c =0.3930664062
c =0.3928222656
c =0.3927001953
c =0.3926391602
c =0.3926696777
c =0.3926849365
c =0.3926925659
c =0.3926963806
c =0.3926982880
c =0.3926992416
c =0.3926987648
c =0.3926990032
-->
-->
-->
-->
-->
-->
-->
-->
-->
-->
-->
-->
-->
-->
-->
-->
-->
-->
-->
-->
-->
-->
-->
e =1.000000 e +00
e =5.000000 e -01
e =2.500000 e -01
e =1.250000 e -01
e =6.250000 e -02
e =3.125000 e -02
e =1.562500 e -02
e =7.812500 e -03
e =3.906250 e -03
e =1.953125 e -03
e =9.765625 e -04
e =4.882812 e -04
e =2.441406 e -04
e =1.220703 e -04
e =6.103516 e -05
e =3.051758 e -05
e =1.525879 e -05
e =7.629395 e -06
e =3.814697 e -06
e =1.907349 e -06
e =9.536743 e -07
e =4.768372 e -07
e =2.384186 e -07
a =0.3926990032 ,
a =0.3926990628 ,
a =0.3926990628 ,
a =0.3926990777 ,
a =0.3926990777 ,
a =0.3926990815 ,
a =0.3926990815 ,
a =0.3926990815 ,
a =0.3926990815 ,
a =0.3926990817 ,
a =0.3926990817 ,
a =0.3926990817 ,
b =0.3926991224 ,
b =0.3926991224 ,
b =0.3926990926 ,
b =0.3926990926 ,
b =0.3926990852 ,
b =0.3926990852 ,
b =0.3926990833 ,
b =0.3926990824 ,
b =0.3926990819 ,
b =0.3926990819 ,
b =0.3926990818 ,
b =0.3926990817 ,
c =0.3926991224
c =0.3926990628
c =0.3926990926
c =0.3926990777
c =0.3926990852
c =0.3926990815
c =0.3926990833
c =0.3926990824
c =0.3926990819
c =0.3926990817
c =0.3926990818
c =0.3926990817
-->
-->
-->
-->
-->
-->
-->
-->
-->
-->
-->
-->
e =1.192093 e -07
e =5.960464 e -08
e =2.980232 e -08
e =1.490116 e -08
e =7.450581 e -09
e =3.725290 e -09
e =1.862645 e -09
e =9.313226 e -10
e =4.656613 e -10
e =2.328306 e -10
e =1.164153 e -10
e =5.820766 e -11
Solution : 0.3926990817
Valeur de la fonction : -4.3014863723 e -11
On voit donc que le programme a converg en 35 itrations ; dautre part, on constate que la fonction
sannule bien 1011 prs au point trouv.
3.2
Cette deuxime mthode est limite au cas dune fonction variations relativement lentes ; dautre part
elle suppose comme la mthode prcdente de connatre a et b tels que f (a)f (b) < 0 (la condition a < b
nest pas ncessaire).
Le principe de la mthode consiste considrer a et b comme les deux premiers points de litration ;
puis construire Pn+2 en fonction de Pn et Pn+1 :
x0 = a, y0 = f (x0 ), P0 = (x0 , y0 ),
x1 = b, y1 = f (x1 ), P1 = (x1 , y1 ),
xn+2 = Intersection (Pn Pn+1 , y = 0), yn+2 = f (xn+2 ),
on itre le processus jusqu ce que kxn+2 xn+1 k < .
xn+1 xn
,
f (xn+1 ) f (xn )
yn+2 = f (xn+2 )
Contrairement la mthode prcdente, rien ne prouve que la longueur de lintervalle courant kxn+1 xn k
diminue dune itration lautre ; par consquent la convergence nest pas garantie comme avec la mthode de la dichotomie.
Dautre part, on constate que lon divise par f (xn+1 ) f (xn ), il y a donc un risque de divergence svre
si cette diffrence est faible.
Mthode de la scante :
a(1) et b(2) satisfont f (a)f (b) < 0,
c(3) est lintersection de la droite (12)
avec laxe des ordonnes,
on remplace [a, b] par [b, c],
on itre jusqu assurer la convergence
du processus.
Remarque : les intervalles sentendent au sens
large, sans conditions sur les bornes.
Le programme ci-dessous donne un exemple de programmation de cette mthode. Les paramtres passs
la fonction sont les valeurs initiales de a et b encadrant la solution cherche, la prcision souhaite,
ainsi que la fonction traiter. En retour, la fonction secante retourne la valeur de la solution trouve.
On pourrait modifier le programme ci-dessous en contrlant :
que la condition f (a)f (b) < 0 est bien satisfaite,
que litration ne diverge pas.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
33
return x3 ;
}
/*
* exemple de fonction dont on recherche le zro
*/
double
func ( double x )
{
return cos ( x + 3.0 * M_PI / 8.0) ;
}
/*
* programme principal
*/
int
main ( void )
{
double res ;
res = secante ( -1.0 , +1.0 , 1.0 E -10 , func ) ;
printf ( " \ nSolution : %.10 f \ n " , res ) ;
printf ( " Valeur de la fonction : %.10 e \ n " , func ( res ) ) ;
return 0;
}
En modifiant le programme ci-dessus pour afficher ltat des diffrentes variables au fur et mesure du
calcul, on obtient la srie daffichages suivante (convergence en 6 itrations) :
iter =
iter =
iter =
iter =
iter =
iter =
1,
2,
3,
4,
5,
6,
x1 =1.0000000000 ,
x1 =0.2659634698 ,
x1 =0.3990669391 ,
x1 =0.3926828633 ,
x1 =0.3926990818 ,
x1 =0.3926990817 ,
x2 =0.2659634698
x2 =0.3990669391
x2 =0.3926828633
x2 =0.3926990818
x2 =0.3926990817
x2 =0.3926990817
-->
-->
-->
-->
-->
-->
e =7.340365 e -01
e =1.331035 e -01
e =6.384076 e -03
e =1.621854 e -05
e =1.093298 e -10
e =5.551115 e -17
Solution : 0.3926990817
Valeur de la fonction : -1.6081226497 e -16
3.3
La mthode de la fausse position est une variante de la prcdente. Dans la mthode de la scante,
chaque itration consiste calculer xn+2 en fonction de xn et xn+1 , puis reprendre le mme schma en
remplaant xn par xn+1 et xn+1 par xn+2 .
La mthode de la fausse position utilise le mme principe, sauf quelle se rserve la possibilit dliminer
soit xn soit xn+1 pour litration suivante. On peut rsumer les deux mthodes par le tableau suivant :
Mthode de la scante
Mthode de la fausse position
Itration courante
[xn , xn+1 ]
[xn , xn+1 ]
Itration suivante
[xn+1 , xn+2 ]
[xn , xn+2 ] si f (xn ) f (xn+2 ) < 0
[xn+1 , xn+2 ] si f (xn+1 ) f (xn+2 ) < 0
35
/* valeurs de la fonction */
/*
/*
/*
/*
condition de convergence */
nouvelle position */
valeur correspondante de f */
limination de P ( n +1) */
/* limination de P ( n ) */
}
return x3 ;
En modifiant le programme ci-dessous pour afficher ltat des diffrentes variables au fur et mesure du
calcul, on obtient la srie daffichages suivante (convergence en 7 itrations) :
iter =
iter =
iter =
iter =
iter =
iter =
iter =
1,
2,
3,
4,
5,
6,
7,
x1 =0.2659634698 ,
x1 =0.2659634698 ,
x1 =0.3926828633 ,
x1 =0.3926828633 ,
x1 =0.3926990817 ,
x1 =0.3926990817 ,
x1 =0.3926990817 ,
x2 =1.0000000000
x2 =0.3990669391
x2 =0.3990669391
x2 =0.3926990818
x2 =0.3926990818
x2 =0.3926990817
x2 =0.3926990817
-->
-->
-->
-->
-->
-->
-->
e =1.265963 e +00
e =6.009331 e -01
e =1.267194 e -01
e =6.367857 e -03
e =1.621843 e -05
e =1.093298 e -10
e =0.000000 e +00
Solution : 0.3926990817
Valeur de la fonction : 6.1232339957 e -17
3.4
On peut comparer lefficacit de ces trois mthodes sur deux fonctions particulires, la seconde illustrant
le risque de divergence associ la mthode de la scante.
Premire fonction :
f (x) = x3 3x2 3x 35
a = 0, b = 7.
Convergence 1012 prs :
dichotomie : 45 calculs de la fonction f ,
scante : 19 calculs de la fonction f ,
fausse position : 37 calculs de la fonction
f.
Cette premire comparaison illustre le fait que la mthode de la scante est la plus rapide, et la dichotomie
la plus lente puisque cest elle qui requiert le plus dvaluations de la fonction traite.
Seconde fonction :
e10x 1
f (x) = 10x
0.5
e
+1
a = 0, b = 1.
Convergence 1012 prs :
dichotomie : 42 calculs de la fonction f ,
scante : divergence,
fausse position : 20 calculs de la fonction
f.
36
3.5
3.5.1
Principes gnraux
Une autre classe de mthodes consiste remplacer la recherche de zro de lquation f (x) = 0 par une
recherche de point fixe de lquation x = g(x), sous rserve que ces deux formulations soient mathmatiquement quivalentes.
Ces mthodes sont trs simples programmer, mais la convergence nest absolument pas garantie.
Dautre part, lcriture sous la forme x = g(x) nest pas unique.
A titre dexemple, on considre la fonction f (x) = x3 3x2 3x 35 et les trois critures suivantes :
g1 (x) =
35
,
x2 3x 3
g2 (x) =
x3 3x2 35
,
3
g3 (x) =
p
3
3x2 + 3x + 35.
// boucle d itration
x1 = g ( x0 ) ;
e = fabs ( x0 - x1 ) ;
em = eps * ( fabs ( x0 ) + fabs ( x1 ) ) ;
x0 = x1 ;
if ( iter > maxiter || ! finite ( x0 ) ) {
err = 1;
break ;
}
} while ( e > em ) ;
if ( err ) {
printf ( " Pas de convergence \ n " ) ;
ret = 0.0;
}
else {
// cart x0 / x1
// contrle d erreur
// - trop d itrations
// - divergence ( x0 infini )
// critre de convergence
// si erreur
37
ret = x0 ;
}
return ret ;
}
/*
* Premire solution possible
*/
double
g1 ( double x )
{
return 35.0 / ( x * ( x - 3.0) - 3.0) ;
}
/*
* Deuxime solution possible
*/
double
g2 ( double x )
{
return (( x - 3.0) * x * x - 35.0) / 3.0;
}
/*
* Troisime solution possible
*/
double
g3 ( double x )
{
# define UNTIERS 0. 333 33 333 33 333 333 33 33
return pow (3.0 * x * ( x + 1.0) + 35.0 , UNTIERS ) ;
}
/*
* Fonction initiale dont on cherche un zro
*/
double
f ( double x )
{
return x * ( x * ( x - 3.0) - 3.0) - 35.0;
}
/*
* Programme principal
*/
int
main ( void )
{
double x0 , x1 ;
int IDg ;
printf ( " Valeur initiale : " ) ;
scanf ( " % le " , & x0 ) ;
printf ( " Entrer 1 , 2 ou 3 ( g1 , g2 , g3 ) : " ) ;
scanf ( " % d " , & IDg ) ;
38
switch ( IDg ) {
case 1:
printf ( " Itration avec g1 :\ n " ) ;
x1 = pointfixe ( x0 , 1.0 E -10 , 100 , g1 ) ;
printf ( " % e % e \ n " , x1 , f ( x1 ) ) ;
break ;
case 2:
printf ( " Itration avec g2 :\ n " ) ;
x1 = pointfixe ( x0 , 1.0 E -10 , 100 , g2 ) ;
printf ( " % e % e \ n " , x1 , f ( x1 ) ) ;
break ;
case 3: default :
printf ( " Itration avec g3 :\ n " ) ;
x1 = pointfixe ( x0 , 1.0 E -10 , 100 , g3 ) ;
printf ( " % e % e \ n " , x1 , f ( x1 ) ) ;
break ;
}
return 0;
}
Lorsque lon excute ce programme avec x0 = 0 en itrant la fonction g1 , on observe les affichages suivants
:
Valeur initiale : 0
Entrer 1 , 2 ou 3 ( g1 , g2 , g3 ) : 1
Itration avec g1 :
iter = 1 , x0 = -11.6666666667
iter = 2 , x0 =0.2081956378
iter = 3 , x0 = -9.7731471333
iter = 4 , x0 =0.2872764923
iter = 5 , x0 = -9.2609701040
iter = 6 , x0 =0.3166031841
iter = 7 , x0 = -9.0919198854
iter = 8 , x0 =0.3272901028
iter = 9 , x0 = -9.0328373385
iter = 10 , x0 =0.3311550822
iter = 11 , x0 = -9.0117889586
iter = 12 , x0 =0.3325488123
iter = 13 , x0 = -9.0042398342
iter = 14 , x0 =0.3330508602
iter = 15 , x0 = -9.0015257981
iter = 16 , x0 =0.3332316371
iter = 17 , x0 = -9.0005492171
iter = 18 , x0 =0.3332967219
iter = 19 , x0 = -9.0001977090
iter = 20 , x0 =0.3333201531
iter = 21 , x0 = -9.0000711741
iter = 22 , x0 =0.3333285884
iter = 23 , x0 = -9.0000256225
iter = 24 , x0 =0.3333316252
iter = 25 , x0 = -9.0000092241
iter = 26 , x0 =0.3333327184
iter = 27 , x0 = -9.0000033207
iter = 28 , x0 =0.3333331120
iter = 29 , x0 = -9.0000011954
iter = 30 , x0 =0.3333332536
iter = 31 , x0 = -9.0000004304
iter = 32 , x0 =0.3333333046
iter = 33 , x0 = -9.0000001549
iter = 34 , x0 =0.3333333230
iter = 35 , x0 = -9.0000000558
iter = 36 , x0 =0.3333333296
iter = 37 , x0 = -9.0000000201
iter = 38 , x0 =0.3333333320
iter = 39 , x0 = -9.0000000072
iter = 40 , x0 =0.3333333329
iter = 41 , x0 = -9.0000000026
iter = 42 , x0 =0.3333333332
iter = 43 , x0 = -9.0000000009
iter = 44 , x0 =0.3333333333
iter = 45 , x0 = -9.0000000003
iter = 46 , x0 =0.3333333333
iter = 47 , x0 = -9.0000000001
iter = 48 , x0 =0.3333333333
iter = 49 , x0 = -9.0000000000
...
iter =100 , x0 =0.3333333333
iter =101 , x0 = -9.0000000000
Pas de convergence
On obtient exactement les mmes rsultats pour x0 = 10 ou x0 = 5.1, alors que cette valeur initiale est
assez proche de la solution x = 5.
On remarque que lon na pas convergence, ni divergence car la variable x0 dans la fonction pointfixe
reste toujours finie. En fait, la non-convergence se traduit par une oscillation entre les deux valeurs 1/3
et -9 ; on peut aisment vrifier g1 (9) = 1/3 et g1 (1/3) = 9.
En itrant la fonction g2 , on obtient
Valeur initiale : 0
Entrer 1 , 2 ou 3 ( g1 , g2 , g3 ) : 2
iter =
iter =
39
4 , x0 = -3.742339909 e +23
5 , x0 = -1.747062486 e +70
avec g2 :
x0 = -11.66666667
x0 = -677.0987654
x0 = -103933325.7
Ce cas de figure traduit une divergence par valeurs infinies ; cette divergence sobserve galement pour
une valeur initiale x0 proche de la solution x = 5.
Enfin en itrant la fonction g3 , on obtient
Valeur initiale : 0
Entrer 1 , 2 ou 3 ( g1 , g2 , g3 ) : 3
Itration avec g3 :
iter = 1 , x0 =3.2710663102
iter = 2 , x0 =4.2527147287
iter = 3 , x0 =4.6725561021
iter = 4 , x0 =4.8561124603
iter = 5 , x0 =4.9367201379
iter = 6 , x0 =4.9721623348
iter = 7 , x0 =4.9877524487
iter = 8 , x0 =4.9946112720
iter = 9 , x0 =4.9976289970
iter = 10 , x0 =4.9989567659
iter = 11 , x0 =4.9995409784
iter = 12 , x0 =4.9997980308
iter = 13 , x0 =4.9999111336
iter = 14 , x0 =4.9999608988
iter = 15 , x0 =4.9999827955
iter = 16 , x0 =4.9999924300
iter = 17 , x0 =4.9999966692
iter = 18 , x0 =4.9999985344
iter = 19 , x0 =4.9999993552
iter = 20 , x0 =4.9999997163
iter = 21 , x0 =4.9999998752
iter = 22 , x0 =4.9999999451
iter = 23 , x0 =4.9999999758
iter = 24 , x0 =4.9999999894
iter = 25 , x0 =4.9999999953
iter = 26 , x0 =4.9999999979
iter = 27 , x0 =4.9999999991
iter = 28 , x0 =4.9999999996
5.000000 e +00 -1.674087 e -08
On peut interprter ces diffrents comportements par une reprsentation graphique des fonctions g1 , g2
et g3 :
40
3.5.2
La mthode de Newton-Raphson est un cas particulier de mthode de recherche de point fixe, supposant
connue la fonction ainsi que sa drive.
Le principe de litration consiste calculer lintersection de la tangente au point (xn , yn = f (xn )) et
laxe y = 0, labscisse de cette intersection dfinissant xn+1 . On peut lillustrer par le diagramme suivant
:
Mthode de Newton-Raphson :
xn+1 = xn
f (xn )
f 0 (xn )
Il est trs facile de modifier le programme prcdent pour mettre en oeuvre cette mthode ; il suffit
simplement de rajouter avant la fonction main les extraits de codes suivants :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
* Calcul de la drive pour Newton - Raphson
*/
double
fd ( double x )
{
return 3.0 * ( x * ( x - 2.0) - 1.0) ;
}
/*
* Itration de Newton - Raphson
*/
double
g4 ( double x )
{
return x - f ( x ) / fd ( x ) ;
}
41
Valeur initiale : 10
Entrer 1 , 2 , 3 , 4 ( g1 , g2 , g3 , g4 ) : 4
Itration avec g4 :
iter = 1 , x0 =7.3206751055
iter = 2 , x0 =5.7871790482
iter = 3 , x0 =5.1340429493
iter = 4 , x0 =5.0048690621
iter = 5 , x0 =5.0000067603
iter = 6 , x0 =5.0000000000
5.000000 e +00 0.000000 e +00
On remarque que lon a convergence dans les deux cas, correspondants deux valeurs diffrentes du
point de dpart de litration. La mthode de Newton-Raphson est gnralement efficace et rapide, sauf
si lexploration des diffrents points ditration conduit au voisinage dun extremum.
Lintrt principal de cette mthode est que la convergence est quadratique. Supposons en effet que x
soit le zro recherch ; on a alors par dveloppement de Taylor au deuxime ordre :
f (x + ) f (x) + f 0 (x) + 2 f 00 (x) /2 +
f 0 (x + ) f 0 (x) + f 00 (x) +
Lors de litration i, le point courant xi est spar de x dune distance (petite, cest la condition de
convergence) i : xi = x + i . Appliquant alors la relation dfinissant litration de Newton, on vrifie
immdiatement que lon a
xi+1 = xi
f (xi )
,
f 0 (xi )
i+1 2i
f 00 (xi )
= C2i
2f 0 (xi )
Hormis la constante C qui ne dpend que du comportement de la fonction au voisinage de son zro x,
on constate bien que la convergence est quadratique. Autrement dit, la convergence sera trs rapide
ds lors que lon aura effectivement atteint une zone proche de la racine recherche. Cette mthode est
largement utilise si lon connat la fonction et sa drive avec bonne prcision.
Noter que cette mthode nest pas utilisable si la racine cherche annule galement la drive, ce qui
serait par exemple le cas dun polynme racine de multiplicit suprieure 1. Noter dautre part quil
est absolument sans intrt dutiliser la mthode de Newton-Raphson avec la drive calcule par une
formule approche du type
f (x + dx) f (x)
f 0 (x)
dx
En effet, on peut montrer que la convergence quadratique est perdue dans ce cas. Dautre part, la
prcision de ce calcul approch est hautement discutable.
Exemple : on cherche calculer la racine k i`eme de A > 0, on choisit donc f (x) = xk A dont la drive
est f 0 (x) = kxk1 ; do litration de Newton-Raphson :
1
A
xn+1 =
(k 1)xn + k1
k
xn
Si k = 2, cette itration scrit encore
A
xn +
xn+1
xn
42
3.6
Les polynmes sont des fonctions particulires pour lesquelles les mthodes prcdentes sont gnralement
applicables. Nanmoins, la forme spcifique des polynmes permet de dfinir dautres mthodes, telles
que la mthode de Laguerre.
A titre de rappel, un polynme de degr n a exactement n racines complexes, distinctes ou non. Il faut
gnralement envisager le problme des racines dun polynme dans le cadre de larithmtique complexe.
Dautre part, dans le cas dun polynme coefficients rels, une racine non relle de la forme a + ib
implique que aib est galement solution ; cette remarque peut permettre dans certains cas dconomiser
en temps de calcul, la seconde solution ne ncessitant aucun calcul.
La mthode de Laguerre se dcompose en deux temps :
la mthode de Laguerre proprement dite, destine calculer une racine particulire du polynme,
la dflation polynmiale, consistant rduire le degr du polynme par division euclidienne.
Premire tape : la recherche dune racine particulire (attention, on nessaie pas de justifier la mthode
de faon parfaitement rigoureuse dun point de vue mathmatique).
Cette premire tape repose sur les observations suivantes :
Pn (x)
ln |Pn (x)|
d ln |Pn (x)|
dx
d2 ln |Pn (x)|
dx2
= (x x1 ) (x x2 ) (x xn )
= ln |x x1 | + ln |x x2 | + + ln |x xn |
1
1
1
P0
=
+
+ +
= n G
x x1
x x2
x xn
Pn
0 2
1
1
Pn
1
Pn00
+
+
+
=
=
H
2
2
2
Pn
Pn
(x x1 )
(x x2 )
(x xn )
On fait alors lhypothse suivante : la racine x1 est situe une distance a de lestimation x un instant
donn, alors que toutes les autres racines sont distantes de b, soit encore
a = x x1 ,
b = x xi , i 6= 1
Moyennant cette hypothse pour le moins drastique, les relations prcdentes scrivent sous la forme
1 n1
+
=G
a
b
soit encore
a=
1
n1
+ 2 =H
2
a
b
et
n
(n 1) (nH G2 )
le signe tant choisi afin de rendre maximum (en module complexe) le dnominateur.
Ce schma est alors utilis de faon itrative : si x est lestimation correspondant litration courante,
alors x a constitue une nouvelle estimation, normalement meilleure. Litration se poursuit jusqu ce
que a soit suffisamment petit.
Aussi tonnant que cela puisse paratre (lhypothse faite ci-dessus est plutt ose !), la mthode converge
bien vers lune des racines du polynme.
Seconde tape : la dflation polynmiale.
La mthode prcdente nous a permis dobtenir la racine x1 , on sait donc que le polynme Pn est divisible
(au sens de la division euclidienne des polynmes) par x x1 :
Pn (x) = (x x1 ) Qn1 (x)
La dflation polynmiale consiste donc calculer cette division euclidienne pour obtenir Qn1 . Il ne
reste alors plus qu itrer lensemble du processus jusqu ce que le polynme rsiduel soit de degr 1.
43
// champs privs
44
double re ;
double im ;
// partie relle
// partie imaginaire
public :
double Re () {
return re ;
}
double Im () {
return im ;
}
complex () {
re = 0.0;
im = 0.0;
}
complex ( double x ) {
re = x ;
im = 0.0;
}
// initialisation re / im
/*
* Dfinition de quelques fonctions simples & utiles
*/
complex conjugue () {
return complex ( re , - im ) ;
}
double module_carre () {
return re * re + im * im ;
}
double module () {
return :: sqrt ( module_carre () ) ;
}
/*
* Dfinition d oprateurs sur variables de type complex
*/
complex operator + ( complex second ) {
return complex ( re + second . re ,
im + second . im ) ;
}
complex operator - ( complex second ) {
return complex ( re - second . re ,
im - second . im ) ;
}
complex operator * ( complex second ) {
return complex ( re * second . re - im * second . im ,
re * second . im + im * second . re ) ;
}
complex operator / ( double second ) {
return complex ( re / second ,
45
im / second ) ;
}
complex operator / ( complex second ) {
return (* this ) * second . conjugue () / second . module_carre () ;
}
/*
* Dclaration de la fonction sqrt ( complex )
*/
complex sqrt () ;
};
/*
* Implmentation de la fonction sqrt ( complex )
*/
complex
complex :: sqrt ()
{
double wk , zre , zim ;
if ( im == 0.0) {
if ( re < 0.0)
return complex (0.0 , :: sqrt ( - re ) ) ;
else
return complex (:: sqrt ( re ) , 0.0) ;
}
wk = re + module () ;
zre = :: sqrt ( wk / 2.0) ;
zim = im / ( zre * 2.0) ;
return complex ( zre , zim ) ;
}
/*
* Dfinition d une classe polynome
* L intrt majeur est de pouvoir assurer une gestion correcte des
* pointeurs , et des allocations / dsallocations correspondantes
*/
class polynome {
private :
int degre ;
complex * a ;
// champs privs
// degr du polynme
// tableau de coefficients
public :
polynome () {
degre = -1;
a = NULL ;
}
~ polynome () {
degre = -1;
if ( a != NULL )
free ( a ) ;
a = NULL ;
}
// destructeur ( dsallocations
// mmoire automatiques )
46
/*
* Dclaration des fonctions manipulant
*/
complex Valeur ( complex x ) ;
int Init ( int deg ) ;
int Init ( int deg ,
complex * v ) ;
int Diff ( polynome * PDiff ) ;
void Affiche ( char * ent ) ;
la classe
// calcul de P ( x )
// initialisation 0
// initialisation v
// drivation de P
// affichage de P
/*
* Redfinition de l oprateur =
*/
polynome & operator = ( polynome & P ) {
Init ( P . degre , P . a ) ;
return * this ;
}
/*
* Fonctions de la classe pour la mthode de Laguerre
*/
int Deflation ( polynome * Q ,
complex r ) ;
int IterLaguerre ( complex x ,
double eps ,
complex * zero ) ;
void Laguerre () ;
};
/*
* Calcul de P ( x )
*/
complex
polynome :: Valeur ( complex x )
{
complex res (0.0 , 0.0) , xi (1.0 , 0.0) ;
int i ;
if ( degre < 0 || a == NULL )
return res ;
for ( i = 0; i <= degre ; i ++) {
res = res + a [ i ] * xi ;
xi = xi * x ;
}
return res ;
}
/*
* Initialisation d un polynme , coefficients nuls
* Le tableau des coefficients est rallou dynamiquement
* Valeur retourne : 0 en cas d erreur , 1 sinon
*/
int
polynome :: Init ( int deg )
{
complex * buf ;
int i , ret = 0;
47
48
if ( ent != NULL )
printf ( " % s " , ent ) ;
for ( i = 0; i <= degre ; i ++) {
printf ( " (% g +% g J ) " , a [ i ]. Re () , a [ i ]. Im () ) ;
if ( i != 0)
printf ( " x ^% d " , i ) ;
if ( i != degre )
printf ( " + " ) ;
}
printf ( " \ n " ) ;
}
/*
* Calcul de la dflation polynmiale par division de P par x - r
*/
int
polynome :: Deflation ( polynome * Q ,
complex r )
{
int i ;
if (! Q - > Init ( degre - 1) )
return 0;
for ( i = Q - > degre ; i >= 0; i - -) {
if ( i == Q - > degre )
Q - > a [ i ] = a [ i + 1];
else
Q - > a [ i ] = a [ i + 1] + r * Q - > a [ i + 1];
}
return 1;
}
/*
* Cette fonction recherche un zro particulier par l itration de
* Laguerre ; x est la valeur initiale de l itration , eps la prcision
* dsire et zero contient la solution trouve .
* Valeur retourne par la fonction : nombre d itrations
*/
int
polynome :: IterLaguerre ( complex x ,
double eps ,
complex * zero )
{
polynome p1 , p2 ;
complex a , px , p1x , p2x , G , G2 , H , SQ , D1 , D2 ;
double m1 , m2 ;
int c = 0;
// Calcul et affichage de P , P et P
Affiche ( " p ( x ) = " ) ;
Diff (& p1 ) ;
p1 . Affiche ( " p ( x ) = " ) ;
p1 . Diff (& p2 ) ;
p2 . Affiche ( " p ( x ) = " ) ;
49
// Boucle d itration
do {
c ++;
px = this - > Valeur ( x ) ;
// Calcul de P ( x )
if ( px . module () < eps ) {
// P ( x ) =0 ?
* zero = x ;
// oui , on a trouv
break ;
}
p1x = p1 . Valeur ( x ) ;
// Calcul de P ( x )
p2x = p2 . Valeur ( x ) ;
// Calcul de P ( x )
G = p1x / px ;
// Calcul de G , H et a
G2 = G * G ;
H = G2 - p2x / px ;
SQ = (( H * this - > degre - G2 ) * ( this - > degre - 1) ) . sqrt () ;
D1 = G + SQ ;
m1 = D1 . module () ;
D2 = G - SQ ;
m2 = D2 . module () ;
a = complex ( this - > degre , 0.0) / ( m1 > m2 ? D1 : D2 ) ;
x = x - a;
// nouvelle valuation
} while ( c < 100) ;
// max 100 itrations ( arbitraire )
return c ;
}
/*
* Cette fonction recherche et affiche les racines du polynme
* Lorsqu une racine est trouve , on calcule la dflation polynmiale ,
* puis on recommence avec le polynme rsultant
*/
void
polynome :: Laguerre ()
{
int i , c ;
complex zero ;
polynome q1 , q2 ;
q1 = * this ;
for ( i = 1; i <= this - > degre ; i ++) {
c = q1 . IterLaguerre ( complex (0.0 , 0.0) , 1.0 E -14 , & zero ) ;
q1 . Deflation (& q2 , zero ) ;
q1 = q2 ;
printf ( " % d iterations , x =% e % e \ n " , c , zero . Re () , zero . Im () ) ;
}
}
/*
* Cette fonction main illustre simplement la faon d utiliser la
* rsolution par la mthode de Laguerre
*/
int
main ( void )
{
complex a [4];
polynome p ;
a [0]
a [1]
a [2]
a [3]
=
=
=
=
-3.0;
-2.0;
-2.0;
1.0;
50
p . Init (3 , a ) ;
p . Laguerre () ;
return 0;
}
51
Chapter 4
Minimisation/maximisation dune
fonction
4.1
Introduction
xi
2h
53
En effet, cette approximation est souvent dune prcision assez mdiocre ; le calcul du gradient complet
ncessite n + 1 valuations de la fonction f , ce qui peut tre relativement long en temps de calcul. Enfin,
une formule de ce type est dlicate car elle doit choisir un pas h adquat : ni trop grand (mathmatiquement, lestimation de la drive est alors plutt mdiocre), ni trop petit (le problme dans ce cas
est plutt numrique, le calcul de la fonction f faisant mal - voire pas du tout - la diffrente entre xi + h
et xi h). Les critres de validit du pas h dpendent beaucoup de la fonction, et du point en lequel
on calcule la drive. Par consquent, il est dlicat de dfinir un algorithme un peu gnral mettant en
oeuvre ce genre de technique.
4.2
Le cas de figure le plus simple est naturellement celui des fonctions une seule variable. Le principe
gnral de recherche dun minimum consiste en une mthode itrative par encadrements successifs du
minimum recherch.
Cette mthode sinspire de la dichotomie : partant dun encadrement initial du minimum, on cherche
rduire lintervalle dencadrement jusqu ce que lon puisse considrer que lon a atteint le seuil de
convergence.
Pour encadrer un zro, deux valeurs suffisent, sous rserve que la fonction change de signe. Dans le cas
dun minimum local, trois valeurs a, b et c sont ncessaires, satisfaisant les conditions suivantes :
a < b < c,
Par continuit de la fonction f , on a alors un minimum entre a et c. On choisit alors un point intermdiaire
x entre a et b, ou entre b et c.
Suivant la position de b par rapport x, et en fonction de f (b) par rapport f (x), on doit distinguer
quatre cas de figures diffrents illustrs par les diagrammes ci-dessous.
On poursuit ainsi litration jusqu ce que lon ait atteint le seuil de convergence souhait, savoir que
la longueur de lintervalle dencadrement |c a| soit suffisamment petite.
Le problme qui se pose ici est "Quentend-on par suffisamment petit ?". La premire rponse que lon
peut apporter cette question est |c a| < , o est la prcision de lordinateur (108 ou 1015 en
simple ou double prcision). De manire gnrale, il est prfrable de faire une comparaison en valeurs
relatives plutt quen valeurs absolues : |c a| < max (|a|, |c|).
Au voisinage de son minimum b, on peut crire par dveloppement de Taylor au second ordre la fonction
sous la forme
1
f (x) f (b) + f 00 (b)(x b)2
2
Si lon veut que la fonction atteigne son minimum la prcision machine prs, on a :
1 00
f (b)(x b) < |f (b)| si f (b) 6= 0
2
1 00
si f (b) = 0
f (b)(x b) <
2
soit encore
2 |f (b)|
|x b| < |f 00 (b)|
s
|x b| < |f 00 (b)|
54
si f (b) 6= 0
si f (b) = 0
x>b
Intervalle courant :
a, b, c
Nouvel intervalle :
a, b, x
Intervalle courant :
a, b, c
Nouvel intervalle :
b, x, c
x<b
Intervalle courant :
a, b, c
Nouvel intervalle :
x, b, c
Intervalle courant :
a, b, c
Nouvel intervalle :
a, x, b
55
Linconvnient de cette mthode est quelle doit garantir que le dnominateur reste suffisamment grand
afin de limiter les risques derreurs numriques (le dnominateur nul correspond trois points aligns).
Dans le cadre de cette mthode, on peut galement considrer que b est une valuation approche du
minimum, et que le second terme de lexpression ci-dessus correspond un terme correctif. On peut
donc ajouter aux critres de convergence prcdents un test portant sur la valeur de ce terme correctif :
sil est assez faible, alors b ou x est la solution recherche.
Le programme ci-dessous donne un exemple dimplmentation de cette mthode, avec la fonction polynmiale f (x) = x4 3x3 + 10x2 5x 5.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
56
void
chang e_intervalle ( double
double
double
double
double
double
double
double
* a,
* b,
* c,
* fa ,
* fb ,
* fc ,
x,
fx )
{
if ( x > * b ) {
if ( fx > * fb ) {
*c = x;
* fc = fx ;
}
else {
*a = *b;
* fa = * fb ;
*b = x;
* fb = fx ;
}
}
else {
if ( fx > * fb ) {
*a = x;
* fa = fx ;
}
else {
*c = *b;
* fc = * fb ;
*b = x;
* fb = fx ;
}
}
}
/*
* Cette fonction calcule le minimum encadr par les 3 points
* de rfrence a , b et c
* Elle retourne la valeur du minimum trouv , ainsi que la
* valeur de la fonction en ce point
*/
int
brent ( double a ,
double b ,
double c ,
double (* f ) ( double ) ,
double * xmin ,
double * fmin )
{
double n , d , fa , fb , fc , x , fx ;
int ok = 1 , it = 0;
// On vrifie que les points a , b et c satisfont les hypothses de base
if ( b <= a || b >= c ) {
printf ( " Paramtres invalides (a , b , c ) \ n " ) ;
return 0;
}
fa = f ( a ) ;
fb = f ( b ) ;
fc = f ( c ) ;
57
if ( fb >= fa || fb >= fc ) {
printf ( " Paramtres invalides ( f ( a ) , f ( b ) , f ( c ) ) \ n " ) ;
return 0;
}
// Boucle d itration de la mthode de Brent
do {
it ++;
n = sqr ( b - a ) * ( fb - fc ) - sqr ( b - c ) * ( fb - fa ) ;
d = ( b - a ) * ( fc - fb ) - ( b - c ) * ( fa - fb ) ;
if ( fabs ( d ) < ZERO ) {
if ( fabs ( n ) < ZERO ) {
x = b;
}
else {
ok = 0;
}
break ;
}
// x rsulte de l interpolation parabolique
x = b + n / (2.0 * d ) ;
fx = f ( x ) ;
// x serait la solution cherche ?
if ( fabs ( b - x ) < EPS * ( fabs ( b ) + fabs ( x ) ) ) {
break ;
}
// nombre excessif d itrations
if ( it > 100) {
ok = 0;
break ;
}
change_intervalle (& a , &b , &c , & fa , & fb , & fc , x , fx ) ;
printf ( " iteration %d , x =% e \ n " , it , x ) ;
} while ( fabs ( c - a ) > EPS * ( fabs ( a ) + fabs ( c ) ) ) ;
// Si tout s est bien pass , on doit avoir ok =1 !
if ( ok == 1) {
* xmin = x ;
* fmin = fx ;
printf ( " brent : minimum x =% e , f ( x ) =% e \ n " , x , fx ) ;
}
return ok ;
}
/*
* f est la fonction minimiser
*/
double
f ( double x )
{
return x * ( x * ( x * ( x - 3) + 10) - 5) - 5;
}
/*
* Programme principal
*/
int
main ( void )
{
double x , fx ;
58
La figure ci-dessous illustre la fonction f (x) = x4 3x3 + 10x2 5x 5 dans lintervalle [1, +2], ce
qui permet de vrifier que les valeurs initiales 1, 0.5 et +2 satisfont effectivement aux conditions
ncessaires pour appliquer ce schma numrique. En outre, on observe que la position du minimum
trouv (0.28112), ainsi que la valeur de la fonction f (x) en ce point, sont cohrentes avec le graphique.
4.3
Daprs ce qui prcde, on est en thorie capable de minimiser une fonction dune variable. A n dimensions, connaissant
59
60
61
double n , d , fa , fb , fc , x , fx = 0.0;
int ok = 1 , it = 0;
if ( b <= a || b >= c ) {
printf ( " Paramtres invalides (a , b , c ) \ n " ) ;
return 0;
}
fa = f (a , fbuffer ) ;
fb = f (b , fbuffer ) ;
fc = f (c , fbuffer ) ;
if ( fb >= fa || fb >= fc ) {
printf ( " Paramtres invalides ( f ( a ) , f ( b ) , f ( c ) ) \ n " ) ;
return 0;
}
do {
it ++;
n = sqr ( b - a ) * ( fb - fc ) - sqr ( b - c ) * ( fb - fa ) ;
d = ( b - a ) * ( fc - fb ) - ( b - c ) * ( fa - fb ) ;
if ( fabs ( d ) < ZERO ) {
if ( fabs ( n ) < ZERO ) {
x = b;
}
else {
ok = 0;
}
break ;
}
x = b + n / (2.0 * d ) ;
fx = f (x , fbuffer ) ;
if ( fabs ( b - x ) < EPS * ( fabs ( b ) + fabs ( x ) ) ) {
break ;
}
if ( it > 100) {
ok = 0;
break ;
}
change_intervalle (& a , &b , &c , & fa , & fb , & fc , x , fx ) ;
} while ( fabs ( c - a ) > EPS * ( fabs ( c ) + fabs ( a ) ) ) ;
if ( ok == 1) {
* xmin = x ;
* fmin = fx ;
}
return ok ;
}
/*
* Dfinition d une structure permettant de passer des
* paramtres la fonction 1 D transmise l algorithme Brent
*/
typedef struct {
double x0 , y0 ;
double nx , ny ;
double (* f2d ) ( double , double ) ;
} FBUFFER ;
/*
*
*
*
*
62
* - le point de dpart ( x0 , y0 )
* - la direction de minimisation ( nx , ny )
* - la fonction f2d (x , y ) minimiser
*/
double
f1d ( double l ,
void * fbuffer )
{
FBUFFER * buf = ( FBUFFER *) fbuffer ;
return buf - > f2d ( buf - > x0 + l * buf - > nx ,
buf - > y0 + l * buf - > ny ) ;
}
/*
* Minimisation 1 D de la fonction f ( x0 + l * nx , y0 + l * ny ) .
*/
void
min1d ( double x0 ,
double y0 ,
double nx ,
double ny ,
double (* f ) ( double , double ) ,
double * x ,
double * y )
{
FBUFFER fbuffer ;
double a , b , c , fa , fb , fc , l , fl ;
// On construit la structure FBUFFER adapte
fbuffer . x0 = x0 ;
fbuffer . nx = nx ;
fbuffer . y0 = y0 ;
fbuffer . ny = ny ;
fbuffer . f2d = f ;
// On recherche les points a , b et c encadrant le minimum
// Veiller viter des boucles infinies !
a = -1.0;
b = 0.0;
c = 1.0;
fa = f1d (a , & fbuffer ) ;
fb = f1d (b , & fbuffer ) ;
fc = f1d (c , & fbuffer ) ;
while ( fa <= fb ) {
a -= 1.0;
fa = f1d (a , & fbuffer ) ;
}
while ( fc <= fb ) {
c += 1.0;
fc = f1d (c , & fbuffer ) ;
}
// Minimisation par la mthode de Brent
brent2 (a , b , c , f1d , & fbuffer , &l , & fl ) ;
* x = x0 + l * nx ;
* y = y0 + l * ny ;
}
/*
* X0 et Y0 correspondent au premier point de l itration
63
*/
# define X0 1.0
# define Y0 1.0
/*
* Minimisation 2 D de la fonction f (x , y ) - mthode de Powell
* Le paramtre rot permet de contrler les directions de
* base utilises dans l algorithme :
* rot =0 : on utilise les vecteurs de base standard
* rot =1 : on tourne ces 2 vecteurs de 45 degrs
*/
void
min2d ( double (* f ) ( double , double ) ,
int rot )
{
double
double
double
double
int it
x0 = X0 ,
nx [] = {
ny [] = {
sqrt2 ;
= 0, c =
y0 = Y0 , x1 , y1 , d ;
1.0 , 0.0 };
0.0 , 1.0 };
0;
64
double y )
{
x -= 0.4321;
y += 0.1234;
return 1.0 - exp ( - sqr ( x + y ) / 2.0) * exp ( -5.0 * sqr ( x - y ) ) ;
}
/*
* Programme principal
* On teste la mthode de Powell avec les fonctions f1 et f2
* avec ou sans rotation de 45 degrs .
*/
int
main ( void )
{
printf ( " Minimisation de f1 :\ n " ) ;
min2d ( f1 , 0) ;
printf ( " \ nMinimisation de f2 ( sans rotation ) :\ n " ) ;
min2d ( f2 , 0) ;
printf ( " \ nMinimisation de f2 ( avec rotation ) :\ n " ) ;
min2d ( f2 , 1) ;
return 0;
}
de f1 :
x =1.000000
x =0.432100
x =0.432100
x =0.432100
y =1.000000
y =1.000000
y = -0.123400
y = -0.123400
de f2 ( avec rotation ) :
x =1.000000 y =1.000000
x =0.154350 y =0.154350
x =0.432100 y = -0.123400
65
# include
# include
# include
# include
66
* fb = fx ;
}
}
else {
if ( fx > * fb ) {
*a = x;
* fa = fx ;
}
else {
*c = *b;
* fc = * fb ;
*b = x;
* fb = fx ;
}
}
}
/*
* Cette fonction calcule le minimum encadr par les 3 points
* de rfrence a , b et c
* Elle retourne la valeur du minimum trouv , ainsi que la
* valeur de la fonction en ce point
* On utilise ici une version un peu modifie de la mthode de
* Brent : la fonction reoit 2 paramtres ( le point de calcul
* et un pointeur rfrenant des donnes utilises par la
* fonction ; cela vite d utiliser des variables globales !
*/
int
brent2 ( double a ,
double b ,
double c ,
double (* f ) ( double , void *) ,
void * fbuffer ,
double * xmin ,
double * fmin )
{
double n , d , fa , fb , fc , x , fx = 0.0;
int ok = 1 , it = 0;
if ( b <= a || b >= c ) {
printf ( " Paramtres invalides (a , b , c ) \ n " ) ;
return 0;
}
fa = f (a , fbuffer ) ;
fb = f (b , fbuffer ) ;
fc = f (c , fbuffer ) ;
if ( fb >= fa || fb >= fc ) {
printf ( " Paramtres invalides ( f ( a ) , f ( b ) , f ( c ) ) \ n " ) ;
return 0;
}
do {
it ++;
n = sqr ( b - a ) * ( fb - fc ) - sqr ( b - c ) * ( fb - fa ) ;
d = ( b - a ) * ( fc - fb ) - ( b - c ) * ( fa - fb ) ;
if ( fabs ( d ) < ZERO ) {
if ( fabs ( n ) < ZERO ) {
x = b;
}
else {
ok = 0;
}
67
break ;
}
x = b + n / (2.0 * d ) ;
fx = f (x , fbuffer ) ;
if ( fabs ( b - x ) < EPS * ( fabs ( b ) + fabs ( x ) ) ) {
break ;
}
if ( it > 100) {
ok = 0;
break ;
}
change_intervalle (& a , &b , &c , & fa , & fb , & fc , x , fx ) ;
} while ( fabs ( c - a ) > EPS * ( fabs ( c ) + fabs ( a ) ) ) ;
if ( ok == 1) {
* xmin = x ;
* fmin = fx ;
}
return ok ;
}
/*
* Dfinition d une structure permettant de passer des
* paramtres la fonction 1 D transmise l algorithme Brent
*/
typedef struct {
double * p ;
// point initial
double * u ;
// direction de minimisation
double * x ;
// zone mmoire temporaire
double (* fnd ) ( double * , int N ) ;
// fonction minimiser
int N ;
// nombre de variables
} FBUFFER ;
/*
* La fonction 1 D utilise la structure prcdente ; elle
* calcule fnd ( p + l *u , N ) .
* Les diffrents champs de la structure FBUFFER permettent de
* dfinir :
* - le point de dpart ( p : tableau de N valeurs )
* - la direction de minimisation ( u : tableau de N valeurs )
* - une zone temporaire ( x : tableau de N valeurs )
* - la fonction fnd (...) minimiser
* - le nombre de variables
*/
double
f1d ( double l ,
void * fbuffer )
{
FBUFFER * buf = ( FBUFFER *) fbuffer ;
int i ;
for ( i = 0; i < buf - > N ; i ++) {
buf - > x [ i ] = buf - > p [ i ] + l * buf - > u [ i ];
}
return buf - > fnd ( buf - >x , buf - > N ) ;
}
/*
* Minimisation 1 D de la fonction f ( p0 + l * u0 , N ) , rsultat
* renvoy dans le tableau x
68
*/
void
min1d ( double
double
double
int N ,
double
* p0 ,
* u0 ,
(* f ) ( double * , int ) ,
* x)
{
FBUFFER fbuffer ;
double a , b , c , fa , fb , fc , l , fl ;
int i ;
fbuffer . p = ( double *) malloc ( N * 3 * sizeof ( double ) ) ;
fbuffer . u = fbuffer . p + N ;
fbuffer . x = fbuffer . u + N ;
for ( i = 0; i < N ; i ++) {
fbuffer . p [ i ] = p0 [ i ];
fbuffer . u [ i ] = u0 [ i ];
}
fbuffer . fnd = f ;
fbuffer . N = N ;
a = -1.0;
b = 0.0;
c = 1.0;
fa = f1d (a , & fbuffer ) ;
fb = f1d (b , & fbuffer ) ;
fc = f1d (c , & fbuffer ) ;
while ( fa <= fb ) {
a -= 1.0;
fa = f1d (a , & fbuffer ) ;
}
while ( fc <= fb ) {
c += 1.0;
fc = f1d (c , & fbuffer ) ;
}
brent2 (a , b , c , f1d , & fbuffer , &l , & fl ) ;
for ( i = 0; i < N ; i ++) {
x [ i ] = p0 [ i ] + l * u0 [ i ];
}
free ( fbuffer . p ) ;
}
/*
* Fonction de calcul de la distance ( norme euclidienne )
* sparant deux vecteurs d un espace N dimensions
*/
double
dist ( double * x ,
double * y ,
int N )
{
double d = 0.0;
int i ;
for ( i = 0; i < N ; i ++) {
d += sqr ( x [ i ] - y [ i ]) ;
}
69
return sqrt ( d ) ;
}
/*
* Minimisation nD de la fonction f (...) - mthode de Powell
* Ici , on utilise les directions de base du repre
* Le paramtre X0 correspond la solution approche initiale
*/
void
powell ( double * X0 ,
double (* f ) ( double * , int ) ,
int N )
{
double * x0 , * x1 , * n , d ;
int i , it = 0 , c = 0;
x0 = ( double *) malloc ( N * 3 * sizeof ( double ) ) ;
x1 = x0 + N ;
n = x1 + N ;
for ( i = 0; i < N ; i ++) {
x0 [ i ] = X0 [ i ];
}
do {
for ( i = 0; i < N ; i ++) {
n [ i ] = ( double ) ( i == c ) ;
}
if (++ c == N ) {
c = 0;
}
min1d ( x0 , n , f , N , x1 ) ;
d = dist ( x1 , x0 , N ) ;
printf ( " iteration % d :\ n " , ++ it ) ;
for ( i = 0; i < N ; i ++) {
printf ( "
% e \ n " , x1 [ i ]) ;
x0 [ i ] = x1 [ i ];
}
} while ( d > EPS || it < N ) ;
free ( x0 ) ;
}
/*
* Fonction minimiser
*/
double
f ( double * X ,
int N )
{
double res = 1.0;
int i ;
for ( i = 0; i < N ; i ++) {
res *= exp ( -( i + 1) * sqr ( X [ i ] - 1.0 / ( i + 1) ) / 10.0) ;
}
return 1.0 - res ;
}
/*
* Programme principal
70
*/
int
main ( void )
{
int i , N ;
double * X0 ;
printf ( " Nombre de variables : " ) ;
scanf ( " % d " , & N ) ;
X0 = ( double *) malloc ( N * sizeof ( double ) ) ;
for ( i = 0; i < N ; i ++) {
X0 [ i ] = 0.0;
}
powell ( X0 , f , N ) ;
free ( X0 ) ;
return 0;
}
4.4
Dans certains cas, il est possible de calculer la fonction ainsi que son gradient ; cette information complmentaire peut alors utilement tre utilise pour amliorer la recherche de minimum.
La premire approche consiste rechercher chaque tape de litration la direction de descente maximale
(ou plus grande pente).
~ on peut crire au premier ordre
Au voisinage dun point X,
~ + X
~ f X
~ + X
~ f
~
~
f X
X
~ est dite direction de descente si X
~ f
~ < 0.
~
La direction X
X
~
A module
X
constant (assez petit pour rester dans lapproximation de Taylor du premier ordre) on
peut crire (~n tant de norme 1)
~ + ~n f
~
~ + X
~ f X
~
X
f X
~ .
~
La direction de la plus grande pente est alors donne par ~n f
X
La mthode de minimisation par la plus grande pente repose sur cette remarque et utilise litration
suivante :
~ 0,
on part dun point initial P
~ , on obtient un point P
~ 1,
~
par minimisation 1D suivant la direction f
X
et ainsi de suite jusqu convergence de litration.
Le programme est identique au prcdent implmentant la mthode de Powell ; la fonction powell est
remplace par la fonction steepest_descent, recevant un paramtre supplmentaire permettant de spcifier la fonction de calcul du gradient.
La fonction minimiser nest pas modifie ; il faut par contre ajouter une nouvelle fonction (df), permettant de calculer le gradient local.
Pour ce qui est de la fonction main, il suffit de remplacer lappel powell par un appel la nouvelle
fonction steepest_descent, avec les paramtres adquats.
71
/*
* Minimisation nD de la fonction f (...) - mthode de la plus
* grande pente . La fonction de calcul du gradient est df .
* Le paramtre X0 correspond la solution approche initiale
*/
void
steepest_descent ( double * X0 ,
double (* f ) ( double * , int ) ,
void (* df ) ( double * , double * , int ) ,
int N )
{
double * x0 , * x1 , * n , d ;
int i , it = 0;
x0 = ( double *) malloc ( N * 3 * sizeof ( double ) ) ;
x1 = x0 + N ;
n = x1 + N ;
for ( i = 0; i < N ; i ++) {
x0 [ i ] = X0 [ i ];
}
do {
df ( x0 , n , N ) ;
min1d ( x0 , n , f , N , x1 ) ;
d = dist ( x1 , x0 , N ) ;
printf ( " iteration % d :\ n " , ++ it ) ;
for ( i = 0; i < N ; i ++) {
printf ( "
% e \ n " , x1 [ i ]) ;
x0 [ i ] = x1 [ i ];
}
} while ( d > EPS || it < N ) ;
free ( x0 ) ;
}
/*
* Fonction minimiser
*/
double
f ( double * X ,
int N )
{
double res = 1.0;
int i ;
for ( i = 0; i < N ; i ++) {
res *= exp ( -( i + 1) * sqr ( X [ i ] - 1.0 / ( i + 1) ) / 10.0) ;
}
return 1.0 - res ;
}
/*
* Gradient de la fonction minimiser
*/
void
df ( double * X ,
double * DX ,
int N )
{
72
Si on excute ce programme avec une fonction 5 variables, on constate que la convergence est assure
avec 43 itrations.
4.5
La mthode du gradient conjugu utilise un critre diffrent pour changer de direction dexploration, ce
qui permet dacclrer la convergence.
4.5.1
~ Au point
Par minimisation 1D suivant une direction donne ~u, on suppose avoir obtenu un point P.
minimum, le gradient de la fonction est orthogonal la direction de minimisation :
~ =0
~
~u f
P
~ on peut crire par un dveloppement de Taylor au deuxime ordre
Au voisinage du point P,
1
~ +X
~ f P
~ +X
~ f
~ + X
~ AX,
~
~
f P
P
2
Aij =
f 2 ~
P
xi xj
~
o A est la matrice des drives secondes. Par diffrentiation
de cette relation, partant du point P
~ + A~v. Le choix optimal de la direction
~
P
suivant une direction ~v, on verra un gradient de la forme f
~v (au sens o lon ne pnalisera pas les calculs prcdents suivant la direction ~u) consiste assurer la
relation
~ + A~v = 0 = ~u A~v = ~v A~u = 0
~
~u f
P
Les directions ~u et ~v sont dites conjugues.
4.5.2
Le calcul de minimum se fait toujours par itrations et de minimisations 1D, mais on va veiller maintenir
en permanence la condition de directions conjugues (les directions de minimisation aux itrations i et
i + 1 sont conjugues).
On part dun vecteur ~g0 arbitraire, ~h0 = ~g0 . On cre ensuite deux squences de vecteurs dfinis par
~gi+1 = ~gi i A~hi ,
satisfaisant les conditions suivantes :
~gi+1 ~gi = 0
~hi+1 A~hi = 0
=
=
~gi ~gi
~gi A~hi
~gi+1 A~hi
i =
~hi A~hi
i =
Cette squence permet ainsi de crer les vecteurs ~gi dont chacun est orthogonal son prcdesseur, ainsi
que les vecteur ~hi dont chacun est conjugu de son prdcesseur.
On obtient ainsi le schma suivant :
itration 0 : on a ~g0 et ~h0 = ~g0 ,
73
Pour i < n :
0
~gn+1 ~gi
z }| {
= ~gn n A~hn ~gi = ~gn ~gi n~gi A~hn = n~gi A~hn
= n ~hi i1 ~hi1 A~hn = n ~hi A~hn +n i1 ~hi1 A~hn = 0
| {z }
| {z }
0
~hn+1 A~hi
z }| {
~
~
~
~
= ~gn+1 + n hn Ahi = ~gn+1 Ahi + n hn A~hi = ~gn+1 A~hi
~gi+1 ~gi
1
= ~gn+1
= ~gn+1 ~gi+1 ~gn+1 ~gi = 0
i
i | {z } | {z }
0
Cela prouve en fait par rcurrence que les vecteurs ~gi et ~hi satisfont en ralit les conditions suivantes :
~gj ~gi = ~hj A~hi = 0, i, j 6= i
Le squence permet ainsi de gnrer une famille de vecteurs ~gi deux deux orthogonaux, et une famille
de vecteurs ~hi deux deux conjugus.
La condition de vecteurs conjugus nous a donn prcdemment
i =
~gi+1 A~hi
~hi A~hi
~gi+1 ~gi
i
1
1
~gi+1 ~gi+1 ~gi+1 ~gi = ~gi+1 ~gi+1
=
| {z }
i
i
0
et
~hi A~hi
z }| {
= ~gi + i1 ~hi1 A~hi = ~gi A~hi + i1 ~hi1 A~hi = ~gi A~hi
~gi+1 ~gi
1
1
~gi ~gi+1 ~gi ~gi = ~gi ~gi
= ~gi
=
i
i | {z }
i
0
de sorte que
i =
~gi+1 ~gi+1
~gi ~gi
De mme, on a
i =
~gi ~gi
~gi A~hi
74
~gi A~hi = ~hi i1 ~hi1 A~hi = ~hi A~hi i1 ~hi1 A~hi = ~hi A~hi
| {z }
0
En outre, on a
~gi ~hi = ~gi ~gi + i1 ~hi1 = ~gi ~gi + i1~gi ~hi1
et
~gi ~hi1
z }| {
= ~gi ~gi1 + i2 ~hi2 = ~gi ~gi1 +i2~gi ~hi2 = i2~gi ~hi2
= (i2 i3 0 ) ~gi ~h0 = (i2 i3 0 ) ~gi ~g0 = 0
| {z }
0
~gi ~hi
~gi ~gi
=
~hi A~hi
~hi A~hi
Sous rserve de connatre la matrice A, on peut donc gnrer compltement la squence i , i , ~gi et ~hi .
Aprs N (nombre de variables) minimisations successives suivant chaque direction ~hi , on doit parvenir
au minimum recherch. En pratique, des itrations supplmentaires seront gnralement requises, la
fonction ntant pas simplement quadratique.
La question qui se pose maintenant est la suivante : comment procder si lon ne connat pas la matrice
des drives secondes A ? On utilise alors le principe suivant :
~i ,
~ i , on dfinit ~gi = f
~
P
en un point P
~ i suivant la direction ~hi , on recherche le minimum P
~ i+1 ,
partant de P
~ i+1 , on dfinit ~gi+1 = f
~ i+1 .
~
en P
P
Compte tenu de la forme suppose quadratique de la fonction f , on peut montrer que cette squence
est la mme que celle prcdemment introduite et calcule partir de la matrice A. Il nest donc plus
ncessaire de connatre la matrice des drives secondes.
Cette mthode numrique correspond lalgorithme du gradient conjugu (FRPR - Fletcher, Reeves,
Polak et Ribiere).
Le programme est identique ceux implmentant les mthodes de Powell et de la plus grande pente ; la
fonction steepest_descent est ici remplace par la fonction frprmn.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/*
* Fonction de calcul du produit scalaire de 2 vecteurs
* d un espace N dimensions
*/
double
ProduitScalaire ( double * x ,
double * y ,
int N )
{
double p = 0.0;
int i ;
for ( i = 0; i < N ; i ++) {
p += x [ i ] * y [ i ];
}
75
return p ;
}
/*
* Minimisation nD de la fonction f (...) - mthode FRPR
* Le paramtre X0 correspond la solution approche initiale
*/
void
frprmn ( double * X0 ,
double (* f ) ( double * , int ) ,
void (* df ) ( double * , double * , int ) ,
int N )
{
double gamma , * x0 , * x1 , * g1 , * g2 , * h1 , * h2 , d ;
int i , it = 0;
x0
x1
g1
g2
h1
h2
=
=
=
=
=
=
Si on excute ce programme avec une fonction 5 variables, on constate que la convergence est assure
avec 20 itrations, l o 43 itrations taient requises avec la mthode de la plus grande pente.
76
Chapter 5
Intgration numrique
5.1
Introduction
Le problme consiste ici calculer, pour une fonction f (x) et deux valeurs a et b fixes, lintgrale dfinie
par
Z b
f (x)dx
T (f ) =
a
Il existe typiquement deux grands types des mthodes, les mthodes dites indirectes pour lesquelles on
recherche une approximation polynomiale de la fonction f (x), et les mthodes dites directes qui reposent
sur lvaluation de la fonction f (x) en certaines valeurs privilgies de lintervalle dintgration.
5.2
La mthode des rectangles est de loin la plus lmentaire possible, elle est aussi la moins prcise. Le
principe consiste subdiviser lintervalle dintgration [a, b] en N sous-intervalles dgale longueur h ; on
a alors
ba
x0 = a,
xN = b,
h=
,
xi = a + ih,
1iN 1
N
La mthode des rectangles consiste considrer que la fonction intgrer f (x) est constante sur chaque
intervalle lmentaire [xi , xi+1 ], de sorte que la contribution correspondante lintgrale totale est trs
simple calculer. Selon les formulations, on peut arbitrairement dcider que la valeur constante de
la fonction sur cet intervalle lmentaire est f (xi ) ou f (xi+1 ), ce qui nous fournira deux variantes
lalgorithme de calcul.
Dans le premier cas, on obtient la formule approche suivante :
Z
f (x)dx
T (f ) =
a
N 1
1 X
f (a + ih)
h i=0
Dans le second cas, la formule approche est identique, seules les bornes de la sommation discrte
changent :
Z b
N
1X
T (f ) =
f (x)dx
f (a + ih)
h i=1
a
On peut donner un exemple de programme de calcul dune intgrale par cette mthode.
1
2
3
4
5
77
78
{
int N , stat ;
double res1 , res2 ;
do {
printf ( " Nombre de subdivisions : " ) ;
stat = scanf ( " % d " , & N ) ;
if ( stat == 0 || N <= 0) {
break ;
}
res1 = integr_rectangles (0.0 , M_PI_2 , cos , N , 1) ;
res2 = integr_rectangles (0.0 , M_PI_2 , cos , N , 2) ;
printf ( " [ algorithme 1]: %e , prec % e \ n " , res1 , fabs (1.0 - res1 ) ) ;
printf ( " [ algorithme 2]: %e , prec % e \ n " , res2 , fabs (1.0 - res2 ) ) ;
} while (1) ;
return 0;
}
7.648280 e -02
8.059683 e -02
5.144586 e -02
5.327390 e -02
3.875581 e -02
3.978400 e -02
2.595147 e -02
2.640841 e -02
1.562572 e -02
1.579021 e -02
7.833420 e -03
7.874543 e -03
7.851925 e -04
7.856038 e -04
7.853776 e -05
7.854187 e -05
7.853961 e -06
7.854003 e -06
On constate immdiatement que la prcision est plutt mdiocre ; il faut aller jusqu 100000 subdivisions
de lintervalle dintgration pour obtenir une prcision en de de 105 , ce qui est trs au-del des
possibilits des rels double prcision !
5.3
La mthode des trapzes est tout de mme un peu plus labore puisquelle consiste considrer que la
fonction se comporte comme un polynme de degr 1 dans chaque sous-intervalle, et non plus comme
une constante. A cette diffrence prs, la mthode est identique.
79
f (xi+1 ) f (xi )
f (xi+1 ) f (xi )
(x xi ) = f (xi ) +
(x xi )
xi+1 xi
h
f (x)dx =
a
N
1 Z xi+1
X
i=0
f (x)dx
xi
N
1 Z xi+1
X
i=0
xi
pi (x)dx =
N 1
h X
[f (xi ) + f (xi+1 )]
2 i=0
En regroupant les diffrents termes, on peut simplifier et r-exprimer le rsultat sous la forme
"
#
Z b
N
1
X
h
f (x)dx
T (f ) =
f (a) + f (b) + 2
f (xi )
2
a
i=1
On peut donner un exemple de programme de calcul dune intgrale par cette mthode.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
80
x = a + h;
max = N - 1;
for ( i = 1; i <= max ; i ++) {
ret += f ( x ) ;
x += h ;
}
return h * ret ;
}
/*
* Programme principal : intgration de cos ( x ) entre 0 et pi /2 et comparaison
* avec le rsultat qui est connu (1.0)
* La fonction boucle l infini le calcul , jusqu ce qu une valeur ngative
* de N soit saisie au clavier
*/
int
main ( void )
{
int N , stat ;
double res ;
do {
printf ( " Nombre de subdivisions : " ) ;
stat = scanf ( " % d " , & N ) ;
if ( stat == 0 || N <= 0) {
break ;
}
res = integr_trapezes (0.0 , M_PI_2 , cos , N ) ;
printf ( " [ algorithme 1]: %e , prec % e \ n " , res , fabs (1.0 - res ) ) ;
} while (1) ;
return 0;
}
2.057014 e -03
9.140193 e -04
5.140948 e -04
2.284735 e -04
8.224806 e -05
2.056176 e -05
2.056168 e -07
2.056259 e -09
2.089839 e -11
On constate que la prcision est largement meilleure ; par exemple pour 1000 subdivisions de lintervalle,
on a gagn trois ordres de grandeurs sur la prcision de calcul de lintgrale.
81
5.4
La mthode de Simpson
Le principe de la mthode de Simpson reste le mme, mais on utilise cette fois une interpolation quadratique de la fonction sur chaque sous-intervalle [xi , xi+1 ].
On peut alors crire le polynme dinterpolation pi (x) de la forme
pi (x) = + (x xi ) + (x xi )
sachant que ce polynme concide avec la vraie fonction f (x) en chacune des bornes de lintervalle xi
et xi+1 , ainsi quau point mdian (xi + xi+1 )/2 ; tous calculs faits, on obtient lexpression suivante des
coefficients , et du polynme pi (x) :
= f (xi )
1
= [f (xi+1 ) + 3f (xi ) 4f (xi + h/2)]
h
f (x)dx =
a
N
1 Z xi+1
X
i=0
xi
f (x)dx
N
1 Z xi+1
X
i=0
xi
pi (x)dx =
N 1
h X
[f (xi ) + f (xi+1 ) + 4f (xi + h/2)]
6 i=0
En regroupant les diffrents termes, on peut simplifier et r-exprimer le rsultat sous la forme
"
#
Z b
N
1
N
1
X
X
h
T (f ) =
f (x)dx
f (a) + f (b) + 2
f (xi ) + 4
f (xi + h/2)
6
a
i=1
i=0
On peut donner un exemple de programme de calcul dune intgrale par cette mthode.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
82
}
// on assure une valeur correcte pour N ...
if ( N <= 0) {
N = 1;
}
// ici , on est certain que l intervalle n est pas vide , avec a < b
h = (b - a) / N;
// il ne reste plus qu calculer
ret = f ( a ) + f ( b ) ;
max = N - 1;
// premire sommation sur les bornes des intervalles
x = a + h;
for ( i = 1; i <= max ; i ++) {
ret += 2.0 * f ( x ) ;
x += h ;
}
// deuxime sommation sur les centres des intervalles
x = a + h / 2.0;
for ( i = 0; i <= max ; i ++) {
ret += 4.0 * f ( x ) ;
x += h ;
}
return h * ret / 6.0;
}
/*
* Programme principal : intgration de cos ( x ) entre 0 et pi /2 et comparaison
* avec le rsultat qui est connu (1.0)
* La fonction boucle l infini le calcul , jusqu ce qu une valeur ngative
* de N soit saisie au clavier
*/
int
main ( void )
{
int N , stat ;
double res ;
do {
printf ( " Nombre de subdivisions : " ) ;
stat = scanf ( " % d " , & N ) ;
if ( stat == 0 || N <= 0) {
break ;
}
res = integr_simpson (0.0 , M_PI_2 , cos , N ) ;
printf ( " [ algorithme 1]: %e , prec % e \ n " , res , fabs (1.0 - res ) ) ;
} while (1) ;
return 0;
}
83
2.115466 e -07
4.176993 e -08
1.321438 e -08
2.609982 e -09
3.382352 e -10
2.113909 e -11
6.217249 e -15
9.692247 e -14
2.976508 e -13
On constate que la prcision est largement meilleure que par la mthode des trapzes ; par exemple pour
1000 subdivisions de lintervalle, on a encore gagn huit ordres de grandeurs sur la prcision de calcul
de lintgrale, qui devient de lordre de 1015 , cest--dire proche de la limite des nombres rels double
prcision.
On observe un phnomne trange : lorsque lon augment encore le nombre de sous-intervalles, on
constate que la prcision se dgrade. Il ne faut pas oublier que la prcision est dans ce cas meilleure dun
point de vue strictement mathmatique ; numriquement, on augmente significativement le nombre total
des calculs faire, ce qui augmente le phnomne daccumulation derreurs darrondis. On a atteint les
limites de la mthode de Simpson (dans ce cas particulier), et il ne sert rien daugmenter encore le
nombre de points de calcul (temps de calcul augment et prcision qui diminue).
5.5
Dans les diffrents cas prcdents, on constate que lvaluation de lintgrale est ramene au calcul de
la fonction en certains points rgulirement rpartis sur lintervalle dintgration, la prcision finalement
obtenue tant lie au pas entre points conscutifs.
Une autre approche consiste considrer que les points en lesquels la fonction doit tre value ne sont
plus ncessairement rpartis de faon uniforme sur lintervalle dintgration. Ainsi les points de rfrence
sont calculs de telle sorte que la mthode numrique minimise lerreur dans lvaluation de lintgrale.
On va prsenter ici la dmarche en deux temps : on va dans un premier temps considrer que les points
de rfrence sont fixes, puis on va gnraliser lapproche au cas de points de rfrence ajustables.
5.5.1
On considre donc N + 1 points fixs xi,0iN deux deux distincts. Loprateur T - ici le calcul de
lintgrale de la fonction entre deux bornes donnes - est exprim sous la forme approche suivante :
Z
f (x)dx
T (f ) =
a
N
X
i f (xi )
i=0
les coefficients inconnus i,0iN sont les coefficients de pondration associs aux diffrents points de
rfrence. Le principe consiste alors dterminer les valeurs donner ces coefficients afin de minimiser
lerreur algorithmique faite en remplaant lintgration continue par une somme discrte. La mthode
classique consiste alors crire que la formulation approche est exacte pour tous les monmes lmentaires 1, x, x2 , ... jusqu ce que lon obtienne suffisamment dquations indpendantes pour calculer les
N + 1 coefficients i (on atteint ainsi le monme xN ).
84
0kN
i=0
On obtient ainsi un systme linaire de N + 1 quations N + 1 inconnues, que lon peut crire sous la
forme matricielle suivante :
T [1]
1
1
1 1
0
x0 x1 x2 xN 1 T [x]
2
x0 x21 x22 x2N 2 T x2
..
..
..
.. ..
..
..
.
.
.
.
.
.
.
N
N
N
N
N
N
x0 x1 x2 xN
T x
Il est intressant de noter que la matrice du systme ne dpend pas de loprateur T ; en particulier
elle ne dpend pas des bornes dintgration par exemple. En fait loprateur que lon cherche valuer
nintervient que dans le second membre. On peut donc envisager de calculer la matrice inverse une bonne
fois pour toutes, et ensuite appliquer cette matrice inverse aux diffrents seconds membres envisageables,
correspondant aux oprateurs tudis. Cette dmarche induit naturellement un gain significatif en temps
de calcul, linversion de la matrice tant lopration qui cote le plus en temps.
Dautre part, la matrice est de type Van Der Monde, qui est mathmatiquement inversible ds lors que
les points de rfrences xi sont deux deux distincts, ce qui est le cas ici. Linversion dune matrice de
ce type peut se faire laide dalgorithmes classiques (pivot de Gauss par exemple), mais la forme trs
particulire de la matrice de Van Der Monde permet dutiliser un algorithme spcifique, avantageux tant
au niveau du temps de calcul quau niveau de la prcision que lon peut attendre du calcul de la matrice
inverse.
A titre dexemple, on considre lexemple simple suivant :
Z
+1
T (f ) =
f (x)gr (x)dx
1
o gr (x) est une fonction de rfrence quelconque et les points de rfrence sont 1.0, 0.0 et +1.0. Le
systme dquations ainsi obtenu scrit sous la forme
R +1
0 + 1 + 2 = T [1] = R1 gr (x)dx
+1
0 + 2 = T [x] = 1 xgr (x)dx
R +1
0 + 2 = T x2 = 1 x2 gr (x)dx
+1
f (x)dx
1
1
4
1
f (1) + f (0) + f (+1)
3
3
3
On retrouve prcisment la formule de Simpson pour une subdivision de lintervalle dintgration [1, +1]
en un seul sous-intervalle.
5.5.2
Le problme est le mme que prcdemment, mais cette fois les points de rfrences xi et les coefficients de
pondrations i correspondants sont ajustables, ce qui fait un total de 2N + 2 paramtres dterminer.
Le principe de calcul de ces paramtres est inchang et consiste crire que la formule approche est
mathmatiquement exacte pour tous les monmes lmentaires xk , k variant de 0 2N + 1 inclus. Par
linarit, la formule approche sera donc exacte pour tous les polynmes de degr infrieur ou gal
85
0 k 2N + 1
i=0
N
Y
(x xi ) = xN +1 +
i=0
N
X
i x i
i=0
Ce polynme est de degr N +1, de sorte que la formule approche applique P (x) est en ralit exacte.
Plus gnralement, la formule est exacte pour tous les polynmes de la forme xk P (x), lindice k variant
de 0 N inclus. On a alors
N
N
X
X
i T xk+i
i xki P (xi ) = 0 = T xk+N +1 +
T xk P (x) =
i=0
i=0
2
2
T [xP (x)] = 0 T [x] + 1 T x2 + 2 T x3 + T x4
= 1 +
3
5
2
2
3
4
5
2
2
T x P (x) = 0 T x + 1 T x + 2 T x + T x
= 0 + 2
3
5
=0
=0
=0
r
3
3
x0 =
,
x1 = 0,
x2 = +
5
5
Reportant ces valeurs dans la matrice de Van Der Monde, on peut vrifier la formulation approche de
loprateur T sous la forme
r !
r !
Z +1
8
5
3
5
3
+ f (0) + f +
f (x)dx f
9
5
9
9
5
1
De mme que dans le cas prcdent, les valeurs des points de rfrences et des coefficients de pondration
correspondants ne dpendent pas de la fonction laquelle loprateur est appliqu. Ces donnes ne
dpendent en ralit que de loprateur lui-mme, ce qui permet un calcul prdfini et la constitution de
banques de donnes en fonction du nombre de points utiliss.
5.6
La mthode dintgration prsente ci-dessus constitue la mthode de Gauss ; nous allons voir ici que
cette mthode est directement relie aux polynmes orthogonaux.
5.6.1
Principe gnral
Daprs ce qui prcde, loprateur T appliqu une fonction f donne sexprime sous la forme approche
Z +1
N
X
T (f ) =
f (x)dx
i f (xi )
1
i=0
A partir de la dfinition de cet oprateur T , on peut dfinir un produit scalaire dans lespace des
polynmes dfini par
Z +1
hP |Qi =
P (x)Q(x)dx
1
Ce produit scalaire permet de dfinir des polynmes orthogonaux, dits polynmes de Legendre. En
particulier, on peut dterminer PN +1 (x), polynme de Legendre de degr N + 1 exactement.
On sait que la formule approche prcdente est exacte pour tout polynme de degr infrieur ou gal
2N + 1 ; soit f2N +1 (x) un tel polynme que lon crit par division euclidienne sous la forme
f2N +1 (x) = g(x)PN +1 (x) + r(x)
g(x) et r(x) tant des polynmes de degr infrieur ou gal N .
Par dfinition du polynme de Legendre PN +1 (x), il est orthogonal tout polynme de degr infrieur,
donc en particulier g(x). Il en rsulte donc
Z +1
N
N
N
X
X
X
f2N +1 (x)dx =
i f2N +1 (xi ) =
i g(xi )PN +1 (xi ) +
i r(xi )
1
i=0
i=0
i=0
Z +1
Z +1
Z +1
Z +1
=
g(x)PN +1 (x)dx +
r(x)dx = hg|PN +1 i +
r(x)dx =
r(x)dx
1
Or, le polynme r(x) tant de degr infrieur ou gal N , il satisfait la condition dgalit
Z +1
N
X
r(x)dx =
i r(xi )
1
i=0
Il en rsulte que la condition dgalit entre la forme approche et la forme exacte, valable pour tout
polynme f2N +1 (x) de degr infrieur ou gal 2N + 1, scrit de faon quivalente
N
X
i=0
Or cette relation devant tre satisfaite pour tout polynme f2N +1 (x), doit par consquent ltre pour
tout polynme g(x). La seule faon de satisfaire cette fonction est de choisir les points de rfrence
comme tant les zros du polynme de PN +1 (x).
87
5.6.2
Ce genre de mthode est particulirement utile pour calculer numriquement une intgrale dont lintgrant
prsente une singularit en lune des bornes, voire les deux. Il faut naturellement que cette singularit
soit intgrable.
Une approche classique consisterait subdiviser plus ou moins finement lintervalle dintgration, tout en
vitant videmment datteindre les bornes pour lesquelles la fonction nest pas dfinie. Si la subdivision
est trop grossire, la prcision du calcul est mauvaise. Par contre, si la subdivision est trop fine, on est
amen valuer la fonction en des points trs voisins de la singularit, points pour lesquels la fonction
a tendance partir linfini. Dans ce cas, les erreurs darrondis risquent de devenir dominantes, et
donnent une prcision l encore assez moyenne. Dautre part, on risque de rencontrer des situations pour
lesquelles la nature des rsultats obtenus dpend de faon trs instable du pas dintgration choisi.
Les mthodes dintgration de Gauss sont utiles dans ce cas, dans la mesure o elles intgrent dans le
mcanisme numrique lui-mme, la prsence des singularits et la faon dont elles assurent malgr tout
la convergence de lintgrale, au sens mathmatique du terme. Ces mthodes vitent en particulier de
sapprocher trop des points singuliers.
Un cas classique consiste calculer une intgrale de la forme
Z b
f (x)
a
(x a) (b x)
dx
les puissances et tant comprises entre 0 et 1. Par un simple changement de variable dintgration,
on peut aisment se ramener un intervalle dintgration [1, +1], avec les singularits en chacune des
bornes.
Si les coefficients et sont tous deux gaux 1/2, on obtient ainsi une formule remarquable :
Z
+1
X
f (x)
dx
f (xi )
N + 1 i=0
1 x2
5.6.3
hP |Qi =
dx
1 x2
1
Ces polynmes satisfont les relations suivantes :
T0 (x) = 1
T1 (x) = x
T
L0 (x) = 1
L1 (x) = 1 x
(n + 1)Ln+1 (x) (2n + 1 x)Ln (x) + nLn1 (x) = 0
x
n
Ln (x) e d
ex xn
n
n! dx
88
hP |Qi =
P (x)Q(x)ex dx
H0 (x) = 1
H1 (x) = 2x
Hn+1 (x) 2xHn (x) + 2nHn1 (x) = 0
n
89
Chapter 6
6.1
On considre dans un premier temps une quation diffrentielle du premier ordre de la forme
y 0 (t) = f (t, y(t))
et satisfaisant la condition initiale y (t0 ) = y0 .
Si lon crit le dveloppement en sries de Taylor lordre k quelconque de la solution y(t), on a
1
y(t) = y (t0 ) +
(t t0 ) 0
(t t0 ) 00
(t t0 ) (k)
k+1
y (t0 ) +
y (t0 ) + +
y (t0 ) + O (t t0 )
1!
2!
k!
La drive premire de la solution y(t) est par hypothse donne par f (t, y(t)), soit encore y 0 (t0 ) =
f (t0 , y0 ).
On peut calculer la drive dordre 2 de la solution y(t) en drivant lquation diffrentielle initiale ; on
obtient ainsi
f
f
y 00 (t) = y 0 (t) = f (t, y(t)) =
(t, y(t)) + y 0 (t)
(t, y(t))
t
t
u
v
f
f
=
(t, y(t)) + f (t, y(t))
(t, y(t))
u
v
en considrant que la fonction f est formellement fonction de deux variables u et v. Par substitution, il
en rsulte donc lexpression suivante :
y 00 (t0 ) =
f
f
(t0 , y0 ) + f (t0 , y0 )
(t0 , y0 )
u
v
On peut alors calculer de la mme faon les drives successives de la solution recherche y(t) au point
initial t0 en fonction des drives partielles de la fonction f (u, v).
Sous rserve de pousser le dveloppement de Taylor assez loin, on peut donc thoriquement calculer la
solution y(t) pour des valeurs de t assez loignes de la valeur initiale t0 . Cependant, il sera indispensable
de considrer un dveloppement dautant plus pouss que t sera plus loign de t0 , afin de garantir une
prcision correcte sur le calcul de la solution y(t). Cette mthode, efficace en thorie sur le papier, est en
gnral dlicate mettre en oeuvre numriquement dans la mesure o il faut trouver les drives partielles
de la fonction f (u, v) dfinissant lquation diffrentielle. Dautre part, on constate numriquement des
difficults majeures relatives la convergence du dveloppement de Taylor. Mathmatiquement, la
convergence est garantie ; numriquement, les drives partielles successives ont une tendance crotre
91
+
n
X
(t t0 )
n
(2f ) cos (2f t0 + n/2)
n!
n=1
Cette srie est mathmatiquement parfaitement convergente ; par contre on va voir que lvaluation
numrique nest pas sans poser quelques difficults.
En pratique, tous les termes en cos sont compris entre 1 et +1, par contre on constate que les coefficients
dans le dveloppement de Taylor prsentent deux composantes :
n
la premire composante, (t t0 ) (2f ) , varie comme une fonction puissance qui peut tre dcroissante (si 2f (t t0 ) < 1) ou inversement croissante (si 2f (t t0 ) > 1),
la deuxime composante, 1/n!, dcrot trs rapidement.
Dans le cas 2f (t t0 ) < 1, les deux composantes du dveloppement sont rapidement dcroissantes et
on peut prvoir que le calcul numrique devrait se passer sans trop de problmes.
Dans lautre cas en revanche, la premire composante sera dominante dans un premier temps, puis elle
sera compense par la deuxime composante partir dun certain ordre dans le dveloppement. Ainsi, on
peut tre sr que la srie convergera numriquement, mais on aura manipul des termes potentiellement
trs grands (rsultant de la croissance rapide de la premire composante) pour un rsultat final qui doit
rester entre 1 et +1 ; dans ce cas les effets derreurs numriques sont rapidement catastrophiques,
aboutissant un rsultat final totalement faux.
Le programme ci-dessous illustre les problmes numriques rencontrs dans une valuation de ce type.
Les coefficients successifs dans le dveloppement de Taylor sont calculs conformment la relation de
rcurrence
n+1
(t t0 )
2f (t t0 )
n+1
cn+1 =
(2f )
=
cn
(n + 1)!
n+1
ce qui permet dacclrer lexcution du programme par rapport un calcul complet et indpendant de
chacun des coefficients.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
92
* recurrence .
*/
void
d e v e l o p p e ment_taylor ( double t ,
double t0 ,
double f )
{
double solution , phase , somme , c , ft , ft0 ;
int n ;
ft = 2.0 * M_PI * f * t ;
ft0 = 2.0 * M_PI * f * t0 ;
solution = cos ( ft ) ;
somme = cos ( ft0 ) ;
phase = 0.0;
c = 1.0;
n = 1;
do {
c = coefficient_taylor (c , ft - ft0 , n ) ;
phase += M_PI_2 ;
somme += c * cos ( ft0 + phase ) ;
printf ( " n =%3 d , c =% e , somme =% e (% e ) \ n " ,
n , c , somme , fabs ( somme - solution ) ) ;
n ++;
} while ( fabs ( c ) > 1.0 e -12) ;
}
/*
* Programme principal
* Saisie des parametres au clavier et calcul
*/
int
main ( void )
{
double t , t0 , f ;
printf ( " Frequence : " ) ;
scanf ( " % le " , & f ) ;
printf ( " t et t0 : " ) ;
scanf ( " % le % le " , &t , & t0 ) ;
d e v e l oppement_taylor (t , t0 , f ) ;
return 0;
}
93
(1.909830 e -01)
(6.409082 e -03)
(6.409082 e -03)
(8.485701 e -05)
(8.485701 e -05)
(5.998117 e -07)
(5.998117 e -07)
(2.634739 e -09)
(2.634739 e -09)
(7.886469 e -12)
(7.886469 e -12)
(2.912469 e +01)
(2.912469 e +01)
(1.690241 e +01)
(1.690241 e +01)
(1.870283 e +01)
(1.870283 e +01)
(1.844777 e +01)
(1.844777 e +01)
(1.848255 e +01)
(1.848255 e +01)
94
Dans le premier cas ci-dessus, la condition 2f (t t0 ) < 1 est satisfaite et la convergence est trs rapide
(13 termes suffisent) ; la limite de la srie correspond bien au rsultat attendu.
Dans le deuxime cas, la condition 2f (t t0 ) < 1 nest pas satisfaite ; on constate ainsi que le terme
correctif cn commence crotre jusqu atteindre des valeurs de lordre de 107 , puis il dcrot lorsque n!
lemporte jusqu ce que la condition de convergence soit atteinte ; ici 76 termes sont ncessaires pour
que cette condition soit satisfaite et le rsultat correspond bien au rsultat attendu (avec un cart absolu
de 108 alors que le premier cas nous donne un cart absolu de 1014 ).
Le troisime cas est similaire au prcdent, sauf que le terme correctif cn crot jusqu des valeurs de
1015 avant que n! ne russisse lemporter ; 129 termes sont alors ncessaires avant que la condition de
convergence ne soit satisfaite. Quant au rsultat, il est clairement totalement faux ! Nous sommes l
clairement dans un cas o le calcul numrique de la srie est impossible de faon directe et simple.
La prsence de valeurs intermdiaires grandes (de lordre de 1015 ) conduit des erreurs darrondis qui
deviennent de lordre de lunit (la norme I.E.E.E. nous garantit un certain nombre de chiffres significatifs,
en valeurs relatives). Du coup, les erreurs darrondis deviennent du mme ordre que le rsultat final
attendu. Dans ces conditions, il nest pas surprenant dobtenir un rsultat final compltement erron.
On peut encore augmenter la valeur de 2f (t t0 ). Dans ce cas, la valeur maximale atteinte par le
terme correctif cn peut tre encore plus leve, ce qui renforce encore ce phnomne. Il nest alors pas
surprenant dobtenir un cos gal 104 .
En pratique, on prfre utiliser une mthode de calcul itrative. Dcoupant lintervalle de calcul de la
solution y(t) en N sous-intervalles de mme longueur h, on calcule y (t1 ) au point t1 = t0 + h, puis y (t2 )
au point t2 = t1 + h, et ainsi de suite jusqu atteindre la limite suprieure de lintervalle de calcul.
Ce faisant, on ralise un chantillonnage de lintervalle de temps, avec un pas temporel gal h, ce qui
correspond une frquence dchantillonnage fe = 1/h.
La valeur du pas dintgration h doit tre choisie assez faible de telle sorte que la solution y(t) et ses
drives varient peu sur lun quelconque des sous-intervalles de calcul. Cest pourquoi on ne peut pas en
gnral rsoudre une quation diffrentielle sur un intervalle dintgration grand, la propagation derreurs
numriques samplifiant dune itration lautre. Dans ce cas, il est souhaitable deffectuer une rsolution
partielle par sous-intervalles successifs, et deffectuer ensuite un raccordement continu des solutions.
Noter que ces critres de choix du pas temporel de rsolution h sont trs fortement lis au comportement
de la solution recherche, en particulier en terme de frquences contenues dans le spectre de cette solution.
on a un lien assez direct avec des critres style Shannon et autres ...
6.2
La mthode dEuler
La mthode dEuler, autrement connue sous le nom de mthode aux diffrences finies, consiste utiliser
un dveloppement de Taylor lordre 1 pour la rsolution de lquation diffrentielle.
Dans ce cas, on considre que le comportement de la solution y(t) dans lintervalle [tn , tn+1 ] sapparente
une droite de pente constante, de sorte que lon peut crire
y 0 (tn ) = f (tn , yn )
1
(yn+1 yn )
h
On dduit alors de cette relation approche la relation ditration permettant de rsoudre lquation
diffrentielle :
yn+1 = yn + f (tn , yn )
Cette solution induit une erreur de lordre de h2 , ce qui est assez mdiocre. Lerreur globale sera dautant
plus faible que h sera plus petit. De mme, la rsolution doit utiliser un intervalle de rsolution assez
petit pour limiter les phnomnes de propagation derreurs numriques et algorithmiques.
Les diffrentes causes derreurs dans un schma de ce type sont :
95
6.3
La mthode de Runge-Kutta
La mthode de Runge-Kutta consiste amliorer la prcision sur la solution y(t) en utilisant des proprits de la fonction en des points autres que les seuls points de calcul. Le principe de dpart de cette
mthode est identique la mthode dEuler, mais on ajoute dautres termes correctifs la relation
itrative afin de rduire les erreurs darrondis et dalgorithme au fur et mesure du calcul.
De mme que dans le cas de la mthode dEuler, lintervalle de calcul de la solution y(t) est subdivis en
N sous-intervalles de mme longueur h. La formule rcurrente de litration de Runge-Kutta est alors
crite sous la forme
I
X
yn+1 = yn +
ai ki
i=1
avec
k1
ki
= hf (tn , yn )
= hf (tn + i h, yn + i ki1 )
6.3.1
Nous allons dtailler ici les diffrentes tapes de calcul qui permettent de dterminer les coefficients
ajustables pour la mthode de Runge-Kutta lordre 2. La formule gnrale rcurrente est alors la
suivante :
yn+1 = yn + a1 k1 + a2 k2
k1
= hf (tn , yn )
k2
= hf (tn + h, yn + k1 )
Utilisant le dveloppement de Taylor, on peut encore crire
k2 = hf (tn , yn ) + h2 u f (tn , yn ) + hk1 v f (tn , yn )
Si lon introduit cette relation dans la formule rcurrente, il vient aprs rduction de lexpression obtenue
:
yn+1 = yn + h (a1 + a2 ) f (tn , yn ) + h2 a2 [u f (tn , yn ) + f (tn , yn ) v f (tn , yn )]
On peut finalement identifier cette relation avec le dveloppement de Taylor au deuxime ordre de la
solution
h2
[u f (tn , yn ) + f (tn , yn ) v f (tn , yn )]
yn+1 = yn + hf (tn , yn ) +
2
96
Par identification des termes dordre 1 et 2, on obtient finalement les conditions suivantes :
a1 + a2 = 1
a2 = a2 = 1/2
On a donc trois quations pour quatre coefficients ajustables dterminer. Il est donc ncessaire de fixer
arbitrairement lun des coefficients afin de calculer les trois autres.
La solution la plus couramment utilise est donne par
a1 = a2 = 1/2
==1
On constate finalement que la mthode de Runge-Kutta lordre 2 utilise un dveloppement de Taylor garanti exact (mathmatiquement) jusquau terme en h2 inclus. Ainsi, les trois premiers termes
du dveloppement sont exacts, alors que seuls les deux premiers termes taient corrects avec la mthode dEuler. Il en rsulte videmment que la mthode de Runge-Kutta lordre 2 est une meilleure
approximation de la solution recherche.
Le choix des coefficients ajustables est sans grande importance dans la mesure o ils satisfont les quations
prcdemment crites. Les seules diffrences entre deux choix particuliers de ces coefficients interviennent
au niveau des erreurs dapproximation (termes en h3 et plus) et correspondent donc un domaine de
prcision au-del de celui retenu pour le calcul de la solution. Ces diffrences sont donc du domaine des
erreurs dapproximation et ne contribuent ni plus ni moins.
Voici finalement les formules finales de litration de Runge-Kutta lordre 2 :
yn+1 = yn + (k1 + k2 ) /2
k1
= hf (tn , yn )
k2
= hf (tn + h, yn + k1 )
6.3.2
La mthode de Runge-Kutta dordre 4 est similaire la prcdente, mais elle considre cette fois une
somme de 4 termes et non plus 2. Le calcul des coefficients ajustables se fait suivant le mme principe
que prcdemment, savoir par identification terme terme avec le dveloppement de Taylor.
Cette mthode est garantie exacte jusquau terme en h4 inclus.
= hf (tn , yn )
k1
k2
= hf (tn + h/2, yn + k1 /2)
k
= hf (tn + h/2, yn + k2 /2)
3
k4
= hf (tn + h, yn + k3 )
6.3.3
La stabilit numrique
Les mthodes prsentes ici sont toutes de type rcurrentes, cest--dire quelles partent de la solution
initiale puis calculent par itration les valeurs de la solution pas par pas ; ce type de mthode comporte
un risque important dinstabilit numrique.
Il est dlicat de dfinir des critres de stabilit gnraux valables pour toutes les quations diffrentielles
; on va ici regarder de plus prs un cas particulier.
On considre lquation diffrentielle
y 0 (t) = y(t)
dont la solution est simplement une fonction exponentielle dcroissante. On regarde alors ce qui se passe
pour les grandes valeurs de tn en fonction du choix de h.
97
yn+1
k1
k2
= yn + (k1 + k2 ) /2
= hf (tn , yn ) = hyn
= hf (tn + h, yn + k1 ) = hyn + h2 yn
soit finalement
yn+1 =
1h+
h2
2
yn
yn =
n
h2
1h+
y0
2
Il est ais de vrifier avec cette formule ditration que la stabilit numrique est assure pour 0 < h < 2 ;
le domaine de stabilit est donc plus vaste que pour la mthode dEuler, ce qui se comprend intuitivement
par le fait que la mthode est mathmatiquement plus rigoureuse.
Dautre part, on peut vrifier que 1 h + h2 /2 reste toujours positif, ce qui vite tout risque dalternance
de signe au cours du calcul.
Pour la mthode de Runge-Kutta dordre 4, on a la relation de rcurrence suivante :
yn+1
h3
h4
h2
+
yn
= 1h+
2
6
24
n
h2
h3
h4
yn = 1 h +
+
y0
2
6
24
On peut alors vrifier que la valeur maximale de h permettant dassurer la stabilit de litration est
approximativement entre 2.78 et 2.80 ; le domaine de stabilit est donc encore largi par rapport la
mthode de Runge-Kutta dordre 2.
6.3.4
Les formulations prcdentes sappliquent au cas dquations diffrentielles scalaires du premier ordre ;
nanmoins on peut parfaitement les gnraliser au cas dune fonction y(t) valeurs vectorielles, auquel
cas les formules prcdentes sappliquent pour chaque composante des vecteurs.
Cette remarque permet alors de gnraliser ces mthodes de rsolution dquations diffrentielles au cas
dune quation dordre N en transformant le problme en systme diffrentiel dordre 1.
Considrons une quation diffrentielle scalaire dordre N donne par lquation
h
i
y (N ) (t) = F t, y(t), y 0 (t), , y (N 1) (t)
la condition initiale portant sur les drives successives de la solution linstant t = t0 : y(t0 ) = y0 ,
(N 1)
y 0 (t0 ) = y00 , ..., y (N 1) (t0 ) = y0
.
98
y(t)
y 0 (t)
~
U(t)
=
y (N 1) (t)
~ 0) = U
~0=
U(t
y0
y00
(N 1)
y0
~
On peut alors calculer la drive premire du vecteur U(t)
par rapport au temps :
y 0 (t)
y 0 (t)
00
y 00 (t)
~ 0 (t) = y (t) =
F t, y(t), y 0 (t), , y (N 1) (t)
y (N ) (t)
i`
eme
~
Or, la composante y (k) (t) nest autre que
composante du vecteur U(t),
elle peut donc
h la i(k + 1)
(k)
~
sexprimer sous la forme y (t) = Pk+1 U(t) , o Pk+1 est la projection du vecteur sur le (k + 1)i`eme
6.3.5
Exemple de programme
Dans lexemple de programme ci-dessous, on cherche rsoudre nimporte quelle quation diffrentielle
dordre N par la technique des systmes diffrentiels dordre 1.
Ensuite, les fonctions gnrales de rsolution sont appliques un cas particulier dquation du second
ordre dcrivant le mouvement dune masse M fixe un ressort de raideur K en prsence de frottements
(coefficient de frottement A).
Lquation du mouvement est dcrit par lquation suivante :
M x00 (t) + Ax0 (t) + Kx(t) = 0
x(t0 ) = x0 , x0 (t0 ) = v0
On sait classiquement que le mouvement est principalement oscillant avec une priode
r
K
= 2
M
avec une attnuation qui dpend du coefficient de frottement A. Un paramtre important lors de la
rsolution numrique sera alors le nombre de points de priode Np , de sorte que la rsolution se fera avec
un pas temporel h = /Np ; le nombre total de points de calcul sera un multiple de Np , ce qui permet
de conserver une fentre temporelle de calcul constante.
Ce programme ncessiterait lcriture dune fonction permettant soit dafficher les rsultats obtenus, soit
de les sauvegarder dans des fichiers pour post-traitement graphique.
Les valeurs numriques des constantes M , A et K sont spcifies directement dans le programme, sans
units particulires. Il en rsulte que lunit de temps nest pas non plus spcifie au niveau des rsultats,
cette unit dpendant des units de base adoptes.
Attention, il ne faut pas oublier que tout problme physique manipule des donnes numriques accompagnes dunits !
99
0
1
2
/*
* Cette fonction renvoie u en fonction de t , u
* Equation diffrentielle vectorielle
* L quation diffrentielle d ordre N est de la forme
*
y ( n ) = f (t ,y , y ,...)
*
* En entre : N = dimension de l espace ( ordre de l q . diff .)
*
t = temps
*
u = vecteur solution l instant t
*
f = fonction implmentant l q . diff . ci - dessus
* En sortie : ud = vecteur driv de u par rapport t
*/
void
eq_diff ( int N ,
double t ,
double * u ,
double * ud ,
double (* f ) ( int , double , double *) )
{
int i ;
for ( i = 0; i < N - 1; i ++) {
ud [ i ] = u [ i + 1];
}
ud [ N - 1] = f (N , t , u ) ;
}
/*
* Cette fonction calcule un pas de l itration d Euler
* Equation diffrentielle vectorielle
* En entre : N = dimension de l espace ( ordre de l q . diff .)
*
t = temps
*
u = vecteur solution l instant t
*
h = pas temporel
*
f = fonction implmentant l q . diff . ci - dessus
*
wkbuf = espace de travail
* En sortie : un = vecteur solution l instant t + h
*/
void
euler_iteration ( int N ,
double t ,
double * u ,
double * un ,
double h ,
double (* f ) ( int , double , double *) ,
double * wkbuf )
{
int i ;
eq_diff (N , t , u , wkbuf , f ) ;
for ( i = 0; i < N ; i ++) {
un [ i ] = u [ i ] + h * wkbuf [ i ];
}
100
}
/*
* Cette fonction calcule un pas de l itration de Runge Kutta ( ordre 2)
* Equation diffrentielle vectorielle
* En entre : N = dimension de l espace ( ordre de l q . diff .)
*
t = temps
*
u = vecteur solution l instant t
*
h = pas temporel
*
f = fonction implmentant l q . diff . ci - dessus
*
wkbuf = espace de travail
* En sortie : un = vecteur solution l instant t + h
*/
void
rk2_iteration ( int N ,
double t ,
double * u ,
double * un ,
double h ,
double (* f ) ( int , double , double *) ,
double * wkbuf )
{
double h2 = wkbuf [0] , * k1 , * k2 , * utmp ;
int i ;
k1 = 1 + wkbuf ;
k2 = k1 + N ;
utmp = k2 + N ;
// calcul de k1
eq_diff (N , t , u , k1 , f ) ;
// calcul de k2
for ( i = 0; i < N ; i ++) {
utmp [ i ] = u [ i ] + h * k1 [ i ];
}
eq_diff (N , t + h , utmp , k2 , f ) ;
// calcul de la nouvelle solution
for ( i = 0; i < N ; i ++) {
un [ i ] = u [ i ] + h2 * ( k1 [ i ] + k2 [ i ]) ;
}
}
/*
* Cette fonction calcule un pas de l itration de Runge Kutta ( ordre 4)
* Equation diffrentielle vectorielle
* En entre : N = dimension de l espace ( ordre de l q . diff .)
*
t = temps
*
u = vecteur solution l instant t
*
h = pas temporel
*
f = fonction implmentant l q . diff . ci - dessus
*
wkbuf = espace de travail
* En sortie : un = vecteur solution l instant t + h
*/
void
rk4_iteration ( int N ,
double t ,
double * u ,
double * un ,
double h ,
double (* f ) ( int , double , double *) ,
101
double * wkbuf )
{
double * k1 , * k2 , * k3 , * k4 , * utmp ;
double h2 = wkbuf [0] , h6 = wkbuf [1];
double tm = t + h2 ;
int i ;
k1 =
k2 =
k3 =
k4 =
utmp
2 + wkbuf ;
k1 + N ;
k2 + N ;
k3 + N ;
= k4 + N ;
// calcul de k1
eq_diff (N , t , u , k1 , f ) ;
// calcul de k2
for ( i = 0; i < N ; i ++) {
utmp [ i ] = u [ i ] + h2 * k1 [ i ];
}
eq_diff (N , tm , utmp , k2 , f ) ;
// calcul de k3
for ( i = 0; i < N ; i ++) {
utmp [ i ] = u [ i ] + h2 * k2 [ i ];
}
eq_diff (N , tm , utmp , k3 , f ) ;
// calcul de k4
for ( i = 0; i < N ; i ++) {
utmp [ i ] = u [ i ] + h * k3 [ i ];
}
eq_diff (N , t + h , utmp , k4 , f ) ;
// calcul de la nouvelle solution
for ( i = 0; i < N ; i ++) {
un [ i ] = u [ i ] + h6 * ( k1 [ i ] + 2.0 * k2 [ i ] + 2.0 * k3 [ i ] + k4 [ i ]) ;
}
}
/*
* Cette fonction calcule l ensemble des itrations Euler , RK2 ou RK4
* Equation diffrentielle vectorielle
* En entre : algorithme = indique l algorithme utiliser
*
N
= dimension de l espace ( ordre de l q . diff .)
*
t0
= instant initial
*
u0
= vecteur solution initiale ( position , vitesse , ...)
*
h
= pas temporel
*
Nbpt
= nombre de points temporels
*
f
= fonction implmentant l q . diff . ci - dessus
* En sortie : sol
= matrice solution ( N x Nbpt )
*/
void
eq_diff ( int algorithme ,
int N ,
double t0 ,
double * u0 ,
double h ,
int Nbpt ,
double ** sol ,
double (* f ) ( int , double , double *) )
102
{
int i ;
double t , * wkbuf ;
void (* iter ) ( int , double , double * , double * , double ,
double (*) ( int , double , double *) , double *) ;
switch ( algorithme ) {
case EQ_DIFF_EULER :
wkbuf = ( double *) malloc ( N * sizeof ( double ) ) ;
iter = euler_iteration ;
break ;
case EQ_DIFF_RK2 :
wkbuf = ( double *) malloc ((1 + 3 * N ) * sizeof ( double ) ) ;
wkbuf [0] = h / 2.0;
iter = rk2_iteration ;
break ;
case EQ_DIFF_RK4 :
default :
wkbuf = ( double *) malloc ((2 + 5 * N ) * sizeof ( double ) ) ;
wkbuf [0] = h / 2.0;
wkbuf [1] = h / 6.0;
iter = rk4_iteration ;
break ;
}
for ( i = 0; i < N ; i ++) {
sol [0][ i ] = u0 [ i ];
}
t = t0 ;
for ( i = 1; i < Nbpt ; i ++ , t += h ) {
iter (N , t , sol [ i - 1] , sol [ i ] , h , f , wkbuf ) ;
}
free ( wkbuf ) ;
}
/*
* Equation diffrentielle dcrivant le mouvement d une masselotte de
* masse M fixe un ressort de raideur K en prsence de frottements
* ( coefficient de frottement A )
* N est l ordre de l quation diffrentielle , ici implicitement 2
* t est l instant en cours , inutilis dans ce cas puisque l quation
* du mouvement ne dpend pas du temps
* u est le tableau ( position , vitesse ) l instant t
* La fonction retourne la valeur de l acclration conformment
* l quation du mouvement M x + A x + K x = 0
*/
# define M 1.0
# define A 0.05
# define K 0.5
double
EquationRessort ( int N ,
double t ,
double * u )
{
return -( K / M ) * u [0] - ( A / M ) * u [1];
}
/*
* Fonction de dsallocation mmoire pour une matrice 2 D quelconque
103
*/
void
free2d ( void ** a ,
int nLignes )
{
int i ;
if ( a != NULL ) {
for ( i = 0; i < nLignes ; i ++) {
if ( a [ i ] != NULL ) {
free ( a [ i ]) ;
}
}
free ( a ) ;
}
}
/*
* Fonction d allocation mmoire pour une matrice 2 D quelconque
*/
void **
alloc2d ( int nLignes ,
int nColonnes ,
size_t taille )
{
void ** a ;
int i ;
a = ( void **) malloc ( nLignes * sizeof ( void *) ) ;
if ( a == NULL ) {
return a ;
}
for ( i = 0; i < nLignes ; i ++) {
a [ i ] = NULL ;
}
for ( i = 0; i < nLignes ; i ++) {
a [ i ] = ( void *) malloc ( nColonnes * taille ) ;
if ( a [ i ] == NULL ) {
free2d (a , nLignes ) ;
return NULL ;
}
}
return a ;
}
/*
* Programme principal
*/
int
main ( void )
{
int Nbpt , NPer ;
double h , ** sol ;
double etat_initial [2] = { 1.0 , 0.0 };
printf ( " Nombre de points par priode : " ) ;
scanf ( " % d " , & NPer ) ;
104
//
eq_diff ( EQ_DIFF_EULER , 2 ,
0.0 , etat_initial ,
h , Nbpt , sol ,
EquationRessort ) ;
affiche_solution ( sol , h , Nbpt ) ;
//
eq_diff ( EQ_DIFF_RK2 , 2 ,
0.0 , etat_initial ,
h , Nbpt , sol ,
EquationRessort ) ;
affiche_solution ( sol , h , Nbpt ) ;
//
eq_diff ( EQ_DIFF_RK4 , 2 ,
0.0 , etat_initial ,
h , Nbpt , sol ,
EquationRessort ) ;
affiche_solution ( sol , h , Nbpt ) ;
free2d ( sol , Nbpt ) ;
return 0;
les mthodes de Runge-Kutta dordre 2 et 4 donnent une position qui oscille entre 1 et +1, ce qui
est normal puisque la position initiale est +1 et la vitesse initiale nulle ; dautre part on observe
clairement leffet damortissement,
en superposant ces deux rsultats, on constaterait quune lgre diffrence apparat vers la fin des
courbes, correspondant une drive de la mthode dordre 2 par rapport la mthode dordre 4,
par contre, la mthode dEuler apparat clairement instable puisquelle prdit une amplification au
cours du temps, ce qui na pas de sens physique.
105
On peut refaire les mmes calculs avec respectivement 100 et 1000 points par priode ; seuls les rsultats
obtenus par les mthodes dEuler et Runge-Kutta dordre 4 sont prsents ici.
107
Chapter 7
Introduction
L encore ce type de problme apparat trs frquemment en simulation numrique. Il existe une trs
grande varit de problmes diffrents et il nest pas question de tout aborder ici. En fait, il est gnralement ncessaire dadapter une dmarche numrique chaque problme pos, afin de mettre en oeuvre
une mthode numrique adapte. On verra ici partir dexemples simples comment dfinir les mthodes
numriques qui conviennent, les principes de bases pouvant ensuite sadapter dautres problmes.
On peut citer quelques exemples classiques de problmes dquations aux drives partielles :
lquation dondes 1D, 2D ou 3D, avec une vitesse qui peut tre constante ou fonction de lespace
et du temps, de la forme
2
1 2u
2u
u 2u
=
+
+ 2
c2 t2
x2
y 2
z
lquation de diffusion, de la forme
u
=
t
x
D
u
x
7.2
La rsolution dune quation de ce type peut se faire par diffrences finies. Le principe de cette mthode
consiste gnraliser les mthodes numriques utilises pour les quations diffrentielles une inconnue
unique (mthode dEuler, mthodes de Runge-Kutta lordre 2 ou 4, ...).
On considre alors un maillage dans le plan xy, le plus simple consistant prendre un maillage rgulier
avec un pas x et y suivant ces deux directions :
xj = x0 + jx 0 j J
yl = y0 + ly
0lL
109
2
x
2x
2
u(x,
y
+
)
+
u(x,
y y ) 2u(x, y)
u
y
2
2
y
y
Posant alors uj,l = u(xj , yl ), lquation de Poisson peut tre dcrite par la relation
1
1
(uj+1,l + uj1,l 2uj,l ) + 2 (uj,l+1 + uj,l1 2uj,l ) = j,l
2
x
y
2u
u
2u
u
2u
+
b(x,
y)
+
c(x,
y)
+
d(x,
y)
+
e(x,
y)
+ f (x, y)u = g(x, y)
x2
x
y 2
y
xy
Dans ce cas, les coefficients de la matrice ne sont plus constants et traduisent les variations spatiales des
diffrentes composantes de lquation diffrentielle.
A titre dexemple, on peut tre amen tudier un problme de taille 100 100 (ce qui reste une taille
rduite !) : lapproche ci-dessus conduit un systme linaire de 10000 quations 10000 inconnues, soit
encore une matrice de 108 lments ! On voit ainsi comment un problme de taille initiale relativement
rduite conduit en final un problme dmesur, tant au niveau du temps de calcul que de lespace
mmoire requis pour stocker les donnes.
On peut alors utilement tenir compte de la remarque prcdente concernant la matrice : en effet, elle est
loin dtre pleine et une grande majorit de ses coefficients sont nuls. Dans le cas particulier des matrices
lacunaires, on peut :
dfinir de nouvelle rgles de stockage des coefficients, permettant de ne garder en mmoire que les
coefficients non nuls,
adapter les algorithmes dinversion pour prendre en compte dans le processus numrique des caractristiques trs particulires de ce genre de matrice.
Ces diffrents critres permettent dconomiser, aussi bien en stockage mmoire quen temps de calcul.
110
7.3
7.3.1
De nombreux problmes aux valeurs initiales une dimension peuvent tre dcrits par une quation du
premier ordre de la forme
~u
~
=
F(~u)
t
x
~ sont des vecteurs ; cette quation dcrit la conservation dun flux F.
~
o ~u et F
A titre dexemple, lquation donde une dimension
2u
2u
= c2 2
2
t
x
peut tre rcrite en posant r =
t
s
u
u
et s =
:
x
t
u
u
s
=
=
=
t x
x t
x
2
2u
2 u
2 u
= 2 =c
=
c
=
c2 r
2
t
x
x
x
x
soit encore
r
0
1
r
=
s
c2 0
s
x
| {z }
|
{z
}
~
u
~ u)
F(~
t
t
Spatiallement, on peut considrer en revanche une approximation du 2`eme ordre :
u
un,j+1 un,j1
x
2x
ce qui nous donne la relation itrative
un+1,j = un,j
ct
(un,j+1 un,j1 )
2x
7.3.2
Stabilit de litration
Pour tudier la stabilit dune itration rsultant dun schma aux diffrences finies, on cherche dans un
premier temps les solutions stationnaires (modes propres) de la forme
u(t, x) = exp (i2f t) v(x)
=
7.3.3
La premire variante que lon peut envisager consiste conserver lordre 1 en temps, mais rduire la
prcision en espace en crivant une formulation lordre 1 galement :
u
un+1,j un,j
u
un,j+1 un,j
t
t
x
x
Dans ce cas, litration aux diffrences finies devient
un+1,j = un,j
ct
(un,j+1 un,j )
x
7.3.4
La deuxime variante envisageable consiste calculer la drive spatiale gauche plutt qu droite :
u
un+1,j un,j
,
t
t
moyennant quoi litration devient
un+1,j = un,j
u
un,j un,j1
x
x
ct
(un,j un,j1 )
x
et le critre de stabilit
(k) = 1
ct
ct
(1 cos (kx)) + i
sin (kx)
x
x
On peut alors vrifier que cette itration est stable condition que |ct/x| 1. Une telle relation est
trs importante, elle exprime que les lois dchantillonnage en espace et en temps ne peuvent pas tre
considres indpendamment lune de lautre.
112
7.3.5
La mthode de Lax consiste en un changement trs simple de lquation aux diffrences finies (obtenue
lordre 1 en temps et 2 en espace), permettant de stabiliser le processus numrique FTCS intrinsquement
instable :
1
un,j
=
(un,j+1 + un,j1 )
2
de sorte que litration scrit maintenant
un+1,j =
1
ct
(un,j+1 + un,j1 )
(un,j+1 un,j1 )
2
2x
Pour caractriser la stabilit de ce processus numrique, on recherche comme prcdemment une solution
numrique de la forme un,j = (k)n exp (ikjx) ; tous calculs faits, on obtient
s
2
ct
ct
2
2
sin (kx)
=
|(k)| = cos (kx) +
sin (kx)
(k) = cos (kx) i
x
x
ce qui nous donne la condition de stabilit |ct/x| 1. Si la condition |ct/x| = 1 est satisfaite,
toutes les composantes en frquences se propagent de la mme faon ; en revanche si |ct/x| < 1, le
facteur dattnuation (k) dpend de k, de sorte que les frquences sont dformes diffremment les unes
des autres. Ceci saccompagne dune modification du spectre, et donc de la forme temporelle du signal
qui se propage ; on a ici un phnomne de dispersion numrique, dont leffet classique est de stabiliser le
processus numrique.
7.3.6
Le domaine spatial est limit par le nombre de points finis utiliss en chantillonnage spatial. En fait le
processus numrique ne pourra pas prendre en compte un domaine spatial de taille infinie.
Les diffrentes itrations crites prcdemment permettent de calculer la solution au temps n + 1 pour
chaque indice j variant de 0 J ; or ces itrations utilisent galement les indices j 1 ou j + 1. Il
en rsulte que lon a un problme chaque bord (droit et gauche) du domaine spatial considr. Pour
rsoudre ce problme, il est ncessaire dinclure dans le processus numrique les conditions aux limites
imposes par le phnomne physique tudi.
Parmi toutes les conditions aux limites possibles, on peut citer les deux plus frquentes (et surtout les
plus faciles mettre en oeuvre) :
la condition de Neumann, qui stipule que la solution est nulle aux bords et en dehors du domaine
spatial considr,
la condition de Dirichlet qui stipule que la drive normale de la solution est nulle aux bords du
domaine spatial considr.
Dans certains cas, on peut galement tre conduit considrer des conditions aux bords diffrentes. Si
lon sintresse lquation de propagation des ondes par exemple, les conditions de Neumann et Dirichlet
conduisent la gnration dondes rflchies aux bords, qui peuvent tre des ondes parasites si elles ne
correspondent pas une ralit physique. Le seul moyen de forcer le processus numrique se comporter
comme si le milieu tait spatiallement infini consiste introduire sur les bords des conditions dabsorption
vitant lapparition de ces ondes rflchies. Ces conditions dabsorption ne sont pas physiques, elles sont
introduites artificiellement dans le processus numrique.
Si on prend pour exemple la relation ditration rsultant de la mthode de Lax, on obtient :
avec la condition de Neumann
1
ct
1
un,1
si j = 0
2
1
ct
un+1,j =
(un,j+1 + un,j1 )
(un,j+1 un,j1 ) si 1 j J 1
2
2x
1
ct
1+
un,J1
si j = J
2
x
113
ct
1
si j = 0
2 (un,1 + un,0 ) 2x (un,1 un,0 )
1
ct
un+1,j =
(u
+ un,j1 )
(un,j+1 un,j1 ) si 1 j J 1
2 n,j+1
2x
114
/*
* Calcul du module maximal
*/
double
umax ( double * u ,
int N )
{
double m , um = fabs ( u [0]) ;
int i ;
for ( i = 1; i < N ; i ++) {
m = fabs ( u [ i ]) ;
if ( m > um ) {
um = m ;
}
}
return um ;
}
# define V 1.0
/*
* Resolution par l algorithme FTCS + methode de LAX
* Nx , Dx : nombre de points et pas spatial
* Nt , Dt : nombre de points et pas temporel
*/
void
lax_ftcs ( int Nx ,
double Dx ,
int Nt ,
double Dt )
{
double ** u , C1 , C2 , c1 , c2 ;
int ix , it ;
// Allocation mmoire pour stocker la solution
u = alloc_matrice ( Nt , Nx ) ;
if ( u == NULL ) {
printf ( " Erreur d allocation mmoire \ n " ) ;
return ;
}
C1 = (1.0 - V * Dt / Dx ) / 2.0;
C2 = (1.0 + V * Dt / Dx ) / 2.0;
// On considre une source unique , au milieu du domaine spatial considr
// mettant une impulsion au temps t =0
for ( ix = 0; ix < Nx ; ix ++) {
u [0][ ix ] = ( double ) ( ix == Nx / 2) ;
}
// Condition aux bords droit et gauche : Neumann ( la solution s annule )
for ( it = 1; it < Nt ; it ++) {
for ( ix = 0; ix < Nx ; ix ++) {
c1 = ix == Nx - 1 ? 0.0 : u [ it - 1][ ix + 1];
c2 = ix == 0 ? 0.0 : u [ it - 1][ ix - 1];
u [ it ][ ix ] = C1 * c1 + C2 * c2 ;
}
printf ( " Iteration %d , | u | max =% e \ n " , it , umax ( u [ it ] , Nx ) ) ;
}
115
// Reste appeler ici une fonction d archivage sur disque pour post - traitement
// graphique par exemple
free_matrice (u , Nt ) ;
}
/*
* Programme principal
*/
int
main ( void )
{
int Nx , Nt ;
double Dx , Dt ;
printf ( " Nx , Dx
scanf ( " % d % le " ,
printf ( " Nt , Dt
scanf ( " % d % le " ,
: ");
& Nx , & Dx ) ;
: ");
& Nt , & Dt ) ;
lax_ftcs ( Nx , Dx , Nt , Dt ) ;
return 0;
}
7.4
On sintresse ici un second exemple frquemment rencontr en simulation numrique, savoir lquation
de diffusion de la forme
u
u
=
D
t
x
x
o D est le coefficient de diffusion (D 0 assure la stabilit des solutions). Dans le cas particulier dun
coefficient D constant, lquation scrit
u
2u
=D 2
t
x
Utilisant les mmes dveloppements que prcdemment, au premier ordre en t et au deuxime ordre en
x, on obtient lquation aux diffrences finies
un+1,j un,j
un,j+1 + un,j1 2un,j
=D
t
x2
soit encore le schma explicite
un+1,j = un,j +
Dt
(un,j+1 + un,j1 2un,j )
x2
Si lon cherche une solution numrique de la forme un,j = (k)n exp (ikjx), on obtient
Dt
kx
2
(k) = 1 4
sin
x2
2
do la condition de stabilit : 2Dt/x2 1.
Une variante possible de cette mthode consiste calculer la drive par rapport x au temps n + 1 et
non au temps n ; une autre interprtation de cette variante consiste calculer la drive temporelle
116
Linconvnient de cette criture est quelle conduit un schma implicite et non explicite comme
prcdemment ; en effet, il nest plus possible de calculer la solution au temps n + 1 en fonction du
temps n uniquement. Posant = Dt/x2 , on peut alors rcrire lquation prcdente sous la forme
un+1,j1 + (1 + 2)un+1,j un+1,j+1 = un,j
Le problme numrique consiste maintenant rsoudre chaque pas de temps un systme linaire pour
obtenir les diffrentes composantes un+1,j de la solution au temps n + 1.
A ce systme se rajoutent les conditions aux limites droite et gauche du domaine spatial. A titre
dexemple, on peut considrer une condition de type Dirichlet (la drive normale de la solution sannule
sur les bords) ou Neumann (la solution sannule sur les bords). Nous allons ici considrer le cas particulier
de la condition de Neumann : la matrice du systme est alors
1 + 2
..
..
.
1 + 2
.
.
.
.
.
.
.
0
0
..
.
.
.
.
.
.
.
.
.
.
0
0 1 + 2
Remarque : la matrice rsultant dune condition de Dirichlet est identique, hormis les coefficients a11
et aN N qui doivent tre remplacs par 1 + .
Le systme rsoudre est tri-diagonal : seuls les lments j, j + 1 et j 1 sont coupls par lquation
prcdente. Dans ce cas, on peut optimiser le processus dinversion de la matrice, dune part en ne
stockant en mmoire que les coefficients non nuls, dautre part en utilisant une approche numrique
adapte aux matrices de ce type.
Si le coefficient de diffusion D est constant, la matrice est coefficients constants sur chacune de ses
diagonales non nulles. Dautre part, la matrice inverser ne dpend pas du temps (sauf si D dpend
explicitement de t) : on peut donc linverser une bonne fois pour toute au dpart, chaque itration
temporelle se rduisant une multiplication de la matrice inverse par le second membre adquat.
De mme que prcdemment, on peut tudier la stabilit de cette itration numrique. Aprs quelques
calculs, on obtient
(k) =
1
Dt
1+4
sin2
x2
kx
2
|(k)| < 1
117
* Calcul de x * x
*/
double
sqr ( double x )
{
return x * x ;
}
# define D 1.0
/*
* Itration par diffrences finies - schma explicite pour
* l quation de diffusion
* Nx , Dx : nombre de points et pas spatial
* Nt , Dt : nombre de points et pas temporel
*/
void
expl_diffus ( int Nx ,
double Dx ,
int Nt ,
double Dt )
{
double ** u , C , c1 , c2 ;
int ix , it ;
// Allocation mmoire pour stocker la solution
u = alloc_matrice ( Nt , Nx ) ;
if ( u == NULL ) {
printf ( " Erreur d allocation mmoire \ n " ) ;
return ;
}
C = D * Dt / sqr ( Dx ) ;
// On considre une source unique , au milieu du domaine spatial considr
// mettant une impulsion au temps t =0
for ( ix = 0; ix < Nx ; ix ++) {
u [0][ ix ] = ( double ) ( ix == Nx / 2) ;
}
// Condition aux bords droit et gauche : Neumann ( la solution s annule )
for ( it = 1; it < Nt ; it ++) {
for ( ix = 0; ix < Nx ; ix ++) {
c1 = ix == Nx - 1 ? 0.0 : u [ it - 1][ ix + 1];
c2 = ix == 0 ? 0.0 : u [ it - 1][ ix - 1];
u [ it ][ ix ] = u [ it - 1][ ix ] + C * ( c1 + c2 - 2.0 * u [ it - 1][ ix ]) ;
}
printf ( " Iteration %d , | u | max =% e \ n " ,it , umax ( u [ it ] , Nx ) ) ;
}
// Reste appeler ici une fonction d archivage sur disque pour post - traitement
// graphique par exemple
free_matrice (u , Nt ) ;
}
/*
* Programme principal
*/
int
main ( void )
118
{
int Nx , Nt ;
double Dx , Dt ;
printf ( " Nx , Dx
scanf ( " % d % le " ,
printf ( " Nt , Dt
scanf ( " % d % le " ,
: ");
& Nx , & Dx ) ;
: ");
& Nt , & Dt ) ;
expl_diffus ( Nx , Dx , Nt , Dt ) ;
return 0;
}
Cet autre programme implmente la mthode implicite pour la mme quation de diffusion. On utilise
ici une fonction dinversion de matrice, qui nest autre quune variante de la mthode du pivot de Gauss
pour rsoudre un systme linaire. On notera que le programme ci-dessous ne tient pas compte de la
structure tri-diagonale de la matrice inverser, de sorte quil est possible de lamliorer, aussi bien en
temps de calcul quen donnes stocker en mmoire.
A nouveau, les fonctions alloc_matrice, free_matrice et umax ne sont pas reproduites ici car elles sont
identiques celles crites prcdemment.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# include
# include
# include
# include
119
120
break ;
}
for ( ligne = 1 + pivot ; ligne < n ; ligne ++) {
coef = A [ ligne ][ pivot ] / A [ pivot ][ pivot ];
A [ ligne ][ pivot ] = 0.0;
for ( colonne = 1 + pivot ; colonne < n ; colonne ++) {
A [ ligne ][ colonne ] = A [ ligne ][ colonne ] - A [ pivot ][ colonne ] *
coef ;
}
for ( colonne = 0; colonne < n ; colonne ++) {
b [ ligne ][ colonne ] = b [ ligne ][ colonne ] - b [ pivot ][ colonne ] *
coef ;
}
}
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
}
if ( err == 1) {
for ( ligne = n - 1; ligne >= 0; ligne - -) {
for ( colonne = 0; colonne < n ; colonne ++) {
v = b [ ligne ][ colonne ];
for ( loop = 1 + ligne ; loop < n ; loop ++) {
v = v - A [ ligne ][ loop ] * b [ loop ][ colonne ];
}
b [ ligne ][ colonne ] = v / A [ ligne ][ ligne ];
}
}
}
free_matrice (A , n ) ;
return err ;
}
/*
* Multiplication matrice ( a ) x vecteur ( b ) = vecteur ( c )
*/
void
mv ( double ** a ,
double * b ,
double * c ,
int n )
{
int i , j ;
for ( i = 0; i < n ; i ++) {
c [ i ] = 0.0;
for ( j = 0; j < n ; j ++) {
c [ i ] += a [ i ][ j ] * b [ j ];
}
}
}
# define D 1.0
/*
* Itration par diffrences finies - schma implicite pour
* l quation de diffusion
* Nx , Dx : nombre de points et pas spatial
* Nt , Dt : nombre de points et pas temporel
*/
void
impl_diffus ( int Nx ,
121
double Dx ,
int Nt ,
double Dt )
{
double alpha , ** u , ** a , ** b ;
int ix , it , i , j ;
alpha = D * Dt / ( Dx * Dx ) ;
// Calcul des matrices a et b = inverse ( a ) - on devrait veiller ce que
// la fonction alloc_matrice ne renvoie pas NULL !
// Les coefficients de la matrice a correspondent la condition de Neumann
a = alloc_matrice ( Nx , Nx ) ;
b = alloc_matrice ( Nx , Nx ) ;
for ( i = 0; i < Nx ; i ++) {
for ( j = 0; j < Nx ; j ++) {
if ( i == j )
a [ i ][ j ] = 1.0 + 2.0 * alpha ;
else if ( i == j -1 || i == j +1)
a [ i ][ j ] = - alpha ;
else
a [ i ][ j ] = 0.0;
}
}
// Une fois b = inverse ( a ) calcule , on n utilise plus a , donc on dsalloue
inver sion_matrice (a , b , Nx ) ;
free_matrice (a , Nx ) ;
// Allocation mmoire pour stocker la solution - nouveau , on devrait veiller
// ce que la fonction alloc_matrice ne renvoie pas NULL !
u = alloc_matrice ( Nt , Nx ) ;
// On considre une source unique , au milieu du domaine spatial considr
// mettant une impulsion au temps t =0
for ( ix = 0; ix < Nx ; ix ++) {
u [0][ ix ] = ( double ) ( ix == Nx / 2) ;
}
// A chaque pas , le calcul se rduit une multiplication matrice x vecteur
for ( it = 1; it < Nt ; it ++) {
mv (b , u [ it - 1] , u [ it ] , Nx ) ;
printf ( " Iteration %d , | u | max =% e \ n " , it , umax ( u [ it ] , Nx ) ) ;
}
// Reste appeler ici une fonction d archivage sur disque pour post - traitement
// graphique par exemple
free_matrice (b , Nx ) ;
free_matrice (u , Nt ) ;
}
/*
* Programme principal
*/
int
main ( void )
{
int Nx , Nt ;
double Dx , Dt ;
122
printf ( " Nx , Dx
scanf ( " % d % le " ,
printf ( " Nt , Dt
scanf ( " % d % le " ,
: ");
& Nx , & Dx ) ;
: ");
& Nt , & Dt ) ;
impl_diffus ( Nx , Dx , Nt , Dt ) ;
return 0;
}
7.5
On peut citer deux autres grandes classes de mthodes permettant de traiter numriquement les problmes dquations aux drives partielles.
La premire mthode consiste utiliser une analyse spectrale par transformes de Fourier sur le temps
et/ou une (plusieurs) variable(s) despace. Cette mthode est toutefois rserve au cas des quations
linaires, la transformation de Fourier tant plutt inadapte aux problmes non linaires.
Lintrt principal de cette approche est quelle permet de dcomposer la solution sur une base (les
fonctions exponentielles) de fonctions propres de loprateur de drivation. Si lon prend lexemple de
lquation dondes 3D, crite sous la forme
1 2u
2u 2u 2u
=
+ 2 + 2
2
2
c t
x2
y
z
on obtient, par transforme de Fourier sur t, x et y (frquences duales f , fx et fy ) :
2
f
2u
2
2
2
+
4
f
u=0
x
y
z 2
c2
Lquation aux drives partielles est ainsi transformes en une simple quation diffrentielle une
inconnue, dont la solution analytique est donne par
!
!
r
r
2
f2
f
u = a+ exp 2iz
fx2 fy2 + a exp 2iz
fx2 fy2
c2
c2
Les coefficients a+ et a rsultent des conditions aux limites imposes par le problme tudi, ils dpendent gnralement des frquences f , fx et fy .
Une fois cette solution obtenue, il reste revenir dans lespace rel (x, y, t) par une approche soit analytique, soit purement numrique (algorithme de transforme de Fourier rapide), soit encore en mixant les
deux approches.
Une autre mthode consiste en lutilisation de codes dlments finis. Cette dmarche utilise un maillage
de lespace (1D, 2D voire 3D) ; la solution est recherche en chaque noeud du maillage et interpole
entre les noeuds (interpolations linaires, par splines ...). Toutes ces donnes sont alors injectes dans
le problme diffrentiel pour parvenir un systme dquations dont les inconnues sont les solutions en
chaque noeud. A linverse de la mthode des diffrences finies qui fonctionne de faon progressive, la
mthode des lments finis est globale. Ceci conduit gnralement des codes de calculs assez complexes.
123
Chapter 8
Le thorme de lchantillonnage
Ce thorme est essentiel dans le domaine de la thorie du signal ; il permet de donner un critre de validit pour lchantillonnage dun signal par une srie de points discrets. Dautre part, ce mme thorme
permet de donner une relation mathmatique reliant le signal chantillonn au signal rel.
Echantillonner un signal consiste ne considrer que certains points rgulirement rpartis temporellement ; cette opration saccompagne donc dune perte dinformations que lon souhaite nulle, ou tout du
moins la plus faible possible.
8.1
Rsultats prliminaires
On considre une fonction s(t) priodique de plus petite priode T , de sorte que les deux fonctions
temporelles s(t) et s(t + T ) sont identiques. Les transformes de Fourier de ces deux fonctions sont
galement identiques, de sorte que lon a la relation suivante :
s(f ) = s(f ) exp (i2f T )
Une telle relation nest possible avec s(f ) non trivial que si exp (i2f T ) = 1, soit encore fn = n/T . Il
en rsulte que la transforme de Fourier de s(t) ne contient que les frquences multiples entiers de la
frquence fondamentale 1/T . Ce rsultat correspond en fait la dcomposition en sries de Fourier de
la fonction priodique s(t) :
s(t) =
+
X
cn exp (i2nt/T ) ,
avec
n=
cn =
1
T
a+T
+
X
(t nT )
n=
Cette distribution est priodique de plus petite priode T ; on peut donc lui appliquer le thorme
prcdent en prenant pour a la valeur T /2 par exemple, de sorte que la dcomposition en sries de
Fourier du peigne de Dirac scrit sous la forme
T (t) =
+
X
(t nT ) =
n=
+
1 X
exp (i2nt/T )
T n=
La transforme de Fourier du peigne de Dirac de plus petite priode T est donc un peigne de Dirac de
priode 1/T .
125
8.2
On considre un signal continu s(t) chantillonn avec un pas temporel T0 (frquence dchantillonnage
f0 = 1/T0 ). Le signal chantillonn se (t) est alors donn par
se (t) = s(t) T0 (t)
Calculant la transforme de Fourier de cette expression, il vient
+
+
1 X
1 X
(f )
se (f ) = s(f )
(f nf0 ) =
s (f nf0 )
T0 (f ) = s
f
f T0 n=
T0 n=
On constate donc que le fait dchantillonner le signal s(t) revient priodiser son spectre, avec le motif
primaire (n = 0) et une infinit de rpliques de ce motif de base (valeurs positives et ngatives de n).
A quelle condition lchantillonnage naltre-til pas le signal initial ? Afin de rpondre cet objectif,
il faut sassurer que leffet de priodisation du spectre naltre pas le motif primaire correspondant au
signal continu.
Pour cela, il est dj impratif dimposer que le signal est spectre born, cest--dire quil existe une
frquence fmax telle que s(f ) = 0 ds que |f | > fmax . Si cette condition nest pas satisfaite, le signal
ne peut thoriquement pas tre chantillonn correctement. Cependant, il faut en gnral considrer
une condition moins stricte, savoir que le spectre du signal initial doit tre de contribution globale
ngligeable au-del dune certaine frquence maximale.
Sous rserve que cette condition de spectre born soit satisfaite, on a les deux cas de figures illustrs de
la faon suivante.
Premier cas : la frquence dchantillonnage fe est suffisamment leve pour assurer que la premire
rplique ne se superpose pas avec le motif primaire (dans ce cas, toutes les rpliques du motif primaire
sont parfaitement isoles les unes des autres). Ce cas de figure correspond un signal correctement
chantillonn pour lequel on peut reconstruire le motif primaire sans ambigut partir du spectre
priodis.
Second cas : la frquence dchantillonnage fe est trop faible, de sorte que le dbut de la premire
rplique se superpose avec la fin du motif primaire (dans ce cas, le phnomne de recouvrement se
reproduit chaque rplique). Ce cas de figure correspond un signal mal chantillonn pour lequel il
nest pas possible de reconstruire le motif primaire sans ambigut partir du spectre priodis. En effet,
dans la zone de recouvrement, la grandeur effectivement accessible est la somme du motif primaire et de
ses rpliques, et il nest pas possible de diffrencier les diffrents motifs les uns des autres dans les zones
de recouvrement.
126
Ces deux cas de figures permettent de conclure que la condition de non recouvrement peut scrire sous
la forme
fe fmax > fmax , soit encore fe > 2fmax
Cette condition correspond la condition dchantillonnage de Shannon. Cette condition assure que
lchantillonnage du signal se fait sans perte dinformations et quil est possible de retrouver le spectre
exact du signal initial partir du spectre priodis su signal chantillonn. Nanmoins, si la frquence
dchantillonnage nest pas suffisamment leve, tout en respectant le critre de Shannon, le signal
chantillonn ne ressemblera pas au signal rel et il sera ncessaire de mettre en oeuvre une formulation
mathmatique spcifique pour reconstruire le signal initial.
Remarque : dans certaines situations, en particulier dans le domaine des radars, il est possible
dchantillonner des frquences qui ne respectent pas le critre de Shannon. Dans ce cas, il est indispensable de tenir compte de proprits caractristiques du signal, connues a priori, pour pouvoir
reconstruire le motif primaire sans ambigut malgr le phnomne de recouvrement.
8.3
On suppose ici que la condition de Shannon est satisfaite afin dviter tout recouvrement entre le motif
primaire du spectre du signal initial et les diffrentes rpliques conscutives lchantillonnage. Dans
cette hypothse, on peut retrouver s(f ) partir de se (f ), simplement en liminant toutes les rpliques.
Pour cela, on dfinit la fonction
1 si |f | < fmax
r(f ) =
0 sinon
dont la transforme de Fourier inverse est classiquement donne par
r(t) = 2fmax
sin (2fmax t)
= 2fmax sinc (2fmax t)
2fmax t
Puisque les diffrentes rpliques ne se superposent pas, on a la relation s(f ) = se (f ) r(f ), soit par
transforme de Fourier inverse :
+
+
X
X
n
n
n
n
se
t
=
se
r t
s(t) = se (t) r(t) = r(t)
t
t n=
f0
f0
f0
f0
n=
+
X
n
n
= 2fmax
se
sinc 2fmax t
f0
f0
n=
Cette formule permet ainsi dinterpoler le signal chantillonn pour calculer sans ambigut le signal rel
pour tout instant t donn. Cette formule est trs utilise dans le domaine du traitement du signal, pour
dterminer des proprits caractristiques de signaux exprimentaux avec une prcision meilleure que la
priode dchantillonnage.
127
Chapter 9
Dfinition
On considre un signal s(t) chantillonn sur N points avec un pas T , soit une frquence dchantillonnage
fe = 1/T . Le signal continu est alors remplac par un signal discret reprsent numriquement par un
tableau de N valeurs : s[i] = s(iT ).
Il rsulte de cet chantillonnage que le signal discret ne peut reprsenter le signal rel que dans la fentre
temporelle [0, (N 1)T ]. Il est clair dans ce cas que lon ne dispose dune reprsentation acceptable
que si le signal rel est nul en dehors de cette fentre temporelle. Il sagit l de la premire hypothse de
travail que nous considrons.
Par convention, le spectre du signal s(f ) sera galement chantillonn sur N points (N/2 points pour
les frquences positives et N/2 points pour les frquences ngatives). Sous rserve que le thorme de
lchantillonnage soit satisfait, on sait que la frquence maximale contenu dans le spectre du signal est
infrieure fe /2. On va donc calculer s(f ) jusqu fe /2, le spectre au-del tant en thorie nul ou
ngligeable. Il en rsulte alors la relation suivante :
N
fe
1
f =
=
2
2
2T
T f =
1
N
Cette relation fondamentale exprime lchantillonnage frquentiel en fonction de lchantillonnage temporel. Une consquence immdiate de cette relation est quil est impossible davoir des chantillonnages
aussi fins que possible, simultanment en temps et en frquence. Ce point est particulirement important
si la transforme de Fourier discrte est utilise dans le domaine de la simulation numrique, les chantillonnages temporel et frquentiel devant tre choisis moyennant un compromis adapt au problme trait.
Remarque : la premire moiti du tableau correspond aux frquences positives, et la seconde moiti
aux frquences ngatives. Par convention, la frquence zro est considre comme frquence positive, ce
qui introduit une dissymtrie entre frquences positives et ngatives. Par convention, la correspondance
entre les indices du tableau S[i] (spectre chantillonn) et les frquences et la suivante :
0 i N 1 = fi = if
2
N
i N 1 = fi = (N i)f
2
Par consquent, les frquences positives vont de 0 (N/2 1)f et les frquences ngatives de N/2f
f .
Par dfinition de la transforme de Fourier continue, on a
Z
s(f ) =
Z
s(t) exp(i2f t)dt =
129
N T
9.2
N
1
X
wl(jk) =
l=0
N
0
si j = k
= N jk
sinon
N
1
X
s[j]jr =
j=0
N 1
N 1
N
1
X
1 X
1 X
s[j]jr =
s[j]
wl(jr)
N j=0
N j=0
l=0
N 1
N 1
N 1
1 X
1 X lr X
w
s[j]wlj =
S[l]wlr
N
N
j=0
l=0
l=0
|
{z
}
S[l]
Cette relation dfinit la transforme de Fourier discrte inverse. On constate immdiatement quelle ne
diffre de la transforme de Fourier discrte directe que par les deux lments suivants :
le facteur de normalisation 1/N ,
le remplacement de w par 1/w = w.
Par consquent, un seul et unique algorithme numrique permettra dvaluer indiffremment la transforme de Fourier discrte directe ou inverse.
9.3
Le thorme de Parseval
=
=
N
1
X
N
1
X
"N 1
X
k=0
N
1
X
n=0
S[k]S[k] =
k=0
N
1
X
n,m=0
s[n]s[m]
s[n]w
kn
wk(nm) = N
k=0
# "N 1
X
m=0
N
1
X
N
1
X
#
s[m]w
km
k,n,m=0
N
1
X
130
s[n]s[n] = N ksk
s[n]s[m]nm = N
n,m=0
s[n]s[m]wk(nm)
n=0
Au facteur multiplicatif N prs (facteur de normalisation), la transformation conserve donc la norme des
vecteurs, ce qui gnralise le thorme de Parseval au cas de la transforme de Fourier discrte.
9.4
9.4.1
La premire tape permettant de rduire le nombre de calculs consiste considrer que le nombre de
points N se dcompose sous la forme N = n1 n2 . On modifie alors la reprsentation des indices k et r
par divisions euclidiennes par n1 et n2 respectivement :
k = k1 n1 + k0 , 0 k0 < n1 et 0 k1 < n2
r = r1 n2 + r0 , 0 r0 < nr et 0 r1 < nr
On peut alors indiffremment reprsenter les indices k et r par (k1 , k0 ) et (r1 , r0 ) respectivement. Pour
simplifier, on utilisera sans distinction les notations s[r] et s[r1 , r0 ], S[k] et S[k1 , k0 ].
Compte tenu de la dcomposition des indices, on a alors
kr = (k1 n1 + k0 ) (r1 n2 + r0 ) = N k1 r1 + r1 n2 k0 + kr0
soit
wkr = wN k1 r1 wr1 n2 k0 wkr0 = wr1 n2 k0 wkr0
On en dduit alors
"
S[k1 , k0 ] =
s[r1 , r0 ]w
kr
r0 ,r1
X
r0
kr0
#
X
s[r1 , r0 ]w
r1 n2 k 0
r1
Cette expression nous permet dintroduire un vecteur intermdiaire, index (k0 , r0 ) et dfini par
X
s1 [k0 , r0 ] =
s[r1 , r0 ]wr1 n2 k0
r1
Compte tenu des domaines de valeurs des sous-indices k0 et r0 , il est ais de vrifier que le vecteur s1
est de longueur N , comme s et S. Un fois le vecteur s1 calcul, il ne reste plus qu valuer
X
S[k1 , k0 ] =
s1 [k0 , r0 ]wkr0
r0
Globalement, le calcul de la transforme de Fourier discrte se fait donc en deux tapes rsumes par le
tableau suivant :
Calcul ralis
Nature du calcul
Nombre doprations complexes
Etape n 1 Calcul de s1 partir de s T.F.D. sur n1 points
2N n1
Etape n 2 Calcul de S partir de s1 T.F.D. sur n2 points
2N n2
Total
2N (n1 + n2 )
A titre dexemple, si lon considre une transforme de Fourier discrte sur N = 1024 points, on peut
choisir n1 = n2 = 32, ce qui nous donne gain en nombre doprations (donc en temps de calcul) dun
facteur 16 par rapport lalgorithme de base. Un tel gain est particulirement apprciable dans le
domaine du traitement numrique.
131
9.4.2
Lalgorithme de Cooley/Tukey consiste gnraliser lapproche prcdente au cas particulier dun nombre
de points N en puissance de 2 : N = 2p . De mme que prcdemment, lide consiste rcrire
diffremment les indices des tableaux, ici par dcomposition binaire :
k = (kp1 , , k0 ) = 2p1 kp1 + + 2k1 + k0
r = (rp1 , , r0 ) = 2p1 rp1 + + 2r1 + r0
Dans cette dcomposition, chaque ki et ri ne prend que les valeurs 0 ou 1. On peut alors rcrire le
produit kr sous la forme suivante :
kr = 2p2 kp1 + + k1 rp1 2p + k0 rp1 2p1 + k 2p2 rp2 + + 2r1 + r0
Compte tenu de la rcriture des indices, la transforme de Fourier discrte scrit
S [kp1 , , k0 ] =
r0
s [rp1 , , r0 ] wkr
rp1
Remplaant kr par son expression ci-dessus, on obtient aprs rorganisation des diffrentes contributions
:
X
X
X
p2
p1
rp2
rp1
p1
rp1
moyennant quoi
S [kp1 , , k0 ] =
X
r0
wk(2
p2
s1 [k0 , rp2 , , r0 ]
rp2
En conclusion, le pi`eme vecteur intermdiaire sp nest autre que le vecteur S que lon cherche calculer,
une rorganisation des sous-indices (k0 , k1 , k2 , , kp1 ) prs. Cette rorganisation, correspondant en fait
un ordre diffrent de stockage des diffrents lments des tableaux, peut tre dcrite par le diagramme
suivant :
(kp1 , , k0 )
=
(k0 , , kp1 )
Cette remise en ordre des lments de tableau est appele cryptage/dcryptage binaire, elle consiste
faire un miroir binaire sur les indices. On donne ici titre indicatif la table de transformation des
diffrents indices correspondant N = 8 :
132
Dcomposition binaire
000
001
010
011
100
101
110
111
Miroir binaire
000
100
010
110
001
101
011
111
Il existe deux variantes de cet algorithme. La premire possibilit consiste calculer les p itrations,
puis rordonner les lments de tableau pour obtenir le rsultat final. La seconde possibilit consiste
rordonner les lments de tableau avant de calculer les itrations. Ces deux variantes sont quivalentes
et constituent lalgorithme de Cooley/Tukey.
Chaque tape de litration consistant calculer sn+1 partir de sn est en fait un calcul de transforme
de Fourier discrte sur 2 points, utilisant des vecteurs N composantes ; il en rsulte que chaque
tape requiert 4N oprations complexes. Comme p itrations sont ncessaires, on obtient finalement
4N p = 4N log2 N oprations complexes.
A titre dexemple, si lon considre une transforme de Fourier discrte sur N = 210 = 1024 points, on
obtient un gain en nombre doprations (donc en temps de calcul) dun facteur 50 environ par rapport
lalgorithme de base !
9.4.3
Cas particuliers
Dans certains cas particuliers, il est possible de modifier lalgorithme de Cooley/Tukey afin dacclrer
encore le processus de calcul.
A titre dexemple, on sait que la transforme de Fourier dun signal rel est hermitienne par rapport aux
frquences. Dans ce cas, il nest pas ncessaire de calculer les composantes correspondant aux frquences
ngatives puisquelles peuvent se dduire des composantes quivalentes en frquences positives. Il existe
alors deux variantes possibles :
la premire possibilit consiste calculer une transforme de Fourier discrte sur un nombre de
points deux fois plus petit ; une analyse mathmatique adapte doit alors tre faite pour reconstruire
sans ambigut toutes les composantes du spectre,
la seconde possibilit consiste calculer simultanment les spectres de deux signaux rels ; ce cas
de figure peut tre intressant si le processus numrique requiert plusieurs calculs de transformes
de Fourier discrte sur diffrents signaux.
Une autre utilisation de cet algorithme gnrique consiste calculer les transformes en sin et cos, pour
lesquelles le noyau de la transformation est modifi par rapport la transforme de Fourier discrte.
On vrifie aisment que ces transformations peuvent tre exprimes en terme de transformes de Fourier
classiques. Dans ce cas, une analyse mathmatique spcifique doit galement tre faite pour utiliser au
maximum la performance des algorithmes numriques.
9.5
Ltude des systmes physiques fait souvent intervenir loprateur de convolution, ds lors que le systme
physique tudi est linaire et invariant par translation.
A titre de rappel, un tel systme physique est caractris par sa rponse impulsionnelle h(t) correspondant
au signal de sortie gnr par ce systme pour une excitation en entre de type (t).
Pour un signal dentre e(t) donn, le signal de sortie s(t) est alors
Z +
e( )h(t )d
s(t) = e(t) h(t) =
t
133
Rsultat obtenu
E[ ]
H[ ]
S[ ] = E[ ] H[ ]
s[ ]
Nombre doprations
N log2 N
N log2 N
N
N log2 N
Il en rsulte que le nombre de calculs faire augmente au maximum comme N log2 N , ce qui est beaucoup
moins rapide quune croissance quadratique. Dautre part, on a ici besoin de calculer les transformes
de Fourier discrtes des deux signaux e(t) et h(t), ce qui peut tre fait de faon encore plus rapide si ces
signaux sont rels (la grande majorit des systmes physiques satisfont cette proprit !).
9.6
Un autre besoin souvent exprim dans le domaine du traitement du signal consiste calculer une dconvolution.
Dans le cas prcdent, taient connus le signal dentre e(t) et la rponse impulsionnelle du filtre h(t),
partir de ces informations on cherche calculer le signal de sortie s(t). Une telle dmarche suppose que
le filtre et sa rponse impulsionnelle soient connus.
Le problme inverse, galement frquent, consiste tudier un filtre dont on ne connat pas la rponse
impulsionnelle. Dans ce cas, une mesure exprimentale permet dobtenir le signal de sortie s(t) pour une
entre donne e(t). De ces mesures exprimentales, on cherche alors calculer la rponse impulsionnelle
h(t).
La premire chose importante comprendre dans un tel contexte est quil sagit dun problme a priori
difficile car mal pos. En effet, lintgrale de convolution induit une perte dinformations par filtrage.
Cette perte dinformations est gnralement irrmdiable et la dconvolution essaie de reconstruire une
information non prsente dans les signaux dentre et de sortie mesurs exprimentalement.
La premire approche possible consiste crire la sommation discrte sur tous les indices possibles et
dinverser le systme linaire rsultant. Si les signaux sont stocks sur N points, on obtient un systme de
N quations N inconnues, soit encore une matrice de N 2 coefficients. Ainsi, pour des signaux stocks
sur 1024 points, on obtient une matrice un million de coefficients : ceci est trs coteux stocker en
mmoire et traiter pour inversion du systme. Rsoudre un tel problme temporel de cette faon est
quasi irraliste !
Lautre approche consiste utiliser la transforme de Fourier :
) = s(f )
h(f
e(f )
Rsultat obtenu
E[ ]
S[ ]
H[ ] = S[ ]/E[ ]
h[ ]
Nombre doprations
N log2 N
N log2 N
N
N log2 N
135
Contents
1 Introduction
1.1 Gnralits . . . . . . . . . . . . . . .
1.2 Do proviennent les erreurs darrondis
1.3 La propagation derreur . . . . . . . .
1.4 Les objectifs de lAnalyse Numrique .
1.5 Quelques principes de base . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
3
3
3
3
4
4
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
7
7
7
14
16
18
18
21
.
?
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
27
29
32
34
36
36
36
40
42
. . . . . .
. . . . . .
de Powell
. . . . . .
. . . . . .
. . . . . .
. . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
51
51
52
57
69
71
71
71
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
75
75
75
77
80
82
82
83
85
85
85
86
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
5 Intgration numrique
5.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.2 La mthode des rectangles . . . . . . . . . . . . . . . . . . . .
5.3 La mthode des trapzes . . . . . . . . . . . . . . . . . . . . .
5.4 La mthode de Simpson . . . . . . . . . . . . . . . . . . . . .
5.5 Gnralisation - les mthodes directes . . . . . . . . . . . . .
5.5.1 Premier cas : les points sont fixes . . . . . . . . . . . .
5.5.2 Second cas : les points sont ajustables . . . . . . . . .
5.6 La mthode dintgration de Gauss . . . . . . . . . . . . . . .
5.6.1 Principe gnral . . . . . . . . . . . . . . . . . . . . .
5.6.2 Application au calcul dintgrales singulires . . . . .
5.6.3 Quelques lments relatifs aux polynmes orthogonaux
137
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
quations diffrentielles
Les sries de Taylor . . . . . . . . . . . . . . . . . . . . . . .
La mthode dEuler . . . . . . . . . . . . . . . . . . . . . .
La mthode de Runge-Kutta . . . . . . . . . . . . . . . . .
6.3.1 La mthode de Runge-Kutta dordre 2 . . . . . . . .
6.3.2 La mthode de Runge-Kutta dordre 4 . . . . . . . .
6.3.3 La stabilit numrique . . . . . . . . . . . . . . . . .
6.3.4 Extension au cas des quations diffrentielles dordre
6.3.5 Exemple de programme . . . . . . . . . . . . . . . .
. .
. .
. .
. .
. .
. .
N
. .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
89
89
93
94
94
95
95
96
97
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
105
105
105
107
107
108
108
108
109
109
112
119
7 Les
7.1
7.2
7.3
8 Le thorme de lchantillonnage
121
8.1 Rsultats prliminaires . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
8.2 Echantillonnage dun signal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
8.3 Reconstruction du signal continu partir du signal chantillonn . . . . . . . . . . . . . . 123
9 La transforme de Fourier discrte
9.1 Dfinition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9.2 Inversibilit de la transforme de Fourier discrte . . . . . . . . . . . . .
9.3 Le thorme de Parseval . . . . . . . . . . . . . . . . . . . . . . . . . . .
9.4 Lalgorithme de base de la transforme de Fourier discrte . . . . . . . .
9.4.1 La transforme de Fourier rapide - premire tape . . . . . . . .
9.4.2 La transforme de Fourier rapide - lalgorithme de Cooley/Tukey
9.4.3 Cas particuliers . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9.5 Application de la T.F.D. pour les calculs de convolution . . . . . . . . .
9.6 Application de la T.F.D. pour les calculs de dconvolution . . . . . . . .
138
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
125
125
126
126
127
127
128
129
129
130