MN05LAB: Różnice pomiędzy wersjami

Z Studia Informatyczne
Przejdź do nawigacjiPrzejdź do wyszukiwania
Przykry (dyskusja | edycje)
Dorota (dyskusja | edycje)
Nie podano opisu zmian
Linia 1: Linia 1:
<!--  
<!--  
Konwertowane  z pliku LaTeX przez latex2mediawiki, zob. http://www.ii.uj.edu.pl/&nbsp;pawlik1/latex2mediawiki.php
Konwertowane  z pliku LaTeX przez latex2mediawiki, zob. http://www.ii.uj.edu.pl/&nbsp;pawlik1/latex2mediawiki.php
Linia 17: Linia 16:
</pre></div>
</pre></div>
   
   
W tym celu Octave oczywiście wewenętrznie wykorzystuje funkcję LAPACKa
W tym celu Octave oczywiście wewnętrznie wykorzystuje funkcję LAPACKa
<code>DGESV</code>. Ale w Octave jest także funkcja <code>inv</code>, wyznaczająca macierz
<code>DGESV</code>. Ale w Octave jest także funkcja <code>inv</code> wyznaczająca macierz
odwrotną, więc niektóre (nie najlepsze, oględnie mówiąc) podręczniki zalecają
odwrotną, niektóre więc (nie najlepsze, oględnie mówiąc) podręczniki zalecają
<div class="code" style="background-color:#e8e8e8; padding:1em"><pre>
<div class="code" style="background-color:#e8e8e8; padding:1em"><pre>
   
   
Linia 26: Linia 25:
   
   
Przedyskutuj, które podejście jest lepsze i dlaczego. Przeprowadź eksperymenty
Przedyskutuj, które podejście jest lepsze i dlaczego. Przeprowadź eksperymenty
numeryczne weryfikujące Twoją tezę.
numeryczne weryfikujące twoją tezę.
</div></div>
</div></div>


Linia 34: Linia 33:
dodatkowo nie jest numerycznie poprawne.
dodatkowo nie jest numerycznie poprawne.


Przykładowy test mógłby wyglądać w poniższy sposób. Duże macierze losowe są
Przykładowy test mógłby wyglądać tak, jak poniżej. Duże macierze losowe są
zazwyczaj dobrze uwarunkowane i najczęściej nieosobliwe.
zazwyczaj dobrze uwarunkowane i najczęściej nieosobliwe.


Linia 76: Linia 75:


<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">   
Rozwiązanie uzyskane bez wyboru elementu głównego jest bardzo mało precyzyjne <math>\displaystyle x_1</math> jest obarczone bardzo duzym błędem! Prosta analiza poazuje, że winę za to ponosi bardzo wielki współczynnik w macierzy <math>\displaystyle L</math>. Tak nie jest, gdy stosujemy wybór elementu: elementy <math>\displaystyle L</math> są zawsze mniejsze od 1. Dlatego inne rozwiązania numeryczne dają w przypadku naszej macierzy wynik, będący bardzo dobrym przybliżeniem wyniku dokładnego. ''A propos:'' Octave korzysta z <code>DGESV</code> LAPACKa, a <code>DGESV</code> korzysta z wyboru w kolumnie...
Rozwiązanie uzyskane bez wyboru elementu głównego jest bardzo mało precyzyjne <math>\displaystyle x_1</math> i jest obarczone bardzo dużym błędem! Prosta analiza pokazuje, że winę za to ponosi bardzo wielki współczynnik w macierzy <math>\displaystyle L</math>. Nie jest tak, gdy stosujemy wybór elementu: elementy <math>\displaystyle L</math> są zawsze mniejsze od 1. Dlatego inne rozwiązania numeryczne dają w przypadku naszej macierzy wynik będący bardzo dobrym przybliżeniem wyniku dokładnego. ''A propos:'' Octave korzysta z <code>DGESV</code> LAPACKa, a <code>DGESV</code> korzysta z wyboru w kolumnie...
</div></div></div>
</div></div></div>


Linia 106: Linia 105:
   
   
function [L,U] = lufa(A)
function [L,U] = lufa(A)
# Na początku warto dodać trochę sprawdzania danych: czy A jest kwadratowa? a w ogóle,
# Na początku warto dodać trochę sprawdzania danych: czy A jest kwadratowa?  
# czy jest macierzą? te linie pozostawiamy inwencji Czytelnika
# A w ogóle czy jest macierzą? Te linie pozostawiamy inwencji Czytelnika


