MN03LAB: Różnice pomiędzy wersjami
Nie podano opisu zmian |
m Zastępowanie tekstu – „,↵</math>” na „</math>,” |
||
(Nie pokazano 4 wersji utworzonych przez 2 użytkowników) | |||
Linia 1: | Linia 1: | ||
<!-- | <!-- | ||
Konwertowane z pliku LaTeX przez latex2mediawiki, zob. http://www.ii.uj.edu.pl/ pawlik1/latex2mediawiki.php. | Konwertowane z pliku LaTeX przez latex2mediawiki, zob. http://www.ii.uj.edu.pl/ pawlik1/latex2mediawiki.php. | ||
Linia 12: | Linia 11: | ||
<div class="mw-collapsible mw-made=collapsible mw-collapsed"> | <div class="mw-collapsible mw-made=collapsible mw-collapsed"> | ||
Oglądaj wskazówki i rozwiązania __SHOWALL__<br> | |||
Ukryj | Ukryj wskazówki i rozwiązania __HIDEALL__ | ||
</div> | </div> | ||
Linia 33: | Linia 32: | ||
<div class="mw-collapsible mw-made=collapsible mw-collapsed"><span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Wskazówka </span><div class="mw-collapsible-content" style="display:none"> | <div class="mw-collapsible mw-made=collapsible mw-collapsed"><span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Wskazówka </span><div class="mw-collapsible-content" style="display:none"> | ||
<div style="font-size:smaller; background-color:#f9fff9; padding: 1em"> Kluczem jest wyjaśnienie, jaka jest reprezentacja liczby <math> | <div style="font-size:smaller; background-color:#f9fff9; padding: 1em"> Kluczem jest wyjaśnienie, jaka jest reprezentacja liczby <math>10^{309}</math> w podwójnej precyzji... A reprezentacja <math>10^{306}</math>? </div> | ||
</div></div> | </div></div> | ||
Linia 42: | Linia 41: | ||
<div class="exercise"> | <div class="exercise"> | ||
Podaj przykłady <strong>zbieżnych</strong> szeregów postaci <math> | Podaj przykłady <strong>zbieżnych</strong> szeregów postaci <math>\sum_{n=1}^{\infty} a_n</math>, których <math>N</math>-te sumy częściowe | ||
obliczone w arytmetyce pojedynczej precyzji algorytmem | obliczone w arytmetyce pojedynczej precyzji algorytmem | ||
<div style="margin: 1em; padding:1em; color: #000; background-color:#fcfcfc;"><pre>suma = 0.0; | <div style="margin: 1em; padding:1em; color: #000; background-color:#fcfcfc;"><pre>suma = 0.0; | ||
for n = 1..N | for n = 1..N | ||
suma += <math> | suma += <math>a_n</math>; | ||
</pre></div> | </pre></div> | ||
będą | będą | ||
* ograniczone niezależnie od <math> | * ograniczone niezależnie od <math>N</math>, albo | ||
* numerycznie rozbieżne, to znaczy takie, że dla bardzo dużych <math> | * numerycznie rozbieżne, to znaczy takie, że dla bardzo dużych <math>N</math> zachodzi <code style="color: #006">suma == Inf</code>. | ||
Wykonaj to samo zadanie, ale podając przykłady szeregów <strong>rozbieżnych</strong> (w | Wykonaj to samo zadanie, ale podając przykłady szeregów <strong>rozbieżnych</strong> (w | ||
Linia 61: | Linia 60: | ||
Rozpatrz na przykład takie szeregi: | Rozpatrz na przykład takie szeregi: | ||
* Szereg zerowy (numerycznie dostajesz oczywiście też 0) | * Szereg zerowy (numerycznie dostajesz oczywiście też 0) | ||
* <math> | * <math>1 + 10^{2006} - 10^{2006} + 0 + \ldots = 1</math> oraz <math>1 + 10^{2006} - 1 + 0 + \ldots = 10^{2006}</math> (numerycznie dostaniesz, odpowiednio, <code style="color: #006">NaN</code> (dlaczego?) i <code style="color: #006">Inf</code>. | ||
* Szereg harmoniczny (numerycznie sumy częściowe w pewnym momencie przestaną rosnąć). | * Szereg harmoniczny (numerycznie sumy częściowe w pewnym momencie przestaną rosnąć). | ||
* Szereg jedynkowy. | * Szereg jedynkowy. | ||
Linia 71: | Linia 70: | ||
<div class="exercise"> | <div class="exercise"> | ||
Dla kolejnych <math> | Dla kolejnych <math>N</math>, wyznacz <math>N</math>-tą sumę częściową szeregu Taylora dla funkcji wykładniczej, gdy <math>x=-90</math>: | ||
<center><math> | <center><math> | ||
e^x \approx \sum_{n=0}^N \frac{x^n}{n!} | e^x \approx \sum_{n=0}^N \frac{x^n}{n!}</math>,</center> | ||
</math></center> | |||
korzystając z algorytmu podanego w poprzednim zadaniu. Oblicz błąd względny | korzystając z algorytmu podanego w poprzednim zadaniu. Oblicz błąd względny | ||
i bezwzględny wyznaczonego przybliżenia, w porównaniu | i bezwzględny wyznaczonego przybliżenia, w porównaniu | ||
do wartości wyznaczonej z wykorzystaniem funkcji bibliotecznej <code>exp()</code>. Powtórz następnie dla <math> | do wartości wyznaczonej z wykorzystaniem funkcji bibliotecznej <code>exp()</code>. Powtórz następnie dla <math>x=10</math>. | ||
Czy --- zgodnie z teorią matematyczną --- sumy te dążą do wartości | Czy --- zgodnie z teorią matematyczną --- sumy te dążą do wartości | ||
<math> | <math>e^{x}</math>. Objaśnij dokładnie, co się stało. | ||
</div></div> | </div></div> | ||
<div class="mw-collapsible mw-made=collapsible mw-collapsed"><span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie </span><div class="mw-collapsible-content" style="display:none"><div style="margin-left:1em"> | <div class="mw-collapsible mw-made=collapsible mw-collapsed"><span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie </span><div class="mw-collapsible-content" style="display:none"><div style="margin-left:1em"> | ||
Zastosowanie naszego algorytmu dla <math> | Zastosowanie naszego algorytmu dla <math>x=-90</math> daje w wyniku (dla arytmetyki | ||
podwójnej precyzji) sumę równą około <math> | podwójnej precyzji) sumę równą około <math>10^{30}</math>, | ||
gdy oczywiście naprawdę <math> | gdy oczywiście naprawdę <math>\exp(-90) | ||
\approx 0</math>). Problem jest skutkiem zjawiska redukcji cyfr przy odejmowaniu: aby | \approx 0</math>). Problem jest skutkiem zjawiska redukcji cyfr przy odejmowaniu: aby | ||
nasza suma była równa zeru, w pewnym momencie musimy odjąć duży składnik od | nasza suma była równa zeru, w pewnym momencie musimy odjąć duży składnik od | ||
Linia 93: | Linia 91: | ||
moment i wartość dodawanego składnika. | moment i wartość dodawanego składnika. | ||
Dla <math> | Dla <math>x=10</math> mamy, dla rosnącego <math>N</math>, całkiem niezły błąd względny ostatecznego | ||
wyniku. | wyniku. | ||
Linia 102: | Linia 100: | ||
<div class="exercise"> | <div class="exercise"> | ||
Już wcześniej stwierdziliśmy, że wyznaczanie <math> | Już wcześniej stwierdziliśmy, że wyznaczanie <math>e \approx (1 + 1/n)^n</math> dla dużego | ||
<math> | <math>n</math> nie jest dobrym pomysłem. Przeprowadź eksperyment numeryczny potwierdzający | ||
to stwierdzenie i objaśnij jego wyniki. | to stwierdzenie i objaśnij jego wyniki. | ||
Linia 116: | Linia 114: | ||
<div class="exercise"> | <div class="exercise"> | ||
Jak wiadomo, szereg harmoniczny <math> | Jak wiadomo, szereg harmoniczny <math>\sum_{n=1}^\infty 1/n</math> jest rozbieżny. | ||
Spróbuj przewidzieć, jaki będzie efekt numerycznego wyznaczenia tej sumy w | Spróbuj przewidzieć, jaki będzie efekt numerycznego wyznaczenia tej sumy w | ||
arytmetyce podwójnej precyzji przy użyciu poniższego kodu. | arytmetyce podwójnej precyzji przy użyciu poniższego kodu. | ||
Linia 145: | Linia 143: | ||
<div class="mw-collapsible mw-made=collapsible mw-collapsed"><span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie </span><div class="mw-collapsible-content" style="display:none"><div style="margin-left:1em"> | <div class="mw-collapsible mw-made=collapsible mw-collapsed"><span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie </span><div class="mw-collapsible-content" style="display:none"><div style="margin-left:1em"> | ||
Nasza suma przekroczy wartość 20, więc aby <code>20 + dskladnik == 20</code>, musi | Nasza suma przekroczy wartość 20, więc aby <code>20 + dskladnik == 20</code>, musi | ||
być dskładnik <math> | być dskładnik <math>\approx 10^{-15}</math> (lub więcej). Tymczasem zakres liczb typu integer wynosi niewiele ponad <math>10^9</math>, więc po jakimś czasie <code>dlicznik</code> przyjmie wartości ujemne. | ||
</div></div></div> | </div></div></div> | ||
Linia 164: | Linia 153: | ||
<div class="exercise"> | <div class="exercise"> | ||
Dla zadanej liczby <math> | Dla zadanej liczby <math>a>1</math> należy wyznaczyć przybliżenie <math>\sqrt{a}</math> stosując metodę Herona. Zaproponuj | ||
dobre przybliżenie początkowe <math> | dobre przybliżenie początkowe <math>x_0</math> wiedząc, że <math>a</math> jest liczbą maszynową typu | ||
<code>double</code>. Ile iteracji wystarczy, by osiągnąć <math> | <code>double</code>. Ile iteracji wystarczy, by osiągnąć <math>\epsilon</math>-zadowalające przybliżenie? | ||
</div></div> | </div></div> | ||
<div class="mw-collapsible mw-made=collapsible mw-collapsed"><span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie </span><div class="mw-collapsible-content" style="display:none"><div style="margin-left:1em"> | <div class="mw-collapsible mw-made=collapsible mw-collapsed"><span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie </span><div class="mw-collapsible-content" style="display:none"><div style="margin-left:1em"> | ||
Jak pamiętamy, <math> | Jak pamiętamy, <math>a = (1+f)2^p = \widetilde{f} 2^{p+1}</math>, | ||
gdzie <math> | gdzie <math>\frac{1}{2}\leq \widetilde{f} < 1</math> oraz <math>p\in N</math>. Stąd | ||
<center><math> | <center><math> | ||
\sqrt{a} = \sqrt{\widetilde{f}}2^{(p+1)/2} = \sqrt{g} 2^k | \sqrt{a} = \sqrt{\widetilde{f}}2^{(p+1)/2} = \sqrt{g} 2^k</math>,</center> | ||
</math></center> | |||
dla pewnego (znanego) <math> | dla pewnego (znanego) <math>k \in N</math>, przy czym <math>\frac{1}{2} \leq \sqrt{g} \leq 1</math>. | ||
Wobec tego, obliczenie | Wobec tego, obliczenie | ||
<math> | <math>\sqrt{a}</math> wymaga po prostu wyznaczenia <math>\sqrt{g}</math>. Najprostsze przybliżenie <math>\sqrt{g}</math> to | ||
<math> | <math>\sqrt{g}\approx 1</math>. Błąd takiego przybliżenia to | ||
<math> | <math>|\sqrt{g} - 1| \leq 0.5</math>. | ||
Jak można jeszcze bardziej poprawić <math> | Jak można jeszcze bardziej poprawić <math>x_0</math>? | ||
</div></div></div> | </div></div></div> | ||
Linia 194: | Linia 182: | ||
<div class="exercise"> | <div class="exercise"> | ||
Należy wyznaczyć przybliżenie <math> | Należy wyznaczyć przybliżenie <math>\frac{1}{a}</math> stosując metodę Newtona do równania | ||
<math> | <math>\frac{1}{x} - a = 0</math>. Zaproponuj | ||
dobre przybliżenie początkowe <math> | dobre przybliżenie początkowe <math>x_0</math> wiedząc, że <math>a</math> jest liczbą maszynową typu | ||
<code>double</code>. Ile iteracji wystarczy, by osiągnąć <math> | <code>double</code>. Ile iteracji wystarczy, by osiągnąć <math>\epsilon</math>-zadowalające przybliżenie? | ||
</div></div> | </div></div> | ||
<div class="mw-collapsible mw-made=collapsible mw-collapsed"><span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie </span><div class="mw-collapsible-content" style="display:none"><div style="margin-left:1em"> | <div class="mw-collapsible mw-made=collapsible mw-collapsed"><span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie </span><div class="mw-collapsible-content" style="display:none"><div style="margin-left:1em"> | ||
Jak pamiętamy, <math> | Jak pamiętamy, <math>a = (1+f)2^p</math>, skąd <math>\frac{1}{a} = \frac{1}{1+f}2^{-p}</math>. | ||
Wystarczy więc przybliżyć <math> | Wystarczy więc przybliżyć <math>\frac{1}{1+f}</math>. Ponieważ dla <math>0 \leq f < 1</math>, | ||
<center><math> | <center><math>\frac{1}{2} \leq \frac{1}{1+f} \leq 1</math>,</center> | ||
</math></center> | |||
to możemy jako pierwsze przybliżenie wybrać <math> | to możemy jako pierwsze przybliżenie wybrać <math>x_0 = \frac{3}{4}2^{-p}</math> (jak | ||
wybrać jeszcze lepsze <math> | wybrać jeszcze lepsze <math>x_0</math>?) | ||
Wtedy mamy następujące oszacowania: | Wtedy mamy następujące oszacowania: | ||
<center><math> | <center><math>|x_0a - 1| = |\frac{3}{4}2^{-p}\cdot (1+f)2^p - 1| = |\frac{3}{4}(1+f) - 1| | ||
\leq \frac{1}{2} | \leq \frac{1}{2}</math></center> | ||
</math></center> | |||
Ponieważ iteracja Newtona spełnia | Ponieważ iteracja Newtona spełnia | ||
<center><math> | <center><math>|x_{k+1}a - 1| = |x_ka-1|^2 = |x_0a-1|^{2^k}</math>,</center> | ||
</math></center> | |||
to, jeśli chcemy, by błąd względny przybliżenia <math> | to, jeśli chcemy, by błąd względny przybliżenia <math>x_{k+1}</math> spełniał <math>\frac{|x_{k+1} - | ||
\frac{1}{a}|}{\frac{1}{a}} = |x_{k+1}a - 1| \leq \epsilon = 2^{-53}</math>, | \frac{1}{a}|}{\frac{1}{a}} = |x_{k+1}a - 1| \leq \epsilon = 2^{-53}</math>, | ||
musimy wykonać co najwyżej <math> | musimy wykonać co najwyżej <math>6</math> iteracji. Ponieważ koszt jednej iteracji | ||
to 3 działania arytmetyczne, wyznaczenie odwrotności <math> | to 3 działania arytmetyczne, wyznaczenie odwrotności <math>a</math> byłoby 18 razy droższe od mnożenia i dodawania, które mają podobny koszt. | ||
Tymczasem, we współczesnych realizacjach, dzielenie jest tylko około 4 razy droższe od mnożenia! Możesz sprawdzić, [http://www.cs.utexas.edu/users/moore/publications/divide_paper.pdf jak to się dzieje np. w procesorach AMD]. | Tymczasem, we współczesnych realizacjach, dzielenie jest tylko około 4 razy droższe od mnożenia! Możesz sprawdzić, [http://www.cs.utexas.edu/users/moore/publications/divide_paper.pdf jak to się dzieje np. w procesorach AMD]. | ||
Linia 238: | Linia 223: | ||
<div class="exercise"> | <div class="exercise"> | ||
Niech <math> | Niech <math>0 < a_1 < a_2 < \cdots < a_n</math>. Czy z punktu widzenia | ||
błędów w <math> | błędów w <math>fl_\nu</math> lepiej jest policzyć sumę tych liczb w kolejności | ||
od najmniejszej do największej, czy odwrotnie? | od najmniejszej do największej, czy odwrotnie? | ||
</div></div> | </div></div> | ||
Linia 251: | Linia 236: | ||
<div class="exercise"> | <div class="exercise"> | ||
Dlaczego w algorytmie bisekcji rozwiązywania równania <math> | Dlaczego w algorytmie bisekcji rozwiązywania równania <math>f(x)=0</math>, sprawdzając warunek różnych znaków <math>f</math> w krańcach przedziału <math>[a,b]</math>, używamy kryterium | ||
<div style="margin: 1em; padding:1em; color: #000; background-color:#fcfcfc;"><pre>if ( sign(f(x)) != sign(f(xl)) ) | <div style="margin: 1em; padding:1em; color: #000; background-color:#fcfcfc;"><pre>if ( sign(f(x)) != sign(f(xl)) ) | ||
... | ... | ||
Linia 268: | Linia 253: | ||
<div class="mw-collapsible mw-made=collapsible mw-collapsed"><span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie </span><div class="mw-collapsible-content" style="display:none"><div style="margin-left:1em"> | <div class="mw-collapsible mw-made=collapsible mw-collapsed"><span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie </span><div class="mw-collapsible-content" style="display:none"><div style="margin-left:1em"> | ||
Gdy zbliżamy się do miejsca zerowego <math> | Gdy zbliżamy się do miejsca zerowego <math>f</math>, wartości <code>f(x)</code> i <code>f(lewy)</code> mogą być na tyle małe, że ich iloczyn --- poprzez niedomiar --- będzie miał numeryczną wartość zero i w efekcie program może przeskoczyć do niewłaściwej gałęzi pętli <code>if</code>, a tym samym --- wybrać niewłaściwą lokalizację przedziału zawierającego poszukiwany pierwiastek. | ||
</div></div></div> | </div></div></div> |
Aktualna wersja na dzień 21:44, 11 wrz 2023
Własności arytmetyki zmiennoprzecinkowej
<<< Powrót do strony głównej przedmiotu Metody numeryczne
Oglądaj wskazówki i rozwiązania __SHOWALL__
Ukryj wskazówki i rozwiązania __HIDEALL__
Ćwiczenie: Równe i równiejsze
Wyjaśnij, dlaczego w arytmetyce podwójnej precyzji IEEE 754 mamy
Oczywiście, "teoretycznie" wszystkie trzy liczby powinny być sobie równe (i niezerowe).
Ćwiczenie: Szeregi zbieżne(?)
Podaj przykłady zbieżnych szeregów postaci , których -te sumy częściowe obliczone w arytmetyce pojedynczej precyzji algorytmem
suma = 0.0; for n = 1..N suma += <math>a_n</math>;
będą
- ograniczone niezależnie od , albo
- numerycznie rozbieżne, to znaczy takie, że dla bardzo dużych zachodzi
suma == Inf
.
Wykonaj to samo zadanie, ale podając przykłady szeregów rozbieżnych (w arytmetyce dokładnej).
Ćwiczenie
Dla kolejnych , wyznacz -tą sumę częściową szeregu Taylora dla funkcji wykładniczej, gdy :
korzystając z algorytmu podanego w poprzednim zadaniu. Oblicz błąd względny
i bezwzględny wyznaczonego przybliżenia, w porównaniu
do wartości wyznaczonej z wykorzystaniem funkcji bibliotecznej exp()
. Powtórz następnie dla .
Czy --- zgodnie z teorią matematyczną --- sumy te dążą do wartości . Objaśnij dokładnie, co się stało.
Ćwiczenie
Już wcześniej stwierdziliśmy, że wyznaczanie dla dużego nie jest dobrym pomysłem. Przeprowadź eksperyment numeryczny potwierdzający to stwierdzenie i objaśnij jego wyniki.
Ćwiczenie
Jak wiadomo, szereg harmoniczny jest rozbieżny. Spróbuj przewidzieć, jaki będzie efekt numerycznego wyznaczenia tej sumy w arytmetyce podwójnej precyzji przy użyciu poniższego kodu.
int dlicznik; double dsuma, dstarasuma; double dskladnik; dstarasuma = 0.0; dsuma = 1.0; dlicznik = 1; while(dstarasuma != dsuma) { dskladnik = 1.0/dlicznik; dstarasuma = dsuma; dsuma += dskladnik; dlicznik++; } printf("Suma = %e. Liczba składników = %d, składnik = %e\n", dsuma, dlicznik-1, dskladnik);
Ćwiczenie: Zadanie o wyznaczaniu odwrotności bez dzielenia metodą Newtona
Należy wyznaczyć przybliżenie stosując metodę Newtona do równania
. Zaproponuj
dobre przybliżenie początkowe wiedząc, że jest liczbą maszynową typu
double
. Ile iteracji wystarczy, by osiągnąć -zadowalające przybliżenie?
Ćwiczenie
Niech . Czy z punktu widzenia błędów w lepiej jest policzyć sumę tych liczb w kolejności od najmniejszej do największej, czy odwrotnie?
Ćwiczenie
Dlaczego w algorytmie bisekcji rozwiązywania równania , sprawdzając warunek różnych znaków w krańcach przedziału , używamy kryterium
if ( sign(f(x)) != sign(f(xl)) ) ...
a nie, matematycznie równoważnego, wyrażenia
if ( f(x)*f(lewy) < 0 ) ...