Anda di halaman 1dari 5

Prctica 5

1. Haga una funcin de Matlab que calcule de forma aproximada por el


mtodo Gauss-Seidel la solucin al problema:
uxx + uyy = rho(x, y), 0 <x<a; 0 <y< b,
sujeta a las condiciones
u(x, 0) = f0(x), u(x, b) = f1(x), 0?x?a y u(0, y) = g0(y), u(a, y) = g1(x),
0?y?b.
Tome como parmetros de entrada
Los nmeros reales a, b.
El nmero de divisiones de los intervalos [0, a] y [0, b].
Las funciones : rho, f0, f1, g0 y g1.
El nmero mximo de iteraciones maxiter y la tolerancia tol mxima.
Mediante un bucle while, debe controlar que no se hagan ms
iteraciones que maxiter. Si
mxi,j |u(k)i,j ? u(k+1)i,j | < tol,
entonces la funcin debe salirse del bucle.
Creamos un fichero llamado seidel.m con el siguiente contenido:
function [U,error_maximo]=seidel(b,d,n,m,rho,f0,f1,g0,g1,maxiter,tol)
% Numero de divisiones del eje x=n y del eje y=m
a = 0; % [a,b] = intervalo de las x
c = 0; % [c,d] = intervalo de las y
h = (b-a)/n; k = (d-c)/m;
alpha = k/h; alpha2 = alpha^2; beta = 2*(1+alpha2);
x = a:h:b;
y = c:k:d;
[X Y] = meshgrid(x,y);
rho=(feval(rho,X,Y))';
f0=feval(f0,x);
f1=feval(f1,x);
g0=feval(g0,y);
g1=feval(g1,y);
u0 = (mean(f0)+mean(f1)+mean(g0)+mean(g1))/4; % Estimacion inicial;
U = u0*ones(n+1,m+1); % Matriz donde se van a almacenar los valores de u
U(:,1) = f0(:);
U(:,end) = f1(:);
U(1,:) = g0;
U(end,:) = g1;
error_maximo=1;
s=0;
T=zeros(size(U));
while s<maxiter
if error_maximo>tol
for i=2:n
for j=2:m
num = alpha2*(U(i-1,j)+U(i+1,j))+U(i,j-1)+U(i,j+1)-k^2*rho(i,j);
U(i,j) = num/beta;
end
end
error = abs(T-U);
error_fila = error(:);
error_maximo = max(error_fila);
T=U;
end
s=s+1;

David Serrano Carrera

MAT III B2B

1/5

end
end

Vamos a explicarlo un poco:


En primer lugar hallamos los intervalos, las divisiones y los parmetros
alpha y beta que se irn utilizando posteriormente en cada iteracin con
los bucles for.
Despus, se crear una matriz XY con todos los valores de x, y calculados.
A continuacin, evaluamos la matriz X Y en la funcin rho y la trasponemos,
mientras que en f0,f1,g0,g1 lo evaluamos en x o y, segn la variable de cul
depende. El comando feval evala estas variables calculadas dentro del
bucle en las funciones de entrada.
Posteriormente construiremos una primera matriz U con dos bucles aninados
for y utilizando los alpha y beta anteriores, que no tendr muy buenas
aproximaciones. Para solucionar esto, lo metemos todo dentro de un
condicional if que terminar cuando el error mximo sea menor que la
tolerancia introducida (empezamos con 1, ya que la tolerancia suele estar
entre 0 y 1).
Adems, para controlar las iteraciones, meteremos todo lo anterior en un
bucle while que se saldr cuando la variable de control s sea mayor o igual
al nmero de iteraciones introducidas por el usuario.
El error mximo es calculado a partir de una matriz y su siguiente (en el
primer paso ya que no tenemos una primera matriz con la que compararla,
hacemos una matriz de 0 de la misma dimensin que U, as saldra un error
alto).
2. Considere a a partir de ahora el problema
uxx + uyy = ?[cos(x + y) + cos(x ? y)] , 0<x<pi ; 0<y<pi/2,
sujeta a u(x, 0) = cos(x), u(x, pi/2) = 0, 0?x?pi y
u(0, y) = cos (y), u(pi, y) = ?cos (y), 0?y?pi/2.
Halle el valor aproximado de u(1, 1) dividiendo los intervalos de las x
y de las y en
10, 20, 30 y 40 trozos y con una tolerancia de 10?3. Cuente el nmero
de iteraciones
y diga si hay una relacin directa con el nmero de divisiones.
En este caso las iteraciones no se necesitan controlar sino que hay contarlas,
teniendo como criterio de parada la tolerancia. As pues, modificamos
ligeramente el bucle:
[U,s]=seidel(b,d,n,m,rho,f0,f1,g0,g1,tol)
while error_maximo<=tol
for i=2:n
for j=2:m
num = alpha2*(U(i-1,j)+U(i+1,j))+U(i,j-1)+U(i,j+1)-k^2*rho(i,j);
U(i,j) = num/beta;
end
end
error = abs(T-U);
error_fila = error(:);
error_maximo = max(error_fila);
T=U;
s=s+1;

David Serrano Carrera

MAT III B2B

2/5

end

El while ahora trabaja con el error mximo, en lugar de con las iteraciones
mximas.
Por otra parte, las funciones y los lmites hemos de establecerlos fuera de
nuestro programa,as:
[U,s]=seidel(pi,pi/2,10,10,'rho','f0','f1','g0','g1',10^-3)

Siendo rho,f0,f1,g0 y g1 las funciones iniciales que hemos declarado en


archivos .m por separado como por ejemplo:
function f0=f0(x)
f0=cos(x);