N = size(A,1);
N = size(A,1);
Linia 128: Linia 127:
</pre></div>
</pre></div>
   
   
Jednak w tej implementacji mamy do czynienia z nawet potójnie zagnieżdżonymi
Jednak w tej implementacji mamy do czynienia z nawet potrójnie zagnieżdżonymi
pętlami, co dla nawet średnich <math>\displaystyle N</math> może być powodem sporego spowolnienia
pętlami, co dla nawet średnich <math>\displaystyle N</math> może być powodem sporego spowolnienia
algorytmu. Warto więc uniknąć pętli, odwołując się do instrukcji wektorowych i
algorytmu. Warto więc uniknąć pętli, odwołując się do instrukcji wektorowych i
Linia 225: Linia 224:
<div class="exercise">
<div class="exercise">


Zrób zadanie poprzednie programując, niczym Zosia-Samosia, wszystko od początku do końca w czystym C. Porównaj czasy działania Twojego programu i programu wywołującego po prostu procedurę biblioteczną LAPACKa
Zrób zadanie poprzednie programując, niczym Zosia samosia, wszystko od początku do końca w czystym C. Porównaj czasy działania twojego programu i programu wywołującego po prostu procedurę biblioteczną LAPACKa
<code>DGESV</code>, najlepiej wspartą dobrze podrasowanymi BLASami.
<code>DGESV</code>, najlepiej wspartą dobrze podrasowanymi BLASami.


Linia 235: Linia 234:


<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">   
No tak, namawiamy Cię do zmierzenia się z LAPACKiem i ATLASem....
No tak, namawiamy cię do zmierzenia się z LAPACKiem i ATLASem....


Prościutki program --- po prostu tłumaczącu algorytm z wykładu bezpośrednio
Prościutki program --- po prostu tłumaczący algorytm z wykładu bezpośrednio
na C --- u nas spisał
na C --- u nas spisał
się, dla macierzy wymiaru <math>\displaystyle N=1\ldots 1024</math>, następująco:
się, dla macierzy wymiaru <math>\displaystyle N=1\ldots 1024</math>, następująco:
Linia 260: Linia 259:
</math></center>
</math></center>


Układy równań z tą samą macierzą, ale ze zmieniającą się prawą stroną równania
Układy równań z tą samą macierzą, ale ze zmieniającą się prawą stroną równania
powstają często przy rozwiązywaniu, np. równań różniczkowych cząstkowych,
powstają często przy rozwiązywaniu np. równań różniczkowych cząstkowych,
gdzie  prawa strona układu odpowiada zmieniającym się warunkom  brzegowym.  
gdzie  prawa strona układu odpowiada zmieniającym się warunkom  brzegowym.  


Linia 271: Linia 270:


<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">   
No tak, oczywiście,
No tak, oczywiście  
wystarczy
wystarczy


Linia 283: Linia 282:


Rozwiązanie każdego z układów <math>\displaystyle LY = B</math> i <math>\displaystyle UX = Y</math> można przyspieszyć, tworząc
Rozwiązanie każdego z układów <math>\displaystyle LY = B</math> i <math>\displaystyle UX = Y</math> można przyspieszyć, tworząc
warianty algorytmów podstawienia w przód i w tył, operujące od razu na wszystkich kolumnach macierzy <math>\displaystyle B</math>. Zaimplementowano je w LAPACKu, w tandemie
warianty algorytmów podstawienia w przód i w tył operujące od razu na wszystkich kolumnach macierzy <math>\displaystyle B</math>. Zaimplementowano je w LAPACKu, w tandemie
funkcji <code>DGETRF</code> (rozkład) i <code>DGETRS</code> (rozwiązanie) oraz w
funkcji <code>DGETRF</code> (rozkład) i <code>DGETRS</code> (rozwiązanie) oraz w
<code>DGESV</code>, łączącej funkcjonalność obu.
<code>DGESV</code>, łączącej funkcjonalność obu.
Linia 300: Linia 299:


