4. laborgyakorlat
Numerikus számítások fizikusoknak
Contents
clear all, close all
Gauss-módszer főelemkiválasztással
A lebegőpontos számításokból eredő hibákat csökkenthetjük részleges- vagy teljes főelemkiválasztással. A részleges főelemkiválasztásnál sorcserét hajtunk végre úgy, hogy a főelem legyen a legnagyobb abszolút értékű elem az adott oszlop hátra lévő részében (A(k:n,k)-ban). Teljes főelemkiválasztásnál sor és oszlopot is cserélünk és az A(k:n,k:n+1) almátrixban lévő abszolút értékben legynagyobb elemet cseréljük a főelem helyére.
Általános LU-felbontás
A részleges főelemkiválasztással elvégzett Gauss-módszerrel egy
alakú ún. általános LU-felbontáshoz jutunk, ahol P megfelelő permutációs mátrix. L elemei most 1-nél nem nagyobb abszolút értékűek.
H=hilb(5) [L,U,P]=lu(H) % Hilbert-mátrix általános LU-felbontása P\(L*U) %=H
H = 1.0000 0.5000 0.3333 0.2500 0.2000 0.5000 0.3333 0.2500 0.2000 0.1667 0.3333 0.2500 0.2000 0.1667 0.1429 0.2500 0.2000 0.1667 0.1429 0.1250 0.2000 0.1667 0.1429 0.1250 0.1111 L = 1.0000 0 0 0 0 0.3333 1.0000 0 0 0 0.5000 1.0000 1.0000 0 0 0.2000 0.8000 -0.9143 1.0000 0 0.2500 0.9000 -0.6000 0.5000 1.0000 U = 1.0000 0.5000 0.3333 0.2500 0.2000 0 0.0833 0.0889 0.0833 0.0762 0 0 -0.0056 -0.0083 -0.0095 0 0 0 0.0007 0.0015 0 0 0 0 -0.0000 P = 1 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 1 0 ans = 1.0000 0.5000 0.3333 0.2500 0.2000 0.5000 0.3333 0.2500 0.2000 0.1667 0.3333 0.2500 0.2000 0.1667 0.1429 0.2500 0.2000 0.1667 0.1429 0.1250 0.2000 0.1667 0.1429 0.1250 0.1111
Cholesky-felbontás
Cholesky-felbontás szimmetrikus, pozitív definit mátrixokra. Műveletszáma kb. fele a Gauss-módszerének
G=chol(H)
G'*G %=H
G = 1.0000 0.5000 0.3333 0.2500 0.2000 0 0.2887 0.2887 0.2598 0.2309 0 0 0.0745 0.1118 0.1278 0 0 0 0.0189 0.0378 0 0 0 0 0.0048 ans = 1.0000 0.5000 0.3333 0.2500 0.2000 0.5000 0.3333 0.2500 0.2000 0.1667 0.3333 0.2500 0.2000 0.1667 0.1429 0.2500 0.2000 0.1667 0.1429 0.1250 0.2000 0.1667 0.1429 0.1250 0.1111
Teli- és ritka mátrixok
Egy mátrix ritka, ha a nemnulla elemek száma O(n) nagyságrendű. A sparse paranccsal lehet egy mátrixot ritkává (ekkor a Matlab tudja, hogy ritka mátrixról van szó) alakítani. A full parancs ritkából csinál teli mátrixot. spy ábrázolja a mátrix nemnulla elemeinek szerkezetét.
A=eye(20); whos A A=sparse(A); whos A spy(A)
Name Size Bytes Class Attributes A 20x20 3200 double Name Size Bytes Class Attributes A 20x20 324 double sparse
A=toeplitz([2,1,zeros(1,8)]) spy(A)
A = 2 1 0 0 0 0 0 0 0 0 1 2 1 0 0 0 0 0 0 0 0 1 2 1 0 0 0 0 0 0 0 0 1 2 1 0 0 0 0 0 0 0 0 1 2 1 0 0 0 0 0 0 0 0 1 2 1 0 0 0 0 0 0 0 0 1 2 1 0 0 0 0 0 0 0 0 1 2 1 0 0 0 0 0 0 0 0 1 2 1 0 0 0 0 0 0 0 0 1 2
Futási idők összehasonlítása
A=rand(1000); % véletlen mátrix [L,U,P]=lu(A); B=A'*A; % szimmetrikus, pozitív definit mátrix C=toeplitz([2,-1,zeros(1,998)]); % tridiagonális mátrix D=sparse(C); b=rand(1000,1); tic, A\b; altalanos_ido=toc tic, U\(L\(P*b)); altalanos_LUval_ido=toc tic, B\b; szimm_poz_def_ido=toc tic, C\b; teli_tridiag_matrix_ido=toc tic, D\b; ritka_tridiag_matrix_ido=toc
altalanos_ido = 0.5663 altalanos_LUval_ido = 0.0116 szimm_poz_def_ido = 0.3485 teli_tridiag_matrix_ido = 0.3140 ritka_tridiag_matrix_ido = 2.4637e-004
Ciklusok
Azokat a programrészeket, melyeket a programmal ismételtetni szeretnénk ciklusoknak hívjuk. Kétféle ciklust használunk: for ill. while ciklust.
Példa for ciklusra
osszeg=0; for i=1:2:999 osszeg=osszeg+i^2; end osszeg
osszeg = 166666500
Sokszor érdemes kiváltani vektor- ill. mátrixműveletekkel
sum([1:2:999].^2) % gyorsabb megvalósítás
ans = 166666500
Példa while ciklusra
osszeg=0; i=1; while i<=999 osszeg=osszeg+i^2; i=i+2; end osszeg
osszeg = 166666500
Egyszerű logikai műveletek
1 az igaz, 0 a hamis logikai értéket jelenti
x=3; y=5; x==y % egyenlő x<y % kisebb x>y % nagyobb x<=y % kisebb vagy egyenlő x>=y % nagyobb vagy egyenlő x~=y % nem egyenlő x>2 & x<4 % és x>2 | y>6 % vagy ~(y==6) % tagadás
ans = 0 ans = 1 ans = 0 ans = 1 ans = 0 ans = 1 ans = 1 ans = 1 ans = 1
Iterációs egyenletrendszer-megoldás
Egy vektoriteráció határértékeként állítjuk elő a megoldást
Jacobi-iteráció
A=[7,2,3;-1,6,4;1,4,8]; b=[2;5;7]; x_pontos=A\b % Ez a Matlab által adott megoldás d=diag(A); % Az A diagonális elemeinek vektora. B=A-diag(d); % Ugyanaz, mint A, csak a főátló helyén nullák állnak. x=[1;2;3]; % Egy tetszőleges kezdővektor, ahonnét az iterációt indítjuk. for i=1:25 x=(b-B*x)./d end
x_pontos = -0.1193 0.3303 0.7248 x = -1.5714 -1.0000 -0.2500 x = 0.6786 0.7381 1.5714 x = -0.5986 -0.1012 0.4211 x = 0.1341 0.4528 1.0004 x = -0.2724 0.1887 0.6318 x = -0.0390 0.3667 0.8147 x = -0.1682 0.2837 0.6965 x = -0.0939 0.3410 0.7542 x = -0.1349 0.3149 0.7163 x = -0.1112 0.3333 0.7344 x = -0.1243 0.3252 0.7222 x = -0.1167 0.3311 0.7279 x = -0.1209 0.3286 0.7240 x = -0.1185 0.3305 0.7258 x = -0.1198 0.3297 0.7246 x = -0.1190 0.3303 0.7251 x = -0.1194 0.3301 0.7247 x = -0.1192 0.3303 0.7249 x = -0.1193 0.3302 0.7248 x = -0.1192 0.3303 0.7248 x = -0.1193 0.3303 0.7248 x = -0.1193 0.3303 0.7248 x = -0.1193 0.3303 0.7248 x = -0.1193 0.3303 0.7248 x = -0.1193 0.3303 0.7248