GNU Octave/Dyskretyzacja laplasjanu

Z testwiki
Wersja z dnia 15:43, 12 kwi 2008 autorstwa imported>Lethern (skopiowane ze str głównej GNU Octave)
(różn.) ← poprzednia wersja | przejdź do aktualnej wersji (różn.) | następna wersja → (różn.)
Przejdź do nawigacji Przejdź do wyszukiwania

Dyskretyzacja laplasjanu

Dyskretyzacją laplasjanu jest macierz:

LN=[210001210001200021001210012]

(a) Utworzyć różnymi metodami macierz LN i porównać czasy wykonania.

Funkcja tworząca macierz LN 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 LN 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 N:

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ć:

{u(x)=sin(πx)u(0)=u(1)=0

Jego rozwiązaniem jest funkcja u(x)=1π2sin(πx). Dyskretyzacja równania ma postać:

{un1+2unun1=h2sin(nh)u0=uN=0

gdzie h=1n.

Zatem musimy rozwiązać równanie: LNu=f, gdzie u=[u1,u2,,un],f=h2sin([h,2h,,Nh]).

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


Szablon:Nawigacja