Dla takich macierzy można nieco zmniejszyć koszt kombinatoryczny  
Dla takich macierzy można nieco zmniejszyć koszt kombinatoryczny  
i zużycie pamięci przeprowadzając trochę inny rozkład na macierze trójkątne:
i zużycie pamięci, przeprowadzając trochę inny rozkład na macierze trójkątne:
tak, aby otrzymać  
tak, aby otrzymać  
rozkład   
rozkład   
Linia 313: Linia 312:
Inny wariant tego samego
Inny wariant tego samego
rozkładu to tak zwany rozkład Cholesky'ego--Banachiewicza, w którym przy tych
rozkładu to tak zwany rozkład Cholesky'ego--Banachiewicza, w którym przy tych
samych założeniach na <math>\displaystyle A</math>, szukamy rozkładu wykorzystującego tylko jedną macierz
samych założeniach na <math>\displaystyle A</math> szukamy rozkładu wykorzystującego tylko jedną macierz
trójkątną dolną:
trójkątną dolną:


Linia 325: Linia 324:
<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">   
Bez zmniejszenia ogólności rozpatrzymy  
Bez zmniejszenia ogólności rozpatrzymy  
tylko pierwszy krok rozkładu <math>\displaystyle LDL^T</math>. W tym celu, zauważmy najpierw, że  
tylko pierwszy krok rozkładu <math>\displaystyle LDL^T</math>. W tym celu zauważmy najpierw, że  
<math>\displaystyle a_{1,1}= e_1^TA e_1>0</math> (gdzie <math>\displaystyle  e_1</math> jest pierwszym  
<math>\displaystyle a_{1,1}= e_1^TA e_1>0</math> (gdzie <math>\displaystyle  e_1</math> jest pierwszym  
wersorem), a więc nie musimy przestawiać wierszy,  
wersorem), nie musimy więc przestawiać wierszy,  
bo element na diagonali jest niezerowy. W pierwszym kroku mnożymy  
bo element na diagonali jest niezerowy. W pierwszym kroku mnożymy  
macierz <math>\displaystyle A</math> z lewej strony przez odpowiednią macierz <math>\displaystyle L_1</math>, a potem  
macierz <math>\displaystyle A</math> z lewej strony przez odpowiednią macierz <math>\displaystyle L_1</math>, a potem  
Linia 365: Linia 364:
Zauważmy, że przy praktycznej realizacji rozkładu <math>\displaystyle A=LDL^T</math>  
Zauważmy, że przy praktycznej realizacji rozkładu <math>\displaystyle A=LDL^T</math>  
wystarczy modyfikować jedynie wyrazy pod i na głównej przekątnej  
wystarczy modyfikować jedynie wyrazy pod i na głównej przekątnej  
macierzy wyjściowej, ponieważ, jak zauważyliśmy, wszystkie kolejne  
macierzy wyjściowej ponieważ, jak zauważyliśmy, wszystkie kolejne  
macierze <math>\displaystyle A^{(k)}</math> są symetryczne. Pozwala to zmniejszyć --- w stosunku do
macierze <math>\displaystyle A^{(k)}</math> są symetryczne. Pozwala to zmniejszyć --- w stosunku do
rozkładu LU --- koszt  
rozkładu LU --- koszt  
Linia 398: Linia 397:


<center><math>\displaystyle  \mbox{det}  (cA) = c^N A,
<center><math>\displaystyle  \mbox{det}  (cA) = c^N A,
</math></center>
</math></center>,


to dość łatwo będzie trafić (przy większych niż średnich wartościach <math>\displaystyle N</math>) na wartości
to dość łatwo będzie trafić (przy większych niż średnich wartościach <math>\displaystyle N</math>) na wartości
wyznacznika, które będą albo potwornie duże, albo potwornie małe. Zresztą, zrób
wyznacznika, które będą albo potwornie duże, albo potwornie małe. Zrób
eksperyment:  
eksperyment:  



Wersja z 17:02, 24 wrz 2006


Ćwiczenia: rozwiązywanie układów równań liniowych

Ćwiczenie: Mnożyć przez odwrotność to nie zawsze to samo...

W Octave układ równań Ax=b rozwiązujemy korzystając z "operatora rozwiązywania równania"

 
x = A \ b;

W tym celu Octave oczywiście wewnętrznie wykorzystuje funkcję LAPACKa DGESV. Ale w Octave jest także funkcja inv wyznaczająca macierz odwrotną, niektóre więc (nie najlepsze, oględnie mówiąc) podręczniki zalecają

 
x = inv(A)*b;

Przedyskutuj, które podejście jest lepsze i dlaczego. Przeprowadź eksperymenty numeryczne weryfikujące twoją tezę.

Rozwiązanie

Ćwiczenie: Wybór elementu głównego jest naprawdę ważny!

Rozwiąż prosty układ równań

Parser nie mógł rozpoznać (nieznana funkcja „\aligned”): {\displaystyle \displaystyle \aligned 10^{-18} x_1 + x_2 &= 1,\\ x_1 + 2x_2 &= 4, \endaligned}

czterema sposobami:

  • na kartce papieru (dokładnie!)
  • w komputerze, w arytmetyce podwójnej precyzji, korzystając z rozkładu LU bez wyboru elementu głównego
  • jak poprzednio, ale z wyborem elementu głównego w kolumnie
  • w LAPACKu lub Octave.

Porównaj uzyskane rozwiązania i wyciągnij wnioski.

Rozwiązanie

Ćwiczenie

Zapisz w Octave algorytm rozkładu LU macierzy (bez wyboru elementu głównego) działający in situ.

Wskazówka

Wykorzystaj go do napisania funkcji, która rozwiąże układ równań Ax=b.

Przetestuj tę funkcję na kilku macierzach i porównaj czas jego działania z czasem wykonania operacji x = A\b.

Spróbuj zastosować swój algorytm do kilku specjalnych macierzy:

  • Hilberta dużego wymiaru
  • diagonalnej z jednym elementem bardzo małym (a nawet równym zero)
Rozwiązanie

Ćwiczenie: Czy Twoje programy działają naprawdę szybko?

Zrób zadanie poprzednie programując, niczym Zosia samosia, wszystko od początku do końca w czystym C. Porównaj czasy działania twojego programu i programu wywołującego po prostu procedurę biblioteczną LAPACKa DGESV, najlepiej wspartą dobrze podrasowanymi BLASami.

Wskazówka
Rozwiązanie

Ćwiczenie: Układy równań z wieloma prawymi stronami

Podaj sposób taniego wyznaczenia rozwiązania sekwencji k<N układów równań z tą samą macierzą ARN×N i różnymi prawymi stronami:

Axi=bi,i=1,,k.

Układy równań z tą samą macierzą, ale ze zmieniającą się prawą stroną równania powstają często przy rozwiązywaniu np. równań różniczkowych cząstkowych, gdzie prawa strona układu odpowiada zmieniającym się warunkom brzegowym.

Wskazówka
Rozwiązanie

Ćwiczenie: Metoda Cholesky'ego

Ważnym przykładem macierzy szczególnej postaci są macierze symetryczne i dodatnio określone. Są to macierze spełniające warunki:

A=ATorazxTAx>0,x0.

Dla takich macierzy można nieco zmniejszyć koszt kombinatoryczny i zużycie pamięci, przeprowadzając trochę inny rozkład na macierze trójkątne: tak, aby otrzymać rozkład

A=LDLT

zamiast PA=LU, przy czym L jest tu jak zwykle macierzą trójkątną dolną z jedynkami na przekątnej, a D jest macierzą diagonalną z dodatnimi elementami na diagonali. Opracuj taki algorytm. W jego implementacji możesz porównywać się z procedurą LAPACKa DPOSV. Inny wariant tego samego rozkładu to tak zwany rozkład Cholesky'ego--Banachiewicza, w którym przy tych samych założeniach na A szukamy rozkładu wykorzystującego tylko jedną macierz trójkątną dolną:

A=L~L~T,

(oczywiście tym razem nie żądamy, aby L~ miała na diagonali jedynki). Jaka jest relacja między rozkładem LDLT a L~L~T?

Rozwiązanie

Ćwiczenie: Obliczanie wyznacznika macierzy

Bardzo rzadko w praktyce numerycznej zdarza się potrzeba obliczenia wartości wyznacznika macierzy ARN×N. Zaproponuj metodę obliczania det(A) oraz wskaż, jakiego rodzaju problemy numeryczne możesz napotkać.

Rozwiązanie