Cálculo Numérico Avanzado

Anuncio
Cálculo Numérico Avanzado
J. Javier Segura Sala
1
February 25, 2004
1
Depto. de Matemáticas, Estadı́stica y Computación. Universidad de Cantabria
ii
Contents
1 La importancia de saber resolver numéricamente ecuaciones diferenciales de
la Fı́sica
1.1 Ejemplo 1: un péndulo para empezar . . . . . . . . . . . . . . . . . . . . . . . . .
1.2 Ejemplo 2: oscilaciones en un circuito eléctrico . . . . . . . . . . . . . . . . . . .
1.3 Ejemplo 3: distribución de temperaturas en una placa . . . . . . . . . . . . . . .
1.4 Ejemplo 4: propagación de la luz en un medio isótropo . . . . . . . . . . . . . . .
1.5 Ejemplo 5: ecuación de Schrödinger dependiente del tiempo... . . . . . . . . . . .
1.6 ... . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.7 ...Ejemplo n:.... . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2 Sistemas de numeración; errores y sus fuentes
2.1 Sistemas de números y conversiones . . . . . . . . . . . . . . . .
2.1.1 Sistemas de numeración en base q . . . . . . . . . . . . .
2.1.2 Conversión de base decimal a base q . . . . . . . . . . . .
2.1.3 Estándar IEEE de representación de números enteros y en
2.2 Errores y sus causas . . . . . . . . . . . . . . . . . . . . . . . . .
2.2.1 Definiciones . . . . . . . . . . . . . . . . . . . . . . . . . .
2.2.2 Fuentes de errores . . . . . . . . . . . . . . . . . . . . . .
2.3 Propagación de errores: condición y estabilidad. . . . . . . . . . .
2.4 Eficiencia de un algorı́tmo numérico . . . . . . . . . . . . . . . .
2.4.1 Ejemplo: Evaluación de polinomios, método de Horner . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
coma flotante
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
.
.
.
.
.
.
.
.
.
.
3
3
4
5
6
8
8
8
9
9
9
10
12
14
15
15
18
20
21
Tema 1. La importancia de saber resolver ecuaciones diferenciales numéricamente
J. Javier Segura Sala
2
1
La importancia de saber resolver
numéricamente ecuaciones diferenciales
de la Fı́sica
Este curso de análisis numérico está dedicado al estudio de métodos numéricos para la resolución de ecuaciones diferenciales ordinarias y ecuaciones diferenciales en derivadas parciales.
¿Por qué es importante su estudio en una licenciatura de Fı́sica?. La respuesta es obvia: las
ecuaciones diferenciales son la expresión matemática (simplificada) de gran parte de fenómenos
y problemas fı́sicos. Para nuestra desgracia la mayorı́a de estas ecuaciones no se pueden resolver
analı́ticamente en términos de funciones “sencillas”, de modo que debemos recurrir a métodos
numéricos para su resolución.
Como muestra, unos pocos ejemplos seleccionados cuya resolución abordaremos en la parte
práctica del curso.
1.1
Ejemplo 1: un péndulo para empezar
El péndulo es probablemente el sistema dinámico más estudiado de todos los tiempos. La
ecuación diferencial que describe su movimiento en ausencia de rozamiento y fuerzas externas es
mL
d2 θ
= −mg sin(θ) ,
dt
(1.1)
siendo θ el ángulo formado por el péndulo con respecto a la vertical, m su masa, L su longitud
y g la aceleración debida a la gravedad.
Habitualmente se estudia el péndulo aproximándolo por una simple ecuación lineal (sin(θ) ≈
θ), que es aproximadamente válido para pequeñas amplitudes de oscilación.
La ecuación (1.1) se puede resolver analı́ticamente en términos de integrales elı́pticas, que
son funciones para la que existen eficientes métodos numéricos. El procedimiento es, en lugar
de resolver directamente
d2 θ
+ ω02 sin(θ) , ω0 = g/L
(1.2)
dt2
tener en cuenta que
1
E=
2
dθ
dt
2
3
− ω02 cos θ
(1.3)
Tema 1. La importancia de saber resolver ecuaciones diferenciales numéricamente
es una constante de movimiento. Integrando esta constante de movimiento podemos obtener
θ(t) en términos de una integral conocida (integral elı́ptica) que el propio MATLAB incluye (ası́
como casi cualquier librerı́a cientı́fica).
Sin embargo, un péndulo moviéndose en ausencia de rozamiento es una simplificación excesiva
del sistema. Si añadimos un término de rozamiento y una fuerza externa, la ecuación presenta
ahora el siguiente aspecto
mL
d2 θ
dθ
+γ
+ mg sin(θ) = A cos(2πfd t) ,
dt
dt
(1.4)
siendo γ la constante de rozamiento, A la amplitud de la fuerza y f d , la frecuencia de ésta.
Esta ecuación no puede ser resuelta, en general, de forma analı́tica en términos de una
integral “simple” y deberemos acudir a alguno de los métodos numéricos de resolución de EDOs
que estudiaremos en el curso.
1.2
Ejemplo 2: oscilaciones en un circuito eléctrico
La ecuación de van der Pol es un modelo para un circuito eléctrico que formaba parte de las
radios antiguas. Este circuito se remonta a los dı́as en que se utilizaban tubos de vacı́o. El
tubo actúa como un resistor normal cuando la corriente es elevada y lo hace como un resistor
negativo cuando la corriente es baja. Por tanto, este circuito aumenta las pequeñas oscilaciones
y disminuye las grandes. Este comportamiento es caracterı́stico de los denominados osciladores
de relajación. La ecuación que describe este sistema es:
d2 i
di
2
2 − µ dt (1 − i ) + i = 0
dt
(2.5)
siendo µ un parámetro caracterı́stico del sistema.
Como ocurrı́a con el oscilador forzado del ejemplo 1, esta ecuación no es resoluble analı́ticamente
si µ 6= 0. De hecho, la influencia del parámetro µ en el comportamiento de las soluciones de esta
EDO es muy acusada. Veremos que esta ecuación es prototipo de los denominados problemas
stiff (rı́gidos) cuando los valores de µ son grandes. Este tipo de problemas requerirán métodos
especı́ficos para que puedan resolverse de forma eficiente.
J. Javier Segura Sala
4
Cálculo Numérico Avanzado
1.3
Ejemplo 3: distribución de temperaturas en una placa
Supongamos que nos interesa encontrar la distribución de temperaturas u(x, y) en la placa que
se muestra en la figura:
1
0.8
0.6
0.4
R1
0.2
0
−0.2
−0.4
−0.6
−0.8
−1
−1.5
−1
−0.5
0
0.5
1
1.5
con unas condiciones de contorno determinadas (por ejemplo, temperatura constante T en los
bordes superior e inferior (BS,BI) y sin pérdidas de calor en los bordes laterales (BL)) y con
una fuente de calor f (x, y) en el interior de la placa (I).
El problema a resolver se aproxima por la siguiente ecuación en derivadas parciales:
 2
