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

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