Derivación Numérica Introducción 1. Actividad 1

Anuncio
Laboratorio de Cálculo Numérico MA-33A
Sesión: Derivación Numérica
Introducción
Los objetivos de esta sesión son
Implementar la técnica de derivación numérica de funciones y obtener fórmulas de alta precisión.
Visualizar el efecto de la precisión de la fórmula de derivación cuando se usan para resolver
ecuaciones diferenciales ordinarias con condiciones de borde.
1.
Actividad 1 (Fórmulas de derivación numérica)
En esta primera parte del laboratorio buscaremos fórmulas de derivación numérica para calcular la segunda
derivada de una función en un punto x0 de su dominio. Es decir, aproximaremos L(f ) = f 00 (x0 ) mediante
una fórmula numérica L̃(f )
1.1.
Breve Teorı́a:
En general, las fórmulas de derivación (o de integración) numérica se obtienen aproximando la función f
mediante su polinomio de interpolación Pf en una malla {x0 , x1 , . . . , xn } y derivando (o respectivamente
integrando) dicho polinomio. Es decir
f ≈ Pf
y
L(f ) ≈ L̃(f ) = L(Pf ).
Usando esta idea general, se demuestra teoricamente, que siempre las fórmulas quedan expresadas en la
forma
n
X
C̃i f (xi ),
L̃(f ) =
i=0
donde C̃i son constantes.
En este Laboratorio usaremos mallas equespaciadas (de paso h), como la que se muestra en la figura.
x0 − 3h x0 − 2h x0 − h
x0
x0 + h
x0 + 2h x0 + 3h
Por esta razón, para hacer el cálculo independiente del punto x0 y del paso de la malla, haremos el
siguiente cambio de variable:
g(t) = f (x0 + th), o sea
x = x0 + th.
Con esto, la malla de puntos xi se transformará en una malla de puntos ti del tipo {. . . , −2, −1, 0, 1, 2, . . .}.
Además, el cambio de variable anterior implica que
g 00 (t) = h2 f 00 (x0 + th)
por lo tanto la derivada buscada de f en x0 se reduce a la derivada correspondiente de g en t0 = 0 siguiente
f 00 (x0 ) =
1
1 00
g (0).
h2
Con este cambio nos concentraremos en buscar una fórmula de derivación numérica para g 00 (0) del tipo
g 00 (0) ≈
md
X
(1)
Ci g(i),
i=−mi
donde hemos denotado por mi > 0 y md > 0 a la cantidad de puntos de la malla que están a la izquierda
y a la derecha de 0. Por ejemplo, la malla de la figura siguiente, tiene 2 puntos a la izquierda y 3 a la
derecha de 0.
md =3
mi =2
z
−2
}|
{
}|
z
−1
0
1
2
{
3
Para el cálculo de las constantes Ci usaremos una forma explı́cita (obtenida en el curso), que consiste en
usar los polinomios de la base de Lagrange {`i (x)} asociados a la malla {ti }. Haciendo esto, se sabe que
Ci = `00i (0).
Una vez encontrada (con el computador) la fórmula de derivación para g, basta con dividirla por h2 para
recuperar la fórmula de derivación de f . Es decir
Ci
C̃i = 2 ,
h
y
md
1 X
L̃(f ) = 2
Ci f (x0 + hi).
h
i=−mi
El método entonces para encontrar una fórmula de derivación numérica es:
Primero definir la malla (o sea cuantos puntos se van a usar),
Luego calcular los polinomios de la base de Lagrange y
Finalmente derivar dichos polinomios.
1.2.
Programación
Nos concentraremos en obtener la fórmula de derivación numérica para la función g.
Comience por abrir su editor de SCILAB y allı́ escribir un nuevo programa llamado derivacion.sce.
En ese archivo programe la técnica de derivación detallada en el recuerdo teórico siguiendo los siguientes pasos:
Para programar la malla {ti } = {−mi , . . . , −1, 0, 1, . . . , md } defina las variables mi y md con los
valores 2 y 3 respectivamente (más tarde cambiaremos estos valores). Usando estas variables,
defina la malla como el vector fila t=(-mi):md;
Para calcular los polinomios de Lagrange, usaremos una función preprogramada por el profesor y
disponible en el archivo funciones preprogramadas.sci. La función se llama Lagrange(). Para
poder usar esa función:
Baje el archivo funciones preprogramadas.sci de la página del Labotarorio
Al principio de su programa agrege la instrucción
getf("funciones preprogramadas.sci");
2
Donde corresponda en su programa, use la instrucción L=Lagrange(t); para obtener los
polinomios de la base de Lagrange para su malla.
Antes de seguir avanzando, investigue un poco esta función Lagrange. Para ello digite en la
ventana SCILAB (¡no en su programa!) las instrucciones siguientes:
Lagrange(0) enter
Lagrange([0 1]) enter
Lagrange([0 1 2]) enter
Lagrange([0 1 -1]) enter
Abra un archivo de texto usando word (u otro procesador de testo de su elección) de nombre
informe.doc e indique allı́ que polinomios se obtienen al ejecutar las instrucciones anteriores.
En particular diga cuantos polinomios hay en cada caso, que grado son y cuales son (en
lenguaje matemático, no computacional).
Para derivar (una vez) un polinomio en SCILAB se usa la instrucción derivat. Por lo tanto, para
derivar dos veces el vector de polinomios L, agregue en su programa la instrucción
Lsegunda=derivat(derivat(L));
Finalmente, para evaluar un polinomio en SCILAB, se usa la instrucción horner(‘‘polinomio’’,’’punto’’).
Por lo tanto, las constantes buscadas se calculan fácilmente con la instrucción C=horner(Lsegunda,0);
Ejecute su programa e investigue la variable C en la ventana SCILAB. Anote los resultados en
informe.doc.
En particular evalúe en la ventana SCILAB las siguientes instrucciones y anote sus resultados en
el informe.doc
--> C
[enter]
--> C’
[enter]
--> C’*12 [enter]
Habrá notado que las constantes C fueron calculadas como un vector columna, por eso, para los
informes es mejor visualizar C’. Además, los numeros obtenidos presentan decimales periodicos,
por esa razón es mejor sacar el mı́nimo común multiplo 12, multiplicando todas las constantes por
ese valor. La última linea es útil para guardar la variable C en un informe, ya que al trasponerlo
se puede escribir en una linea y al multiplicarlo por 12 desaparecen los decimales.
Con esto su programa calcula las constantes de la fórmula de derivación numérica para la función g y la
malla {−2, −1, 0, 1, 2, 3}. Verifique si su programa está bien, comparando sus constantes con las definidas
por la instrucción
CC= [ -1
6
-30
-16
0]’/12;
Ahora que el programa funciona bien y entiende lo que hace, ejecútelo para las diferentes mallas
definidas por los siguientes valores.
Malla 1:
mi = md = 1 (O sea un punto a cada lado de x0 )
Malla 2:
mi = md = 2 (O sea dos puntos a cada lado de x0 )
Malla 3:
mi = 1 y md = 3 (O sea un punto a la izquierda de x0 y tres puntos a la derecha de
x0 ).
Malla 4:
mi = 1 y md = 4. Pruebe también el caso mi = 4 y md = 1 y comente lo observado en
informe.doc.
Para cada caso, anote en su informe.doc los valores obtenidos de las constantes en el formato
SCILAB siguiente:
3
Para la Malla 1 se obtiene:
C1=[ xxx xxx xxx]’;
Para la malla 2 se obtiene:
C2=[ xxx xxx xxx]’ / 12;
De este este modo, cuando más tarde necesite las constantes calculadas, las pueda recuperar
fácilmente de su informe sin necesidad de calcularlas.
2.
Actividad 2 (Precisión)
En esta actividad, calcularemos la precisión de las diferentes fórmulas de derivación encontradas en la
actividad 1.
2.1.
Recuerdo teórico:
Definición. La precisión de una fórmula de derivación numérica es el valor del número natural m tal
que la fórmula es exacta para todos los polinomios de grado ≤ m y deja de ser exacta para polinomios de
grado superior.
Observación. Si la precisión de la fórmula de derivación es m entonces el error teórico de aproximación
depende de la derivada f (m+1) (x).
Por ejemplo, si una fórmula deriva exactamente a todos los polinomios de grado inferior
o igual a 5, pero no a los de grado 6, entonces, se dice que su precisión es 5.
En este caso, el error de derivación es de la forma
f 00 (x0 ) = L̃(f ) + Kf (6) (ξ)hp .
O sea depende de la sexta derivada de la función f y tiende a cero si h → 0.
Observación. Claramente, si la malla tiene k puntos, la fórmula de derivación debe ser exacta para
polinomios de grado ≤ (k − 1). Por lo tanto la precisión de la fórmula debe ser ≥ (k − 1). Esto cosntituye
una cota inferior de la precisión.
Comience por anotar en su informe.doc cuales son las cotas inferiores para la precisión de cada
una de las fórmulas de derivación encontradas al final de la actividad 1 (donde se usaron diferentes
mallas).
Teóricamente, para encontrar la precisión de una fórmula, se pueden tomar las funciones f (x) = xn
para n = 0, 1, 2 . . . calcular su segunda derivada exacta (que llamaremos Dex en el programa), su derivada
numérica (que llamaremos Dnum en el programa) y ver si la diferencia es o no es cero. Sin embargo, en el
computador existen los errores de redondeo los que perturban los resultados. Antes de seguir avanzando,
piense en lo siguiente:
Que pasa si para f (x) = x4 en x0 = 2 se obtiene
Dex =24.00001 y
Dnum=24.00003
¿Significa esto que la fórmula de derivación no es exacta? o ¿sı́ es exacta, pero al
evaluarla hubo un error de redondeo?
Como no es posible dar una u otra respuesta con este cálculo, realizaremos los siguiente “truquito”:
evaluaremos la fórmula para diferentes valores de h y haremos un gráfico del error ER (Dex,Dnum). Si
4
el error de evaluación es producido por la fórmula, este error debiera tener un gráfico que muestra que
cuando h → 0 el error también. Si no, es porque el error es de redondeo (De hecho este último tiende a
∞ cuando h → 0.
2.2.
Programación
Guarde su programa derivadas.sce con el nombre precision.sce (save as). No borre ninguna
linea, ya que la precisión será calculada para las diferentes mallas.
Agregue la definición de todos los valores de h que se usarán para hacer el gráfico:
h=logspace(-8,0,300)’; //matriz de 300 × 1
Ahora defina las variables n=10; y x0=2; que representan el grado del polinomio a probar y el
punto de derivación.
En el archivo funciones preprogramadas.sci, ya se han programado, con los nombres f0 y f2 las
funciones f (x) = xn y f 00 (x) = n(n − 1)xn−2 respectivamente.
Por lo tanto puede calcular inmediatamente Dex como f2(x0).
Ahora el problema es calcular la derivada numérica. Recordemos que para cada valor de hk se debe
calcular
L̃(f, hk ) =
1 X
Ci f (x0 + ti hk ).
h2
i
La sumatoria de esta fórmula se evalua en SCILAB como un producto matricial. En efecto, observemos que:
h es una matriz de 300 × 1 y t es una matriz de 1 × m (m representa el largo de la malla).
Por lo tanto la matriz h*t es de tamaño 300 × m y en la posición (i, j) contiene los valores
(hi tj )
Como x0 es una constante, f0(x0+h*t) será una matriz del mismo tamaño 300 × m.
Las constantes C están guardadas en una matriz columna de m × 1.
Por lo tanto la sumatoria es implı́cita en el producto matricial f0(x0+h*t)*C, que entregará
un vector fila de 300 × 1.
Finalmente, para encontrar las 300 derivadas numéricas (una por cada hk ) basta con dividir,
componente a componente, el vector anterior por h.^2. O sea
Dnum= (
) ./ h.^2;
Una vez programada la derivada numérica Dnum, calcule el error relativo de la aproximación como
Err=abs( (Dnum-Dex)/Dex ) + 1e-15;
Grafique el error relativo producido por la derivada numérica en función de h mediante
xselect();plot( log10(h) , log10(Err) );
Grabe el gráfico obtenido en grafico n10.gif. Agregue este gráfico en su informe.doc e indique
donde se ven claramente las dos fuentes de error (truncación y redondeo) en el cálculo de la derivada
numérica de x10 en x0 = 2.
Note que el error de truncación (que no es cero, ya que n es muy grande) tiene un aspecto suave y
disminuye cuando h decrece. A partir de un cierto instante aparece el error de redondeo el cual se
caracteriza por su forma errática.
5
Grafique nuevamente el error relativo pero ahora cambie el valor de n a n = 2. Como n es pequeño,
se sabe que no debiera haber error de truncación, sin embargo observará que en el gráfico si lo hay
y crece cuando h tiende a cero. Esta es nuevamente la presencia del error de redondeo. Exporte el
gráfico como grafico n2.gif e incorpórelo en su informe.doc. Anote las diferencias conceptuales
entre los dos gráficos anteriores (es decir, donde están los dos errores).
A partir de esto, indique en su informe (mirando el gráfico anterior) cuando hay o no error de
truncación, es decir, como saber si la fórmula es “matemáticamente” exacta o no. Con esto detalle
la estrategia a seguir para encontrar numéricamente la precisión de las diferentes fórmulas de
derivación numérica.
Use la estrategia anterior y encuentre las precisiones de las 4 fórmulas de derivación obtenidas en
la actividad 1. Anote todo en su informe.doc.
3.
Actividad 3. Ecuación diferencial de segundo orden con valores en
los lı́mites
En esta segunda parte del laboratorio usaremos las diferentes fórmulas de derivación numérica para
resolver numéricamente la ecuación diferencial siguiente:
Dadas, la función f : [a, b] → R y las constantes ua y ub ∈ R se desea encontrar la función u: [a, b] → R
continua en [a, b] y dos veces derivable en (a, b) de modo que

 d2 u
− 2 = f (x), ∀x ∈ (a, b)
(2)
 dx
u(a) = ua , u(b) = ub
Realizaremos la experiencia numérica en el caso particular en que a = 0, b = π, f (x) = sin(x), ua = 0
y ub = 0. Este caso es interesante ya que la solución exacta de la ecuación es conocida e igual a
u(x) = sin(x). Por lo tanto podremos ver si el método numérico es capaz de encontrar este resultado con
un error pequeño.
3.1.
Teorı́a de resolución numérica
Comenzamos por dividir el intervalo [0, π] mediante una partición equiespaciada de N + 1 intervalos de
largo h = N 1+1 .
0
h
x0
x1
2h
x2
ih
Nh
xi
xN
π
xN +1
En cada punto xi = ih, i = 1, . . . , N de la malla calcularemos aproximaciones ui de la solución u(xi ).
Usando las condiciones de borde del problema es útil definir
u0 = 0,
uN +1 = 0.
Ası́, las incógnitas del problema son u1 , . . . , uN , es decir, un vector de RN .
Se llama ecuación discretizada de (??) a la que resulta de usar una fórmula de derivación numérica que
aproxime u00 (xi ) en términos de las incógnitas uj .
La fórmula de derivación mas sencilla (y más usada) es aquella que usa un solo vecino de cada lado de x
(mi=md=1). Recordará qu esta fórmula es
u00 (x) ≈
u(x − h) − 2u(x) + u(x + h)
h2
6
(Caso de la malla t=[-1 0 1]).
En este caso, la ecuación discretizada se obtiene reemplazando esta fórmula desde el punto x1 hasta el
xN . Es decir
x1
1
0
0
1
u0 u1 u2
0
1
0
1
0 x2
1
0
1
u1 u2 u3
0
1
x3
0
1
0
1
0
1
se impone
z}|{
=
h2 f1
−h2 u00 (x1 )
≈ − u0 +2u1 − u2
|{z}
− h2 u00 (x2 )
≈ −u1 + 2u2 − u3
=
h2 f2
− h2 u00 (x3 )
≈ −u2 + 2u3 − u4
=
h2 f3
..
.
..
.
..
.
=
h2 fN .
(=0)
u2 u3 u4
1
0
0
1
0
1
0
un−1un u1
n+1
xn
− h2 u00 (xN ) ≈ −uN −1 + 2uN − uN +1
| {z }
(=0)
Ordenando estas aproximaciones se obtiene un

2 −1 0
 −1 2 −1


..
.
A=
 0 −1 2

.
.
..
..

0
0
−1
sistema de ecuaciones Au = B donde



0
f1

0 
 f2 



..  .
2

y
B
=
h



 . 

 fN −1 
−1 
fN
2
Es decir en lenguaje SCILAB:
A=2*diag( ones(N,1) ) - diag( ones(N-1,1) , 1) - diag( ones(N-1,1), -1);
b=h*h*f(x);
Programación:
Usando el método de derivación numérica de tres puntos, escriba un programa (actividad3.sce)
que le permita resolver numéricamente la ecuación diferencial (??) según el método numérico anterior. Comience con N = 10.
Indicación:
N=10; h=%pi / (N+1);
x=linspace(0,%pi,N+2)’;
b=h*h* sin(x(2:N+1));
A=.....//ver lineas más arriba
u=A\b ;
Grafique la diferencia en valor absoluto entre la solución numérica y la solución exacta.
Indicación:
uex= sin(x); u = [0 ; u ; 0];
err= abs(u-uex); max(err)
xbasc();xselect(); plot(x,err);xgrid(3);
Aumente el valor de N según la progresión 20, 40, 80, etc. de modo de encontrar aquel N tal que
el máximo error (max(err)) sea inferior a 10−8
En la medida que N crezca, para almacenar la matriz A será necesario aumentar el tamaño del
stack de SCILAB, el cual es originalmente 1e6 (o sea, inicialmente se puede almacenar hasta un
millón de datos). Para ello, al principio de su programa escriba alguna de las 4 lineas siguientes
7
clear;stacksize(2e6) //stack de 2 millones de números (16Mb)
clear;stacksize(10e6) //stack de 10 millones de números (80Mb)
clear;stacksize(20e6) //stack de 20 millones de números (160Mb)
clear;stacksize(.....e6) //stack tan grande como su PC lo permita.
Cada vez que pruebe con un valor de N registre en su informe.doc el valor de max(err) y del
tiempo que demora el cálculo. Este tiempo puede tomarlo usando su reloj de pulsera o también
puede agregar en su programa, antes de comenzar el cálculo, la instrucción timer(); (con ;) y
después del cálculo la instrucción timer() (sin ;). Esta instrucción le mostrará los segundos usados
por el PC para resolver el problema.
Construya una tabla del tipo
N
max(err)
Tiempo (seg)
Cuando haya llegado a N entre 4000 y 5000, use la tabla anterior para estimar cual debiera ser el
buen valor de N y cuanto se demorarı́a su PC en alcanzar el error mı́nimo requerido.
Puede usar SCILAB como una calculadora, escribiendo algo ası́ como:
NN =[4000
4500
5000
10000];
Merr=[1e-4
1e-5
1e-6
1e-8 ];
plot(N,log10(Merr));
donde en la variable NN va poniendo los N con que probó y en Merr los errores obtenidos.
Con estos datos, comente en su informe respecto a la posibilidad de encontrar una solución numérica con
error pequeño en tiempo razonable.
8
Descargar