GNU Octave/Dyskretyzacja laplasjanu
Dyskretyzacja laplasjanu
edytujDyskretyzacją laplasjanu jest macierz:
(a) Utworzyć różnymi metodami macierz i porównać czasy wykonania.
Funkcja tworząca macierz z użyciem pętli for. Pamięć na macierz alokujemy przed wykonaniem funkcji za pomocą zeros.
function [L]=laplasjan(N) #Funkcja tworzaca macierz -laplasjanu L=zeros(N,N); for k=1:(N-1) L(k:(k+1),k:(k+1)) = [2 -1; -1 2]; endfor; endfunction;
Funkcja tworząca macierz z użyciem funkcji diag.
function [L]=laplasjan_diag(N) #Funkcja tworzaca macierz v = -1.*ones(1,N-1); w = 2.*ones(1,N); L = zeros(N,N) + diag(w, 0) + diag(v, 1) + diag(v, -1); endfunction;
Przykładowe wykonanie:
octave:178> laplasjan(5) ans = 2 -1 0 0 0 -1 2 -1 0 0 0 -1 2 -1 0 0 0 -1 2 -1 0 0 0 -1 2
Sprawdzamy czas wykonania dla dużych :
octave:3> tic; laplasjan(2000); toc ans = 0.22324 octave:4> tic; laplasjan_diag(2000); toc ans = 0.58647
Wniosek: użycie diag jest wolniejsze niż tworzenie macierzy iteracyjnie.
(b) Rozwiązać dyskretne równanie Laplace'a za pomocą odwrotności tej macierzy, policzonej na dwa różne sposoby. Patrz także zagadnienie własne dla operatora Laplace'a. Równanie ma postać:
Jego rozwiązaniem jest funkcja . Dyskretyzacja równania ma postać:
gdzie .
Zatem musimy rozwiązać równanie: , gdzie .
N=800; h=1/N; f=(h*h)*sin((pi*h).*(1:N)); Z=laplasjan(N); U1=Z\f'; U2=inv(Z)*f';
Obliczamy błędy:
rozw = f*N*N/(pi*pi); blad_LU = norm(U1'-rozw, 2) blad_inv = norm(U2'-rozw, 2)
co na komputerze autora dało rezultat:
blad_LU = 0.0064975 blad_inv = 9.6543e+08