MN03LAB: Różnice pomiędzy wersjami
mNie podano opisu zmian |
mNie podano opisu zmian |
||
Linia 1: | Linia 1: | ||
= | |||
<!-- | |||
Konwertowane z pliku LaTeX przez latex2mediawiki, zob. http://www.ii.uj.edu.pl/ pawlik1/latex2mediawiki.php | |||
--> | |||
=Ćwiczenia. Własności arytmetyki zmiennopozycyjnej.= | |||
<div style="margin-top:1em; padding-top,padding-bottom:1em;"> | |||
<span style="display: block; background-color:#fefeee; border-bottom: 1px solid #E5E5E5; line-height: 1.1em; padding-bottom: 0.2em; font-variant:small-caps; color:#1A6ABF;">Ćwiczenie: Równe i równiejsze</span> | |||
<div class="exercise"> | |||
Wyjaśnij, dlaczego w arytmetyce podwójnej precyzji IEEE 754 mamy | |||
<div class="output" style="background-color:#e0e8e8; padding:1em"><pre> | |||
octave:19> 2006/1e309 | |||
ans = 0 | |||
octave:20> 2.006/1e306 | |||
ans = 2.0060e-306 | |||
octave:21> (2006/1000)/(1e309/1000) | |||
ans = 0 | |||
</pre></div> | |||
Oczywiście, "teoretycznie" wszystkie trzy liczby powinny być sobie | |||
równe (i niezerowe). | |||
<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:#efe"> Kluczem jest stwierdzenie, jaka jest reprezentacja liczby <math>\displaystyle 10^{309}</math> w podwójnej precyzji? A | |||
<math>\displaystyle 10^{306}</math>? </div> | |||
</div></div> | |||
</div></div> | |||
<div style="margin-top:1em; padding-top,padding-bottom:1em;"> | <div style="margin-top:1em; padding-top,padding-bottom:1em;"> | ||
Linia 5: | Linia 35: | ||
<div class="exercise"> | <div class="exercise"> | ||
Podaj przykłady | Podaj przykłady <strong>zbieżnych</strong> szeregów postaci <math>\displaystyle \sum_{n=1}^{\infty} a_n</math>, którego <math>\displaystyle N</math>-te sumy częściowe | ||
obliczone w arytmetyce pojedynczej precyzji algorytmem | obliczone w arytmetyce pojedynczej precyzji algorytmem | ||
<div class="code" style="background-color:#e8e8e8; padding:1em"><pre> | <div class="code" style="background-color:#e8e8e8; padding:1em"><pre> | ||
suma | suma = 0.0; | ||
for n | for n = 1..N | ||
suma + | suma += <math>\displaystyle a_n</math>; | ||
</pre></div> | </pre></div> | ||
Linia 17: | Linia 47: | ||
* ograniczone niezależnie od <math>\displaystyle N</math>, albo | * ograniczone niezależnie od <math>\displaystyle N</math>, albo | ||
* numerycznie rozbieżne, to znaczy takie, że dla bardzo dużych <math>\displaystyle N</math> zachodzi | * numerycznie rozbieżne, to znaczy takie, że dla bardzo dużych <math>\displaystyle N</math> zachodzi | ||
<code>suma | <code>suma == Inf</code>. | ||
Wykonaj to samo zadanie, ale podając przykłady szeregów | Wykonaj to samo zadanie, ale podając przykłady szeregów <strong>rozbieżnych</strong> (w | ||
arytmetyce dokładnej). | arytmetyce dokładnej). | ||
</div></div> | </div></div> | ||
Linia 25: | Linia 55: | ||
<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"> | ||
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>\displaystyle 1 + 10^{2006} - 10^{2006} + 0 + \ldots = 1</math> oraz <math>\displaystyle 1 + 10^{2006} - 1 + 0 + \ldots = 10^{2006}</math> | * <math>\displaystyle 1 + 10^{2006} - 10^{2006} + 0 + \ldots = 1</math> oraz <math>\displaystyle 1 + 10^{2006} - 1 + 0 + \ldots = 10^{2006}</math> | ||
Linia 90: | Linia 120: | ||
double dskladnik; | double dskladnik; | ||
dstarasuma | dstarasuma = 0.0; dsuma = 1.0; dlicznik = 1; | ||
while(dstarasuma ! | while(dstarasuma != dsuma) | ||
{ | { | ||
dskladnik | dskladnik = 1.0/dlicznik; | ||
dstarasuma | dstarasuma = dsuma; | ||
dsuma + | dsuma += dskladnik; | ||
dlicznik++; | dlicznik++; | ||
} | } | ||
printf("Suma | printf("Suma = dsuma, dlicznik-1, dskladnik); | ||
</pre></div> | </pre></div> | ||
Linia 109: | Linia 139: | ||
<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 | Nasza suma przekroczy wartość 20, więc aby <code>20 + dskladnik == 20</code>, musi | ||
być dskładnik <math>\displaystyle \approx 10^{-15}</math> (lub więcej). Tymczasem zakres liczb typu integer wynosi | być dskładnik <math>\displaystyle \approx 10^{-15}</math> (lub więcej). Tymczasem zakres liczb typu integer wynosi | ||
niewiele ponad <math>\displaystyle 10^9</math>, więc po jakimś czasie dlicznik przyjmie wartości ujemne. | niewiele ponad <math>\displaystyle 10^9</math>, więc po jakimś czasie dlicznik przyjmie wartości ujemne. |
Wersja z 16:46, 2 wrz 2006
Ćwiczenia. Własności arytmetyki zmiennopozycyjnej.
Ćwiczenie: Równe i równiejsze
Wyjaśnij, dlaczego w arytmetyce podwójnej precyzji IEEE 754 mamy
octave:19> 2006/1e309 ans = 0 octave:20> 2.006/1e306 ans = 2.0060e-306 octave:21> (2006/1000)/(1e309/1000) ans = 0
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órego -te sumy częściowe obliczone w arytmetyce pojedynczej precyzji algorytmem
suma = 0.0; for n = 1..N suma += <math>\displaystyle 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. Porównaj błąd: względny
i bezwzględny 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 = dsuma, dlicznik-1, dskladnik);
Ćwiczenie
Jak szybko i na jakiej wysokości musiałby lecieć samolot npla, aby pocisk wystrzeliwany z działka z prędkością 7500 km/h nie trafił w cel, gdy potrzebne pierwiastki liczone są wzorem szkolnym?
Ćwiczenie: Zadanie o wyznaczaniu pierwiastka kwadratowego metodą Newtona
Dla zadanej liczby , należy wyznaczyć przybliżenie stosując metodę Herona. 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: 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
Aby obliczyć można zastosować dwa algorytmy: oraz . Pokazać, że oba algorytmy są numerycznie poprawne, ale drugi z nich wywołuje mniejszy błąd względny wyniku w przypadku, gdy i .
Ćwiczenie
Pokazać, że naturalny algorytm obliczania cosinusa kąta między dwoma wektorami Parser nie mógł rozpoznać (nieznana funkcja „\inR”): {\displaystyle \displaystyle a, b\inR^n} ,
jest numerycznie poprawny. Oszacować błąd względny wyniku w .
Ćwiczenie
Pokazać, że naturalny algorytm obliczania dla danej macierzy Parser nie mógł rozpoznać (nieznana funkcja „\inR”): {\displaystyle \displaystyle A\inR^{n\times n}} i wektora Parser nie mógł rozpoznać (nieznana funkcja „\inR”): {\displaystyle \displaystyle x\inR^n} jest numerycznie poprawny. Dokładniej,
gdzie . Ponadto, jeśli jest nieosobliwa to
Ćwiczenie
Niech będzie algorytmem numerycznie poprawnym w zbiorze danych , przy czym dla małych , , gdzie i nie zależy od i (). Pokazać, że w ogólności nie musi być "numerycznie poprawny po współrzędnych", tzn. w ogólności nie istnieje bezwzględna stała taka, że dla małych i dla dowolnej
gdzie .
Ćwiczenie
Podaj przykład funkcji , której miejsce zerowe ma wspólczynnik uwarunkowania
- mały
- duży