GNU Octave/Dyskretyzacja laplasjanu: Różnice pomiędzy wersjami

Z testwiki
Przejdź do nawigacji Przejdź do wyszukiwania
imported>Lethern
skopiowane ze str głównej GNU Octave
 
(Brak różnic)

Aktualna wersja na dzień 15:43, 12 kwi 2008

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