MN01LAB: Różnice pomiędzy wersjami

Z Studia Informatyczne
Przejdź do nawigacjiPrzejdź do wyszukiwania
Przykry (dyskusja | edycje)
mNie podano opisu zmian
Przykry (dyskusja | edycje)
mNie podano opisu zmian
Linia 1: Linia 1:


==Eksperymenty ze środowiskiem obliczeń numerycznych==
<!--
Konwertowane  z pliku LaTeX przez latex2mediawiki, zob. http://www.ii.uj.edu.pl/&nbsp;pawlik1/latex2mediawiki.php
-->
=Ćwiczenia. Eksperymenty ze środowiskiem obliczeń numerycznych=


W Linuxie, czas działania programu można zbadać poleceniem <code>time</code>.
W Linuxie, czas działania programu można zbadać poleceniem <code>time</code>.
Linia 11: Linia 15:
<div class="code" style="background-color:#e8e8e8; padding:1em"><pre>
<div class="code" style="background-color:#e8e8e8; padding:1em"><pre>
   
   
x <nowiki>=</nowiki> 1.0;
x = 1.0;
for( i <nowiki>=</nowiki> 0; i < N; i++)
for( i = 0; i < N; i++)
x <nowiki>=</nowiki> x/3.0;  
x = x/3.0;  
</pre></div>
</pre></div>
   
   
Linia 19: Linia 23:
<div class="code" style="background-color:#e8e8e8; padding:1em"><pre>
<div class="code" style="background-color:#e8e8e8; padding:1em"><pre>
   
   
x <nowiki>=</nowiki> 1.0; f <nowiki>=</nowiki> 1.0/3.0;
x = 1.0; f = 1.0/3.0;
for( i <nowiki>=</nowiki> 0; i < N; i++)
for( i = 0; i < N; i++)
x <nowiki>=</nowiki> x*f;  
x = x*f;  
</pre></div>
</pre></div>
   
   
Linia 32: Linia 36:
<div class="code" style="background-color:#e8e8e8; padding:1em"><pre>
<div class="code" style="background-color:#e8e8e8; padding:1em"><pre>
   
   
x <nowiki>=</nowiki> 1.0;  
x = 1.0;  
for( i <nowiki>=</nowiki> 0; i < N; i++)
for( i = 0; i < N; i++)
x <nowiki>=</nowiki> x*(1.0/3.0);  
x = x*(1.0/3.0);  
</pre></div>
</pre></div>
   
   
Linia 54: Linia 58:
* binarnego
* binarnego
   
   
kolejne wartości <math>\displaystyle \sin(\pi*i*0.4)</math>, gdzie <math>\displaystyle i=0,\ldots, 1024</math>. Następnie porównaj
kolejne wartości <math>\displaystyle \sin(\pi\cdot i\cdot 0.4)</math>, gdzie <math>\displaystyle i=0,\ldots, 1024</math>. Następnie porównaj
rozmiary plików i możliwości ich odczytania zewnętrznymi narzędziami. Wreszcie,
rozmiary plików i możliwości ich odczytania zewnętrznymi narzędziami. Wreszcie,
wczytaj liczby z pliku i porównaj je z oryginalnymi wartościami sinusa. Czy
wczytaj liczby z pliku i porównaj je z oryginalnymi wartościami sinusa. Czy
Linia 74: Linia 78:


Pomyśl, jak obliczać, korzystając jedynie z czterech działań podstawowych: <math>\displaystyle +,\,
Pomyśl, jak obliczać, korzystając jedynie z czterech działań podstawowych: <math>\displaystyle +,\,
-, \, \times, \, \div</math>, wartość funkcji <code>exp(</code><math>\displaystyle x</math><code>)</code> <nowiki>=</nowiki> <math>\displaystyle e^x</math> dla
-, \, \times, \, \div</math>, wartość funkcji <code>exp(</code><math>\displaystyle x</math><code>)</code> = <math>\displaystyle e^x</math> dla
dowolnych <math>\displaystyle x</math> rzeczywistych. Naszym kryterium jest, by <math>\displaystyle |e^x - \exp(x)| \leq
dowolnych <math>\displaystyle x</math> rzeczywistych. Naszym kryterium jest, by <math>\displaystyle |e^x - \exp(x)| \leq
\epsilon</math>, czyli by błąd bezwzględny aproksymacji nie przekroczył zadanego
\epsilon</math>, czyli by błąd bezwzględny aproksymacji nie przekroczył zadanego
Linia 133: Linia 137:
<div class="code" style="background-color:#e8e8e8; padding:1em"><pre>
<div class="code" style="background-color:#e8e8e8; padding:1em"><pre>
   
   
function [y, N] <nowiki>=</nowiki> expa(x, epsilon)
function [y, N] = expa(x, epsilon)
y <nowiki>=</nowiki> skladnik <nowiki>=</nowiki> 1.0; N <nowiki>=</nowiki> 1;
y = skladnik = 1.0; N = 1;
while (abs(skladnik) > epsilon)
while (abs(skladnik) > epsilon)
skladnik *<nowiki>=</nowiki> (x/N);
skladnik *= (x/N);
y +<nowiki>=</nowiki> skladnik;
y += skladnik;
N++;
N++;
end
end
Linia 148: Linia 152:
<div class="code" style="background-color:#e8e8e8; padding:1em"><pre>
<div class="code" style="background-color:#e8e8e8; padding:1em"><pre>
   
   
function [blad, relblad, koszt] <nowiki>=</nowiki> testexp(expX, x)
function [blad, relblad, koszt] = testexp(expX, x)
dokladnie <nowiki>=</nowiki> exp(x);
dokladnie = exp(x);
[wartosc, koszt] <nowiki>=</nowiki> feval(expX,x,1e-8);
[wartosc, koszt] = feval(expX,x,1e-8);
blad <nowiki>=</nowiki> abs(wartosc-dokladnie);
blad = abs(wartosc-dokladnie);
relblad <nowiki>=</nowiki> blad/dokladnie;
relblad = blad/dokladnie;
end
end