∂ u ∂2u


 ∂x2 + ∂y 2 = f (x, y) en I
u = T en BS, BI


 ∂u = 0 en BL
∂n
(3.6)
siendo n la dirección normal al borde en cuestión.
Éste es un problema de tipo elı́ptico con condiciones de contorno Dirichlet y Neumann. Es
un problema estático: asumimos que no hay dependencia temporal en las variables del sistema.
Dada la geometrı́a regular del sistema, veremos que un método numérico apropiado para resolver
esta EDP será un esquema de diferencias finitas.
En la siguiente figura se muestra la resolución de uno de estos problemas estáticos de temperaturas para un caso en el que se puede encontrar solución analı́tica (lo que no es lo habitual).
5
Cálculo Numérico Avanzado. J. Segura
Tema 1. La importancia de saber resolver ecuaciones diferenciales numéricamente
Sobre este caso volveremos en las clases prácticas.
Si la placa tuviese una geomeotrı́a irregular, como la que se muestra en la siguiente figura,
optaremos por el método de elementos finitos. Al estudio de este método dedicaremos una parte
importante del curso.
1
0.8
0.6
0.4
0.2
0
P1
−0.2
−0.4
−0.6
−0.8
−1
−1.5
1.4
−1
−0.5
0
0.5
1
1.5
Ejemplo 4: propagación de la luz en un medio isótropo
La luz monocromática en un medio isótropo con una permitividad que varı́a poco, se describe
mediante la ecuación de Helmholtz:
−∆E = k02 E
(4.7)
donde E representa cualquier componente del campo eléctrico y k 0 = 2π/λ es el número de
J. Javier Segura Sala
6
Cálculo Numérico Avanzado
ondas del vacı́o. Supongamos que E es, de forma aproximada, una onda plana que se propaga
en una dirección que llamaremos z, de forma que podamos escribir
E(t, x, y, z) = u(x, y, z)eiβz−iωt
En estas condiciones, sustituyendo en (4.7) y asumiendo que se puede despreciar el término en
uzz obtenemos:
iuz =
−uxx − uyy + (β 2 − k02 )u
2β
(4.8)
que es la ecuación de Fresnel. Suponemos que conocemos u(x, y, 0) = u 0 (x, y) y queremos
obtener u(x, y, z) en z. Esta ecuación (de tipo parabólico) es un prototipo de problema de
propagación. La siguiente gráfica muestra la resolución de uno de estos problemas (sin considerar propagación en el eje y. Representamos la amplitud en función de x y z (dirección de
propagación).
Otro ejemplo prototipo de este tipo de problemas es, como veremos, la ecuación del calor
Ṫ = κ∆T , donde T (t, x) representa un campo de temperaturas. Se asume que el dato T (0, x) =
T 0 (x) es conocido y se desea obtener T (t, x) para t > 0. Un aspecto importante a tener en cuenta
será, como estudiaremos, los resultados de estabilidad para algunos algoritmos de métodos en
diferencias aplicados a estas EDPs. Este análisis de estabilidad, debido a Von Neumann, nos
permitirá entender el comportamiento numérico de estos algoritmos y nos ayudará en la selección
de aquéllos que resulten más adecuados para el problema a abordar.
7
Cálculo Numérico Avanzado. J. Segura
Tema 1. La importancia de saber resolver ecuaciones diferenciales numéricamente
1.5
Ejemplo 5: ecuación de Schrödinger dependiente del tiempo...
La ecuación de Schrödinger dependiente del tiempo:
∂ψ(x, t)
1 d2
i
= −
+ V (x) ψ(x, t)
∂t
2m dx2
(5.9)
donde utilizamos unidades naturales para no escribir la constante de Planck, es “manejable”
analı́ticamente para casos ideales (potenciales simples y combinación de pocos autoestados de
energı́a), pero en general son necesarios métodos numéricos para estudiar cuantitativamente la
propagación de paquetes de ondas.
Ver [4] para una interesante discusión sobre la resolución de la evolución temporal de un
paquete de ondas. Ver también [6]
1.6
...
1.7
...Ejemplo n:....
J. Javier Segura Sala
8
2
Sistemas de numeración; errores y sus
fuentes
En este tema se introducen los distintos sistemas de numeración y se describe cómo realizar la
conversión entre distintos sistemas, ası́ como el estándar IEEE de representación de números
en el sistema binario. A continuación, se introducen las nociones de error absoluto y relativo
y se analizan las causas más frecuentes de error en un cálculo computacional, ilustrándolo con
ejemplos. Finalmente, se introducen los conceptos de (in)estabilidad y condición.
2.1
Sistemas de números y conversiones
Es necesario conocer como se representan los números enteros y decimales en formato digital para
entender las limitaciones intrı́nsecas que nos encontraremos al programar un algoritmo numérico,
tanto en cuanto a la mayor precisión alcanzable como en cuanto al rango de valores admisibles.
Veremos además cómo un mı́nimo conocimiento del sistema de representación estándar sirve
para evitar la aparición de desastrosos errores de programación (como bucles infinitos).
2.1.1
Sistemas de numeración en base q
El sistema de numeración decimal es el sistema posicional de numeración más utilizado, que
utiliza como base de numeración el 10 (dı́gitos 0...9). Como es bien sabido, se puede utilizar
cualquier número natural mayor que 1 como base de numeración.
Un número en base q se denota como (an an−1 ...a1 a0 .b1 b2 ...bk ...)q donde ai y bj pertenecen al
conjunto de los q dı́gitos elementales. Estos q dı́gitos representarán valores desde 0 hasta q − 1.
La conversión a decimales es, por definición:
(an an−1 ...a1 a0 .b1 b2 ...bk ...)q = an q n + an−1 q n−1 + ... + a1 q + a0 q 0
+b1 q −1 + b2 q −2 + ... + bk q −k + ...
(1.1)
El sistema natural de numeración digital es el binario (base 2), utilizando sólo los dı́gitos 0
y 1.
Ejemplo 2.1
Decimal: (123.25)10 = 1 × 102 + 2 × 101 + 3 × 100 + 2 × 10−1 + 5 × 10−2 .
Binario (base 2) con 2 dı́gitos 0 y 1: 0 + 1 = 1, 1 + 1 = 10.
9
Tema 2. Sistemas de numeración. Errores y sus fuentes.
(1011.01)2 = 1 × 23 + 0 × 22 + 1 × 21 + 1 × 20 + 0 × 2−1 + 1 × 2−2 = 11.25.
Hexadecimal (base 16) tiene 16 dı́gitos: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E y F , que representan los valores desde 0 hasta 15 respectivamente. Por tanto:
(7B.4)15 = 7 × 161 + B × 160 + 4 × 16−1 = 123.25.
Los sistemas de numeración octal y hexadecimal, también son muy utilizados, en parte
debido a que es muy sencilla su conversión a binario con la ventaja de que un mismo número se
representa con menos cifras cuanto mayor es la base.
2.1.2
Conversión de base decimal a base q
Ya sabemos como convertir un número en base q a base decimal (1.1). La conversión de base
decimal a base q se base en el hecho de que, acudiendo a la definición (1.1) observamos que
(eliminamos el subı́ndice 10 para números en base decimal):
(an an−1 ...a1 a0 .b1 b2 ...bk ...)q × q = (an an−1 ...a1 a0 b1 .b2 b3 ...bk ...)q
(an an−1 ...a1 a0 .b1 b2 ...bk ...)q × q −1 = (an an−1 ...a1 .a0 b1 b2 ...bk ...)q
(1.2)
Utilizaremos esto para obtener la conversión de un número en base 10 a base 2. Para esto,
conviene separar la conversión de la parte entera (antes del punto decimal) de la fraccionaria
(después del punto); observemos que un número entero es necesariamente entero en cualquier
base y que un número fraccionario lo es en cualquier base.
Conversión entera
De (1.2) deducimos que:
(an ...a0 )q −1 = (an ...a1 )q + (.a0 )q
es decir, que
(an ...a0 )q = (an ...a1 )q × q + (.a0 )q × q = (an ...a1 )q × q + (a0 )q
(1.3)
que es una identidad entre números, que podemos evaluar en cualquier base, y en particular
en base 10 (obsérvese que de hecho mezclamos base números en distintas bases). Vemos pues
que al dividir un número entero entre q el resto es el dı́gito menos significativo del número en
base q. Dividiendo sucesivamente (hasta llegar al cociente 0) obtenemos los sucesivos dı́gitos del
número en base q.
J. Javier Segura Sala
10
Cálculo Numérico Avanzado
Conversión fraccionaria
A partir de (1.2) vemos que:
(.b1 b2 ...bk )q × q = (b1 )q + (.b2 ...bk )q
Vemos pues que la parte entera del resultado de multiplicar nuestro número por q es el
primer dı́gito tras el punto decimal. Reteniendo la parte fraccionaria que resulta en cada paso
y repitiendo sucesivamente el proceso, vamos obteniendo el resto de cifras tras el punto.
Ejemplo 2.2 Escribamos (26.1)10 en base 2.
1. Parte entera. Dividiendo sucesivamente, tenemos que:
26 = 2 × 13 + 0 ; 13 = 2 × 6 + 1 ; 6 = 2 × 3 + 0 ; 3 = 2 × 1 + 1 ; 1 = 2 × 0 + 1
Leyendo de izquierda a derecha los números subrayados: (26) 10 = (11010)2
2. Parte fraccionaria. Multiplicando sucesivamente por dos y separando la parte fraccionaria:
0.1 × 2 = 0.2 ; 0.2 × 2 = 0.4 ; 0.4 × 2 = 0.8 ; 0.8 × 0.2 = 1.6 ; 0.6 × 2 = 1.2 ; 0.2 × 2 = ...
Leyendo de izquierda a derecha tenemos los dı́gitos de la parte fraccionaria (subrayados)
luego:
(0.1)10 = (0.00011)2
donde las cifras subrayadas son las cifras periódicas.
Obsérvese que el número 0.1 tiene infinitas cifras distintas de cero cuando se escribe en
base 2 (se repiten indefinidamente desde la segunda a la quinta cifra fraccionaria).
Sumando los resultados de la parte entera y la fraccionaria tenemos que
(26.1)10 = (11010.00011)2
En el anterior ejemplo hemos aprendido que un número fraccionario con un número finito de
dı́gitos en cierta base no tiene por qué tener un número finito en otra base. En efecto, (0.1) 10
es un número periódico con infinitas cifras cuando se escribe en base 2. Esto es importante
puesto que en un procesador digital los números se almacenar en binario utilizando un número
finito de cifras. Esto quiere decir que el número 0.1 no se representa exactamente en un ordenador. Esto hay que tenerlo en cuenta para evitar errores que conduzcan a bucles que se repiten
indefinidamente. El siguiente algoritmo en Matlab es un ejemplo de bucle infinito,
Algoritmo 2.3 Bucle infinito en precisión finita binaria:
x=0;
while x∼=10 (Nota: en Matlab esto significa x 6= 0)
x=x+0.1;
end
11
Cálculo Numérico Avanzado. J. Segura
Tema 2. Sistemas de numeración. Errores y sus fuentes.
Esto nos deberı́a prevenir de utilizar bucles que terminan cuando se alcanza cierto valor
concreto de una variable que involucra números no enteros.
Ejercicio 2.4 Si en la tercera lı́nea del anterior algoritmo cambiamos 0.1 por 0.125, ¿seguirı́amos
teniendo un bucle infinito?.
2.1.3
Estándar IEEE de representación de números enteros y en coma flotante
Números enteros
Asumamos, como es común en la mayor parte de los procesadores, que cada palabra tiene una
longitud de 32 bits, es decir, que cada número vendrá representado por 32 dı́gitos binarios. La
forma más sencilla de representar un número entero es asignando uno de los 32 bits para designar
el signo (0 para +, 1 para menos) y utilizando las 31 restantes posiciones para representar los
dı́gitos del módulo del número entero. En consecuencia, el mayor número entero que se puede
representar es 231 − 1.
Éste es el estándar IEEE salvo porque, por lo general, no se suele reservar un bit para el signo,
sino que se utiliza una ordenación distinta para guardar los enteros negativos. Sin embargo, en
la práctica una y otra prescripción son prácticamente equivalentes.
También pueden utilizarse enteros en longitud doble, utilizando dos palabras de 32 bits, con
lo que se aumenta el rango de enteros admisibles.
Números no enteros
Para representar números con parte fraccionaria se utiliza el formato de punto (o coma) flotante.
Esta representación es la correspondiente versión binaria de la conocida notación cientı́fica o
exponencial para los números decimales:
±M × 10E , 1 ≤ M < 10
pero utilizando base 2:
x = ±M × 2E , 1 ≤ M < 2
donde M es la mantisa y E el exponente. Inevitablemente el número de dı́gitos que se pueden
almacenar de la mantisa y exponente es limitado. Hay dos tipos de precisión, la simple y la
doble, que difieren en el número de bits de los que se dispone para almacenar las cifras; la
distribución estándar es:
1. Precisión simple: 32 bits, de los cuales:
(a) uno corresponde al signo,
(b) 8 al exponente, luego −128 ≤ E ≤ 127 (2 × 128 = 2 8 )
(c) 23 a la mantisa
J. Javier Segura Sala
12
Cálculo Numérico Avanzado
2. Precisión doble
(a) uno para el signo
(b) 11 al exponente (−1022 ≤ E ≤ 1023)
(c) 52 para la mantisa
Ejemplo 2.5 Veamos de forma simplificada como se guardarı́a el número 5.5 en precisión
simple. Primero lo pasamos a binario: 5.5 = (101.1) 2 y normalizamos para que la mantisa
1 < M ≤ 2, de forma que 5.5 = (1.011)2 × 22 , que tiene exponente E = 2 (que se guardará en
binario), signo + (bit 0) y mantisa 1.011. Normalmente, salvo para el caso del número cero,
que se almacenan de distinta forma, el número delante del punto será siempre 1, por lo que no
se suele almacenar.
Ejemplo 2.6 El anterior es un ejemplo de un número decimal que se puede guardar de forma
exacta en una palabra de 32 bits. Un ejemplo en el que esto no serı́a ası́ es el ya conocido caso de
0.1 = (0.00011)2 = (1.1001)2 ×2−4 , que necesariamente ha de redondearse antes de almacenarse;
esquemáticamente (sin entrar en detalles de como se almacena el exponente), tendrı́amos, en
precisión simple, la representación (recordemos que el 1 antes del punto decimal no se suele
almacenar)
0|E = −4|10011001100110011001101
donde la 23a cifra tras el punto se ha redondeado a 1 porque la siguiente era 1. De esta forma,
lo que realmente se almacena es:
(1.10011001100110011001101)2 × 24 = 0.10000000149011611938
Esto muestra explı́citamente que, efectivamente, el algoritmo 2.3 es un bucle infinito.
Debemos resaltar que la especificación del número de bits que se utilizan para almacenar
mantisa y exponente es lo único que necesitamos para determinar cuales son los mayores y
menores números que se pueden almacenar en coma flotante ası́ como la máxima precisión que
se puede obtener. Veamos como obtener estos parámetros en el caso de doble precisión (que es
la precisión utilizada por Matlab).
Ejemplo 2.7 Obtener los números de “overflow” y “underflow” ası́ como la precisión máquina
en doble precisión, es decir:
1. Obtener el mayor número entero positivo representable en formato de coma flotante en el
caso de doble precisión (lı́mite de “overflow”)
Puesto que el mayor exponente es 1023, el mayor número representable es (1.1....1) 2 ×
21023 ' 1.8 × 10308 (hay 52 unos detrás del punto “decimal”).
13
Cálculo Numérico Avanzado. J. Segura
Tema 2. Sistemas de numeración. Errores y sus fuentes.
2. Obtener el menor número entero positivo representable en formato de coma flotante en
el caso de doble precisión (lı́mite de “overflow”). El menor decimal representable con 52
dı́gitos significativos binarios es (1.00...01) 2 × 10−1022 ' 2.23 × 10−308 . Sin embargo, el
estándar IEEE admites números más pequeños, aunque tengan menos cifras significativas
(es lo que llaman números sub-normales); estrictamente el número más pequeño representable en coma flotante es: (0.00..01) 2 × 2−1022 = 2−1074 ' 4.94 × 10−324 (52 dı́gitos
tras la coma decimal). Para no perder dı́gitos significativos es mejor moverse en el rango
(1/Nov , Nov ), donde Nov es el número de overflow Nov ' 2.23 × 10−308 .
3. Obtener la diferencia entre 1 y el menor número positivo mayor que 1 en coma flotante
(épsilon-máquina). Obtener asimismo la diferencia entre 1 y el mayor número positivo
menor que 1.
El número que se nos pide es (1.0...01) 2 − (1.0...0)2 = (0.0...01)2 = 2−52 ' 2.2 × 10−16 .
Este número representa el mejor error relativo que se puede manejar en doble precisión
(definimos este conocido concepto a continuación). Este valor de épsilon-maquina significa
que todos los números con 15 cifras significativas se pueden guardar de forma exacta en
doble precisión y que ocurre lo mismo para la mayor parte de los números de 16 cifras.
En cuanto a la diferencia entre 1 y el mayor número positivo menor que 1, esta es:
(1.0..0)2 − (1.1...1)2 × 2−1 = 2−53 ' 1.1 × 10−16
Nota 2.8 Es importante tener en cuenta que Matlab trabaja en doble precisión aunque por
defecto sólo muestre 5 cifras significativas. Para que el sistema muestre más cifras se puede
utilizar el comando “format long”.
Además de los detalles señalados hay otras caracterı́sticas fundamentales del estándar IEEE
que no describiremos como son:
1. Redondeo correcto de la aritmética (volveremos más adelante sobre este punto) 1 .
2. Tratamiento de excepciones. Es decir, que un operación del tipo log(0.0) no da error e
interrumpe la ejecución del programa, sino que se asigna un valor especial para representar
esta excepción (para significar −∞).
3. Compatibilidad entre procesadores. Esta es por supuesto, una de las grandes ventajas de
los estándares.
2.2
Errores y sus causas
El análisis numérico trata de la construcción de métodos discretos para la resolución de problemas continuos. Esta discretización, que se presenta tanto en la representación numérica en
1
Un error en el “hardware” de punto flotante de los Intel Pentium (1994) le dio una considerable mala publicidad
a la compañı́a. El problema fue solventado reemplazando los procesadores defectuosos
J. Javier Segura Sala
14
Cálculo Numérico Avanzado
un ordenador como en los propios algoritmos de cálculo, necesariamente implica la aparición de
errores cuyo origen y propagación debemos estudiar 2 .
2.2.1
Definiciones
Si xA es una aproximación del verdadero valor x T , definimos entonces:
Error absoluto:
Error relativo:
Eabs = |xT − xA |
Erel = |1 −
xA
|, si xT 6= 0.
xT
También se pueden utilizar estas definiciones con signo (es decir, sin el valor absoluto).
El error relativo en ocasiones se expresa también en tanto por ciento. El error relativo mide
el número de cifras significativas exactas de x A . Ası́, si
2Erel < 10−m , m ∈ N
se dirá que xA tiene m cifras significativas exactas.
2.2.2
Fuentes de errores
Las fuentes de error en un cálculo numérico pueden ser de variada naturaleza, algunas de ellas
independientes del método numérico empleado.
1. Un métodos numérico para resolver determinado problema cientı́fico puede dar lugar a
resultados erróneos si el modelo no es una fiel descripción de la realidad.
2. Un algoritmo numérico puede depender de ciertos datos de entrada (por ejemplo, datos
fı́sicos) afectados de cierto error. Se debe vigilar que el método numérico no sea crucialmente dependiente de la exactitud de tales valores de entrada y que la precisión de
estos valores sea suficiente para nuestros propósitos. En el caso en que el propio modelo fı́sico/matemático sea muy sensible a estos parámetros, tendremos un problema mal
condicionado e imposible de resolver numéricamente de forma estable.
3. Los errores de programación son prácticamente inevitables durante la construcción de un
método numérico. Una vez construido un algoritmo numérico que en apariencia funciona
correctamente es necesario certificar su funcionamiento mediante todos los tests que estén
a nuestro alcance.
2
No por ello se debe adoptar la visión reduccionista consistente en definir el análisis numérico como el área de
la matemática que analiza los errores de cálculo
15
Cálculo Numérico Avanzado. J. Segura
Tema 2. Sistemas de numeración. Errores y sus fuentes.
4. Errores en la aritmética de punto flotante: errores de redondeo, pérdida de cifras significativas por cancelaciones, problemas de “underflow/overflow”. Estos son los problemas
derivados de la representación en punto flotante, en la cual se dispone de un número finito
de bits para representar la mantisa y el exponente. Como ya vimos, esto limita tanto la
mejor precisión relativa alcanzable (15-16 dı́gitos decimales en doble precisión) como el
rango de valores disponible.
Aunque la segunda de las limitaciones no suele presentar graves problemas, es necesario
evitar la evaluación de cantidades demasiado grandes o pequeñas.
La limitación de la precisión tiene por lo general mayores consecuencias. Por ejemplo,
cuando se sustraen cantidades muy parecidas, el error relativo empeora drásticamente por
pérdida de cifras significativas.
5. Errores de truncamiento o de discretización, inherentes al hecho de aproximar un problema continuo mediante una aproximación discreta. Por ejemplo, veremos que la regla
trapezoidal sirve para aproximar integrales mediante:
Z
a
b
f (x)dx ≈
N
−1
X
h
b−a
(f (a) + f (b)) + h
f (a + kh) ≡ S(h) , donde h =
, h = (b − 1)/N
2
N
k=1
El significado de “≈” es “aproximadamente”, lo cual significa que
Z
b
f (x)dx = S(h) + (h)
a
donde (h) es el error de truncamiento, que es de esperar que sea menor cuanto menor
sea h (N ∈ N lo mayor posible). Un cálculo explı́cito de los errores de truncamiento es
al menos igual de difı́cil que el cálculo del problema original. Nos conformaremos con un
conocimiento cualitativo de estos errores y con buscar acotaciones lo más finas posible.
Trataremos de estimar los errores de truncamiento en cada algoritmo numérico que se presente.
Discutamos en este punto acerca de los errores debidos a las limitaciones en la representación
de punto flotante, en particular por lo que respecta a la precisión limitada del sistema
Redondeo y pérdida de cifras significativas
Puesto que la representación en coma flotante es limitada en cuanto al número de cifras significativas que se pueden almacenar, los números reales se redondearán a un determinado número
de cifras (siempre utilizando el sistema de numeración binario) cuando el valor verdadero tenga
más cifras de las que se pueden almacenar.
J. Javier Segura Sala
16
Cálculo Numérico Avanzado
Asimismo, tras cada operación aritmética se vuelve a redondear el resultado. En el estándar
IEEE esto se hace de la mejor manera posible en el sentido de que el resultado de la operación
aritmética está redondeado de forma que se almacena el valor más próximo al resultado exacto.
Ası́, por ejemplo, supongamos que, para simplificar, la precisión fuese de tres dı́gitos binarios
tras el punto (y no consideremos limitación en el exponente), si se suman los números en punto
flotante x = (1.010)2 , y = (1.001)2 × 2−4 tenemos que el resultado exacto es (1.0101001) 2 que no
serı́a un número en punto flotante (sólo disponemos de 3 posiciones tras el punto). El resultado
IEEE serı́a redondear la última cifra, aumentándola si la siguiente fuese 1 y dejándola como está
en otro caso. Ası́, x + y se almacenarı́a como (1.011) 2 .
Otra posibilidad (menos recomendable) es, sin más, eliminar las cifras que no quepan (truncamiento). Esta desafortunada prescripción se utilizaba en los supercomputadores Cray, pero
está en total deshuso.
Aún cuando en el estándar IEEE se redondea al número en coma flotante más cercano, que
es la opción más conveniente, es necesario estudiar como pueden afectar sucesivos redondeos al
resultado de un algoritmo numérico.
Por otra parte, la limitación en el número de bits para la mantisa tiene como consecuencia
la posible pérdida de cifras significativas en ciertos cálculos donde dos cantidades tienden a
cancelarse entre sı́ 3 . Para evitar este tipo de errores, es recomendable:
a) O bien reescribir la fórmula en cuestión de modo que se eviten las restas de cantidades de
la misma magnitud.
b) O bien utilizar (cuando sea posible) un desarrollo de Taylor para aproximar la fórmula hasta
la precisión requerida.
Veamos algunos ejemplos en los que se da pérdida de cifras significativas
Ejemplo 2.9 Obtener las raı́ces de x 2 − 106 x + 1.
Enpuna modesta calculadora con 10 decimales y aplicando la archiconocida fórmula x =
−b ± b2 − 4ac , vamos obteniendo los resultados:
2a
p
106 ± 1012 − 4
106 ± 106
x=
'
2
2
que da x = 106 para la mayor raı́z y x = 0 para la menor. Es evidente que hemos perdido todas
las cifras significativas para la menor raı́z. De hecho, la famosa fórmula deberı́a ser desterrada
de cualquier método numérico. Es mucho mejor reescribir la solución de la ecuación de segundo
grado como:
p
x1 = L/2a , x2 = 2c/L , L = −b − signo(b) b2 − 4ac
3
Un famoso y lamentable error de éste tipo fue el que motivó le fallo de los misiles Patriot para derribar
los misiles Skud iraquı́es durante la guerra del golfo: se medı́an intervalos de tiempo restando tiempos desde el
reinicio del sistema con la consiguiente pérdida progresiva de precisión
17
Cálculo Numérico Avanzado. J. Segura
Tema 2. Sistemas de numeración. Errores y sus fuentes.
De esta forma la mayor raı́z es como antes y en la calculadora la menor saldrı́a x = 10 −6 , cuyo
error relativo respecto a la solución verdadera es ∼ 10 −12 .
√
√
Ejemplo 2.10 Consideremos por ejemplo f (x) = ( x + 1 − x) para x > 0.
√ Cuando√x es
grande, se producen errores de redondeo importantes puesto que los valores de x + 1 y x se
aproximan considerablemente. ¿Cómo evitarı́amos esta fuente de error?. Lo que podemos hacer
es reescribir f (x) del siguiente modo:
√
√
√
√
1
x+1+ x
f (x) = ( x + 1 − x) √
√ =√
√ .
x+1+ x
x+1+ x
En la expresión resultante podemos apreciar que no se producen cancelaciones de cantidades
de la misma magnitud.
1 − cos(x)
. Cuando se evalúa g(x) para |x| << 1 se
Ejemplo 2.11 Consideremos g(x) =
x2
produce una pérdida considerable de cifras significativas. En este caso, para remediar el problema
consideramos el desarrollo de Taylor de cos(x) entorno a 0. De este modo:
1 − [1 − x2 /2! + x4 /4! + ...]
1 x2 x4
≈
−
+ .
2
4!
6!
x2
Esta expresión es apropiada entonces para evaluar g(x) cuando x << 1.
g(x) =
Errores de overflow /underflow
Aunque los lı́mites de overflow/underflow son considerablemente generosos, conviene escribir
las expresiones que se utilicen de manera que se minimice esta posibilidad.
Por ejemplo, es
p
2
preferible calcular el módulo de un número complejo, z = x + iy, |z| = x + y 2 , como
p
|z| = |x| 1 + (y/x)2
De esta forma, no hay que elevar al cuadrado números que pueden ser muy grandes. De la
misma forma, hay que tomar precauciones para calcular la argumento de un número complejo
de manera que no se produzcan “overflows/underflows” en el cálculo de y/x.
Ejercicio 2.12 Escribir un programa en Matlab que obtenga la representación polar de un
número complejo dado z = reiθ , 0 ≤ θ < 2π, eliminando el riesgo de problemas de overflowunderflow.
2.3
Propagación de errores: condición y estabilidad.
Un error en un cálculo numérico contamina las sucesivas evaluaciones. Esta propagación del error
puede describirse en términos de dos conceptos relacionados, los de (in)estabilidad y condición.
J. Javier Segura Sala
18
Cálculo Numérico Avanzado
La condición de una función f (x) mide la sensibilidad de los valores de f (x) a pequeños
cambios en x y se define como
Erel (f (x)) C=
Erel (x) donde Erel (f (x)) es el error relativo de f (x) para un error relativo E rel (x) en x.
Entonces, como 4
f (xT ) − f (xA ) ' f 0 (xt )(xT − xA ) → Erel (f (x)) '
f 0 (xT )
(xT − xA )
f (xT )
luego
f 0 (xT ) C ' xT
f (xT ) Utilizaremos esta última expresión como definición de condición para funciones f (x) de una
variable real. Definimos entonces los números de condición como
0 f (x) C(x) = x
f (x) Cuando para un x dado 0 < C(x) < 1 para ese x se dirá que el problema (cálculo de f)
está bien condicionado (y cuanto menor sea C mejor condicionado), mientras que si C(x) > 1
el problema estará mal condicionado. Si C(X) = 1, el error relativo se mantiene.
√
x está bien condicionada, pues C(x) = 1/2, luego el error
2x2 2
En cambio f (x) = x − 1 está mal condicionada para x ' 1 pues C(x) = 2
x − 1
Ejemplo 2.13 La función f (x) =
relativo se reduce.
El concepto de condicionamiento se puede extender a situaciones más generales que la de
una función de una variable continua. Por ejemplo, un problema clásico que involucra funciones
de una variable discreta, es el estudio del condicionamiento de relaciones de recurrencia:
Ejemplo 2.14 Las funciones de Bessel J n (x) satisfacen la relación de recurrencia: J n+1 (x) =
−Jn−1 (x) + 2n
x Jn (x), pero como las funciones de Bessel de segunda especia cumplen la misma
relación y limn→∞ Jn (x)/Yn (x) = 0, el cálculo de las funciones J n a partir de J0 y J1 está mal
condicionado, pues una pequeña perturbación en los datos iniciales J 0 y J1 contamina nuestra
secuencia de funciones {Jn } con la secuencia {Yn }, que crece más rápido con n.
Ası́, por ejemplo, empezando con los valores en precisión simple J 0 (2) = 0.22389078 y
J1 (2) = 0.57672481, y aplicando la recurrencia obtenemos J 8 (2) = 4.00543213 × 10−5 que no
tiene bien ni siquiera un cifra significativa: J 8 (2) = 2.2180 × 10−5 .
4
Recordemos el teorema del valor medio: Si g(x) continua en [a, b] y derivable en (a, b) entonces ∃c ∈ (a, b) :
f (b) − f (a) = f 0 (c)(b − a)
19
Cálculo Numérico Avanzado. J. Segura
Tema 2. Sistemas de numeración. Errores y sus fuentes.
Un concepto relacionado, que no equivalente, es el de (in)estabilidad de un algoritmo, que
describe la sensibilidad de un método numérico especı́fico respecto a los inevitables errores de
redondeo cometidos durante su ejecución en aritmética de precisión finita. Observemos que
la condición no depende de errores de redondeo pero que la estabilidad de un algoritmo sı́
depende del condicionamiento de la función que queramos evaluar. Un ejemplo puede servir
para distinguir estos dos conceptos relacionados:
√
√
Ejemplo 2.15 Dada la función f (x) = x + 1 − x, su número de condición es:
0 f (x) x
= √ √
C(x) = x
f (x)
2 x x+1
y vemos que C(x) < 1/2 para x > 0, luego la función está bien condicionada (su error relativo
es menor que el error relativo en x).
Sin embargo, √
el algorı́tmo para calcular x consistente en ir realizando las operaciones impli√
cadas en f (x) = x + 1 − x, a saber:
1. Input: x
2. y = x + 1
√
3. f1 = x + 1
√
4. f2 = x
5. f = f1 − f2
es inestable para x grande por culpa del paso 5 (hay cancelaciones entre números similares).
Como sabemos, un algoritmo estable lo proporciona la siguiente reescritura de la función:
1
f (x) = √
√
x+1+ x
2.4
Eficiencia de un algorı́tmo numérico
Por supuesto, cualquier algoritmo numérico sensato debe evitar ser inestable. Por otra parte,
si existieran varios métodos para evaluar una misma función, entonces convendrá adoptar aquel
método que sea más eficiente, es decir, más rápido. Con la mejora en proporción geométrica de
la velocidad de los procesadores, podrı́amos estar tentados en despreocuparnos por la rapidez
de cálculo. Esta es, sin embargo, una pésima filosofı́a: se trata de aprovechar los recursos para
poder resolver problemas más complejos y no para resolver peor problemas simples. La eficiencia
es y siempre será de importancia capital en el desarrollo de buenos métodos numéricos.
La diferencia en tiempos de ejecución pueden llegar a ser muy considerables si ciertas operaciones elementales, que se pueden repetir miles y miles de veces, no se realizan con cuidado.
J. Javier Segura Sala
20
Cálculo Numérico Avanzado
Por ejemplo, para calcular x4 para cierto valor de x, es muy mala idea calcular x 4.0 (exponente
en coma flotante); hay que tener cuidado en utilizar un exponente entero ya que los métododos
de exponenciación en coma flotante son distintos que los de enteros y mucho más lentos; aún es
mejor idea considerar el cálculo en dos pasos: x 2 = x ∗ x, x4 = x2 ∗ x2 , con lo que se economizar
un producto frente a x4 = x ∗ x ∗ x ∗ x.
2.4.1
Ejemplo: Evaluación de polinomios, método de Horner
Otro ejemplo notable (y por desgracia no suficientemente) conocido es la evaluación de polinomios. Por ejemplo, supongamos que nos planteamos evaluar el polinomio
P (x) = 2 + 4x − 5x2 + 2x3 − 6x4 + 8x5 + 10x6
Contando con que cada potencia de exponente k entero cuente como k −1 productos, tendrı́amos
que el número total de productos para evaluar el polinomio de forma directa es:
1 + 2 + 3 + 4 + 5 + 6 = 21
y el número de sumas es 6.
Una forma mejor de proceder es ir calculando primero las potencias de forma sucesiva:
x2 = x x , x 3 = x x 2 , x 4 = x x 3 , x 5 = x x 4 , x 6 = x x 5
con lo que sólo se añade una nueva multiplicación por potencia, par un total de
1 + 2 + 2 + 2 + 2 + 2 = 11
Pero aún se puede hacer mejor reescribiendo
P (x) = 2 + x(4 + x(−5 + x(2 + x(−6 + x(8 + x10)))))
con lo que sólo necesitamos 6 multiplicaciones (y el número de sumas no cambia). Vemos pues
que para evaluar un polinomio de grado n en el que ninguno de los coeficientes es cero, se
necesitan n(n + 1)/2 multiplicaciones por el primer método, 2n − 1 por el segundo y n para el
tercero. De forma que se debe procurar utilizar el último método, particularmente cuando n es
grande.
Este método es además sencillo de programa, en efecto:
Algoritmo 2.16 (Algoritmo de Horner o de división sintética)
21
Cálculo Numérico Avanzado. J. Segura
Tema 2. Sistemas de numeración. Errores y sus fuentes.
Algoritmo de Horner
Dado el polinomio
P (x) = a0 + a1 x + ... + an xn , an 6= 0
la evaluación de P (x) para cierto valor x = z se puede realizar en n pasos
mediante
(1) bn = an
(2) bn−1 = an−1 + z ∗ bn
(3) bn−2 = an−2 + z ∗ bn−1
...
(n) b0 = a0 + z ∗ b1
donde P (z) = b0 .
Es fácil programa este algoritmo en forma de bucle, sobretodo si no nos interesan los cálculos
intermedios. Ası́, se puede escribir:
(1) b = an
(2) Repetir mientras n > 0
(3) n = n − 1
(4) b = an + z ∗ b
(5) Volver a (2)
(6) p(z) = b.
Esta forma de evaluar polinomios es mucho mejor que el método directo, especialmente para
órdenes grandes. Dependiendo del órden de un polinomio y las veces que se repita el cálculo,
será importante aplicar el método de Horner.
J. Javier Segura Sala
22
Bibliography
[1] Atkinson, K., Elementary Numerical Analysis (2nd. Ed), John Wiley & Sons, 1993.
[2] Acton, F. S., Numerical Methods that work, Washington: The Mathematical Association of
America, 1990.
[3] Conte, S. D., de Boor, C., Elementary Numerical Analysis (An Algorithmic Approach),
McGraw-Hill, 1981.
[4] Koonin, S.E., D.C. Meredith, Computational Physics ( Fortran version), Addison-Wesley,
1990.
[5] Press, W. H., S.A: Teukolsky, W.T. Vetterling y B.P. Flannery, Numerical recipes in Fortran
77, Cambridge University Press, 1992.
[6] Segura, J., Fernández de Córdoba, P. Estudio numérico de la evolución de un paquete de
ondas en mecánica cuántica. Revista Española de Fı́sica 7 (1993) 57–61.
23
Descargar