]> AND Private Git Repository - cours-mesi.git/blob - pbnum.tex
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
j
[cours-mesi.git] / pbnum.tex
1 Ce chapitre s'inspire de~\cite{jedrzejewski2005introduction} et 
2 de~\cite{bastien2003introduction}. 
3 On y pointe quelques erreurs classiques en calcul numérique.
4 On peut classer ces erreurs en plusieurs groupes:
5 \begin{itemize}
6 \item les erreurs de calcul en machine: elles sont dues aux arrondis de 
7   calcul pour les nombres flottants, par exemple.
8 \item les erreurs de méthode: elles sont dues à l'algorithme utilisé.
9   Par exemple, approximation d'une somme infinie par une somme finie, 
10   d'une limite d'une suite par un terme de grand indice, 
11   d'une intégrale par une somme finie.
12 \item les erreurs sur les données (imprécision des mesures physiques, 
13   résultats d'un calcul approché). Ces données ne peuvent pas être modifiées, 
14   mais on peut étudier l'influence de ces erreurs sur le résultat final.
15 \end{itemize}
16
17
18
19
20  
21 % \section{Représentation} 
22 % \begin{Def}[Nombres en base $\Beta$}
23 % Soit $\Beta$ un nombre entierstrictement supérieur à 1. 
24 % pour tout entier $n$ supérieur ou égal à 1, 
25 % il existe un unique entier $p$ et 
26 % des entiers  $d_i$ ($0 \le i \le p$) tous compris entre 0 
27 % et $\Beta -1$ avec $d_p \neq 0$ tels que
28 % $$ n = \Sum_{i=0}^p d_i \Beta^1.$$
29 % Lemembre de droite est la représentation de $n$ en base 
30 % $\Beta$
31
32 \section{Erreurs de calcul en machine sur les entiers}
33
34
35 On donne à la figure~\ref{script:facto:java} les codes java et python 
36 permettant d'évaluer la fonction factorielle.
37
38 \lstset{language=Java}
39 \begin{figure}
40 \begin{scriptsize}
41 \begin{minipage}{0.65\textwidth}
42 \begin{lstlisting}
43  class TestFactorielle{    
44    public static int  factorielle(int n){
45      int r = 1;
46      for (int i=2; i<=n ; i++){
47        r = r * i;}
48      return r;}
49
50    public static void main(String args[]){
51      for (int j=1; j< 36; j++){
52        System.out.println(j+' '+
53                           factorielle(j));
54      }}}
55 \end{lstlisting}
56 \end{minipage}
57 \begin{minipage}{0.30\textwidth}
58 \lstset{language=Python}
59 \begin{lstlisting}
60 def factorielle(n):
61   r=1
62   i=2
63   while i<=n :
64     r=r*i
65     i+=1
66     return r
67
68 for j in range(36):
69     print(str(j) + " " 
70           + str(factorielle(j)))
71 \end{lstlisting}
72 \end{minipage}
73 \end{scriptsize}
74 \caption{Factorielle en Java, en Python}\label{script:facto:java}
75 \end{figure}
76
77 En Java, on a:
78 $$
79 \begin{array}{rcr}
80 5!&=& 120\\
81 & \vdots&\\
82 12! &= & 479001600 \\
83 13! &=& 1932053504 \\
84 & \vdots&\\
85 15! &=& 2004310016\\
86 16! &=&2004189184\\
87 17! &=&-288522240\\
88  &\vdots&\\
89 34! & = & 0 \\
90 35! & = & 0 
91 \end{array}
92 $$
93 On remarque que 
94 \begin{itemize}
95 \item le résultat donné pour 13! est différent de 13 fois le résultat de 12!
96 \item le résultat donné pour 16! est plus petit que celui donné pour 15!
97 \item le résultat donné pour 17! est négatif
98 \item tous les résultats donnés à partir de 34! sont nuls!
99 \end{itemize}
100
101 Par contre en Python 2.7 on a des résultats cohérents:
102 $$
103 \begin{array}{rcr}
104 12! &= &479001600\\
105 13! & =& 6227020800\\
106 & \vdots & \\
107 17! &=& 355687428096000\\
108  & \vdots & \\
109 34!&=& 295232799039604140847618609643520000000 \\
110 35! & =&10333147966386144929666651337523200000000
111 \end{array}
112 $$
113
114 Les deux langages travaillent pourtant avec des entiers et ne sont donc pas 
115 exposés aux erreurs d'arrondis.
116
117 Expliquons l'erreur d'interprétation du langage java. 
118 Celui-ci code chaque entier avec 32 bits. 
119 Le bit le plus à gauche est celui de signe. Il reste donc 31 bits.
120 Cela permet de couvrir tous les entiers de l'intervalle
121 $$\llbracket -2147483648, 2147483647 \rrbracket.$$ 
122 Le tableau~\ref{table:codage:entiers} donne la correspondance entre 
123 certains entiers et le version binaire. 
124
125
126 \begin{table}
127 \centering{
128 \begin{scriptsize}
129 $$
130 \begin{array}{|r|r|r|r|r|}
131 \hline
132 -2147483648&-2147483647&\ldots&-2&-1 \\
133
134 \hline
135 100\ldots000&100\ldots001&\ldots&111\ldots110&111\ldots111\\
136 \hline
137 \hline
138 0&1&2&\ldots&2147483647\\
139 \hline
140 000\ldots000&000\ldots001&000\ldots010&\ldots&011\ldots111\\
141 \hline
142 \end{array}
143 $$
144 \end{scriptsize}}
145 \caption{Correspondance entiers-binaires}\label{table:codage:entiers}
146 \end{table}
147
148
149 Multiplier par un facteur revient à effectuer des opérations sur les bits.
150 Tant que le résultat est inférieur à la valeur maximale des entiers, 
151 tout se passe bien. 
152 Par contre dès que le résultat est supérieur, l'interpréteur 
153 fait n'importe quoi. C'est le cas à partir de 13!.
154 De plus lorsqu'on a dépassé les capacités, on peut ateindre 0 sans que cela ait 
155 du sens (comme à partir de 34!)
156
157 Si le langage python réussit (au moins à partir de 2.7),
158 c'est parce qu'il stocke les entiers
159 sous 64 bits et les convertit en long si besoin, dont le nombre de bits 
160 n'est pas borné. 
161 Python 3, dont le type int équivaut au long de la version 2.7 n'a pas un 
162 nombre borné de bits pour les entiers. Il ne faillit pas dans ce calcul.
163
164
165 \section{Erreurs de calcul en machine sur les flottants}
166
167 Un ordinateur  représente chaque nombre réel sur
168 un nombre fini de bits. 
169 Ceci  ne permet la représentation exacte que d'un petit sous-ensemble des réels.
170 La plupart des calculs sur les réels conduisent ainsi à des résultats approchés
171 qui résultent de la discrétisation de la représentation.
172
173
174 Le tableau~\ref{table:xpl:flottants} donne 
175 des exemples de nombres réels et leur représentation 
176 par des flottants en java et en python.
177
178 \begin{table}
179 \centering{
180 \begin{scriptsize}
181 \begin{tabular}{|l|l|l|l|}
182 \hline
183 Nombre & Représentation        & Valeur approchée &   Erreur \\
184 \hline
185 $\frac{1}{7}$   & $0,\overline{142 857}\ldots$  & 0.14285714285714285 & $7.10^{-18}+\frac{10^{-19}}{7}$ \\
186 \hline 
187 $\ln 2$ &     0.693147180559945309417232121458\ldots &  0.6931471805599453  & $\approx 10^{-17}$ \\
188 \hline 
189 $\sqrt{2}$ &  1.414213562373095048801688724209\ldots & 1.4142135623730951 & $ >  10^{-17}$ \\
190 \hline 
191 $\pi$ &       3.141592653589793238462643383279\ldots& 3.141592653589793& $ >  10^{-17}$ \\
192 \hline 
193 \end{tabular}
194 \end{scriptsize}
195 }\caption{Interprétation erronée de nombres réels particuliers}\label{table:xpl:flottants}
196 \end{table}
197
198 On constate que les deux langages utilisent 64 bits dont 1 pour le signe, 
199 53 pour le contenu et 11 pour l'exposant de la puissance de 10. Ils peuvent
200 donc mémoriser au plus 17 chiffres significatifs. 
201
202
203
204 \section{Adaptation de la méthode pour contourner 
205 les approximations }
206
207 \begin{Exo}
208 Soit l'équation $x^2 +bx +c = 0$ avec $b$ et $c$ strictement positifs.
209 On suppose que le discriminant $\Delta$ est strictement positif et proche 
210 numériquement de $b^2$.
211 \begin{enumerate}
212 \item Exprimer les deux racines $x_1$ et $x_2$ ($x_1 < x_2$).
213 \item Que dire du signe du numérateur de $x_2$ en théorie? 
214 \item En pratique quelle va être sa valeur si l'interpréteur fait des 
215   approximations. 
216 \item Cette erreur d'arrondi est-elle effectuée dans le calcul de $x_1$?
217 \item Montrer qu'on pourrait calculer la racine $x_2$ avec $x_2= \frac{c}{x_1}$.
218 \item Cette nouvelle méthode permet-elle de trouver le signe de $x_2$?  
219 Est-elle plus précise?
220 \end{enumerate}   
221 \end{Exo}
222
223 \begin{TP}
224 Soit l'équation $x^2+1.5.10^{9}x +1 = 0$. Donner une réponse pratique  
225 aux questions précédentes en effectuant les calculs en java.
226 \end{TP}
227
228
229
230 \section{Erreurs sur les données}
231
232 Les données provenant de mesures physiques sont souvent entachées d'erreurs.
233 Par exemple, un traceur GPS ne peut avoir une précision inférieure à 8m
234
235 Ainsi, lorsqu'une méthode de calcul s'applique à des données physiques, 
236 on doit étudier l'influence des erreurs sur le résultats numérique calculé.
237 Si une petite erreur sur les données provoque un changement radical de 
238 la solution calculée, le problème est dit \emph{mal conditionné}.
239
240
241 On cherche par exemple à résoudre le problème à deux équations 
242 et deux inconnues suivant:
243 $$
244 \left\{
245   \begin{array}{llllll}
246     1,2969 x & + & 0,8648 y & = & 0,8642 & L_1\\
247     0,2161 x & + & 0,1441 y & = & 0,1440 & L_2.
248   \end{array}
249 \right.
250 $$
251 Ce système est équivalent à 
252 $$
253 \left\{
254   \begin{array}{llllll}
255     1,2969 x & + & 0,8648  y & = & 0,8642 & L_1\\
256              & + & 10^{-8} y & = & -2 \times 10^{-8} & 1,2969.L_2-0,2161.L1 
257   \end{array}
258 \right.
259 $$
260 qui a pour unique solution $\left(\begin{array}{r} 2 \\ -2
261   \end{array}
262   \right)$.
263 Si on considère maintenant le système légèrement modifié suivant:
264 $$
265 \left\{
266   \begin{array}{llllll}
267     1,2969 x & + & 0,8648 y & = & 0,8642 & L_1\\
268     0,2161 x & + & 0,144 y & = & 0,1440 & L_2
269   \end{array}
270 \right.
271 $$
272 Une valeur approchée à $10^{-5}$ près de l'unique solution de ce système 
273 serait $\left(\begin{array}{r} 0.66626 \\ 0.00015
274   \end{array}
275   \right)$. 
276
277 On constate qu'une infime modification du système initial a eu de 
278 grandes répercutions sur les solutions du système.
279
280
281   
282
283
284
285
286
287  
288
289
290
291
292
293 \begin{TP}
294
295 \begin{Def}[conditionnement]
296 Soit $A$ une matrice inversible. Le  \emph{conditionnement} de $A$, noté 
297 $\textit{cond}(A)$ est défini par 
298 $$ 
299 \textit{cond}(A) = ||A||~||A^{-1}||.
300 $$
301 Une matrice $A$ est dite bien conditionnée si son conditionnement 
302 $\textit{cond}(A)$ est proche de 1.
303 \end{Def}
304
305 On considère les matrices 
306 $$ A = \left( 
307 \begin{array}{llll}
308 4 & 1 & 0 & 0 \\
309 1 & 4 & 1 & 0 \\
310 0 & 1 & 4 & 1 \\
311 0 & 0 & 1 & 4 \\
312 \end{array}
313 \right) ,
314 A' = \left( 
315 \begin{array}{llll}
316 4 & 1 & 0,1 & 0,2 \\
317 1,08 & 4,04 & 1 & 0 \\
318 0 & 0,98 & 3,89 & 1 \\
319 -0,01 & -0,01 & 1 & 3,98 \\
320 \end{array}
321 \right) , 
322 B = \left(
323 \begin{array}{l}
324 5 \\
325 6 \\
326 6 \\
327 5 \\
328 \end{array}
329 \right) \textrm{ et } 
330 B' = \left(
331 \begin{array}{l}
332 5,1 \\
333 5,9 \\
334 6,1 \\
335 4,9 \\
336 \end{array}
337 \right).  
338 $$ 
339
340 \begin{enumerate}
341 \item Que dire de $A$ et $A'$, $B$ et $B'$.
342 \item Résoudre à l'aide de numpy le système $AX_1=B$.
343 \item Résoudre à l'aide de numpy le système $AX_2=B'$.
344 \item Résoudre à l'aide de numpy le système $A'X_3=B$.
345 \item Que dire des différents vecteurs $X_1$, $X_2$ et $X_3$?
346 \item Calculer le conditionnement de $A$.
347 \item Reprendre les questions précédentes avec 
348  
349 $$ A = \left( 
350 \begin{array}{llll}
351 10 & 7 & 8 & 7 \\
352 7 & 5 & 6 & 5 \\
353 8 & 6 & 10 & 9 \\
354 7 & 5 & 9 & 10 \\
355 \end{array}
356 \right) ,
357 A' = \left( 
358 \begin{array}{llll}
359 10 & 7 & 8,1 & 7,2 \\
360 7,08 & 5,04 & 6 & 5 \\
361 8 & 5,98 & 9,98 & 9 \\
362 6,99 & 4,99 & 9 & 9,98 \\
363 \end{array}
364 \right) , 
365 B = \left(
366 \begin{array}{l}
367 32 \\
368 23 \\
369 33 \\
370 31 \\
371 \end{array}
372 \right) \textrm{ et } 
373 B' = \left( 
374 \begin{array}{l}
375 32,1 \\
376 22,9 \\
377 33,1 \\
378 30,9 \\
379 \end{array}
380 \right).  
381 $$ 
382 \item Que peut-on en conclure?
383 \end{enumerate}
384
385 \end{TP}
386