i <nowiki>=</nowiki> 0; zakres <nowiki>=</nowiki> linspace(0,7,100);  
i = 0; zakres = linspace(0,7,100);  
for x <nowiki>=</nowiki> zakres
for x = zakres
fprintf(stderr,'x <nowiki>=</nowiki> i++;
fprintf(stderr,'x = &#37;e\n', x);
[blad, relblad, koszt] <nowiki>=</nowiki> testexp('expa',x);  
i++;
koszta(i) <nowiki>=</nowiki> koszt; relblada(i) <nowiki>=</nowiki> relblad;
[blad, relblad, koszt] = testexp('expa',x);  
blada(i) <nowiki>=</nowiki> blad;
koszta(i) = koszt; relblada(i) = relblad;
blada(i) = blad;
end
end


xlabel('x');
xlabel('x');
ylabel('blad');
ylabel('blad');
title(['Epsilon <nowiki>=</nowiki> ', num2str(epsilon)]);
title(['Epsilon = ', num2str(epsilon)]);
plot(zakres, relblada, ';blad wzgledny;');
plot(zakres, relblada, ';blad wzgledny;');
plot(zakres, blada, ';blad bezwzgledny;');
plot(zakres, blada, ';blad bezwzgledny;');
Linia 172: Linia 177:
Zgodnie z oczekiwaniami, błąd jest poniżej zadanej tolerancji, tutaj: <math>\displaystyle 10^{-8}</math>.
Zgodnie z oczekiwaniami, błąd jest poniżej zadanej tolerancji, tutaj: <math>\displaystyle 10^{-8}</math>.


[[Image:MNbladwzglednyexpa.png|thumb|300px|Błąd względny aproksymacji wielomianem Taylora.]]
[[Image:MNbladwzglednyexpa.png|thumb|450px|center|Błąd względny aproksymacji wielomianem Taylora.]]


Jednak koszt aproksymacji rośnie wraz z <math>\displaystyle x</math>:
Jednak koszt aproksymacji rośnie wraz z <math>\displaystyle x</math>:


[[Image:MNkosztexpa.png|thumb|300px|Koszt aproksymacji wielomianem Taylora.]]
[[Image:MNkosztexpa.png|thumb|450px|center|Koszt aproksymacji wielomianem Taylora.]]


Niektóre wyniki mogą Cię jednak zaskoczyć:  
Niektóre wyniki mogą Cię jednak zaskoczyć:  
* Błąd bezwzględny przekracza założoną wartość, gdy <math>\displaystyle \epsilon = 2.2\cdot
* Błąd bezwzględny przekracza założoną wartość, gdy <math>\displaystyle \epsilon = 2.2\cdot
10^{-15}</math>, a błąd względny od pewnego momentu ''rośnie'' z <math>\displaystyle x</math>.  
10^{-15}</math>, a błąd względny od pewnego momentu <strong>rośnie</strong> z <math>\displaystyle x</math>.  
[[Image:MNbladbezwzglednyexpaeps.png|thumb|300px|Błąd względny aproksymacji wielomianem Taylora dla zadanej bardzo małej
[[Image:MNbladbezwzglednyexpaeps.png|thumb|450px|center|Błąd względny aproksymacji wielomianem Taylora dla zadanej bardzo małej
tolerancji błędu.]]
tolerancji błędu.]]
* Nie daje się tak policzyć <math>\displaystyle e^{2006}</math>.
* Nie daje się tak policzyć <math>\displaystyle e^{2006}</math>.
Linia 187: Linia 192:
   
   
Wyjaśnienie tych szokujących faktów (które nie mają nic wspólnego z błędem w
Wyjaśnienie tych szokujących faktów (które nie mają nic wspólnego z błędem w
implementacji) musisz odłożyć do momentu, gdy bliżej przyjrzymy się temu, ''jak''
implementacji) musisz odłożyć do momentu, gdy bliżej przyjrzymy się temu, <strong>jak</strong>
liczy komputer.
liczy komputer.


Linia 214: Linia 219:
</math></center>
</math></center>


Tak więc zadanie redukuje się do wyznaczenia <math>\displaystyle \exp(t)</math> dla ''małego'' <math>\displaystyle t</math> oraz
Tak więc zadanie redukuje się do wyznaczenia <math>\displaystyle \exp(t)</math> dla <strong>małego</strong> <math>\displaystyle t</math> oraz
do co najwyżej <math>\displaystyle k</math> dodatkowych mnożeń potrzebnych do wyznaczenia całkowitej
do co najwyżej <math>\displaystyle k</math> dodatkowych mnożeń potrzebnych do wyznaczenia całkowitej
potęgi <math>\displaystyle e^k</math> (ile mnożeń ''naprawdę'' wystarczy?). Pamiętaj, przyjęliśmy, że
potęgi <math>\displaystyle e^k</math> (ile mnożeń <strong>naprawdę</strong> wystarczy?). Pamiętaj, przyjęliśmy, że
znamy reprezentację numeryczną liczby <math>\displaystyle e</math>.
znamy reprezentację numeryczną liczby <math>\displaystyle e</math>.


<div class="code" style="background-color:#e8e8e8; padding:1em"><pre>
<div class="code" style="background-color:#e8e8e8; padding:1em"><pre>
  [Wersja B]
  [Wersja B]
function [y, N] <nowiki>=</nowiki> expb(x, epsilon)
function [y, N] = expb(x, epsilon)
k <nowiki>=</nowiki> floor(x); t <nowiki>=</nowiki> x - k;  
k = floor(x); t = x - k;  
[y, N] <nowiki>=</nowiki> expa(t, epsilon);  
[y, N] = expa(t, epsilon);  
for i <nowiki>=</nowiki> 1:k
for i = 1:k
  y *<nowiki>=</nowiki> e;
  y *= e;
end
end
N +<nowiki>=</nowiki> (k+2);
N += (k+2);
end
end
</pre></div>
</pre></div>
   
   
[[Image:MNkosztexpab.png|thumb|300px|Wersja B jest istotnie tańsza.]]
[[Image:MNkosztexpab.png|thumb|450px|center|Wersja B jest istotnie tańsza.]]


</div></div></div>
</div></div></div>

Wersja z 16:44, 2 wrz 2006


Ćwiczenia. Eksperymenty ze środowiskiem obliczeń numerycznych

W Linuxie, czas działania programu można zbadać poleceniem time.

Ćwiczenie

Który program wykona się szybciej:

 
x = 1.0;
for( i = 0; i < N; i++)
	x = x/3.0; 

czy

 
x = 1.0; f = 1.0/3.0;
for( i = 0; i < N; i++)
	x = x*f; 
Rozwiązanie

Ćwiczenie

Napisz program w C, który zapisuje do pliku

  • tekstowego
  • binarnego

kolejne wartości sin(πi0.4), gdzie i=0,,1024. Następnie porównaj rozmiary plików i możliwości ich odczytania zewnętrznymi narzędziami. Wreszcie, wczytaj liczby z pliku i porównaj je z oryginalnymi wartościami sinusa. Czy możesz wyjaśnić przyczyny różnic?

Powtórz to samo w Octave.

Rozwiązanie

Ćwiczenie: Implementacja funkcji matematycznych

Pomyśl, jak obliczać, korzystając jedynie z czterech działań podstawowych: +,,×,÷, wartość funkcji exp(x) = ex dla dowolnych x rzeczywistych. Naszym kryterium jest, by |exexp(x)|ϵ, czyli by błąd bezwzględny aproksymacji nie przekroczył zadanego ϵ.

Wykonaj eksperymenty w C lub w Octave, pokazujące koszt metody w zależności od x oraz w zależności od ϵ. Przeprowadź też sekwencję testów potwierdzających Twoje rachunki co do oczekiwanej dokładności (porównując się z funkcją biblioteczną). W C możesz korzystać ze stałej M_E e=exp(1), zdefiniowanej w pliku nagłówkowym math.h.

Rozwiązanie

Ćwiczenie: Ciag dalszy

Spróbuj obniżyć koszt wyznaczania exp(x) dla dużych x!

Wskazówka
Rozwiązanie