As pues con 10 trozos, nos da una solucin:


>> U(1,1)
ans =
1
>> s
s =
32

Para 20 trozos [U,s]=seidel(pi,pi/2,20,20,'rho','f0','f1','g0','g1',10^-3);


>> U(1,1)
ans =
1
>> s
s =
85

Para 30 trozos [U,s]=seidel(pi,pi/2,30,30,'rho','f0','f1','g0','g1',10^-3);


>> U(1,1)
ans =
1
>> s
s =
144

Para 40 trozos [U,s]=seidel(pi,pi/2,40,40,'rho','f0','f1','g0','g1',10^-3);


>> U(1,1)
ans =
1
>> s
s =
198

Hay una relacin nmerica aproximada que por cada 10 nuevas divisiones, el
bucle se realiza aproximadamente 50 veces ms, ya que al dividir en ms
trozos, hay que analizar una matriz ms grande y por tanto, recorrerla hasta
llegar a la tolerancia costar ms.
3. Compare la solucin aproximada con la exacta, que es u(x, y) = cos
x cos y.
Realizaremos una matriz con los mismo lmites que las condiciones iniciales.
As pues copiaremos parte del cdigo seidel.m
>>n=10;
>>m=10;
>>b=pi;
>>d=pi/2;
>>a = 0;

David Serrano Carrera

MAT III B2B

3/5

>>c
>>h
>>x
>>y

=
=
=
=

0;
(b-a)/n; k = (d-c)/m;
a:h:b;
c:k:d;

Ahora la rellenaremos con la solucin exacta (para que nos quepa,


utilizaremos la matriz de 10 trozos):
>> for i=1:11
for j=1:11
U(i,j)=cos(x(i))*cos(y(j));
end
end
>> U
U =

Columns 1 through 9
1.0000
0.9511
0.8090
0.5878
0.3090
0.0000
-0.3090
-0.5878
-0.8090
-0.9511
-1.0000

0.9877
0.9393
0.7991
0.5805
0.3052
0.0000
-0.3052
-0.5805
-0.7991
-0.9393
-0.9877

0.9511
0.9045
0.7694
0.5590
0.2939
0.0000
-0.2939
-0.5590
-0.7694
-0.9045
-0.9511

0.8910
0.8474
0.7208
0.5237
0.2753
0.0000
-0.2753
-0.5237
-0.7208
-0.8474
-0.8910

0.8090
0.7694
0.6545
0.4755
0.2500
0.0000
-0.2500
-0.4755
-0.6545
-0.7694
-0.8090

0.7071
0.6725
0.5721
0.4156
0.2185
0.0000
-0.2185
-0.4156
-0.5721
-0.6725
-0.7071

0.5878
0.5590
0.4755
0.3455
0.1816
0.0000
-0.1816
-0.3455
-0.4755
-0.5590
-0.5878

0.4540
0.4318
0.3673
0.2668
0.1403
0.0000
-0.1403
-0.2668
-0.3673
-0.4318
-0.4540

0.3090
0.2939
0.2500
0.1816
0.0955
0.0000
-0.0955
-0.1816
-0.2500
-0.2939
-0.3090

Columns 10 through 11
0.1564
0.1488
0.1266
0.0919
0.0483
0.0000
-0.0483
-0.0919
-0.1266
-0.1488
-0.1564

0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
-0.0000
-0.0000
-0.0000
-0.0000
-0.0000

Si en nuestro programa original, hacemos 2 o 3 iteraciones, el valor U(1,1) nos


saldr igual, pero los dems valores variarn. En cambio, con, por ejemplo, 50
iteraciones, la solucin sale prcticamente exacta:
[U,error_maximo]=seidel(pi,pi/2,10,10,'rho','f0','f1','g0','g1',50,10^-3);
>>U =
Columns 1 through 9
1.0000
0.9511
0.8090
0.5878
0.3090
0.0000
-0.3090
-0.5878
-0.8090
-0.9511
-1.0000

0.9877
0.9390
0.7986
0.5805
0.3059
0.0015
-0.3031
-0.5785
-0.7975
-0.9386
-0.9877

0.9511
0.9039
0.7687
0.5590
0.2952
0.0028
-0.2902
-0.5553
-0.7666
-0.9032
-0.9511

0.8910
0.8466
0.7199
0.5237
0.2771
0.0036
-0.2705
-0.5188
-0.7171
-0.8456
-0.8910

0.8090
0.7686
0.6536
0.4756
0.2520
0.0040
-0.2446
-0.4701
-0.6504
-0.7674
-0.8090

0.7071
0.6717
0.5712
0.4158
0.2206
0.0041
-0.2132
-0.4103
-0.5680
-0.6705
-0.7071

0.5878
0.5584
0.4749
0.3458
0.1836
0.0037
-0.1769
-0.3407
-0.4719
-0.5572
-0.5878

0.4540
0.4313
0.3668
0.2672
0.1419
0.0030
-0.1365
-0.2631
-0.3644
-0.4304
-0.4540

0.3090
0.2936
0.2498
0.1819
0.0966
0.0021
-0.0929
-0.1791
-0.2481
-0.2929
-0.3090

Columns 10 through 11
0.1564
0.1487
0.1265
0.0921
0.0489
0.0010
-0.0471
-0.0907
-0.1256

0.0000
0
0
0
0
0
0
0
0

David Serrano Carrera

MAT III B2B

4/5

-0.1483
-0.1564

0
-0.0000

Con un error_maximo de 8.7302e-004 .

David Serrano Carrera

MAT III B2B

5/5

Anda mungkin juga menyukai