Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Análisis Numérico
de
Ecuaciones Diferenciales
usando MATLAB
2
Índice general
Notaciones 5
Introducción 6
1. Introducción a MATLAB. 11
1.1. Vectores en MATLAB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.2. Matrices en MATLAB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
1.3. Funciones de vectores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
1.4. Bucles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
1.4.1. Relaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
1.5. La instrucción if . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
1.6. Ficheros ejecutables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
1.7. Subrutinas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
1.8. Cadenas de texto, mensajes de error, entradas . . . . . . . . . . . . . . . . 33
1.9. Comparando la eficiencia de algoritmos: cputime . . . . . . . . . . . . . . . 34
1.10. Formatos de salida . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
1.11. Gráficos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
1.11.1. Representaciones en 2D . . . . . . . . . . . . . . . . . . . . . . . . 35
1.11.2. Representaciones en 3D . . . . . . . . . . . . . . . . . . . . . . . . 37
1.12. Resumen de funciones elementales y matrices especiales . . . . . . . . . . . 39
3
4
NOTACIONES
Notaciones generales
Sı́mbolo Significado
x = (x1 , x2 , ..., xN ) Elemento de IRN
r = |x|= (x21 + x22 + ...+ x2N )1/2 Módulo de x
∂u ∂u ∂u
∇u = ∂x ,
1 ∂x2
, ..., ∂x N
Gradiente de u
Espacios de funciones
Sı́mbolo Significado
C(Ω) Funciones continuas en Ω
C0 (Ω) Funciones continuas en Ω con soporte compacto
C k (Ω) Funciones de clase k en Ω
C0k (Ω) Funciones de C k (Ω) con soporte compacto
C ∞ (Ω) Funciones indefinidamente diferenciables en Ω
C0∞ (Ω) = D(Ω) Funciones de C ∞ (Ω) con soporte compacto
6
Introducción
7
8
Parte I
9
Capı́tulo 1
Introducción a MATLAB.
Vamos a optar por MATLAB para programar los algoritmos que aparecen asociados
a los distintos métodos numéricos que estudiaremos a lo largo del curso. La razón de ello
es que, para propósitos docentes, existen ventajas en la utilización de este software de
cálculo matemático respecto a lenguajes de programación como C o Fortran: por un lado,
la sintaxis de programación de MATLAB es bastante similar a la de cualquier lenguaje
de alto nivel, lo que nos permitirá adaptarnos a las peculiaridades de su programación
sin demasiados problemas; por otro lado, podremos utilizar como test de nuestros propios
algoritmos las rutinas especı́ficas que incorpora MATLAB; por último, la integración
de una serie de paquetes gráficos en el entorno de programación de MATLAB facilita
extraordinariamente la tarea de presentación de resultados.
Los ejemplos que se incluyen en las secciones siguientes se han obtenido con la versión
6.0 (R12) de MATLAB. Al tratarse de ejercicios sencillos, no es esperable diferencias
significativas cuando se reproduzcan en versiones posteriores de MATLAB.
La aritmética de trabajo en MATLAB es doble precisión (concepto que aclararemos
posteriormente) aunque la versión 7.0 ha introducido la posibilidad de trabajar con arit-
mética entera y real de precisión simple.
Una vez hemos accedido a MATLAB y estando situados en la ventana de coman-
dos, comenzamos nuestro recorrido introductorio. En el texto que sigue a continuación,
cualquier lı́nea que comienza con dos signos >> se utiliza para denotar una lı́nea de
comando MATLAB.
11
12
>> 0:2:8
ans =
0 2 4 6 8
>> ans’
ans =
0
2
4
6
8
Para guardar los vectores creados de modo que seamos capaces de trabajar con ellos
posteriormente, debemos darles nombre. Por ejemplo, para crear el vector fila v, tecleamos:
>> v = [0:2:8]
v =
0 2 4 6 8
13
>> v
v =
0 2 4 6 8
>> v;
>> v’
ans =
0
2
4
6
8
Podemos darnos cuenta a partir del ejemplo anterior que si finalizamos una lı́nea con
un punto y coma no se muestra el resultado. MATLAB permite también trabajar con
elementos especı́ficos del vector:
>> v(1:3)
ans =
0 2 4
>> v(1:2:4)
ans =
0 4
>> v(1:2:4)’
ans =
14
0
4
Una vez especificada la notación podemos realizar diversas operaciones. Por ejemplo:
>> v(1:3)-v(2:4)
ans =
-2 -2 -2
>> A = [ 1 2 3; 3 4 5; 6 7 8]
A =
1 2 3
3 4 5
6 7 8
B =
1 2 3
15
2 4 5
3 7 8
>> whos
Name Size Elements Bytes Density Complex
A 3 by 3 9 72 Full No
B 3 by 3 9 72 Full No
ans 1 by 3 3 24 Full No
v 1 by 5 5 40 Full No
Volviendo a las matrices y a la hora de realizar operaciones básicas con las mismas, la
notación que utiliza MATLAB es la usual en álgebra lineal. Obviamente, las operaciones
matriciales deben ser legales si no queremos tener problemas:
>> v = [0:2:8]
v =
0 2 4 6 8
>> A*v(1:3)
??? Error using ==> * Inner matrix dimensions must agree.
>> A*v(1:3)’
ans =
16
16
28
46
Podemos trabajar con diferentes partes de una matriz, al igual que vimos que se podı́a
hacer con vectores. De nuevo, debemos tener cuidado en hacer operaciones permitidas:
>> A(1:2,3:4)
??? Index exceeds matrix dimensions.
>> A(1:2,2:3)
ans =
2 3
4 5
>> A(1:2,2:3)’
ans =
2 4
3 5
>> inv(A)
ans =
17
1.0e+15 *
Conviene hacer notar, en este punto, que MATLAB distingue entre mayúsculas y
minúsculas. Esta es otra potencial fuente de problemas cuando trabajamos con algoritmos
complicados:
>> inv(a)
??? Undefined function or variable a.
Otra posible operación es, por ejemplo, la obtención de los valores propios aproxima-
dos de una matriz. Hay dos versiones de esta rutina: una encuentra los valores propios y
la otra encuentra los valores y vectores propios. Si no recordamos cuál es cuál, podemos
obtener más información tecleando eig en la lı́nea de comandos.
>> eig(A)
ans =
14.0664
-1.0664
0.0000
v =
e =
14.0664 0 0
0 -1.0664 0
0 0 0.0000
>> diag(e)
ans =
14.0664
-1.0664
0.0000
Existen también rutinas que permiten encontrar soluciones de ecuaciones. Por ejem-
plo, si Ax = b y queremos encontrar x, un modo “lento” de hacerlo es, simplemente,
invertir A y realizar una multiplicación por la izquierda sobre ambos lados de la ecuación.
Obviamente, hay métodos más eficientes y más estables para hacer esto (descomposiciones
L/U con pivotes, por ejemplo). MATLAB tiene comandos especiales para hacer esto.
MATLAB posee además dos tipos diferentes de operadores / y \. La acción del primer
operador es la siguiente: x = A\v ≡ A−1 v; la acción del segundo operador es: x = v/B ≡
vB −1 . Se dan ejemplos de su uso a continuación:
>> v = [1 3 5]’
v =
1
3
5
>> x = A\v
x =
1.0e+15 *
1.8014
-3.6029
1.8014
>> x = B\v
x =
2
1
-1
>> B*x
ans =
1
3
5
>> x1 = v’/B
x1 =
>> x1*B
20
ans =
Finalmente, si queremos borrar todos los datos del sistema y comenzar de nuevo uti-
lizaremos el comando clear. Conviene utilizar este comando con cuidado porque MATLAB
no pide una segunda opinión ...
>> clear
>> whos
>> v = [1 2 3]’
v =
1
2
3
>> b = [2 4 6]’
b =
2
21
4
6
>> v+b
ans =
3
6
9
>> v-b
ans =
-1
-2
-3
>> v*b
Error using ==> * Inner matrix dimensions must agree.
>> v*b’
ans =
2 4 6
4 8 12
6 12 18
>> v’*b
ans =
22
28
Hay ocasiones en las que queremos realizar una operación sobre cada elemento de un
vector o matriz. MATLAB permite hacer este tipo de operaciones. Por ejemplo, supon-
gamos que queremos multiplicar cada componente de un vector v por la correspondiente
componente del vector b. En otras palabras, Supongamos que queremos hallar v(1)*b(1),
v(2)*b(2) y v(3)*b(3). Estarı́a bien utilizar el sı́mbolo * puesto que estamos haciendo un
tipo de multiplicación. Sin embargo, como este sı́mbolo ha sido definido con otra función,
debemos recurrir a otra cosa. Los programadores ocupados del desarrollo de MATLAB
decidieron entonces utilizar los sı́mbolos .* para hacer esta operación. De hecho, se puede
emplear este sı́mbolo antes de cualquier sı́mbolo matemático para especificar a MATLAB
que la operación en cuestión debe tener lugar sobre cada entrada del vector.
>> v.*b
ans =
2
8
18
>> v./b
ans =
0.5000
0.5000
0.5000
>> sin(v)
23
ans =
0.8415
0.9093
0.1411
>> log(v)
ans =
0
0.6931
1.0986
>> x = [0:0.1:100]
x =
Columns 1 through 7
(stuff deleted)
>> y = sin(x).*x./(1+cos(x));
>> plot(x,y)
>> plot(x,y,’rx’)
obtenemos la misma gráfica pero las lı́neas son reempladas por puntos rojos en forma de
x. Para ver más opciones del commando plot, podemos teclear
El comando help es, sin duda, el camino más corto para estar seguro de la sintaxis de un
determinado comando de MATLAB.
La notación compacta permitirá realizar un gran número de operaciones utilizando
pocos comandos. Veamos el siguiente ejemplo:
ans 3 by 1 3 24 Full No
b 3 by 1 3 24 Full No
coef 1 by 1001 1001 8008 Full No
v 3 by 1 3 24 Full No
x 1 by 1001 1001 8008 Full No
y 1 by 1000 1000 8000 Full No
ans =
0.0500
25
>> y = (y(2:1000)-y(1:999))./(x(3:1001)-x(1:999));
>> coef(3) = y(1);
>>
>>
1.4. Bucles
En esta sección veremos cómo utilizar los bucles for y while. En primer lugar, dis-
cutiremos el uso del bucle for con ejemplos para operaciones fila sobre matrices. A con-
tinuación, mostraremos el uso del bucle while.
El bucle for permite repetir ciertos comandos. Todas las estructuras de bucles en
MATLAB comienzan con una palabra clave (como for o while) y terminan con un end
(parece sencillo, ¿no?). Veamos un ejemplo trivial:
j =
j =
j =
26
j =
>>
Otro ejemplo:
>> v = [1:3:10]
v =
1 4 7 10
v =
1 2 3 4
Éste es un ejemplo simple y una demostración bonita de cómo funcionan los bucles
for. Sin embargo, no se debe utilizar en la práctica: la notación utilizada en la primera
lı́nea es mucho más rápida que el bucle. Un mejor ejemplo se presenta a continuación,
donde realizamos operaciones sobre las filas de una matriz. Si queremos comenzar en
la segunda fila de una matriz y restar la fila previa y repetir esta operación sobre las
siguientes filas, un bucle for puede ocuparse de esto:
A =
27
1 3 2
2 2 1
3 1 3
>> B = A;
>> for j=2:3,
A(j,:) = A(j,:) - A(j-1,:)
end
A =
1 3 2
1 -1 -1
3 1 3
A =
1 3 2
1 -1 -1
2 2 4
B =
1 3 2
0 -4 -3
3 1 3
28
B =
1 3 2
0 -4 -3
0 -8 -3
B =
1 3 2
0 -4 -3
0 0 3
Las operaciones se repetirán mientras que las condiciones sean ciertas. Por ejemplo,
dado un número a, el siguiente bloque permite calcular y mostrar el entero no negativo
más pequeño tal que 2n ≥ a:
>> n=0;
>> while 2^n < a
n=n+1;
end
>> n
1.4.1. Relaciones
Los operadores de relación en MATLAB son:
29
& y
| o
∼ no
1.5. La instrucción if
La forma general de una instrucción if simple es:
>> if (condiciones)
(operaciones)
end
Las operaciones se realizarán únicamente si se cumplen las condiciones especificadas.
Se admiten las ramificaciones múltiples como puede verse en el siguiente ejemplo:
>> if n <0
a=1;
elseif n<5
a=2;
else
a=3;
end
Si una tarea MATLAB la vamos a ejecutar muchas veces, es buena idea escribir un fichero
con estos comandos para poder ejecutarlos tantas veces como queramos.
La edición del fichero ejecutable la realizamos con un editor cualquiera. Si nos resulta
más cómodo, podemos utilizar el editor que incorpora MATLAB y al que invocaremos
desde la lı́nea de comandos como:
>>edit
Los ficheros ejecutables de MATLAB (llamados ficheros M) deben tener como exten-
sión “.m”. En el ejemplo que damos a continuación, crearemos un programa que calcula
el factorial de 6:
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Este es un programa no muy util,
%que calcula el factorial de 6
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
n=6; fac=1; for i=2:n
fac=fac*i;
end fac
Si guardamos esto en el fichero fac.m en el directorio de trabajo (o cualquier otro
incluido en el “path”) y tecleamos el comando fac, obtenemos
>> fac
fac =
720
Las lineas tras el sı́mbolo “ %” son lı́neas de comentario, que se conviene utilizar como
explicación del programa. El comando help sirve para mostrar esas lı́neas:
>> help fac
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Este es un programa no muy util,
que calcula el factorial de 6
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
31
En efecto, este no es un programa muy útil, en primer lugar porque el propio MAT-
LAB tiene su comando para calcular el factorial de números enteros:
)) factorial(6)
ans =
720
y en segundo lugar porque nuestro programa sólo calcula el factorial de 6. Para poder
calcular el factorial para distintos números deberemos crea una subrutina o función MAT-
LAB.
1.7. Subrutinas
Si ahora escribimos en un fichero con nombre facf.m los siguientes comandos
habremos definido una función que podemos utilizar tal como lo hacemos con los comandos
intrı́nsecos de MATLAB. Por ejemplo, tecleando en la linea de comandos facf(6) tenemos:
>> facf(6)
ans =
720
Las funciones pueden tener varios parámetros de entrada y/o salida. Por ejemplo,
la siguiente es una función que, dados dos vectores con la misma longitud, devuelve dos
valores (es decir, la subrutina implementa una función f : Rn × Rn → R2 ).
32
>> x=1:1:5
x =
1 2 3 4 5
>> y=0:0.1:0.4
y =
>> [f1,f2]=funci(x,y);
>> f1
f1 =
-0.7568
>> f2
f2 =
-41.6241
>> [a,b]=funci(1:1:5,0:1:4);
>> [a,b]=funci(1:1:5,0:1:5);
??? Error using ==> * Inner matrix dimensions must agree.
Importante:
function [output1,output2,...]=nombre(input1,input2,...)
Por supuesto, las funciones ası́ definidas pueden ser utilizadas tantas veces como sea
necesario dentro de otras funciones y programas.
Una norma muy conveniente que conviene seguir es será escribir todos los progra-
mas en ficheros de texto (utilizando un editor simple) y procurar que estos sean lo más
estructurados posibles, utilizando subrutinas (funciones) para implementar tareas inde-
pendientes. Se trata de programar de la forma más modular y estructurada posible.
puesto que cuando se utiliza en un fichero “.m”, interrumpe la ejecución del mismo.
Podemos, asimismo, en un fichero “.m” pedir que un usuario introduzca datos de
forma interactiva utilizando la función input. Cuando, por ejemplo, durante la ejecución
de un programa aparece la lı́nea
f ormat short Punto fijo y 4 decimales (es el que hay por defecto)
f ormat long Punto fijo y 14 decimales
f ormat short e notación cientı́fica con 4 decimales
f ormat long e notación cientı́fica con 14 decimales
35
1.11. Gráficos
Aunque ya hemos mencionado anteriormente la utilización del comando plot, vamos
a dar en esta sección algún detalle adicional sobre las posibilidades gráficas de MATLAB.
MATLAB permite generar representaciones gráficas de curvas en 2D y 3D. Los co-
mandos básicos con los que nos manejaremos serán plot, plot3, mesh y surf.
1.11.1. Representaciones en 2D
El comando plot crea gráficos de curvas en el plano x-y; si x e y son vectores de la
misma longitud, el comando plot(x,y) abre una ventana gráfica y dibuja en el plano x-y
los elementos de x versus los elementos de y. Podemos, por ejemplo, dibujar el gráfico de
la función seno en el intervalo -4 a 4 con los siguientes comandos:
Entonces el comando
fplot(’expcu’,[-1.5,1.5])
title(’Hola caracola’)
axis([xmin,xmax,ymin,ymax])
dibuja una lı́nea discontinua y punteada, respectivamente, para los dos primeros gráficos
mientras que el tercer gráfico se muestra con el sı́mbolo “+”. Los tipos de lı́nea y marca
son:
Tipos de lı́nea: sólida (-), discontinua (–), punteada (:), discontinua y punteada (-.)
Tipos de marca: punto (.), mas (+), estrella (*), cı́rculo (o), x (x)
Se pueden especificar colores para los distintos tipos de lı́nea y marca:
Colores: amarillo (y), magenta (m), rojo (r), verde (g), azul (b), blanco (w), negro
(k)
El comando subplot puede utilizarse para hacer una partición de la terminal gráfica,
de modo que pueden situarse varios subgráficos en una misma figura.
1.11.2. Representaciones en 3D
Gráficos de lı́nea
El comando plot3 en 3 dimensiones es el análogo al comando plot en 2 dimensiones:
produce curvas en el espacio tridimensional. Si x, y y z son vectores del mismo tamaño,
entonces el comando plot3(x,y,z) producirá un gráfico de perspectiva de la curva en el
espacio tridimensional que pasa por los puntos especificados por x, y y z. Estos vectores
suelen estar definidos de forma paramétrica. Por ejemplo,
proporciona una hélice que está comprimida cerca del plano x-y.
mesh(eye(10))
surf(eye(10))
[x,y]=meshgrid(xx,yy);
Una vez hecho esto, obtenemos la matriz z haciendo actuar f sobre las matrices x
e y. La representación de la matriz z se puede hacer acudiendo a los comandos mesh y
surf.
Veamos un ejemplo:
2 2
Vamos a dibujar el gráfico de z = e−x −y sobre el cuadrado [−2, 2] × [−2, 2] del
siguiente modo:
Las caracterı́sticas del comando axis introducido previamente son aplicables también
a los gráficos tridimensionales, ası́ como lo son las de los comandos para tı́tulos, etiquetado
de ejes y el comando hold.
El color de las superficies se ajusta utilizando el comando shading. Hay 3 opciones
para este comando: faceted (el que está por defecto), interpolated y flat. Se accede a
estas opciones tecleando:
hsv (por defecto), hot, cool, jet, pink, copper, flag, gray, bone
Introducción a la construcción de
algoritmos
41
Capı́tulo 2
43
44
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 1 . 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 × q = (an an−1 ...a1 a0 b1 .b2 b3 ...bk ...)q
(2.2)
(an an−1 ...a1 a0 .b1 b2 ...bk ...)q × q −1 = (an an−1 ...a1 .a0 b1 b2 ...bk ...)q
1
Vamos a utilizar el punto decimal (.) en lugar de la coma decimal (′ ) para ser consistentes con los
ejemplos MATLAB.
45
Conversión entera
De (2.2) deducimos que:
que es una identidad entre números, que podemos evaluar en cualquier base, y en par-
ticular 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.
Conversión fraccionaria
A partir de (2.2) vemos que:
26 = 2 × 13 + 0 ; 13 = 2 × 6 + 1 ; 6 = 2 × 3 + 0 ; 3 = 2 × 1 + 1 ; 1 = 2 × 0 + 1
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 = ...
(26.1)10 = (11010.00011)2
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.2. Si en la tercera lı́nea del anterior algoritmo cambiamos 0.1 por 0.125,
¿seguirı́amos teniendo un bucle infinito?.
47
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:
2. Precisión doble
Ejemplo 2.1.3. Veamos de forma simplificada como se guardarı́a el número 5.5 en pre-
cisió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.
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
Debemos resaltar que la especificación del número de bits que se utilizan para al-
macenar 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.1.5. Obtener los números de “overflow” y “underflow” ası́ como la precisión
máquina en doble precisión, es decir:
49
Nota 2.3. Es importante tener en cuenta que MATLAB trabaja en doble precisión2
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:
3. Compatibilidad entre procesadores. Esta es por supuesto, una de las grandes ven-
tajas de los estándares.
2.2.1. Definiciones
Si xA es una aproximación del verdadero valor xT , definimos entonces:
xA
Error relativo: Erel = |1 − |, 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.
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.
4
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
51
b N −1
h b−a
Z X
f (x)dx ≈ (f (a)+f (b))+h f (a+kh) ≡ S(h) , donde h = , h = (b−1)/N
a 2 k=1
N
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.
tienden a cancelarse entre sı́ 5 . 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.
1 − cos(x)
Ejemplo 2.2.3. Consideremos g(x) = . Cuando se evalúa g(x) para |x| << 1
x2
se 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:
6
Entonces, como
f ′ (xT )
f (xT ) − f (xA ) ≃ f ′ (xt )(xT − xA ) → Erel (f (x)) ≃ (xT − xA )
f (xT )
luego
f ′ (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
′
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.
√
Ejemplo 2.3.1. La función f (x) = x está bien condicionada, pues C(x) = 1/2, luego
el error relativo se reduce.
2
En cambio f (x) = x2 − 1 está mal condicionada para x ≃ 1 pues C(x) = 22x
x −1
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:
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
implicadas 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 simi-
lares). Como sabemos, un algoritmo estable lo proporciona la siguiente reescritura de la
función:
1
f (x) = √ √
x+1+ x
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. Por ejemplo, para calcular x4 para cierto valor de x, es muy mala idea calcular
x4.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: x2 = x ∗ x,
x4 = x2 ∗ x2 , con lo que se economizar un producto frente a x4 = x ∗ x ∗ x ∗ x.
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 , x4 = x x 3 , x5 = x x 4 , x6 = 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) = a0 + a1 x + ... + an xn , an 6= 0
(1) bn = an
(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
(3) n = n − 1
(4) b = an + z ∗ b
(6) p(z) = b.
59
Esta forma de evaluar polinomios es mucho mejor que el método directo, especial-
mente 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.
60
>> a=1+2^(-53);b=a-1
y comparando con
>> a=1+2^(-52);b=a-1
x1 = L/2a , x2 = 2c/L
√
donde L = −b − signo(b) b2 − 4ac.
La sintaxis de la llamada a la funciones ha de ser
>> [x1,x2]=buena(a,b,c);
5. Escribir una rutina que implemente el algoritmo de Horner (horn.m) para la eval-
uación de polinomios. La sintaxis de llamada a la rutina habrá de ser:
>> p=horn(coefs,x);
donde p es el valor del polinomio, coefs es un vector con los coeficientes del poli-
nomio, de mayor a menor grado y x es el valor de la variable independiente. Es decir
que si, por ejemplo, hacemos: