MN08LAB: Różnice pomiędzy wersjami
Nie podano opisu zmian |
Nie podano opisu zmian |
||
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. | ||
Niezb�dne rozszerzenia i modyfikacje oryginalnego latex2mediawiki | |||
wprowadzi� przykry@mimuw.edu.pl | |||
--> | --> | ||
= | =Układy liniowe z macierzami rzadkimi= | ||
{{powrot |Metody numeryczne | do strony głównej | |||
przedmiotu <strong>Metody numeryczne</strong>}} | |||
<div class="mw-collapsible mw-made=collapsible mw-collapsed"> | |||
Oglądaj wskazówki i rozwiązania __SHOWALL__<br> | |||
Ukryj wskazówki i rozwiązania __HIDEALL__ | |||
</div> | |||
<div style="margin-top:1em; padding-top,padding-bottom:1em;"> | <div style="margin-top:1em; padding-top,padding-bottom:1em;"> | ||
Linia 9: | Linia 20: | ||
<div class="exercise"> | <div class="exercise"> | ||
Jedną z najprostszych klasycznych metod iteracyjnych dla równania <math>\displaystyle Ax=b</math> jest metoda Richardsona zadana | Jedną z najprostszych klasycznych metod iteracyjnych dla równania <math>\displaystyle Ax=b</math> jest metoda Richardsona, zadana | ||
wzorem | wzorem | ||
Linia 19: | Linia 30: | ||
parametru <math>\displaystyle \tau</math> jest kluczowy dla skuteczności metody. | parametru <math>\displaystyle \tau</math> jest kluczowy dla skuteczności metody. | ||
Dla <math>\displaystyle A</math> symetrycznej dodatnio określonej sprawdź, przy jakich założeniach o | Dla <math>\displaystyle A</math> symetrycznej, dodatnio określonej sprawdź, przy jakich założeniach o | ||
<math>\displaystyle \tau</math> metoda będzie zbieżna do rozwiązania <math>\displaystyle x^*</math> z dowolnego wektora startowego | <math>\displaystyle \tau</math> metoda będzie zbieżna do rozwiązania <math>\displaystyle x^*</math> z dowolnego wektora startowego | ||
<math>\displaystyle x_0</math> i oceń szybkość tej zbieżności. | <math>\displaystyle x_0</math> i oceń szybkość tej zbieżności. | ||
Testuj na macierzy jednowymiarowego laplasjanu <math>\displaystyle L</math> różnych wymiarów. Jak najefektywniej zaimplementować mnożenie przez <math>\displaystyle L</math>? | Testuj na macierzy jednowymiarowego laplasjanu <math>\displaystyle L</math> różnych wymiarów. Jak najefektywniej zaimplementować mnożenie przez <math>\displaystyle L</math>? | ||
<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"> Zadanie można rozwiązać przez analogię do opisywanego w wykładzie przypadku [[MN08#Macierz laplasjanu|zastosowania metody Jacobiego do macierzy jednowymiarowego laplasjanu]]: wystarczy uogólnić! </div> | |||
</div></div> | |||
</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"> | |||
Niech ekstremalnymi wartościami własnymi macierzy <math>\displaystyle A</math> będą <math>\displaystyle 0 < \lambda_{\min} \leq \lambda_{\max}</math>. Ponieważ macierz iteracji metody Richardsona <math>\displaystyle B= I - \tau A</math>, to jej wartości własne muszą leżeć w przedziale <math>\displaystyle [1-\tau \lambda_{\max}, 1 - \tau \lambda_{\min}]</math> i --- oczywiście --- aby iteracja miała sens, <math>\displaystyle \tau > 0</math> (dlaczego?). | |||
Co więcej, <math>\displaystyle ||B||_2 < 1</math> wtedy i tylko wtedy, gdy <math>\displaystyle 0 < \tau < \frac{2}{\lambda_{\max}}</math>, a najmniejszą normę spektralną macierzy <math>\displaystyle B</math> uzyskamy, gdy <math>\displaystyle \tau = \frac{2}{\lambda_{\max} + \lambda_{\min}}</math> i wówczas | |||
<center><math>\displaystyle ||x_k-x||_2 \leq \frac{\lambda_{\max} - \lambda_{\min}}{\lambda_{\max} + \lambda_{\min}}||x_{k-1}-x||_2. | |||
</math></center> | |||
(Przy okazji zauważ, że gdyby macierz <math>\displaystyle A</math> nie była określona, tzn. miałaby zarówno dodatnie, jak i ujemne wartości własne, to metoda Richardsona mogłaby w ogóle nie być zbieżna (dla pewnych wektorów startowych)) | |||
Jeśli chodzi o mnożenie przez macierz jednowymiarowego laplasjanu, to najprościej wcale nie używać struktury macierzy! Rzeczywiście, jedyne, czego potrzebujemy to operacja <strong>mnożenia wektora przez macierz</strong> <math>\displaystyle L</math>, a to realizuje pętla: | |||
<div style="margin: 1em; padding:1em; color: #000; background-color:#fcfcfc;"><pre>void LapMult(double *x, int N, double *y) | |||
/* | |||
Mnożenie wektora przez macierz 1-wym laplasjanu L wymiaru N | |||
Wejście: | |||
x - wektor, który mnożymy przez L | |||
N - jego długość | |||
Wyjście: | |||
y - wynik: y = Lx | |||
*/ | |||
{ | |||
int i; | |||
for (i = 1; i < N-1; i++) | |||
y[i] = -x[i-1] + 2.0*x[i] - x[i+1]; | |||
y[0] = 2.0*x[0] - x[1]; | |||
y[N-1] = -x[N-2] + 2.0*x[N-1]; | |||
} | |||
</pre></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 49: | Linia 100: | ||
Dodawanie nowego elementu w formacie AIJ jest bardzo łatwe. W przeciwieństwie do | Dodawanie nowego elementu w formacie AIJ jest bardzo łatwe. W przeciwieństwie do | ||
pozostałych, w których trzeba zachowywać uporządkowanie. Mnożenie przez wektor | pozostałych, w których trzeba zachowywać uporządkowanie. Mnożenie przez wektor | ||
najwygodniejsze jest w CSR. Wyłuskanie wartości jest najmniej efektywne w | najwygodniejsze jest w CSR, bo dodatkowo narzuca zasadę lokalności w przestrzeni. Wyłuskanie wartości jest najmniej efektywne w | ||
formacie AIJ. | formacie AIJ. Szczegóły opisane są w rozdziale 3.5 książki | ||
* <span style="font-variant:small-caps">Y. Saad</span>, <cite> [http://www-users.cs.umn.edu/ saad/books.html Iterative methods for sparse linear systems]</cite>, PWS, 1996. | |||
Zobacz także implementacje w Fortranie, w pakiecie [http://www-users.cs.umn.edu/ saad/software/SPARSKIT/sparskit.html SPARSKIT], będącym czymś w rodzaju odpowiednika BLAS dla macierzy rozrzedzonych. | |||
</div></div></div> | </div></div></div> | ||
<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: Konwersja formatu macierzy rzadkiej</span> | |||
<div class="exercise"> | |||
Napisz procedurę <code>aij2csr</code>, konwertującą macierz w formacie AIJ do CSR i <code>csr2aij</code>, działającą w drugą stronę. | |||
</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"> | |||
Zobacz, jak to zrobiono w pakiecie [http://www-users.cs.umn.edu/ saad/software/SPARSKIT/sparskit.html SPARSKIT]. | |||
</div></div></div> | |||
<!-- | |||
<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</span> | |||
<div class="exercise"> | |||
Format AIJ można implementować na dwa sposoby: jako strukturę złożoną z trzech wektorów: | |||
<div style="margin: 1em; padding:1em; color: #000; background-color:#fcfcfc;"><pre>typedef struct { | |||
int i[NNZ]; | |||
int j[NNZ]; | |||
double v[NNZ]; | |||
} matrix; | |||
matrix A; | |||
</pre></div> | |||
lub jako wektor struktur: | |||
<div style="margin: 1em; padding:1em; color: #000; background-color:#fcfcfc;"><pre>typedef struct { | |||
int i; | |||
int j; | |||
double v; | |||
} element; | |||
element B[NNZ]; | |||
</pre></div> | |||
Przedyskutuj wady i zalety obu podejść i wskaż lepsze. | |||
</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"> | |||
Korzystniejszy jest wariant z wektorem struktur: łatwiej wtedy dodawać i wyłuskiwać całe elementy, poza tym (choć, prawdę mówiąc, zysk jest marginalny) jest wtedy mniej "skakania" po pamięci: cała informacja o elemencie jest zlokalizowana w jednym obszarze pamięci, co może trochę poprawiać wykorzystanie hierarchii pamięci. | |||
</div></div></div> | |||
--> | |||
<div style="margin-top:1em; padding-top,padding-bottom:1em;"> | <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</span> | <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</span> | ||
Linia 75: | Linia 178: | ||
<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:# | <div style="font-size:smaller; background-color:#f9fff9; padding: 1em"> Dziel i rządź! (Tylko: jak?) </div> | ||
</div></div> | </div></div> | ||
Linia 82: | Linia 185: | ||
<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"> | ||
Gdyby pominąć ostatni wiersz i kolumnę, macierz byłaby trójdiagonalna, a my już wiemy, co z nią zrobić... Jak więc sprytnie pozbyć się ostatniej niewiadomej i | Gdyby pominąć ostatni wiersz i kolumnę, macierz byłaby trójdiagonalna, a my już wiemy, co z nią zrobić... Jak więc sprytnie pozbyć się ostatniej niewiadomej i ostatniego równania? W naszej macierzy wyróżnijmy ostatni wiersz i kolumnę: | ||
ostatniego równania? | |||
W naszej macierzy wyróżnijmy ostatni wiersz i kolumnę: | |||
<center><math>\displaystyle A = | <center><math>\displaystyle A = | ||
Linia 135: | Linia 236: | ||
<div class="exercise"> | <div class="exercise"> | ||
Ktoś mógłby sugerować, że skoro CG działa tylko dla macierzy symetrycznych, to dowolny układ <math>\displaystyle Ax=b</math> z macierzą nieosobliwą można transformować do równoważnego mu układu [[ | Ktoś mógłby sugerować, że skoro CG działa tylko dla macierzy symetrycznych, to dowolny układ <math>\displaystyle Ax=b</math> z macierzą nieosobliwą można transformować do równoważnego mu układu [[MN12#Układ równań normalnych|równań normalnych]] | ||
<center><math>\displaystyle A^TAx = A^T b, | <center><math>\displaystyle A^TAx = A^T b, | ||
</math></center> | </math></center> | ||
którego macierz <math>\displaystyle A^TA</math> jest już oczywiście macierzą symetryczną i dodatnio określoną. | którego macierz <math>\displaystyle A^TA</math> jest już oczywiście macierzą symetryczną i dodatnio określoną. | ||
Linia 145: | Linia 246: | ||
<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:# | <div style="font-size:smaller; background-color:#f9fff9; padding: 1em"> Jakie jest uwarunkowanie macierzy <math>\displaystyle A^TA</math>? </div> | ||
</div></div> | </div></div> | ||
Linia 154: | Linia 255: | ||
<center><math>\displaystyle \mbox{cond} (A^TA) = ( \mbox{cond} (A))^2, | <center><math>\displaystyle \mbox{cond} (A^TA) = ( \mbox{cond} (A))^2, | ||
</math></center> | </math></center> | ||
a więc w przypadku macierzy źle uwarunkowanych należy spodziewać się patologicznie dużej liczby iteracji. Chociaż | a więc w przypadku macierzy źle uwarunkowanych należy spodziewać się patologicznie dużej liczby iteracji. Chociaż dobre (symetryczne, dodatnio określone) imadło <math>\displaystyle M</math> mogłoby pomóc, np. | ||
<center><math>\displaystyle MA^TMAx = MA^T Mb, | <center><math>\displaystyle MA^TMAx = MA^T Mb, | ||
</math></center> | </math></center> | ||
to jednak znacznie lepiej stosować metody opracowane specjalnie dla | to jednak znacznie lepiej stosować metody opracowane specjalnie dla macierzy niesymetrycznych, np. GMRES (oczywiście z nieodzownym ściskaniem macierzy, gdy jest źle uwarunkowana...). | ||
Implementacja metody to tylko decyzja, jak realizować mnożenie przez <math>\displaystyle A^TA</math>. | Implementacja metody iteracyjnej to tylko decyzja, jak realizować mnożenie przez <math>\displaystyle A^TA</math>. Niedobra metoda to | ||
<div | <div style="margin: 1em; padding:1em; color: #006; background-color:#fcfcfc;"><pre>B = <math>\displaystyle A^TA</math>; | ||
B = A^TA; | |||
... | ... | ||
while ... | while ... | ||
y = B*x; | y = B*x; | ||
end | end | ||
</pre></div> | </pre></div> | ||
gdyż <math>\displaystyle B</math> będzie bardziej wypełniona niż A. Znacznie lepiej | gdyż <math>\displaystyle B</math> będzie bardziej wypełniona niż A. Znacznie lepiej | ||
<div | <div style="margin: 1em; padding:1em; color: #006; background-color:#fcfcfc;"><pre>... | ||
... | |||
while ... | while ... | ||
y = A*x; | y = A*x; | ||
y = (y'*A)'; | y = (y'*A)'; | ||
end | end | ||
</pre></div> | </pre></div> | ||
co realizuje się kosztem równym dwukrotnemu mnożeniu przez macierz <math>\displaystyle A</math> (w formacie AIJ) i nie wymaga dodatkowej pamięci. | |||
</div></div></div> | </div></div></div> |
Wersja z 21:22, 29 wrz 2006
Układy liniowe z macierzami rzadkimi
<<< 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: Metoda Richardsona
Jedną z najprostszych klasycznych metod iteracyjnych dla równania jest metoda Richardsona, zadana wzorem
gdzie jest pewnym parametrem. Gdy , mamy do czynienia ze zwykłą metodą iteracji prostej, która najczęściej nie będzie zbieżna, dlatego wybór parametru jest kluczowy dla skuteczności metody.
Dla symetrycznej, dodatnio określonej sprawdź, przy jakich założeniach o metoda będzie zbieżna do rozwiązania z dowolnego wektora startowego i oceń szybkość tej zbieżności.
Testuj na macierzy jednowymiarowego laplasjanu różnych wymiarów. Jak najefektywniej zaimplementować mnożenie przez ?
Ćwiczenie
Zaimplementuj operacje:
- mnożenia macierzy przez wektor ,
- wyłuskania wartości elementu ,
- zmiany wartości pewnego zerowego wyrazu macierzy na niezerową,
jeśli macierz jest zadana w formacie
- AIJ,
- CSC,
- CSR.
Przetestuj dla kilku macierzy z kolekcji MatrixMarket.
Ćwiczenie: Konwersja formatu macierzy rzadkiej
Napisz procedurę aij2csr
, konwertującą macierz w formacie AIJ do CSR i csr2aij
, działającą w drugą stronę.
Ćwiczenie
Jak tanio rozwiązywać układ równań z macierzą cykliczną trójdiagonalną, tzn.
Dla uproszczenia załóżmy, że macierz jest dodatnio określona i symetryczna.
Zaimplementuj opracowaną metodę, korzystając z BLASów i LAPACKa.
Ćwiczenie: CGNE
Ktoś mógłby sugerować, że skoro CG działa tylko dla macierzy symetrycznych, to dowolny układ z macierzą nieosobliwą można transformować do równoważnego mu układu równań normalnych
którego macierz jest już oczywiście macierzą symetryczną i dodatnio określoną.
Wskaż potencjalne wady tej metody i podaj sposób jej implementacji.