You are on page 1of 280

Matlab en cinco lecciones de Numérico

Vı́ctor Domı́nguez Báguena Ma Luisa Rapún Banzo

Febrero de 2006

Disponible en
http://www.unavarra.es/personal/victor dominguez/
Prefacio
Bo
El origen de este libro es una asignatura de libre elección que uno de los autores im-
partió durante los cursos 2004–2005 y 2005–2006 en la Universidad Pública de Navarra.
Nuestra intención original era tratar temas algo avanzados de Cálculo Cientı́fico y utilizar
Matlab como vı́a para su aprendizaje. Los alumnos, obviamente, estaban más interesados
en aprender Matlab y veı́an el Numérico como forma de probar y ensayar las diferentes
herramientas de Matlab que se iban exponiendo en clase. Desafortunadamente, la forma-
ción en Numérico de nuestros alumnos nos obligó a relajar considerablemente el contenido
matemático del curso y a ser más modestos, desde el punto de vista teórico, en nuestros
rra
objetivos. El resultado final en su vertiente matemática se podrı́a enmarcar sin problemas
en un curso introductorio de Cálculo Numérico. En cuanto a Matlab, creemos que hemos
tratado todos sus aspectos fundamentales aunque en ocasiones sea de forma superficial.
Nuestro objetivo era conseguir no tanto un conocimiento muy profundo de Matlab como
el de colocar al alumno en una buena posición de arranque para un autoaprendizaje.
El enfoque y los temas tratados son consecuencia de diversos factores entre los que
conviene citar nuestro propio bagaje matemático1 , el uso que hemos tenido que hacer de
Matlab en nuestra carrera investigadora y, como ya hemos mencionado, los conocimientos
de partida que tenı́an nuestros propios alumnos. Hemos insistido bastante en la manip-
ulación de vectores y matrices y a la programación en forma vectorizada. Ésta es una
de las diferencias más acusadas con los lenguajes de programación tradicionales y una
implementación eficiente en Matlab pasa necesariamente por la vectorización.
Los apuntes están organizados en torno a temas o lecciones, cada cual dividido en dos
do
partes, la primera de Matlab y la segunda con un tema especı́fico de Cálculo Numérico.
En la primera parte se presentan los aspectos instrumentales de Matlab que utilizaremos
en la implementación de los algoritmos de la parte de Numérico. La longitud de cada
parte es variable, y dependiente de la dificultad tratada ya sea en la parte instrumental
(Matlab) o en la parte matemática. De tanto en tanto nos hemos permitido hacer algo de
Matemáticas tratando de presentarlas en la forma más simple posible.
A lo largo de estas páginas el lector podrá encontrar ejercicios, algunos de ellos resuel-
tos, que tratan de ahondar en puntos especı́ficos, matemáticos e informáticos. Finalmente
se han introducido algunas notas históricas que describen brevemente la evolución que han
r
tenido las ideas a lo largo del tiempo. Con ello tratamos de combatir la idea gaussiana,
demasiado extendida, de las Matemáticas como un mundo estático, monolı́tico y perfecto
donde la teorı́a se presenta cerrada y completa. Las Matemáticas en general y el Cálculo
Cientı́fico en particular recorren un largo trecho antes de llegar a este estado, durante
el cual brotan ideas constantemente, siempre prometedoras en un primer momento, que
1
modelado por nuestra formación cientı́fica, común en muchos aspectos.

i
evolucionan con los años, con muchas de ellas desechadas finalmente e incluso algunas
rescatadas años después de considerarse como vı́as muertas.
Hemos adjuntado al final una bibliografı́a utilizada en este texto. Nos gustarı́a resaltar
tres textos sobre los demás. En primer lugar, Numerical Computing with Matlab, de Cleve
Moler, que descubrimos cuando andábamos en la redacción de la Lección II. Su sencillez
y la buena elección de ejemplos ha ejercido una influencia considerable en estas notas.
Bo
El segundo libro es ya un clásico entre los que aprendimos Matlab hace algunos años.
Andábamos entonces en la búsqueda de recursos en la web cuando nos encontramos con
unos apuntes muy completos de libre divulgación. Nos referimos al libro de Garcı́a de
Jalón y sus colaboradores, Aprenda Matlab ?.? como si estuviera en primero. Diferentes
versiones de estos apuntes llevan cubriendo de forma incansable la evolución de Matlab
desde la versión 4.0.
Por último, aunque no es un texto propiamente, la enciclopedia libre on line Wikipedia2
ha sido utilizada profusamente para obtener datos y fuentes utilizadas en la redacción de
este texto. Debemos señalar que estas informaciones han sido debidamente contrastadas.
A pesar de algunos problemas iniciales, es seguro que la influencia de esta enciclopedia
libre crecerá exponencialmente en el futuro.
Finalmente, queremos dejar patente nuestro agradecimiento al Profesor Javier Sayas
rra
que se ofreció muy generosamente a revisar este libro. Sus numerosas y acertadas indica-
ciones y sugerencias han contribuido, y mucho, en la redacción final de este texto.
do
Pamplona, Febrero de 2006 Vı́ctor Domı́nguez Báguena
Ma Luisa Rapún Banzo
r
2
http://www.wikipedia.org

ii
Bo
A Javier
Amigo y maestro.
rra
do
r
r
do
rra
Bo
Capı́tulo 1
Bo
Introducción
... and the first lesson of all was the basic trust that he
could learn. It is shocking to find how many people do
not believe they can learn, and how many more believe
learning to be difficult.
rra
Dune
Frank Herbert

1.1. ¿Qué es?


Matlab es un entorno de trabajo para el cálculo cientı́fico. Programado originalmente
por Cleve Moler a finales de los años 70, su finalidad original era proporcionar una forma
sencilla de acceder a las librerı́as LINPACK y EISPACK donde están implementadas de una
forma altamente eficiente los algoritmos clave del análisis matricial1 . De hecho, Matlab es
una abreviatura de Matrix Laboratory
Su primera implementación se hizo en Fortran que era, y en buena medida aún sigue
siéndolo, el lenguaje estándar en la implementación de métodos numéricos2 . Posterior-
do
mente se reimplementó en C, que es como se encuentra en la actualidad.
Las aplicaciones de Matlab se fueron extendiendo a otras ramas del cálculo cientı́fico
y de las ciencias aplicadas en general, dotándole de una gran popularidad en ambientes
cientı́ficos (especialmente en Ingenierı́a). Dichas extensiones se consiguieron en gran parte
mediante la implementación de toolboxes, librerı́as escritas en el lenguaje de programación
propio de Matlab y que ampliaban el rango de problemas que podı́an resolverse.
Sin miedo a equivocarse, se pueden enunciar las siguientes áreas donde Matlab muestra
un gran potencial:

álgebra lineal numérica;


r
procesamiento de señales (análisis, compresión de datos,..);
1
por ejemplo, el método de Gauss, el cálculo de las descomposiciones más habituales del álgebra
matricial numérica (LU , LL> , QR), métodos iterativos,...
2
Fortran significa Formula translation. Desarrollado por IBM en 1954, es considerado como el primer
lenguaje de alto nivel. Las últimas actualizaciones (Fortran 95 y Fortran 2003) han dado nuevo vigor a
este veterano lenguaje de programación.

1
diseño de sistemas de control;

salidas gráficas;

estadı́stica;
Bo
simulación de sistemas dinámicos.

La extensa gama de problemas que cubre hace de Matlab un lenguaje difı́cil de entender
y manejar en su completitud. Esto no quiere decir que sea inarbodable: el conocimiento
base que permite empezar a trabajar es muy sencillo. No obstante el elevado número de
comandos que se encuentra a disposición del usuario3 provoca que en ocasiones existan
problemas no sólo para encontrar los comandos adecuados sino también para tener una
idea de qué posibilidades exactamente ofrece Matlab en un problema o tarea en particular.

1.2. ¿Cómo trabaja?


rra
El lenguaje de programación de Matlab es bastante más flexible que el de los lenguajes
tradicionales. No es preciso la declaración inicial de variables, éstas se pueden introducir
en el momento que se necesiten, y por ejemplo, vectores y matrices pueden declararse
sin especificar sus dimensiones e incluso cambiar sus tamaños sobre la marcha. Ello per-
mite una programación algo más desordenada, aunque debe tenerse bien claro que una
programación clásica, más al uso, suele generar código más eficiente.
Por otro lado, una gran cantidad de métodos numéricos se encuentran implementados
de una forma muy eficiente y son accesibles como simples comandos. De esta forma, Mat-
lab se puede utilizar como una caja negra: el usuario pregunta y el ordenador responde sin
que éste tenga que preocuparse de qué tipo de operaciones se han efectuado por el camino.
De todas formas es conveniente tener una idea de qué métodos se están utilizando para
ası́ ser conscientes de en qué condiciones van a funcionar, cuál es en cada caso el méto-
do
do adecuado, y especialmente el significado de los, posiblemente, numerosos argumentos
opcionales que controlan el funcionamiento del algoritmo.
A priori se pueden distinguir dos tipos de funciones en Matlab: funciones compiladas
(Built in functions) y funciones no compiladas. Las primeras están optimizadas, son pro-
gramas ya compilados y con el código no accesible para el usuario. Como ejemplos se
pueden citar

operaciones fundamentales +, *,. . . .

las funciones matemáticas básicas (sin, cos, exp, log,. . . )


r
algoritmos básicos del Álgebra Lineal (inv, det, lu, chol, qr,...)

sálidas gráficas (plot, surf,...)


3
A modo de ejemplo, estos comandos cubren salidas gráficas: plot, line, ezplot, ezsurf, surf,
surfc, line, patch, plot3, contour, contourf, ezcontour, pcolor, trimesh, trisurf,...

2
Las funciones no compiladas están escritas siguiendo el lenguaje de programación
propio de Matlab. Estos comandos se guardan en ficheros *.m que es la extensión estándar
de los ficheros de Matlab4 .
Originalmente, Matlab funcionaba como un interprete. Es decir, cada lı́nea de código
era traducido antes de su ejecución. Ello hacı́a que una programación similar a lenguajes
clásicos de programación diera lugar a código poco eficiente.
Bo
Este problema se puede subsanar en gran medida recurriendo a la programación vec-
torizada. El siguiente ejemplo muestra las diferencias con una programación estándar

No vectorizada Vectorizada

y=zeros(1,1000); y=sin(linspace(0,2*pi,1000));
h=2*pi/999;
for i=0:999
y(i+1)=sin(h*i);
rra
end

En la primera parte del código, encontramos una estructura tı́pica en los lenguajes de
programación: el comando for. Su significado es claro: las lı́neas comprendidas entre el for
y end se repiten 1000 veces con la variable i tomando valores de 0 a 999. El resultado final
es el vector fila y que recoge el valor del seno en 1000 puntos uniformemente espaciados
en [0, 2π].
Por otro lado, el comando linspace devuelve un array que contiene 1000 puntos
equidistantes entre 0 y 2π. La función seno es aplicada sobre todo el array devolviendo
un vector con estos valores que se guarda en y. La diferencia entre ambas formas de
programar es ahora patente. Mientras que en la primera realizamos 1000 llamadas a la
do
función seno con un argumento por llamada, en la segunda hay una única llamada donde
se requiere el cálculo del seno en 1000 puntos, y el resultado se devuelve en un vector con
estos valores (y por tanto también de longitud 1000).
Desde el punto de vista de Matlab el segundo código es más eficiente. Habitualmente,
la vectorización lleva consigo una reducción del código a la vez que se incrementan las
necesidades de memoria.
Con Matlab 6.5 se inició un proyecto a más largo plazo consistente en la aceleración
(Performance Acceleration) de las versiones no vectorizadas dirigida a estrechar las difer-
encias con los lenguajes clásicos de alto nivel como Fortran, C o Pascal5 . En cualquier caso,
r
la posibilidad de ejecutar instrucciones en bloque sobre vectores o matrices, en contraste
con operaciones elemento a elemento como en los lenguajes tradicionales, es algo que
conviene explotar por las importantes ventajas que proporciona.

4
También está la extensión *.mat, propia de ficheros de datos.
5
De hecho en la version 6.5 apenas hay diferencias en tiempo de ejecución entre los dos códigos
expuestos.

3
1.3. ¿Cómo aprenderemos?
Como ya hemos señalado anteriormente, aprender a manejar Matlab en su totalidad
está fuera de los contenidos de un curso introductorio como éste. No ası́ aprender los
fundamentos y preparar el terreno para un autoaprendizaje de las partes en las que cada
uno esté interesado. Encontramos en este punto dos dificultades que salvar: saber de la
Bo
existencia del comando adecuado y aprender a utilizarlo. En no pocas ocasiones, la primera
es la mayor dificultad. No obstante los comandos llevan siempre nombres nemotécnicos
para facilitar su memorización. Las funciones de ayuda también echan una mano.
Como a programar se aprende programando, comenzaremos escribiendo código desde
los primeros pasos. Los esquemas numéricos que implementaremos se encuentran prácti-
camente en cualquier curso introductorio de Análisis Numérico. En cada lección imple-
mentaremos dichos algoritmos, introduciendo órdenes, estructuras de decisión, datos,...
según sea necesario.
En los apuntes se incluyen múltiples ejercicios cuya realización ayudará al aprendizaje
de la asignatura. Estos apuntes no deben tomarse como un manual en el estilo usual, sino
como una forma de aprender Matlab y repasar o aprender el Análisis Numérico básico.
Ya existen manuales extensos y concienzudos, en la bibliografı́a citamos algunos de ellos,
rra
que pueden servir para ese fin.
do
r
4
Bo
Lección I

Primeros pasos en Matlab.


rra
Métodos directos para sistemas de ecuaciones
lineales
do
r
5
r
do
rra
Bo
Introducción
Bo
When asked whether a programming language supports
matrices, many people will think of two-dimensional
arrays and respond, “Yes.” Yet matrices are more than
two-dimensional arrays -they are arrays with operations.
It is the operations that cause matrices to feature so
prominently in science and engineering

G.W. Stewart, Matrix Algorithms


rra
Comenzaremos en la primera parte de esta lección tratando nociones básicas de Matlab,
introduciendo el entorno de trabajo y las estructuras básicas de programación. En segundo
lugar entraremos en uno de los detalles fuertes de Matlab, la manipulación de vectores y
matrices.
En la parte matemática estudiaremos métodos directos para la resolución de sis-
temas de ecuaciones lineales. En la implementación de estos algoritmos repasaremos los
conocimientos de Matlab expuestos en la primera parte.
do
r
7
r
do
rra
Bo
Capı́tulo 2
Bo
Matlab: Primeros pasos

2.1. Entorno de trabajo


En las primeras secciones comenzaremos explorando Matlab de la forma más simple, en
modo comando: el usuario pregunta y Matlab responde. El interfaz de Matlab es bastante
pobre, con un aspecto estético que en modo alguno es comparable al de programas como
rra
Maple o Mathematica. El modo interactivo de trabajar es sencillo aunque algo incómodo. A
modo de ejemplo, requiere algo de esfuerzo editar instrucciones ejecutadas con anterioridad
y manejarse con bloques de comandos es muy engorroso. Éste y otros problemas del modo
interactivo se subsanan en gran medida empaquetando instrucciones con ficheros script
y/o programando en funciones (subrutinas) que es la forma natural de trabajar en Matlab.
En un segundo paso, se puede implementar un interfaz gráfica, las guides de Matlab, que
hacen más amigable la comunicación con el usuario.
En la Figura 2.1 podemos ver el aspecto inicial de Matlab. Distinguimos las siguientes
ventanas

Command window: ventana donde podemos ejecutar los comandos;


do
Ventanas auxiliares: command history, workspace, current directory que informan
sobre (y permiten editar) los comandos insertados, las variables declaradas y el
directorio en el que estamos trabajando.

Ventana de ayuda: en una ventana independiente proporciona un acceso completo


a las funciones de ayuda de Matlab, incluyendo búsquedas, demostraciones, etc.

Éstas son las caracterı́sticas básicas que debemos considerar:

El prompt de Matlab es >>. El usuario escribe a continuación.


r
Para ejecutar se pulsa la tecla Enter.

Se pueden recuperar comandos anteriores navegando con las flechas ↑ y ↓.

Cuando se trabaje en Matlab, debemos tener muy en cuenta que:

Se distinguen mayúsculas y minúsculas.

9
2.1 Entorno de trabajo LECCIÓN I
Bo
rra
Figura 2.1: Pantalla Principal.

Todos los comandos de Matlab se escriben en minúsculas y los argumentos se envı́an


entre paréntesis separados por comas.
do
El carácter % se utiliza para insertar comentarios. Todo lo que sigue (en la misma
lı́nea) es ignorado por Matlab.

Si se teclea al final de una instrucción ’;’ ésta se ejecuta pero el resultado no se


visualiza por pantalla.

Dos comandos se pueden insertar en la misma lı́nea separados por “,” o por “;”. La
diferencia entre los dos es que con “,” se muestran los resultados de las operaciones
mientras que con “;” la operación se ejecuta pero no se visualiza.
r
Ejercicio 2.1 Ejecuta las instrucciones

>> 4+4 % mi primera operacion


>> 3^4, 4/9
>> 3^4; 4/9
>> 3^4, 4/9;
>> 3^4; 4/9;

10
LECCIÓN I Capı́tulo 2. Matlab: Primeros pasos

y observa la salida.

Haremos algunos comentarios sobre el ejercicio anterior. El circunflejo ^ es la poten-


ciación:

>> 3^5
Bo
ans=

243

El término ans es la primera variable que vemos de Matlab. Concretamente, guarda la


última salida dada por Matlab (answer):

>> 4+6

ans =

10
rra
>> ans*2

ans =

20

>> ans*2

ans =

40
do
La raı́z cuadrada se puede calcular bien elevando a 1/2 (^(1/2)) o bien utilizando sqrt.

Ejercicio 2.2 Comprueba la diferencia entre

4/4+6 4/(4+6) 3^5*2 3^(5*2)

Nota. La prioridad de ejecución entre operaciones matemáticas es la habitual: primero


se calcula la potenciación ^, posteriormente los productos y divisiones *, / y en último
lugar, las sumas y restas + y -. Este orden se puede cambiar utilizando los paréntesis.
La regla es sencilla: dada una expresión, lo primero que se calcula es lo que está dentro
r
de cada paréntesis. Esta regla es recursiva, es decir, si dentro de un paréntesis hay otros
paréntesis, para evaluar el primero se empezará con los paréntesis interiores. 
Los números reales se pueden insertar también en notación cientı́fica, muy adecuada si
se trata de números grandes o muy pequeños (en valor absoluto). Ası́, se tiene la siguiente
regla de construcción:
m · 10r m er

11
2.1 Entorno de trabajo LECCIÓN I

Por ejemplo

0.005 5e − 3 115 · 1012 115e12


−1201200000 −1.2012e009 0.00031415 3.1415e − 004

Existen además dos números especiales: inf y NaN. El primer signo representa la can-
Bo
tidad infinita (∞). El segundo es una abreviatura de “no es un número” (Not a Number)
y es el resultado que se devuelve ante una operación indefinida como 0/0. Este sı́mbolo
se puede utilizar en ámbitos, en principio tan extraños, como en el dibujo de superficies
(vér la Lección V).
En general los resultados numéricos se presentan con cuatro cifras decimales correctas,
aunque todas las operaciones se ejecutan en doble precisión1 . Si se desean las salidas con
toda la precisión disponible se debe insertar la instrucción

>> format long

A partir de este punto, el resultado de cualquier operación se mostrará con 16 cifras


significativas. La instrucción
rra
>> format short

devuelve a la forma estándar con cuatro cifras decimales. Existen más opciones con format.
Las siguiente lı́neas muestran algunas de ellas:

>> pi % el numero pi

ans =

3.1416

>> format long % mayor precision


>> pi
do
ans =

3.14159265358979

>> format compact % compacto


>> pi
ans =
3.14159265358979
>> format bank %No fijo de cifras decimales
r
>> pi
ans =
3.14
1
Aproximadamente 16 cifras decimales correctas. En el momento de redactar estas lı́neas, los proce-
sadores de 32 bits dominan todavı́a el parqué de ordenadores. Las nuevas generaciones, con procesadores
con 64 bits, duplican la precisión de trabajo.

12
LECCIÓN I Capı́tulo 2. Matlab: Primeros pasos

>> format rat %salidas en forma fraccionaria


>> pi
ans =
355/113
>> format loose % mas espaciada
>> pi
Bo
ans =

355/113
Observa la diferencia de espaciamiento que se obtiene con las opciones compact y loose.

Números complejos
La √aritmética compleja se encuentra también integrada en Matlab. La unidad imagi-
naria ( −1) se representa en Matlab con i ó j:
>> clear i j % borramos posibles valores de i y j
rra
>> i^2

ans=

-1

>> j^2

ans=

-1
do
El signo i suele ser habitual en Matemáticas mientras que en diversas ramas de la Fı́sica
y en Ingenierı́a de Telecomunicaciones o Eléctrica se prefiere el sı́mbolo j (en este caso
para no confundir con la intensidad de corriente eléctrica). De ahı́ que Matlab permita
ambas representaciones.
Todas las operaciones matemáticas incluyen la aritmética compleja en el sentido usual

>> 1+i +5-6i % suma de dos numeros complejos

ans =
r
6.0000 - 5.0000i

>> (5+3i)*(5-3i), (1+2i)/(3-4i)

ans =

13
2.2 Comandos de ayuda LECCIÓN I

34.00

ans =

-0.20
Bo
+
>> conj(3e-3+2e-4i) % conjugado

ans =

0.0030 - 0.0002i

>> abs(3+4i), angle(2i) % modulo y argumento

ans =

5
rra
ans =

1.5708

2.2. Comandos de ayuda


La ayuda de Matlab es ciertamente muy clara y completa. Los comandos siempre
dispuestos a echarnos una mano son:

help: muestra una ayuda por pantalla, en la ventana de comandos, con la informa-
do
ción esencial sobre un comando concreto.

helpwin: similar a help pero despliega la ayuda en una ventana auxiliar, permitien-
do ası́ una navegación, estilo web, muy cómoda.

lookfor: permite buscar una cadena en la primera lı́nea de todos los ficheros de
ayuda.

Por ejemplo, si deseamos ayuda sobre la función sin, podemos ejecutar

>> help sin


r
SIN Sine.
SIN(X) is the sine of the elements of X.

Overloaded methods
help sym/sin.m

14
LECCIÓN I Capı́tulo 2. Matlab: Primeros pasos
Bo
rra
Figura 2.2: Pantalla de ayuda.

o bien
>> helpwin sin
do
y obtener la pantalla que se muestra en la Figura 2.3. Además, si aparece el enlace “Go to
online doc for ...”, éste nos permite navegar entre una ayuda mucho más completa
donde se muestran ejemplos y detalles sobre la implementación del comando (ver la Figura
2.42 ).

Ejercicio 2.3 Utilizando las funciones de ayuda, obtener información de alguna de estas
funciones elementales de Matemáticas
sin cos tan asin acos atan
sec csc cot asec acsc acot
r
sinh cosh tanh asinh acosh atanh
exp log log10 log2 sign
Mediante la instrucción
2
Para que esta opción esté disponible es necesario que se haya instalado la ayuda completa de Matlab.
A partir de la versión 6.0 la instalación consta de (al menos) dos CDs, el primero con el programa y las
librerı́as habituales y el segundo con la documentación de la ayuda.

15
2.3 Variables LECCIÓN I
Bo
rra
Figura 2.3: Ayuda con helpwin. Comprueba si aparece la opción Go to online doc...

>> help +

se pueden además visualizar las operaciones “elementales” según Matlab.


do
2.3. Variables
Matlab no necesita la declaración de variables como en un lenguaje tradicional. En prin-
cipio todas las variables son reales, y basta hacer uso de ellas para que queden declaradas:

>> a=1; b=2; c=3;


>> a-b

ans =
r
-1

>> a*b*c

ans =

16
LECCIÓN I Capı́tulo 2. Matlab: Primeros pasos
Bo
rra
Figura 2.4: Ayuda on line.

6
do
El comando who sirve para conocer los nombres de las variables declaradas, mientras
que con whos obtenemos una información más precisa:

>> who

Your variables are:

a b c

>> whos a
r
Name Size Bytes Class

a 1x1 8 double array

Grand total is 1 element using 8 bytes

Para borrar una variable se utiliza la instrucción clear, por ejemplo,

17
2.3 Variables LECCIÓN I

>> a=4;
>> whos a

Name Size Bytes Class

a 1x1 8 double array


Bo
Grand total is 1 element using 8 bytes

>> clear a
>> whos a
>>
borra la variable (es decir, whos no devuelve nada). Con la orden
>> clear all
se borran todas las variables declaradas hasta el momento.
rra
Nota. En Matlab es correcto declaraciones de este tipo
>> sin=1;
>> sin+1

ans=

2
De esta forma sin pasa a ser una variable que sobrescribe el valor original que tenı́a como
función seno. Para recuperar el valor original basta ejecutar
>> clear sin

do
Almacenamiento de variables en ficheros
Matlab ofrece la posibilidad de grabar las variables que deseemos en un fichero. De esta
forma, podemos recuperarlas más adelante, ya sea en la misma sesión o en otra diferente3 .
Por ejemplo
>> a=4+i;% numero complejo
>> b1=cos(2);
>> b2=sin(2);
>> save datos a b1 b2
r
graba dentro del directorio de trabajo, en un fichero de nombre datos.mat, las variables
indicadas. Para recuperar, basta ejecutar
>> load datos
3
Se entiende por sesión el tiempo que transcurre entre que se abre y se cierra Matlab. Al cerrar el
programa, todas las variables locales se pierden.

18
LECCIÓN I Capı́tulo 2. Matlab: Primeros pasos

2.4. Ficheros script y funciones


La forma más eficiente de empaquetar series de instrucciones simples y mecánicas es
utilizando ficheros script. Tareas más elaboradas, con, por ejemplo, variables de entrada
y salida, requieren del uso de funciones.
Bo
2.4.1. Ficheros script
Un fichero script es un simple documento de texto que contiene una sucesión de co-
mandos de Matlab. Esencialmente es equivalente a teclear estas instrucciones directamente
en la ventana de comandos.
Describiremos el manejo de este tipo de ficheros mediante un sencillo ejemplo. Comen-
zamos creando un fichero tecleando en modo comando la orden4
>> edit prueba
Se despliega ası́ en una ventana aparte el editor de Matlab con el fichero prueba.m (“.m”es
la extensión estándar de Matlab). Es importante saber cuál es el directorio de trabajo5 ,
pues es donde se guardará por defecto el fichero.
rra
Tecleamos ahora en el editor
a=1+i; b=1-i;
disp(’a*b=’)
disp(a*b)
disp(’a/b=’)
disp(a/b)
disp(’sqrt(a)=’)
disp(sqrt(a))
El comando disp (de display) muestra vectores por pantalla de forma compacta. Dado que
para Matlab un cadena de caracteres es simplemente un vector de carácteres, se consigue
con ello mostrar por pantalla mensajes de forma concisa.
Una vez que el documento está grabado, para ejecutar las órdenes que contiene basta
do
teclear el nombre del fichero en la ventana de comandos:
>> prueba
Se puede modificar las veces que se precise las variables a y b en el fichero script sin tener
que teclear de nuevo todas las instrucciones.

2.4.2. Funciones
En principio existen dos tipos de funciones: las funciones inline, que se insertan en
la lı́nea de comandos y las que se escriben en un documento de texto externo. Esta última
r
forma, que es la evolución natural de los ficheros script, es más flexible y es en la que nos
centraremos a continuación. Dejaremos pendiente para la Lección III la descripción de las
funciones inline.
Como antes, para crear un fichero que contenga a una función se puede teclear:
4
También es posible crear este fichero a golpe de ratón.
5
Por defecto es C:\MATLAB6p5\work.

19
2.4 Ficheros script y funciones LECCIÓN I

>> edit mifuncion

En el editor puedes insertar este simple ejemplo:

01 % MIFUNCION
02 %
Bo
03 % Y=MIFUNCION(X) devuelve
04 %
05 % Y=X^2-COS(X)
06 %
07 function y=mifuncion(x)
08
09 y=x^2-cos(x);
10
11 return

La función se declara con function, la variable de entrada es x y se declara como variable


de salida y. Se termina la ejecución de la función cuando se ejecuta un return o bien se
llega al final de la función6 .
rra
Ahora, para calcular el valor de π 2 − cos(π) podemos ejecutar la orden:

>> mifuncion(pi)

ans =

10.8696

Nota. Los números correlativos situados a la izquierda no forman parte del código
de la función. Han sido insertados con el fin de numerar las lı́neas y ası́ facilitar los
comentarios que podamos hacer sobre el programa. 
Una función puede no tener salidas, por ejemplo,
do
01 % INFORMACION
02 %
03 % INFORMACION devuelve informacion sobre
04 % la precision de la maquina
05 %
06 function informacion
07
08 disp(’precision de la maquina’)
09 disp(eps)
r
10 disp (’mayor numero real’)
11 disp(realmax)
12 disp (’menor numero real’)
13 disp(realmin)
14 return
6
En este sentido, el return del ejemplo anterior es superfluo.

20
LECCIÓN I Capı́tulo 2. Matlab: Primeros pasos

o bien devolver múltiples salidas:


01 % MIFUNCION2
02 %
03 % [Y1,Y2]=MIFUNCION2(X1,X2,X3) devuelve
04 %
Bo
05 % Y1=X1+X2+X3;
06 % Y2=X1-X2+X3;
07 %
08 function [y1,y2]= mifuncion2(x1,x2,x3)
09
10 y1=x1+x2+x3;
11 y2=x1-x2+x3;
12
13 return
Observa cómo se recogen los resultados
>> [z1,z2]=mifuncion2(1,2,3);
rra
>> z1

ans=

>> z2

ans=

>> z=mifuncion2(1,2,3); % Ahora solo devuelve el primero


do
ans=

6
La cabecera que hemos introducido en el preámbulo de las funciones, es decir las lı́neas
anteriores a la declaración de la función y precedidas con “%”, constituyen la ayuda de la
función:
>> help mifuncion2
r
MIFUNCION2

[Y1,Y2]=MIFUNCION2(X1,X2,X3) devuelve

Y1=X1+X2+X3;
Y2=X1-X2+X3;

21
2.5 Vectores y matrices LECCIÓN I

Aunque muy recomendables7 , su inclusión en una función es opcional. La ayuda puede


estar antes o después de la declaración de la función. En cualquiera de los dos casos,
Matlab despliega como ayuda todas las lı́neas que esten precedidas con % hasta que se
encuentra con la primera lı́nea no comentada.
Bo
Nota. Para ser consecuentes, lo correcto es denominar de igual modo a la función y
al archivo que la contiene. Sin embargo esto no es obligatorio, es decir, se pueden dar
nombres distintos, pero en este caso Matlab da preferencia al nombre del archivo.
Aunque Matlab distingue entre mayúsculas y minúsculas en sus comandos, esto no es
extensible para funciones programadas en m-files, al menos en Windows. Es decir, para
ejecutar una función en un archivo, digamos, operaciones, se puede utilizar OPERACIONES,
Operaciones y cualquier combinación con mayúsculas y minúsculas. Esto es debido a que
el sistema de archivos de Windows tampoco hace esa distinción8 . Versiones más avanzadas
de Matlab, 7.0 en adelante, muestran sin embargo un aviso si no existe una concordancia
exacta minúsculas-mayúsculas entre el nombre del fichero y el comando utilizado para
llamarlo.
rra
Todas las variables se envı́an por valor, no por referencia. Es decir, si una función
modifica una variable de entrada, esta modificación se pierde cuando finalice su ejecución,
recuperando el valor original.
Por último, en un fichero se pueden incluir varias funciones. En este caso sólo la primera
función es accesible desde el exterior (lı́nea de comandos, otras funciones,...) mientras que
el resto de funciones presentes en ese fichero son internas, es decir, utilizables únicamente
por las funciones presentes en el archivo. Esto es importante a la hora de realizar una
programación modular. Si un conjunto de funciones son sólo utilizadas por una función
principal, se pueden insertar en el mismo fichero que ésta. Evitamos ası́ llenar la carpeta
de trabajo, o de nuestro proyecto, con ficheros y más ficheros. 

2.5. Vectores y matrices


do
Dado que principalmente trabajaremos sólo con arrays de una y dos dimensiones
hablaremos en lo que sigue de los objetos matemáticos correspondientes: vectores y ma-
trices. Todo lo que sigue se puede adaptar a arrays con más dimensiones, aunque por
simplificar, nos centraremos ahora en el manejo de vectores y matrices y dejaremos pen-
diente para la Lección IV el uso de arrays multidimensionales (tensores).

2.5.1. Definición de matrices y vectores


Un vector o una matriz se puede definir dando sus elementos entre corchetes y sepa-
r
rando filas mediante “;”. Por ejemplo, las instrucciones
7
No hay que subestimar nunca la capacidad de olvido de uno mismo: el código claro y legible de hoy
es ilegible semanas después. Las ayudas facilitan la edición de los programas no sólo para un usuario
externo sino para el propio programador.
8
Es decir, si existe un fichero llamado operaciones.m no es posible crear otro con nombre
Operaciones.m

22
LECCIÓN I Capı́tulo 2. Matlab: Primeros pasos

>> a=[1 3 -1; 2 3 4; 4 5 1];


>> a2=[1 2 4; -1 0 1; 2 1 5];
>> b=[1; 3; 1]; b2=[-1 1 -2 2];
definen las matrices y vectores
     
1 3 −1 1 2 4 1
Bo
 
a= 2  3 4  , a2 =  −1 0 1  , b =  3 , b2 = −1 1 −2 2 .
4 5 1 2 1 5 1
Matlab distingue entre vectores fila y columna por lo que habrá que tenerlo en cuenta por
ejemplo cuando se desee hacer operaciones como sumas o productos.
Desde una vertiente práctica, si se va a trabajar con una matriz grande, por ejemplo
de tamaño 20 × 10, y sus valores se van a introducir más adelante, se puede empezar con
>> a=zeros(20,10);
A partir de este instante se pueden insertar los elementos, accediendo a cada posición
mediante paréntesis
>> a(4,5)=9; a(2,1)=6; a(1,1)=-3.4;
rra
>> a(4,5)

ans=

9
En cualquier caso, si tratamos de introducir un valor en una posición no definida de la
matriz, Matlab irá adaptando el tamaño según juzgue apropiado9 , y no dará ningún
error. El siguiente ejemplo ilustra esta caracterı́stica
>> clear c % c esta borrado
>> c(1,2)=4 % c es ahora 1 x 2

c =
do
0 4

>> c(3,3)=2 % c pasa a ser 3 x 3

c =

0 4 0
0 0 0
0 0 2
r
Esta habilidad, aunque permite una programación muy flexible y descuidada, debe uti-
lizarse con mesura dado que puede provocar errores de ejecución muy difı́ciles de detectar.
9
Ello obliga a que haya que redimensionar constantemente la memoria otorgada a la variable a. Esto
supone un costo adicional, inapreciable con ejemplos pequeños, pero importante para grandes cantidades
de memoria. Por tanto es mejor declarar primero las dimensiones de la matriz e informar ası́ a Matlab de
cuánta memoria tiene que reservar.

23
2.5 Vectores y matrices LECCIÓN I

2.5.2. Operaciones
Todas las operaciones habituales entre matrices, tales como la suma, producto, poten-
ciación, cálculo de determinantes, inversas..., están ya implementadas en Matlab. No hay
por tanto necesidad de programarse estas tareas. Por ejemplo, si a y a2 son matrices de
tamaños compatibles, las instrucciones
Bo
a*a2 a^2 a+a2
devuelven el producto matricial de a y a2, el cuadrado de a (es decir, a*a) y la suma de
a y a2.
Es importante observar la diferencia con estas lı́neas
a.*a2 a.^2
En el primer caso, se devuelve la matriz resultado de multiplicar elemento a elemento
a y a2 (por tanto deben tener el mismo tamaño) y en el segundo, una matriz cuyas
entradas son el cuadrado de las de a. Esto es una constante en Matlab: el signo “.”
indica que la operación (un producto, una potencia o una división) se hace elemento a
elemento, mientras que en caso contrario se calcula la operación matemática, en este
caso el producto matricial.
rra
Ejercicio 2.4 Introduce en a y a2 dos matrices de igual tamaño. Observa el resultado de
ejecutar
a+a2 a*a2 a.*a2
Define un vector b fila o columna y ejecuta
b.^3 b’
Comprueba si estas operaciones están bien definidas
a*2 a+1
¿Qué hacen exactamente? ¿Por qué crees que no es necesario “.” en la primera instrucción?.
do
Otros comandos importantes son
det inv / \ /. \.
Los dos primeros son el determinante y la inversa de una matriz cuadrada. Los operadores
“/” y “\” (slash y backslash) son ciertamente especiales:
a/a2 es equivalente a a*inv(a2), a\a2 es equivalente a inv(a)*a2
En cuanto a su relación con ./ y \. es la misma que ha surgido antes, esto es, aplicado
sobre matrices procede a realizar los cocientes elemento a elemento. Requiere por tanto
que ambas matrices tengan el mismo tamaño.
r
Ejercicio 2.5 Ejecuta las instrucciones
>> 3/5
>> 3\5
y observa el resultado. ¿Tiene sentido desde el punto de vista anterior?.
Ejercicio 2.6 Dado b una matriz, ¿qué hace 1/b?.

24
LECCIÓN I Capı́tulo 2. Matlab: Primeros pasos

Nota. El operador backslash “\” se utiliza profusamente para resolver sistemas de ecua-
ciones lineales, bajo la idea de que

Ax = b ⇔ x = A−1 b.

Ası́, si b es n × 1 y a es n × n,
Bo
>> x=a\b;

devuelve en x la solución del sistema correspondiente.


El funcionamiento real de \ dista mucho de ser tan simple. Esto es, no calcula la
inversa de a para multiplicarla por b, sino que resuelve el sistema de ecuaciones por
alguna variante del método de Gauss. Se puede utilizar helpwin mldivide (o helpwin
mrdivide para /) para leer en detalle cómo procede este comando. 
Las funciones propias de Matlab trabajan de forma natural sobre vectores y matrices.
El resultado final es equivalente a aplicar el comando elemento a elemento. Por ejemplo,

>> a=[0 pi/3; -pi/3 0];


>> cos(a)
rra
ans =

1.0000 0.5000
0.5000 1.0000

es equivalente a

>> [cos(0) cos(pi/3); cos(-pi/3) cos(0)]

ans =

1.0000 0.5000
do
0.5000 1.0000

2.5.3. Detalles adicionales


Cómo obtener las dimensiones de vectores y matrices
Los comandos de Matlab size y length nos proporcionan esta información:

>> a3=[1 2; 3 6; 5 -1];


>> size(a3)
r
ans =

3 2

>> length(a3)

25
2.5 Vectores y matrices LECCIÓN I

ans =

>> a3=a3’; % cambiamos la forma de a3


>> size(a3)
Bo
ans =

2 3

>> [m,n]=size(a3); % m son las filas y n las columnas


>> m

ans =

2
rra
>> n

ans =

>> length(a3)

ans =

3
do
El comando size devuelve un vector de tamaño 2×1 con el número de filas y columnas
del vector/matriz. El resultado es diferente según se aplique a vectores fila o columna. La
orden length devuelve la longitud de una matriz o vector. Su significado en el caso de un
vector está clara mientras que para matrices devuelve el máximo entre el número de filas
y el número de columnas.

Matrices especiales
Matlab dispone de una serie de comandos que permiten construir matrices con una
estructura particular. Cabe señalar las siguientes órdenes:
r
eye(n) es la matriz identidad de orden n;

ones(m,n) es una matriz m x n de 1s;

zeros(m,n) es una matriz m x n de 0s, esto es, igual que ones pero con ceros;

y algunas más exóticas como hilb, invhilb, pascal, magic.

26
LECCIÓN I Capı́tulo 2. Matlab: Primeros pasos

Existen dos formas de introducir vectores cuyos valores siguen una distribución regular

a:b:c construye el vector de valores [a a+b a+2*b .... a+k*b] donde a+k*b es
el mayor número natural que cumple a+k*b≤ c. La instrucción a:c toma b = 1.

linspace(a,b,n) devuelve una partición uniforme de [a, b] en n puntos.


Bo
Por ejemplo,

>> 0:10

ans=

0 1 2 3 4 5 6 7 8 9 10

>> 10:-1:0

ans=
rra
10 9 8 7 6 5 4 3 2 1 0

>> 0.1:0.3:1.5

ans =

0.1000 0.4000 0.7000 1.0000 1.3000

>> linspace(0,2,4)

ans =
do
0 0.6667 1.3333 2.0000

>> linspace(2,0,4)

ans =

2.0000 1.3333 0.6667 0

Nota. Cuando Matlab tiene que devolver un vector y no se le especifica el formato,


devuelve una fila. 
r
2.5.4. Acceso a partes de matrices
El manejo de partes de vectores y matrices, ası́ como la eliminación de filas o columnas,
cambios de tamaño, etc, se hace vı́a instrucciones muy simples en Matlab. Aunque pueda
resultar algo extraño al principio, un poco de práctica es suficiente para que el usuario se

27
2.5 Vectores y matrices LECCIÓN I

adapte a la nueva sintaxis, tan diferentes a la de un lenguaje tradicional, y pueda utilizarlo


en sus códigos.
Comencemos viendo un ejemplo:

>> a=[1 2 3; 4 5 6; 7 8 9; 10 11 12];


>> a(2,3) % elemento (2,3) de a
Bo
ans =

>>a(2,:) % fila 2 de a

ans =

4 5 6

>>a(:,1) % columna 1
rra
ans =

1
4
7
10

>>a(:,2)=0 % columna 2 es ahora 0

a =
do
1 0 3
4 0 6
7 0 9
10 0 12

Podemos acceder a partes de una fila o columna:

>> a(1,2:3) % vector [a(1,2) a(1,3)]

ans =
r
0 3

>> a(2:4,3) % vector columna [a(2,3); a(3,3); a(4,3)]

ans =

28
LECCIÓN I Capı́tulo 2. Matlab: Primeros pasos

6
9
12

>> a(1:2,2:3) % matriz [a(1,2) a(1,3); a(2,2) a(2,3)]


Bo
ans =

0 3
0 6

En general, si p es un vector de números enteros, v(p) devuelve [v(p(1)), v(p(2)),


..., v(p(n))]. Por ejemplo,

>> v=[0.1 0.2 0.3 0.4 0.5 0.6];


>> v(4:-1:2)

ans=
rra
0.4000 0.300 0.2000

>> p=[5 1 2 3 3 3]; % no importa que esten repetidos


>> v(p)

ans=

0.5000 0.1000 0.2000 0.3000 0.3000 0.3000

Ejercicio 2.7 Ejecuta las siguientes lı́neas

>> a=[1 2 3 4; 5 6 7 8; 9 10 11 12];


do
>> p=[1 3 2]; q=[1 2 1];
>> a(p,q)

¿Qué hacen exactamente?.

Igualmente es fácil añadir filas y columnas a una matriz:

>> a=[1 2 3 4; 5 6 7 8]

a =
r
1 2 3 4
5 6 7 8

>> a=[a; [1 -1 2 4]] % adosamos una fila nueva

a =

29
2.6 Bucles y estructuras de decisión LECCIÓN I

1 2 3 4
5 6 7 8
1 -1 2 4

>> a=[a [0; 2; 4] ] % una nueva columna


Bo
a =

1 2 3 4 0
5 6 7 8 2
1 -1 2 4 4

Si se desea eliminar una fila o columna se puede utilizar el sı́mbolo vacı́o []. Por
ejemplo,

>> a(:,2)=[] % suprime la segunda columna


rra
a =

1 3 4 0
5 7 8 2
1 2 4 4

Ejercicio 2.8 Programa una función cuyas entradas sean una matriz cuadrada y un término
independiente compatible y que devuelva la matriz ampliada del sistema de ecuaciones lineales.
Esto es, una matriz con la matriz original y una última columna con el término independiente.

2.6. Bucles y estructuras de decisión


do
Claves en cualquier lenguaje de programación, Matlab dispone de varias de ellas entre
las que sobresalen for e if, un estándar en el mundo de la informática.

2.6.1. Bucles: el comando for


En Matlab, la estructura

for j=inicio:paso:final
.....
end
r
implementa un bucle donde las lı́neas de código entre for y end son ejecutadas repetida-
mente con j tomando los valores del vector inicio:paso:final (véase la Sección 2.5.3)
Por ejemplo,

>> for j=1:3; disp(j); end


1

30
LECCIÓN I Capı́tulo 2. Matlab: Primeros pasos

>> for j=6:-2:2; disp(j-2); end


Bo
4

En general, si v es un vector,
for j=v
.....
end
rra
procede a ejecutar las lı́neas internas con j tomando los valores del vector v. Por ejemplo,
>> v=[2 5 3 1];for j=v; disp(j); end
2

1
Asociados a for, y en general a cualquier bucle, encontramos los comandos break y
continue. El primero fuerza la salida inmediata del bucle mientras que el segundo reini-
do
cializa la iteración con el siguiente valor del ı́ndice.

Ejercicio 2.9 La matriz de Hilbert de orden n es


1 12 · · · · · · 1
 
n
 1 1 ··· ··· 1 
 2 3 n+1 
A=  .. . . . . . . . . . .. 
 . .


1 1 1
n 2n−2 2n−1

Construye la matriz anterior mediante un fichero script y el uso de dos “for” anidados.
r
2.6.2. Operadores lógicos y estructuras de decisión
Los operadores lógicos más básicos en Matlab son
== igualdad, ~= desigualdad, > mayor, < menor,
>= mayor o igual, <= menor o igual, & “y” lógico, | “o” lógico

31
2.6 Bucles y estructuras de decisión LECCIÓN I

El resultado de una comparación es 1 si es verdadero, 0 si es falso:


>> a=1; b=2; c=3;
>> a>0

ans =
Bo
1

>> a>0 & b<3

ans =

>> a<0 | b<1

ans =
rra
0

>> test= (a~=0)

ans =

>> whos test

Name Size Bytes Class


do
test 1x1 1 logical array

Grand total is 1 element using 1 bytes


Estos “0” y “1” no son valores numéricos sino lógicos como se comprueba con la última
instrucción10 . Cuando se aplica a un vector, devuelve un vector de verdadero/falso de la
misma longitud que el vector original:
>> b=[1 2 -3 -1 2 -4]; p=(b>=1) % entradas de b>=1

p=
r
1 1 0 0 1 0
En el ejemplo anterior, p(i)==1 si b(i)≥1 y cero en caso contrario. Ahora, podemos
aislar los elementos mayores o iguales que 1 simplemente con
10
Ocupan un único byte mientras que un número real utiliza ocho bytes.

32
LECCIÓN I Capı́tulo 2. Matlab: Primeros pasos

>> b(p)

1 2 2

Desde este punto de vista es correcta y recomendable utilizar la instrucción

>> b(b>=1) % elementos de b mayores o iguales que 1


Bo
1 2 2

que además resulta muy natural (y fácil de entender).

Nota. El comando logical puede utilizarse para construir vectores y estructuras lógicas
a partir de vectores de números enteros:

>> b=[2 4 6 8 10]; p=[1 0 0 1 1];


>> b(p) % Dara error
rra
??? Subscript indices must either be real positive integers or logicals.

>> p=logical(p);
>> b(p)

ans =

2 8 10


La estructura de decisión, como en muchos otros lenguajes, es if. Su sintaxis es la
siguiente:
do
if simple: si la operación lógica efectuada es verdadera, se ejecutan las lı́neas de
código comprendidas entre if y end

if (x<-1 | x>1)
disp(’valor absoluto de x mayor que 1’)
end

if compuesto: como el anterior, pero un nuevo conjunto de lı́neas, comprendidas


entre else y end son ejecutadas en caso de que la operación lógica efectuada en el
if sea falsa:
r
if (x<0 & x>-10)
f=x^2; % x entre -10 y 0
else
f=sin(x^2); % x menor que -10 o mayor que 0
end

33
2.6 Bucles y estructuras de decisión LECCIÓN I

if de decisión múltiple:

if (x<0)
f=x.^2;
disp(’x menor que cero’)
elseif (x<sqrt(pi))
Bo
f=sin(x^2);
disp(’x en [0,sqrt(pi))’)
elseif (x<2*sqrt(pi))
f=(x-sqrt(pi))^2;
disp(’x en [sqrt(pi),2*sqrt(pi))’)
else
f=pi*cos(x^2);
disp(’x en [2*pi,infinito)’)
end

Esta última instrucción es equivalente a anidar diferentes estructuras if, de la sigu-


iente forma
rra
if (x<0)
f=x.^2;
disp(’x menor que cero’)
else
if (x<sqrt(pi))
f=sin(x^2);
disp(’x en [0,sqrt(pi))’)
else
if (x<2*sqrt(pi))
f=(x-sqrt(pi))^2;
disp(’x en [sqrt(pi),2*sqrt(pi))’)
do
else
f=pi*cos(x.^2);
disp(’x en [2*pi,infinito)’)
end
end
end

Obviamente, la primera forma es más clara y concisa.

Nota. Con la instrucción switch se puede implementar una estructura de decisión que
r
es esencialmente equivalente a un if anidado.
Está disponible también el bucle while que procede a ejecutar un bucle (que se cierra
también con un end) mientras una condición sea verdadera. Por tanto, es algo más flexible
que un for.
En general todos los bucles y estructuras que requieran cerrarse, lo hacen con end. El
uso de break y continue es exactamente el mismo.

34
LECCIÓN I Capı́tulo 2. Matlab: Primeros pasos

Por último, y volviendo a end, este comando tiene una curiosa funcionalidad extra:
sirve para referenciar el último elemento de una fila o columna de una matriz. Por ejemplo
b(4:end) selecciona todos los elementos de b desde la posición cuarta en adelante. 

Ejercicio 2.10 ¿Qué hace el siguiente fragmento de código?


Bo
01 r=[]; aux=0;
02 while aux<0.8
03 aux=rand(1);
04 r=[r aux];
05 end
06 r(end)=[];

Ejercicio 2.11 Con la ayuda de Matlab, programa un par de ejemplos donde utilices switch
y while.

Ejercicio 2.12 (Un poco de todo) Implementa una función de nombre findnonzeros
que dado un vector de entrada devuelva el número de elementos no nulos y un vector que
contenga dichos elementos.
rra
Solución. Una implementación posible es la siguiente
01 % FINDNONZEROS
02 %
03 % [N,P]=FINDNONZEROS(X) devuelve
04 %
05 % N el numero de elementos no nulos en el vector X
06 % P un vector con los elementos no nulos de X
07 %
08 function [n,p]=findnonzeros(x)
09
do
10 p=[]; % p es vacio
11 for i=1:length(x)
12 if (x(i)~=0) % si x(i) no es cero
13 p=[p x(i)]; % apuntamos i al vector p
14 end
15 end
16 n=length(p);
17 return
Observa como se recogen los resultados de la función, n y p,
r
>> a=[0.1 0. 0.3 0.1 0.6 0 0.1 0.2 0.4]; % vector!!
>> [n,p]=findnonzeros(a)

n =

35
2.6 Bucles y estructuras de decisión LECCIÓN I

p =

Columns 1 through 5

0.1000 0.3000 0.1000 0.6000 0.1000


Bo
Columns 6 through 7

0.2000 0.4000

Otra posible implementación (mucho más elaborada y más propia de Matlab) es la sigu-
iente

01 % FINDNONZEROS
02 %
03 % [N,P]=FINDNONZEROS(X) devuelve
04 %
rra
05 % N el numero de elementos no nulos en el vector X
06 % P un vector con los elementos no nulos de X
07 %
08 function [n,p]=findnonzeros(x)
09
10 p=x(x~=0);
11 n=length(p);
12 return

Haz un esfuerzo en entender bien los comandos anteriores. Tras la suficiente práctica,
esta versión se ve más clara y natural que la anterior. Observa cómo se toman los elementos
no nulos del vector x (lı́nea 10).

do
r
36
Capı́tulo 3
Bo
Métodos directos para sistemas de
ecuaciones lineales

3.1. Método de Gauss


El método de Gauss, también conocido como eliminación gaussiana, es el algoritmo
rra
más sencillo para la resolución de sistemas de ecuaciones lineales. Consta de dos partes
bien diferenciadas:

i) Transformación del sistema lineal en otro equivalente, es decir, con la misma solu-
ción, donde la matriz es triangular superior.

ii) Resolución del sistema triangular por sustitución regresiva.

El paso i) se acomete vı́a dos operaciones elementales:

(a) Sumar a una ecuación otra multiplicada por un número.

(b) Intercambiar dos ecuaciones.


do
Si sólo utilizamos la operación (a) hablaremos del método de Gauss sin pivotaje, y
con pivotaje parcial si también realizamos las operaciones (b)1 cuando la elección de
las filas que se conmutan sea una muy particular.
Representando el sistema de ecuaciones en la forma matricial, todo lo anterior se
reescribe en términos de operaciones matriciales (sumar a una fila otra fila e intercambiar
filas2 ). En lo que sigue expresaremos el sistema en la forma

Ax = b, A ∈ Rn×n , x, b ∈ Rn ,

donde A es la matriz de coeficientes, b el término independiente y x el vector de soluciones.


r
Los elementos de A se denotarán por aij , y con bi los de b.
1
Existe una tercera operación (c), que consiste simplemente en multiplicar filas por constantes no
nulas. Esta operación recibe el nombre de reescalado (de filas) y en problemas prácticos se suele utilizar
con el fin de mejorar la estabilidad del sistema frente a errores de redondeo.
2
Otra posibilidad es intercambiar columnas, que se corresponde con reordenar las incógnitas). En este
caso se habla de pivotaje total.

37
3.1 Método de Gauss LECCIÓN I

3.1.1. Método de Gauss sin pivotaje


El pseudocódigo se expone a continuación

Método de Gauss
Bo
01 for i = 1 : n − 1
02 for k = i + 1 : n
03 `ki = aki /aii
04 for j = i + 1 : n
05 akj = akj − `ki aij
06 end
07 bk = bk − `ki bi
08 end
09 end
10
11 xn = bn /ann
12 for i = n − 1 : −1 : 1
rra
 Xn 
13 x i = bi − aij xj /aii
j=i+1
15 end

Las lı́neas 01--09 se corresponden con la reducción a la forma triangular de la matriz


y las lı́neas 11--15 con la resolución del sistema triangular resultante. El elemento aii se
denomina pivote y debe ser distinto de cero para que el algoritmo funcione, dado que en
caso contrario la operación en 03 está mal definida.
El algoritmo efectúa O(n3 /3) productos3 y otras tantas sumas para la reducción a la
forma triangular y O(n2 /2) sumas y productos para la resolución del sistema triangular.
do
Por tanto el costo se concentra en la primera fase del algoritmo y duplicar la dimensión
del sistema exige multiplicar por ocho el tiempo de cálculo (y por cuatro el costo en
memoria).

Ejercicio 3.1 Implementa una función cuyas entradas sean la matriz de coeficientes y el
término independiente y devuelva la solución del sistema por el método de Gauss.

Solución. El siguiente programa es una solución del ejercicio

01 % GAUSS
r
02 %
03 %
04 % X=GAUSS(A,B) Solucion del sistema Ax=b con el metodo
05 % de Gauss sin pivotaje
3
es decir, el número de multiplicaciones es n3 /3 + αn2 + βn + γ, donde α, β y γ son constantes
adecuadas. Con n creciente, el primer término es el dominante.

38
LECCIÓN I Capı́tulo 3. Métodos directos para sistemas de ecuaciones lineales

06
07 function x = gauss(a,b)
08 n=length(a);
09
10 % transformacion del sistema en uno triangular
11 for i=1:n-1
Bo
12 for k=i+1:n
13 l=a(k,i)/a(i,i);
14 for j=i+1:n
15 a(k,j)=a(k,j)-l*a(i,j);
16 end
17 b(k)=b(k)-l*b(i);
18 end
19 end
20
21 % resolucion del sistema triangular
22 x=zeros(n,1); % tambien vale x=b*0;
23 x(n)=b(n)/a(n,n);
rra
24 for i=n-1:-1:1
25 s=0;
26 for j=i+1:n
27 s=s+a(i,j)*x(j); % sumatorio
28 end
29 x(i)=(b(i)-s)/a(i,i);
30 end
31 return


El código anterior es correcto y ciertamente recuerda a la sintaxis que usarı́amos en una
do
programación en un lenguaje tradicional como C o Pascal. Sin embargo desde el punto de
vista de Matlab es claramente redundante y muy mejorable. Los siguientes ejercicios
ahondan en estos aspectos por lo que resolverlos es muy recomendable.

Ejercicio 3.2 Reescribe el programa utilizando instrucciones y sintaxis propia de Matlab.

Solución. Las filas 14-16 del programa (04--06 del algoritmo) se pueden implementar
como una diferencia de dos vectores, a(k,i+1:n) y a(i,i+1:n), con cualquiera de estas
dos instrucciones
r
a(k,i+1:n) =a(k,i+1:n) - l*a(i,i+1:n)
a(k,:) =a(k,:) - m*a(i,:)

La segunda es más cómoda de utilizar pero multiplica por dos el número de operaciones
en la ejecución del método4 .
4
¿Por qué?.

39
3.1 Método de Gauss LECCIÓN I

De forma análoga, el sumatorio de las lı́neas 25-29 del código (13 del algoritmo del
método de Gauss) es simplemente el producto escalar, y de hecho también matricial, de
dos vectores, el vector fila a(i,i+1:n) y el vector columna x(i+1:n). Esto es el código
de las lı́neas 25--29 se puede sustituir por
x(i)=(b(i)- a(i,i+1:n)*x(i+1:n))/a(i,i);
Bo

Ejercicio 3.3 (Avanzado) Podemos avanzar aún más hacia la consecución de algoritmos
matriciales. Consideremos la partición de A
a11 c>
   
1 b1
A= , b=
d1 A11 b1
donde c1 , d1 son vectores (n − 1) × 1 y A11 una matriz (n − 1) × (n − 1). Entonces, el primer
paso del método de Gauss se puede escribir
c>
   
a11 1 b 1
, b=
0 A11 − (a11 )−1 c> 1 d1 b1 − a−1
11 b1 d1 .
rra
| {z } | {z }
(1) (1)
A b
El segundo paso del método de Gauss se aplica ahora sobre la matriz A(1) (de tamaño (n−1)×
(n − 1)) y el vector b(1) (de tamaño (n − 1) × 1) y ası́ se procede sucesivamente. Implementa
esta resolución alternativa del método de Gauss.
(Ayuda. Observa estas tres instrucciones
l=a(i+1:n,i)/a(i,i) a(i+1:n,i+1:n)-l*a(i,i+1:n) b(i+1:n)-l*b(i)
¿Qué hacen?)

Nota sobre la vectorización


La noción de vectorización, trabajar con vectores y matrices en lugar de elemento a ele-
do
mento, no es nueva ni en el Análisis Numérico ni en la computación a alto nivel. El objetivo
que se persigue es que las todas las operaciones se reduzcan a operaciones matemáticas
sencillas, como productos escalares, productos matriciales, búsqueda de máximos y mı́ni-
mos en un vector/matriz, suma de vectores y matrices... cuya implementación se opti-
miza tomando en consideración el entorno en el que se trabaja, tanto en software como
en hardware. Este conjunto de instrucciones se conocen como BLAS (basic linear algebra
subprograms). Se distinguen tres niveles. El nivel uno está formada por operaciones entre
vectores, tales como la suma o el producto escalar de dos vectores, de O(n) operaciones, el
nivel dos se ocupa de operaciones matriz-vector con O(n2 ) operaciones y el nivel tres son
operaciones entre matrices, O(n3 ) operaciones. En máquinas con múltiples procesadores
r
estos subprogramas deben adaptarse a dividir la tarea entre los procesadores disponibles
de forma óptima y a buscar algoritmos que soporten este tipo de trabajo5 .
5
Se deben buscar en primer lugar algoritmos que permitan dividir la tarea principal en subtareas
equiparables, y de forma que finalicen en tiempos similares puesto que basta con que una de las subtareas
se retrase respecto a las demás para que el conjunto de procesadores deba parar a esperar al rezagado
con la consiguiente pérdida de tiempo (y dinero).

40
LECCIÓN I Capı́tulo 3. Métodos directos para sistemas de ecuaciones lineales

Uno de los detalles más sencillos que hay que plantear es la estrategia de almace-
namiento de las matrices en memoria. Se puede optar por un almacenamiento por filas,
como hace C,

 
a11 a12 a13
A= ⇒ a11 → a12 → a13 → a21 → a22 → a23
a21 a22 a23
Bo
donde con la notación anterior queremos decir que aij y aij+1 ocupan posiciones consec-
utivas en memoria.
Sin embargo Fortran o Matlab proceden por columnas

 
a11 a12 a13
A= ⇒ a11 → a21 → a12 → a22 → a13 → a23 .
a21 a22 a23

Según sea el caso se trata de primar algoritmos que accedan a la matriz por filas o por
columnas para que el procesador trabaje con posiciones consecutivas de memoria6 . En esta
rra
dinámica, la resolución del sistema triangular según el algoritmo expuesto en el Ejercicio
3.3 está mejor adaptado a la arquitectura de Matlab puesto que todas las operaciones se
hacen sobre columnas de la matriz a.

3.1.2. Método de Gauss con pivotaje parcial

Para evitar que el método de Gauss se colapse, es decir, que encuentre en un paso i
que el elemento aii es nulo (lı́nea 03 del algoritmo), se introduce la noción de pivotaje. La
idea es muy sencilla: en el caso de que en el i–ésimo paso el pivote sea nulo, se procede a
intercambiar la fila i por una fila k tal que aki 6= 0 para cierto k > i. Si esto no es posible,
do
el sistema no es compatible determinado, es decir, o no tiene solución o tiene infinitas
soluciones.
Desde un punto de vista práctico, el método de Gauss con pivotaje procede a inter-
cambiar siempre filas de forma que en cada paso

|aki | = máx |a`i |,


`=i,...,n

esto es, el pivote es el mayor posible. Ello dota al sistema de una mayor estabilidad frente
a los errores de redondeo. El algoritmo resultante es el siguiente (denotamos por a ↔ b el
r
intercambio de valores de a y b).

6
Cuando un procesador moderno lee algo en memoria, suele cargar a su memoria internar, la memoria
caché, posiciones adicionales y consecutivas de memoria bajo la convicción de que es probable que las
requiera en el siguiente paso.

41
3.1 Método de Gauss LECCIÓN I

Método de Gauss con pivotaje parcial

01 for i = 1 : n − 1
02
03 Encontrar k ∈ {i, . . . , n} tal que |aki | = máx |a`i |
j=`,...,n
04 for j = i : n
Bo
05 aij ↔ akj %intercambio filas y termino independiente
08 end
07 bi ↔ bk
08
09 for k = i + 1 : n
10 `ki = aki /aii
11 for j = i + 1 : n
12 akj = akj − `ki aij
13 end
14 bk = bk − `ki bi
15 end
16 end
rra
Ejercicio 3.4 Implementa una función con el método de Gauss con pivotaje a partir de la
función definida en el Ejercicio 3.2.
Para este fin la instrucción max te puede resultar útil. Especı́ficamente,
>> [m,i]=max(v)
devuelve en m el mayor valor del vector v y en i su posición, esto es, m = v(i). Añade también
un control sobre el tamaño de a(i, i) de forma que si éste es próximo a cero7 se termine la
ejecución y se devuelva un mensaje de error.
do
(Ayuda. La instrucción [m,r]=max(abs(a(i:n,i))) te devolverá en r la posición del máximo
en el vector columna abs(a(i:n,i)). Por tanto, la fila en la matriz a con el mayor valor en la
columna i es i+r-1.)

El intercambio de filas de las lı́neas 04--08 se puede implementar de varias formas.


La primera es simplemente con un bucle que recorra las filas y proceda a intercambiar los
valores elemento a elemento. En la segunda forma se hace de forma global mediante
aux=a(i,i:n); a(i,i:n)=a(k,i:n); a(k,i:n)=aux;
La tercera forma probablemente será la que resulte más extraña pero vuelve a ser natural
en Matlab. Basta hacer
r
a([i,k],i:n)=a([k,i],i:n)
Fı́jate que tiene perfecto sentido sintáctico de acuerdo a las reglas de manipulación de
vectores y matrices expuestas en la primera parte de esta lección.
7
¿Cuándo se decide que un número es cero? En la práctica depende de los tamaños del resto de
elementos de la matriz.

42
LECCIÓN I Capı́tulo 3. Métodos directos para sistemas de ecuaciones lineales

3.1.3. Método de Gauss con pivotaje parcial ficticio


Desde un punto de vista práctico no hace falta intercambiar fı́sicamente las filas de la
matriz. En lugar de ello se puede utilizar un vector de ı́ndices p de forma que p(i) sea la
posición fı́sica en memoria de la fila i.
Inicialmente, las filas están sin reordenar, es decir, se empieza declarando
Bo
p=1:n;

Intercambiar las filas i y k es equivalente a intercambiar los valores de p en las posiciones


iyk

p([i k])=p([k i])

y se procede a hacer ceros en las filas p(i+1),. . . , p(n). El acceso la fila i se consigue con

a(p(i),:)

y la búsqueda del máximo valor para el intercambio de filas con


rra
[m,r]=max(abs(a(p(i:n),i)));r=r+i-1;

La fila con el máximo elemento en valor absoluto es la p(r).


Para la resolución del sistema triangular despejamos igual que en el método de Gauss,
desde la n-ésima incógnita a la primera, con

22 x(p(n))=b(p(n))/a(p(n),n);
23 for i=n-1:-1:1
24 x(p(i))=(b(p(i))-a(p(i),i+1:n)*x(i+1:n))/a(p(i),i);
25 end

Desde un punto de vista estrictamente matemático se trata de llevar la matriz a una


forma que, si bien no es triangular, una reordenación adecuada de las filas la transforma
do
en triangular. El vector p recoge en qué orden se deben despejar las incógnitas a la hora
de resolver el sistema reducido. En concreto el orden viene dado por p(n), p(n-1),. . . ,
p(1). En cualquier caso, a(p,:) es una matriz triangular8 .

Ejercicio 3.5 Implementa el método de Gauss con pivotaje parcial ficticio.

Ejercicio 3.6 Las lı́neas 22–25 proceden a resolver el sistema triangular accediendo a los
elementos por filas. Adapta el algoritmo para la resolución de este sistema por columnas, tal
como se hizo en el Ejercicio 3.3.
r
Ejercicio 3.7 Sea A una matriz inversible de tamaño n × n y A−1 su inversa. Si ai es la
columna i−ésima de A−1 , esto es,

A−1 = [a1 |a2 | · · · |an ],


8
La importancia de estas técnicas ha decrecido con las últimas generaciones de ordenadores, donde la
manipulación de enormes cantidades de memoria está muy optimizada.

43
3.2 Descomposiciones matriciales LECCIÓN I

entonces  
0
 .. 
 . 
Aai = ei =  1  → i.
 
 . 
 .. 
0
Bo
Utilizando alguna de las diferentes versiones del método de Gauss, implementa el cálculo de la
inversa mediante la resolución de los n sistemas de ecuaciones. Observa que los n comparten
la misma matriz de coeficientes.

3.2. Descomposiciones matriciales


Uno de los aspectos que mejores resultados dio a lo largo del siglo XX, en los albores del
Análisis Numérica, fue la constatación de que numerosos algoritmos del Álgebra Lineal,
podı́an reescribirse como factorizaciones de matrices en producto de otras matrices con
caracterı́sticas muy particulares. Éste es el caso del algoritmo de Gram-Schmidt, la matriz
rra
original escrita como el producto de una ortogonal por una triangular, o el caso que nos
ocupa, el método de Gauss, visto como la búsqueda de la factorización de A como el
producto de una matriz triangular inferior por una superior.
La utilidad que se concedió a este tipo de factorizaciones fue en un primer momen-
to más bien teórica pero rápidamente se encontró aplicaciones prácticas y su uso en la
actualidad es profuso.
Estudiaremos en lo que sigue la factorización LU y variantes y dejaremos para más
adelante (Lección IV) otro tipo de factorizaciones.

3.2.1. Descomposición LU
Supongamos que se dispone de una descomposición
do
A = LU

donde L y U son matrices triangulares inferior y superior respectivamente. En este caso, la


resolución del sistema lineal Ax = b es equivalente a resolver dos sistemas de ecuaciones
triangulares
Ly = b, U x = y.
el primero triangular superior y el segundo triangular inferior. Puesto que el costo de
resolución de cada sistema es O(n2 ) operaciones (total de sumas y productos) obtenemos
una ventaja decisiva en la resolución del sistema.
r
Ejercicio 3.8 Implementa la resolución de un sistema de ecuaciones Lx = b donde L es
triangular inferior con 1s en la diagonal.

Si abordamos directamente la resolución de la ecuación A = LU , nos encontramos


con un sistema no lineal con n2 + n incógnitas (las entradas de L y U ) y n2 ecuaciones
(una por cada elemento de a). Por tanto, el sistema resultante no deberı́a admitir solución

44
LECCIÓN I Capı́tulo 3. Métodos directos para sistemas de ecuaciones lineales

única. Si exigimos que L tenga 1s sobre la diagonal, el número de incógnitas pasa a ser
de n2 y por tanto tenemos ya un sistema cuadrado (aunque no lineal). Se trata entonces
de estudiar el siguiente problema: dada una matriz A de tamaño n × n, encontrar L y U
de la forma
   
1 u11 u12 · · · u1n
Bo
 `21 1   u22 · · · u2n 
L =  .. , U = ..  ,
   
.. . . . .
 . . .   . . 
`n1 `n2 · · · 1 unn

y tales que A = LU.


El cálculo de esta descomposición se puede llevar a cabo sin más que exigir que el
producto LU sea igual al de A. Ası́ empezamos despejando la primera fila de U (que es
igual que la de A por ser `11 = 1). Una vez conocida esa fila, se puede despejar la primera
columna de L, utilizando que el producto de L por la primera columna de U (que consta
de un único elemento no nulo y ya es conocido del paso anterior) da la primera columna de
A. Procedemos sucesivamente de esta forma, construyendo U por filas y L por columnas.
rra
Descomposición LU (Método de Doolittle)

01 for k = 1 : n
02 for j = k : n
k−1
X
03 ukj = akj − `kp upj
p=1
04 end
05 `kk = 1
06 for i = k + 1:n
 k−1
X 
07 `ik = aik − `ip upk /ukk
do
p=1
08 end
09 end

El número de operaciones del algoritmo resulta ser igual al del método de Gauss,
con lo cual no hemos conseguido una ventaja significativa. Sin embargo, disponer de esta
descomposición es especialmente útil si se requiere resolver varios sistemas de ecuaciones
lineales con la misma matriz pero con términos independientes diferentes. Las operaciones
que conllevan un mayor coste son las correspondientes al cálculo de las matrices L y
r
U , pero únicamente hay que realizar esta descomposición una vez para posteriormente
resolver en cada caso dos sistemas triangulares.

Ejercicio 3.9 Implementar la descomposición LU en Matlab mediante una función cuya


entrada sea una matriz cuadrada y su salida sean las matrices L y U correspondientes.
(Ayuda: la función por tanto devuelve dos valores.)

45
3.2 Descomposiciones matriciales LECCIÓN I

Al observar el algoritmo del método, las operaciones recuerdan a las efectuadas por el
método de Gauss. Esto no es tan sorprendente cuando se analizan con detenimiento los
calculados realizados. Se puede ver entonces que en el cálculo de la descomposición LU se
están haciendo exactamente las mismas operaciones que al aplicar el método de Gauss.
En efecto, definamos
( (1)
Bo
aij = aij i, j = 1, . . . , n
(k+1) (k) (k)
aij = aij − `ik akj , k ≥ 1, 1 ≤ i, j ≤ n − k
donde `ki viene dada por el algoritmo de Doolitle (lı́nea 07).
Entonces, de acuerdo con el algoritmo de la factorización LU , los elementos de la
primera fila de U y de la primera columna de L vienen dados por
(1)
(1) ai1
u1j = a1j , `i1 = (1)
.
a11
En el siguiente paso, se observa que
(1) (1) (2)
u2j = a2j − `21 u1j = a2j − `21 a1j = a2j
rra
(1) (1) (2)
ai2 − `i1 u12 a − `i1 a a
`i2 = = i2 (2) 12 = i2(2)
.
u22 a22 a22
Reiterando el mismo razonamiento concluimos que
(j)
(i) aij
uij = aij , i ≤ j, `ij = (j)
, i > j.
ajj
Por tanto U es de hecho la matriz triangular que queda al aplicar el método de Gauss
mientras que L está formada por los elementos que se han utilizado para hacer ceros en
el proceso. Esto es, el elemento i, j de L, denotado por `ij , coincide con la constante `ij
calculado en la lı́nea 03 del método de Gauss y por tanto no hay una contradicción de
notaciones.
do
En particular, la propiedad anterior propone una forma alternativa de calcular la de-
scomposición LU de una matriz es la siguiente modificación del programa del Ejercicio 3.1:

11 for i=1:n-1}
12 a(i,i+1:n)=0; %hacemos cero la columna i
13 for k=i+1:n}
14 l(k,i)=a(k,i)/a(i,i);
15 a(k,i+1:n)=a(k,i+1:n)-l(k,i)*a(i,i+1:n);
16 end
17 end
r
La matriz U estarı́a entonces almacenada en a.
Ejercicio 3.10 Una forma compacta de devolver la descomposición LU es insertar L en la
parte triangular inferior de a. De esta forma, tras aplicar el método, a tiene en la parte superior
la matriz U , mientras que por debajo de la diagonal encontramos L (exceptuando su diagonal
de 1s). Implementa esta modificación.

46
LECCIÓN I Capı́tulo 3. Métodos directos para sistemas de ecuaciones lineales

3.2.2. Casos particulares


Método de Cholesky
En una gran variedad de problemas prácticos aparecen matrices simétricas definidas
positivas. Este tipo de matrices puede descomponerse en la forma
Bo
A = LL>

donde  
`11
 `21 `22 
L= .
 
.. .. . .
 . . . 
`n1 `n2 · · · `nn
Gracias a la simetrı́a de la matriz, tanto el número de operaciones como de posiciones
de memoria requeridos pueden reducirse a la mitad. El algoritmo resultante es conocido
como el método de Cholesky.
Método de Cholesky
rra
01 for k = 1:n
v
u
u k−1
X
02 `kk = takk − `2kr
r=1
03 for j = k + 1:n
 k−1
X 
04 `jk = ajk − `jr `kr /`kk
r=1
05 end
06 end
do
Ejercicio 3.11 Implementa una función que tenga como entrada una matriz A y devuelva
la matriz L correspondiente. Debe avisar si la descomposición no ha podido llevarse a cabo.
Implementa también una segunda función que tenga como entradas la matriz L triangular
y un término independiente b y que devuelva la solución del sistema

(LL> )x = b.

Para ello se requiere la resolución de los sistemas triangulares


r
Ly = b, L> x = y.

LU con permutación
El método de Gauss con pivotaje parcial es equivalente a la decomposición

P A = LU

47
3.2 Descomposiciones matriciales LECCIÓN I

donde P es el resultado de permutar las filas (o columnas) de la identidad. Alternativa-


mente, equivale a una descomposición de la forma

A = LU
b
Bo
b = P −1 L, de forma que L
donde L b es una permutación de la matriz triangular inferior9 .
La siguiente subrutina devuelve esa descomposición.

01 % LUPERMUTACION
02 %
03 % [L,U]=LUPERMUTACION(A)
04 %
05 % devuelve U triangular superior, L permutacion
06 % por filas de una matriz triangular inferior con
07 % 1s en la diagonal de forma que A=L*U
rra
08
09 function [l,u]= LUPermutacion(a)
10 n=length(a);
11 p=1:n;
12
13 for i=1:n-1
14 [maximo,r]=max(abs(a(p(i:n),i)));r=r+i-1;
15 p([i r])=p([r i]);
16 for k=i+1:n
17 l(p(k),i)=a(p(k),i)/a(p(i),i);
18 a(p(k),i:n)=a(p(k),i:n)-l(p(k),i)*a(p(i),i:n);
19 end
do
20 end
21 for i=1:n
22 l(p(i),i)=1;
23 end
24 u=a(p,:);
25 return

3.2.3. Comandos correspondientes en Matlab


r
Todas las factorizaciones vistas con anterioridad están, por supuesto, implementadas
en Matlab. Algunos de los comandos relacionados son

9
Esto es, es el resultado de reordenar las filas de L.

48
LECCIÓN I Capı́tulo 3. Métodos directos para sistemas de ecuaciones lineales

[l,u]=lu(a) devuelve u triangular superior, l permutación de una triangular inferior


con 1s en la diagonal de forma que a=l*u.

[l,u,p]=lu(a) devuelve u triangular superior, l triangular inferior con 1s en la diagonal


y p matriz de permutación de forma que p*a=l*u.

r=chol(a) devuelve r triangular superior de forma que a=r’*r. Observa que con
Bo
las notaciones introducidas r es precisamente la traspuesta de la matriz
L, expuesta en nuestro algoritmo. El comando asume que la matriz es
simétrica por lo que sólo trabaja con la parte superior de la matriz.

Otra descomposición habitual10 es la denominada QR que devuelve Q ortogonal (es decir,


Q> Q = In ) y R triangular superior de forma que A = QR. El comando encargado de esta
tarea es qr.
Con estas instrucciones la solución de un sistema utilizando la descomposición LU se
ejecuta con las siguientes lı́neas

[l,u]=lu(a); x=u\(l\b);
rra
La colocación de los paréntesis es esencial. Con u\l\b se calcula (u−1 l)−1 b que obvia-
mente no tiene nada que ver con la solución del sistema. No hay que preocuparse por el
hecho de que las matrices sean triangulares (o permutación de una triangular). Matlab, y
en concreto la instrucción \ detecta esto y resolverá el sistema por sustitución progresiva
(o regresiva), sin intentar realizar la eliminación gaussiana.

Nota histórica11
Ideas similares a la eliminación gaussiana pueden encontrarse muchos siglos atrás, con
referencias que se remontan a las matemáticas babilónicas y chinas. Carl Friedreich Gauss
introdujo el método que lleva su nombre entorno a 1800 cuando trataba de resolver un
problema de ajuste por mı́nimos cuadrados relacionado con el cálculo de la órbita del
do
asteroide Palas. Parece ser que Joseph Louis Lagrange habı́a utilizado ideas similares 50
años antes para dilucidar si una forma cuadrática (hoy dirı́amos matriz) era definida pos-
itiva. El matemático alemán Carl Gustav Jacob Jacobi extendió la idea de la eliminación
gaussiana a matrices arbitrarias.
Es reseñable que la noción de matriz tal como la conocemos ahora era desconocida
para Gauss y Lagrange. El concepto de matriz, y el álgebra asociada (esto es, las opera-
ciones) habrı́an de esperar a los trabajos de James J. Sylvester (que en 1848 introdujo el
término matriz) y de Arthur Cayley (que siete años después definió el producto matricial
identificándolo con el cálculo de la composición de aplicaciones lineales y definió la in-
versa de una matriz). Importantes fueron también las contribuciones del fı́sico Hermann
r
10
Veremos dos algoritmos para obtener esta descomposición en la Lección IV. Aunque para la resolución
de sistemas de ecuaciones lineales la descomposición QR es más estable numéricamente que la LU, se
suele optar por esta última por tener un menor coste computacional (aproximadamente la mitad).
11
Las principales referencias utilizadas para esta nota han sido “Very Early Days of Matrix Compu-
tations”, Beresford Parlett en SIAM News, 3, no 9; “Matrix Algorithms”, G.W. Stewart; “Computer
solutions of large system of equations”, G. Merant y “An introduction to Numerical Analysis”, E. Süli y
D. Mayers. Estas referencias están completamente detalladas en la bibliografı́a.

49
3.2 Descomposiciones matriciales LECCIÓN I

Grassmann (introdujo la primera álgebra vectorial no conmutativa, basada en el producto


vectorial de dos vectores; consideró también el producto de un vector fila por un vector
columna que daba lugar a una matriz de rango uno), Willard Gibbs y Paul A. Dirac.
La equivalencia entre la descomposición LU y la eliminación gaussiana parece que fue
probada por primera vez por Paul S. Dwyer en 1944. Curiosamente, la descomposición
de Cholesky es anterior. Publicado póstumamente en 1924 en una revista de Geodesia
Bo
(André-Louis Cholesky murió en 1918). El trabajo original trataba sobre la resolución
de un problema de ajuste por mı́nimos cuadrados y pasó desapercibido hasta que fue
rescatado por John Todd a finales de los años 1940.
Los primeros análisis sobre la estabilidad numérica de la eliminación gaussiana, es
decir la viabilidad de su programación, se remontan a los trabajos de Harold Hotelling,
Alan Turing12 , John von Neumann y Herman Heine Goldstine. Los resultados iniciales
eran descorazonadores. Harold Hotelling probó en torno a 1940 que el error de redondeo
podrı́a crecer como 4n donde n era el orden de la matriz. Este resultado colocaba al método
de Gauss como un método inviable para la resolución de grandes sistemas lineales. Turing
llegó a resultados similares de manera informal. El análisis de Neumann y Goldstine ya
probaba que el método era estable para matrices definidas positivas13 . James H. Wilkinson,
reconocido universalmente como el padre del análisis moderno de estabilidad (frente a los
rra
errores de redondeo), extendió el análisis a matrices generales y mostró que el pivotaje
mejoraba enormemente la estabilidad del método. Lo más curioso es que el análisis inicial
estaba enfocado más hacia el cálculo de la inversa de la matriz que al método de Gauss.
Como curiosidad final, Cleve Moler, programador original de Matlab, cita14 a Wilkinson
y Todd entre las personas que tuvieron una gran influencia en su formación y por ende
en los orı́genes de Matlab.
do
12
La vida de Alan Turing es una de las más trágicas en historia de las matemáticas. Dotado de una in-
teligencia precoz, realizó contribuciones importantes en lógica y computación. Trabajó durante la segunda
guerra mundial en Bletchley Park en el descifrado de los códigos alemanes encriptados con la máquina
r
Enigma mediante la utilización del primer ordenador electrónico en el mundo (Colossus). El papel que
este trabajo anónimo tuvo en la victoria aliada, los alemanes siempre estuvieron seguros de que su código
era indescifrable, sólo ha empezado a reconocerse en fechas recientes. La presión y aislamiento a la que
Turing fue sometido por su homosexualidad, llegando incluso a ser detenido por ello, le llevó al suicidio
en 1954 después de haberse sometido a un tratamiento con bromuro para curarle de su enfermedad.
13
En los primeros años se sugirió incluso resolución de un sistema Ax = b mediante las ecuaciones
normales A> Ax = A> b (A> A es simétrica y definida positiva).
14
http://www.mathworks.com/company/newsletters/news notes/clevescorner/dec04.html

50
Bo
Lección II

Programación avanzada en Matlab.


rra
Métodos iterativos para sistemas de
ecuaciones lineales
do
r
51
r
do
rra
Bo
Introducción
Bo
Homer: Marge? Since I’m not talking to Lisa, would you
please ask her to pass me the syrup?
Marge: Dear, please pass your father the syrup, Lisa.
Lisa: Bart, tell Dad I will only pass the syrup if it won’t be
used on any meat product.
Bart: You dunkin’ your sausages in that syrup homeboy?
Homer: Marge, tell Bart I just want to drink a nice glass of
syrup like I do every morning.
Marge: Tell him yourself, you’re ignoring Lisa, not Bart.
rra
Homer: Bart, thank your mother for pointing that out.
Marge: Homer, you’re not not-talking to me and secondly I
heard what you said.
Homer: Lisa, tell your mother to get off my case.
Bart: Uhhh, dad, Lisa’s the one you’re not talking to.
Homer: Bart, go to your room.

The Simpsons, Episodio 5, temporada 5, Lisa the Vegetarian

En el primer apartado entraremos en aspectos más avanzados en el tratamiento de


vectores y matrices en Matlab, haciendo hincapié especial en la manipulación de matrices
sparse. Veremos también cómo se pueden implementar funciones donde el número de
do
argumentos de entrada y salida son variables.
En la parte matemática, tocaremos la teorı́a básica de métodos iterativos para sistemas
de ecuaciones lineales. Empezaremos con los métodos clásicos: Jacobi, Gauss–Seidel y
relajación de Young, para pasar luego a métodos más modernos y elaborados: el método
del Gradiente y especialmente, el método del Gradiente Conjugado.
En esta lección nos permitiremos hacer algo de Matemáticas. Animamos a que el lector
no se asuste por ello y a que trate de entender los enunciados y las demostraciones que se
ofrecen. Para ello se asumen unos conocimientos mı́nimos en Álgebra Lineal.
r
53
r
do
rra
Bo
Capı́tulo 4
Bo
Matlab: programación avanzada

4.1. Retorno a las matrices


A estas alturas el lector ya deberı́a estar convencido sobre las capacidades de Matlab
en lo que se refiere al manejo de enormes cantidades de memoria. En esta sección expon-
dremos algunos comandos adicionales y entraremos con cierto detalle en la manipulación
rra
de matrices sparse1 .

4.1.1. Acceso a partes estructuradas de una matriz


En ocasiones es importante tomar partes precisas de una matriz que no son necesaria-
mente partes de filas, columnas o simplemente submatrices (estas acciones ya se trataron
en la primera lección). Para este fin nos pueden servir las siguientes instrucciones

diag triu tril

La primera toma la diagonal de una matriz mientras que la segunda y tercera toman
la parte triangular superior (upper) e inferior (lower) respectivamente. Además estos co-
do
mandos son algo más flexibles de lo que pueda parecer a simple vista como veremos a
continuación.
Empecemos introduciendo una matriz

>> a=[11 12 13; 21 22 23; 31 32 33];

El resultado de los siguientes comandos es, a la luz de lo anterior, esperable

>> diag(a)

ans =
r
11
22
33
1
Aceptaremos este anglicismo en lo que sigue. En ocasiones este vocablo se traduce por matrices huecas
o matrices dispersas.

55
4.1 Retorno a las matrices LECCIÓN II

>> triu(a)

ans =

11 12 13
Bo
0 22 23
0 0 33

>> tril(a)

ans =

11 0 0
21 22 0
31 32 33
El usuario puede especificar qué diagonal se escoge, o a partir de qué diagonal se toma
rra
la matriz triangular. La diagonal principal es la cero y las subdiagonales inferiores (respec-
tivamente superiores) están numeradas consecutivamente con números enteros negativos
(respectivamente positivos). El siguiente ejemplo ilustra estas caracterı́sticas.

>> diag(a,-1)

ans =

21
32

>> tril(a,-1)
do
ans =

0 0 0
21 0 0
31 32 0

>> triu(a,0)

ans =
r
11 12 13
0 22 23
0 0 33

Ejercicio 4.1 Programa una función que dada una matriz a devuelva un vector d con los
elementos de la diagonal, una matriz triangular superior u con todos los elementos de a situados

56
LECCIÓN II Capı́tulo 4. Matlab: programación avanzada

encima de la diagonal superior y l una matriz triangular inferior con todas las entradas de
debajo de la diagonal principal.

Ejercicio 4.2 ¿Qué sucede si aplicamos los comandos anteriores a matrices rectangulares?.

Con diag podemos también construir a partir de un vector una matriz diagonal
Bo
>> diag([1 2]) % es lo mismo que diag([1 2],0)

ans =

1 0
0 2

>> diag([1 2],1)

ans =
rra
0 1 0
0 0 2
0 0 0

Ejercicio 4.3 ¿Cómo utilizarı́as el comando diag para generar una matriz con la diagonal
de una dada?.

Nota. El comando blkdiag permite construir matrices diagonales por bloques:

>> blkdiag(1,[1 2; 3 4], 5)

ans=
do
1 0 0 0
0 1 2 0
0 3 4 0
0 0 0 5

Trasposición de matrices
Dada una matriz A, la matriz traspuesta A> es la matriz resultante de intercambiar
las filas con las columnas de A. Esto es, las filas de A pasan a ser las columnas de A> .
r
Esta operación se denota en Matlab con “ ’ ” :

>> a=[1 2 3; 0 2 4];


>> a’

ans =

57
4.1 Retorno a las matrices LECCIÓN II

1 0
2 2
3 4

Obviamente, también se aplica sobre vectores:


Bo
>> b=[1;2;3]; % vector COLUMNA con tres elementos
>> b’ % vemos ahora un vector FILA

ans =

1 2 3

De nuevo nos encontramos con esta propiedad sobre la que ya hemos incidido: Matlab
distingue entre vectores filas y columnas, y esta diferencia se hace especialmente palpable
(y en ocasiones molesta) a la hora de realizar operaciones como productos matriz-vector.
rra
Nota. En Matlab existe también el operador “.’”. Sobre matrices reales funciona exac-
tamente igual que el comando anterior, pero no ası́ sobre números complejos. Además de
trasponer, “’”, conjuga todas las entradas. Es decir, cambia el signo a la parte imaginaria
de cada elemento. Matemáticamente hablando, éste es el operador de trasposición o con-
jugación, denotado habitualmente en matemáticas con “A∗ ”. Por contra, “.’” se limita a
intercambiar filas por columnas en la matriz:

>> clear i % i es ahora la unidad imaginaria


>> a=[i 1-2i; 1 0.3+4i];
>> a.’
do
ans =

0 + 1.0000i 1.0000
1.0000 - 2.0000i 0.3000 + 4.0000i

>> a’

ans =

0 - 1.0000i 1.0000
r
1.0000 + 2.0000i 0.3000 - 4.0000i


Dada una matriz a, si ejecutamos a(:), obtenemos el vector columna que se con-
struye concatenando las columnas de a. Técnicamente hablando, nos está mostrando la
matriz tal como se guarda en memoria. Por ejemplo,

58
LECCIÓN II Capı́tulo 4. Matlab: programación avanzada

>> a=[1 2 3; 0 2 4];


>> a(:)

ans =

1
Bo
0
2
2
3
4

>> a=a’; %trasponemos a


>> a(:)

ans =

1
rra
2
3
0
2
4

Esto puede utilizarse para hacer un par de trucos:

En ocasiones la entrada de una función es un vector, sin importar si éste es fila o


columna.
La instrucción
do
>> b=b(:);

hará de b un vector columna, sea cual sea su formato inicial. Si lo que se desea es
un vector fila, basta con trasponer

>> b=b(:)’; % b=b(:).’ mejor por si b es complejo

Se puede utilizar para introducir las entradas de una matriz por columnas. A modo
de ejemplo,
r
>> a=zeros(4,3);
>> a(:)=[1 2 3 4 5 6 7 8 9 10 11 12]

a =

59
4.1 Retorno a las matrices LECCIÓN II

1 5 9
2 6 10
3 7 11
4 8 12

>> a2=zeros(2,6);
Bo
>> a2(:)=a(:)

a2=

1 3 5 7 9 11
2 4 6 8 10 12

Nota. El comando reshape permite modificar las dimensiones de una matriz (o array
en general). Es más flexible que el comando “:”. 
rra
4.1.2. Más operaciones sobre matrices
Hasta ahora las operaciones matriciales que han centrado nuestra atención son las fun-
damentales: suma y producto. En Matlab están también implementadas otras operaciones
comunes en el Álgebra Lineal. Entre todas ellas destacamos

dot: Calcula el producto escalar de dos vectores:

>> dot([1 2 3],[4 5 6])

ans =
do
32

Devuelve el produto 1 · 4 + 2 · 5 + 3 · 6 = 32. Este comando no distingue entre vectores


filas y columnas, y es aplicable siempre que tengan la misma longitud.
La función se puede aplicar a matrices bien por columnas, ésta es la forma estándar2 ,
o por filas.

>> a=[1 2 3; 4 5 6]; a2=[1 1 1; 1 1 1];


>> dot(a,a2) % producto por columnas
r
ans =

5 7 9

2
Recuerda la predilección de Matlab por las columnas.

60
LECCIÓN II Capı́tulo 4. Matlab: programación avanzada

>> dot(a,a2,2) % producto por filas

ans =

6
15
Bo
sum: calcula la suma de las entradas un vector. Es aplicable también a matrices, en el
sentido del comando anterior

>> v=[1 2 3]; a=[1 2 3; 4 5 6];


>> sum(v)

ans =

6
rra
>> sum(a) % suma por columnas

ans =

5 7 9

>> sum(a,2) % suma por filas

ans =

6
15
do
prod: Como sum pero con el producto.

max: Calcula el máximo en un vector. Puede devolver su posición en el vector. Aplicado


sobre matrices funciona de la misma forma que dot o sum. Esto es, devuelve el
máximo de cada columna por defecto, o de cada fila si ası́ se le indica

>> v=[-2 -5 -3]; a=[2 3 8; -4 2 9];


>> max(v)
r
ans=

-2

>> [p,m]=max(abs(v)); [p,m]

61
4.1 Retorno a las matrices LECCIÓN II

ans =

5 2

>> max(a)
Bo
ans =

2 3 9

>> max(a,[],2) % busqueda por filas

ans =

8
9
>> [m,p]=max(a,[],2); p % posicion del maximo
rra
ans=

1
1

La razón por la que se utiliza [] en la lı́nea anterior es que esta instrucción también
se puede utilizar para comparar dos arrays del mismo tamaño

>> a1=[3 1 2; 5 3 2]; a2=[4 2 1; 1 2 3];


>> max(a1,a2)

ans =
do
4 2 2
5 3 3

Al insertar el vacı́o indicamos a Matlab que no existe un segundo vector y que debe
proceder a buscar el máximo de a en su segunda dimensión, esto es, el máximo por
filas.

min: Calcula el mı́nimo procediendo exactamente igual que max.

norm: norma de una matriz o vector. Se puede escoger entre varias normas.
r
>> v=[1 2 3];a=[1 2; 3 4];
>> [norm(v) norm(v,1) norm(v,inf)] % norma 2, 1 e infinito de v

ans =

62
LECCIÓN II Capı́tulo 4. Matlab: programación avanzada

3.7417 6.0000 3.0000

>> [norm(a) norm(a,1) norm(a,inf)] % normas matriciales

ans =
Bo
5.4650 6.0000 7.0000

En la Sección 5.2.3 comentaremos brevemente la definición de estas normas.

rank: rango numérico de una matriz. Esto es, el número máximo de filas o columnas
linealmente independientes3 .

cond: Calcula norm(a)*norm(inv(a)), el condicionamiento de una matriz4 . El condi-


cionamiento da una medida de la sensibilidad del sistema a perturbaciones en el
término independiente.

rcond: estimador del inverso del condicionamiento de una matriz. Es sensiblemente más
económico de calcular que cond.
rra
Nota. Cuando el comando dot se aplica a dos vectores complejos, procede siempre a
conjugar el primer vector. Es decir, matemáticamente
n
X
dot(u, v) ui v i .
i=1

Ası́,
>> u=[1+i 2+2i]; v=[2 1];
>> dot(u,v)
do
ans =

4.0000 - 4.0000i

>> dot(v,u)

ans =

4.0000 + 4.0000i

r
Ejercicio 4.4 ¿Cómo sumarı́as los elementos de una matriz?. ¿Cómo encontrarı́as el mı́nimo
y el máximo?. ¿Y su posición?
3
Una matriz tiene, en general, rango máximo por los errores de precisión de la máquina. Este comando
hace una estimación del rango, eliminando este factor.
4
En realidad no construye la inversa de la matriz por ser costoso.

63
4.1 Retorno a las matrices LECCIÓN II

4.1.3. Matrices sparse


Las matrices sparse son una importante clase de matrices que surge en diferentes
ámbitos del Análisis Numérico y de las Matemáticas y ciencias en general (elementos
finitos, teorı́a de grafos,...).
En la Figura 4.1 se puede ver un ejemplo de una matriz sparse simétrica donde los
Bo
puntos indican las entradas diferentes de cero. Desde una óptica puramente computacional
hace falta desarrollar sistemas de almacenamiento especiales dado que la inmensa mayorı́a
de las entradas no deben ser almacenadas porque son nulas.
rra
Figura 4.1: Diagrama de un matriz sparse 400 × 400 con 2690 elementos no nulos.

Matlab provee de forma muy sencilla ese almacenamiento. Con


do
>>a=sparse(100,100); b=sparse(100,1);

declaramos a como una matriz sparse 100×100 y un vector columna b de 100 elemen-
tos. Todas las entradas son inicialmente ceros, pero se guarda la estructura básica para
introducir los elementos no nulos

>> a=sparse(100,100)

a =

All zero sparse: 100-by-100


r
>> a(4,4)=1; a(8,9)=-4; a(80,45)=-1; a(99,100)=4;
>> a

a =

64
LECCIÓN II Capı́tulo 4. Matlab: programación avanzada

(4,4) 1
(8,9) -4
(80,45) -1
(99,100) 4

Para transformar una matriz llena (convencional) en una matriz sparse podemos utilizar
Bo
también este comando

>> a=diag([1 2 3 4 5]);


>> a=sparse(a)

a =

(1,1) 1
(2,2) 2
(3,3) 3
(4,4) 4
(5,5) 5
rra
Con full realizamos la operación inversa: transforma una matriz sparse en una matriz
llena,

>> a=full(a)

a =

1 0 0 0 0
0 2 0 0 0
0 0 3 0 0
0 0 0 4 0
0 0 0 0 5
do
La instrucción spalloc tiene un funcionamiento muy similar a sparse. Es útil si se sabe
el número de elementos no nulos que tendrá dicha matriz. Concretamente

>> a=spalloc(8,7,12)

declara una matriz 8 × 7 con a lo sumo 12 elementos no nulos. Al informar de cuántos


elementos no nulos se esperan Matlab hace una gestión más eficiente de la memoria.
El comando nnz (Non zeros) nos informa del número de elementos no nulos de una
matriz, mientras que su esquema (pattern), como el que aparece en la Figura 4.1, se obtiene
con spy:
r
>> a=sparse(10,10);
>> a(1,4)=1; a(2,8)=-4; a(3,9)=1; a(7,8)=5;
>> nnz(a)

ans=

65
4.2 Argumentos de funciones LECCIÓN II

>> spy(a)

La gráfica se despliega en una ventana separada.


Todas las operaciones que hemos visto están adaptadas al nuevo entorno. Ası́, los
Bo
operadores

: triu tril diag

devuelven vectores/matrices sparse. Las operaciones

* + .* dot ’

están asimismo optimizadas. El problema de generar código eficiente no es tan simple


como pudiera parecer. Por ejemplo, si se aplica la función dot a dos vectores sparse es
preciso saber antes qué entradas hay que multiplicar. De otra forma podrı́amos estar
dedicando un alto porcentaje de nuestro esfuerzo en simplemente calcular productos por
cero. Afortunadamente, Matlab hace ese trabajo por nosotros.
rra
Por otro lado, aparecen una nueva serie de comandos, que devuelven matrices sparse,
entre los que merece la pena destacar
spdiags maneja las diagonales de una matriz de forma análoga a diag;

speye devuelve una matriz diagonal con unos, o similar (análoga a eye);

spones matriz de 1s, similar a ones;

sprand, sprandn construyen una matriz sparse con entradas aleatorias (similar a
rand);

Ejercicio 4.5 Con la ayuda de Matlab averigua la sintaxis concreta de los comandos ante-
do
riores y comprueba con algún ejemplo cómo funcionan.

4.2. Argumentos de funciones


Veremos a continuación cómo se pueden programar funciones en las que tanto el
número de argumentos de entrada como de salida sean variables. Esta caracterı́stica dota
de una mayor flexibilidad a la programación en Matlab.
Los comandos esenciales que precisamos son

varargin nargin varargout nargout


r
La instrucciones nargin y nargout informan respectivamente sobre el número de variables
de entrada y el número de variables de salida (number of input arguments y number of
output arguments).
Una función puede aceptar una serie de argumentos fijos, al estilo de las funciones que
programamos en la lección anterior, y un conjunto de argumentos opcionales, que pueden

66
LECCIÓN II Capı́tulo 4. Matlab: programación avanzada

ser o no especificados por el usuario. Para su acceso se utilizan respectivamente varargin


(variable input argument) y varargout (variable output argument) mediante llaves ({})5 .
Mostramos a continuación un ejemplo de utilización conjunta de estas nuevas instruc-
ciones. En la cabecera se informa de qué hace la función, dependiendo de los argumentos
de entrada y salida.
Bo
01 % DESCOMPOSICIONLU
02 %
03 % [L,U] = DESCOMPOSICIONLU(A)
04 % Devuelve U triang superior, L permutacion de una
05 % triang inferior con 1s en la diagonal tal que A=LU
06 %
07 % [L,U,X] = DESCOMPOSICIONLU(A,B)
08 % Devuelve U triang superior, L permutacion de una
09 % triang. inferior con 1s en la diagonal tal
10 % que A=LU y la solucion del sistema AX=B
11
12 function varargout=DescomposicionLU(a,varargin)
rra
13
14 [l,u]=lu(a); % descomposicion LU
15
16 if nargin==1 & nargout==2
17 varargout{1}=l;
18 varargout{2}=u;
19 elseif nargin==2 & nargout==3
20 b=varargin{1}; % leemos el primer argumento opcional...
21 varargout{1}=l; varargout{2}=u;
22 varargout{3}=u\(l\b); % solucion del sistema
23 end
do
Como puede comprobarse, la función precisa de un argumento obligatorio, la matriz
a, uno opcional, el término independiente, y devuelve dos o tres argumentos según se
requiera. Observa los resultados que se han obtenido para varios ejemplos:

>> a=[1 3; 2 4];


>> [l,u]=DescomposicionLU(a)

l =

0.5000 1.0000
r
1.0000 0

u =

5
Las variables varargin y varargout son de un tipo especial denominado cell array. En la Lección
IV estudiaremos su funcionamiento con más detalle.

67
4.2 Argumentos de funciones LECCIÓN II

2 4
0 1

>> [l,u,x]=DescomposicionLU(a,[1 2].’)

l =
Bo
0.5000 1.0000
1.0000 0

u =

2 4
0 1

x =

1
rra
0

>> [l,u]=DescomposicionLU(a,[1 2]) %falta un arg. de salida

??? Error using ==> DescomposicionLU


Too many output arguments.

>> [l,u,x]=DescomposicionLU(a) %faltan arg. de entrada


??? Error using ==> DescomposicionLU
Too many output arguments.

Ejercicio 4.6 A partir de la función anterior implementa una función que opere según la
do
“siguiente cabecera”
% DESCOMPOSICIONLU2
%
% R = DESCOMPOSICIONLU2(A)
% Si A es simetrica definida positiva devuelve
% R triang superior tal que A=R’R
% [R,X] = DESCOMPOSICIONLU2(A,B)
% Si A es simetrica definida positiva devuelve
% R triang superior tal que A=R’R y la solucion
% del sistema AX=B
r
% [L,U] = DESCOMPOSICIONLU2(A)
% Devuelve U triang superior, L permutacion de
% una triang. inferior con 1s en la diagonal
% tal que A=LU
% [L,U,X]= DESCOMPOSICIONLU2(A,B)
% Devuelve U triang superior, L permutacion de

68
LECCIÓN II Capı́tulo 4. Matlab: programación avanzada

% una triang. inferior con 1s en la diagonal


% tal que A=LU y la solucion del sistema AX=B

Nota: Realizar la comparación A’==A para testar si la matriz es simétrica. ¿Qué devuelve esta
comparación? ¿Cómo se puede utilizar para comprobar si efectivamente la matriz es simétrica?
¿Y para ver que es definida positiva?.
Bo
rra
do
r
69
4.2 Argumentos de funciones LECCIÓN II
Bo
rra
do
r
70
Capı́tulo 5
Bo
Matrices sparse en Matemáticas.
Métodos iterativos para sistemas de
ecuaciones lineales

5.1. Método de Gauss para matrices sparse


rra
Esta sección se centra en el estudio del método de Gauss para matrices sparse. Mostraremos
los problemas que presenta la aplicación de este algoritmo a este tipo de matrices, espe-
cialmente el efecto relleno y algunas estrategias de reordenamiento que mitigan estos
efectos adversos. Sirve asimismo para ahondar en la problemática de los métodos directos
y allanar y fundamentar los métodos iterativos que se tratan en las siguientes secciones.
Recordemos que en Matlab la resolución de sistemas de ecuaciones utilizando

>> x=a\b;

se basa en el método de Gauss (o alguna de sus variantes). Puede plantearse la cuestión de


si es adecuado utilizar “\” para matrices con formas especiales como por ejemplo matrices
do
triangulares o permutaciones de éstas, para las que la eliminación gaussiana no es nece-
saria puesto que las variables se pueden despejar de forma progresiva. Afortunadamente
Matlab detecta estas estructuras básicas y resuelve de una manera óptima el sistema. Si
se consulta la ayuda para este comando se puede leer que se reconoce si una matriz es,
por ejemplo, sparse o llena, simétrica o no simétrica, triangular o permutación de ésta,
bandeada (los elementos concentrados en torno a la diagonal), de Hessenberg1 (con todos
los elementos por debajo de la subdiagonal principal nulos), etc., y aplica el método di-
recto más conveniente en cada caso. Testar si una matriz pertenece a uno de estos tipos
se puede realizar en un número de operaciones despreciable respecto a las del método de
Gauss.
r
Hemos visto al final de la Lección I que el método de Gauss es matemáticamente
equivalente a calcular dos matrices L y U triangular inferior y superior respectivamente
con 1s en la diagonal de L de forma que

A = LU.
1
Ver Lección IV

71
5.1 Método de Gauss para matrices sparse LECCIÓN II

Si se dispone de esta descomposición, la resolución del sistema de ecuaciones se reduce a


la resolución de dos sistemas triangulares,

Ax = b, Ly = b, U x = y,

o en código de Matlab2
Bo
[l,u]=lu(a); x=u\(l\b);
Una caracterı́stica muy habitual del método de Gauss para matrices sparse es el efecto
relleno (en inglés fill in), esto es, la inserción de nuevos elementos en el proceso. Por
ejemplo, tras un único paso del método de Gauss
   
x x x x x x x x x x x x
 x x   x x x x x 
   
 x x   x x x x x 
 ∼ 
 x x   x x x x x 
   
 x x   x x x x x 
x x x x x x x
rra
y la matriz es ahora llena. Sin llegar a esos extremos, es habitual que las necesidades
de memoria se multipliquen al aplicar la eliminación gaussiana. En la descomposición
LU esto se refleja en un incremento en el número de entradas no nulas de la matriz con
los problemas que ello lleva consigo (mayores requerimientos de memoria, mayor costo
computacional,...).
Vamos a ver como podemos reducir este molesto comportamiento con un reorde-
namiento adecuado de filas (ecuaciones) y columnas (incógnitas). Dado que en aplica-
ciones prácticas las matrices simétricas son muy comunes3 nos restringiremos en lo que
sigue a esta familia de matrices. Con el fin de preservar la simetrı́a, cualquier intercambio
de filas debe ser seguido por el intercambio de columnas correspondientes:
   
x 0 0 x x x x 0 0 x
 0 x x 0 0   x x 0 0 0 
do
 0 x x 0 x  1↔ 3 
  
  −→  0 0 x x x 
 
 x 0 0 x 0   0 0 x x 0 
x 0 x 0 x x 0 x 0 x
En los comandos
symrcm symmmd
están implementados dos algoritmos de reordenación muy populares: el algoritmo de
Cuthill-McKee inverso y el algoritmo de mı́nimo grado. El primero reordena de forma
que los términos no nulos de la matriz tienden a estar concentrados cerca de la diagonal.
r
El algoritmo de mı́nimo grado por su parte tiende a mover los elementos no nulos hacia el
final de la matriz de forma que la estructura inicial de la matriz es esencialmente diagonal
y el efecto relleno surge cuando el método de Gauss está ya muy avanzado.
2
Recuerda la colocación de los parántesis.
3
O al menos matrices con estructura simétrica, esto es, a(i, j) 6= 0 ⇔ a(j, i) 6= 0. Todo lo que sigue es
igualmente válido para este tipo de matrices.

72
LECCIÓN II Capı́tulo 5. Matrices sparse en Matematicas. Metodos iterativos
Bo
rra
do
Figura 5.1: Resultado de reordenar las filas y columnas con symrcm y symmmd.

Este tipo de técnicas tuvieron su origen en la resolución de ecuaciones en derivadas


parciales mediante métodos numéricos. Un buen ejemplo lo encontramos en la Figura 5.1
obtenido al aplicar estas dos reordenaciones a una matriz proveniente de la resolución de la
ecuación de Laplace por elementos finitos. Observa como se reduce el número de entradas
en las matrices L y U cuando se aplica alguno de los algoritmos anteriores (referido en la
figura como nz).
La descomposición LU debe calcularse sin pivotaje puesto que en otro caso el reor-
denamiento que introduce el método de Gauss con pivotaje arruina el orden introducido
r
con los algoritmos de reordenamiento anteriores. Para ello se debe utilizar el comando
>> [l,u]=lu(a,0);
El segundo argumento, que sólo está disponible si la matriz a es sparse, fija un umbral
para la realización del pivotaje parcial. El valor 1 es el de defecto. De esta forma, valores
próximos a cero obligan a que el pivotaje se produzca sólo cuando el desequilibrio entre

73
5.1 Método de Gauss para matrices sparse LECCIÓN II

el pivote y el resto de elementos de la columna sea muy acusado. Surge seguidamente la


cuestión de estabilidad del método sin pivotaje. Afortunadamente para matrices definidas
positivas o diagonal dominantes, el método de Gauss sin pivotaje es estable numérica-
mente. La solución del (o de los) sistemas se lleva a cabo con
Solución con reordenamiento...
Bo
01 p=symmmd(a); % permutacion. vale tb p=symrcm(a);
02 [l,u]=lu(a(p,p)); % l y u son ahora "mas sparse"
03 x=l\b(p); x=u\x; % resolvemos los dos sistemas triangulares
04 x(p)=x; % reordenamos las incognitas

En la lı́nea 01, el vector p recoge una permutación de 1:n (n es el número de filas y


columnas de a) que reduce el efecto relleno de L y U . La matriz a(p,p) es el resultado
de reordenar ecuaciones e incógnitas. La lı́nea 04 reordena las incógnitas para recuper-
arlas en su orden original. Observa que la lı́nea 03 podrı́a sustituirse simplemente por
rra
x=u\(l\b(p));

Nota. A partir de la versión 7.0, el comando symmmd que contiene el algoritmo de mı́nimo
grado se ha declarado obsoleto y será eliminado en futuras versiones. Se recomienda
utilizar symamd. 

Comentarios finales
Si la matriz es además simétrica definida positiva podemos utilizar la descomposición
de Cholesky,
A = LL>
donde L es triangular inferior con elementos sobre la diagonal estrictamente posi-
tivos. El sistema se reduce ahora a dos sistemas triangulares
do
Ly = b, L> x = y.
La instrucción correspondiente en Matlab es chol, que devuelve R triangular supe-
rior de forma que
A = R> R
(es decir, en la notación de estos apuntes, L = R> ). Ası́, el algoritmo anterior, con
reordenación adecuada, queda ahora
Solución con reordenamiento...
r
01 p=symmmd(a); % permutacion. vale tb p=symrcm(a);
02 r=chol(a(p,p)); % r es ahora "mas sparse"
03 x=r’\b(p); x=r\x; % resolvemos los dos sist. triang.
04 x(p)=x; % reordenamos las incognitas

74
LECCIÓN II Capı́tulo 5. Matrices sparse en Matematicas. Metodos iterativos

2 4 2 4 2 4 2 4 2 4

1 1 1 1 1

3 5 3 5 3 5 3 5 5
3
x x 0 x 0 x x 0 x 0 x x 0 x 0 x x 0 x 0 x x 0 x 0
Bo
x x x 0 x 0 x x x x 0 x x x x 0 x x x x 0 x x x x
0 x x 0 0 0 x x 0 0 0 0 x x x 0 0 x x x 0 0 x x x
x 0 0 x 0 0 x 0 x 0 0 0 x x x 0 0 0 x x 0 0 0 x x
0 x 0 0 x 0 x 0 0 x 0 0 x x x 0 0 0 x x 0 0 0 0 x

5 3 5 3 5 3 5 3 5 3

2 2 2 2 2
1 4 1 4 1 4 1 1
4 4

x 0 0 0 x x 0 0 0 x x 0 0 0 x x 0 0 0 x x 0 0 0 x
0 x x 0 x 0 x x 0 x 0 x x 0 x 0 x x 0 x 0 x x 0 x
0 x x 0 0 0 x x 0 0 0 0 x 0 x 0 0 x 0 x 0 0 x 0 x
0 0 0 x x 0 0 0 x x 0 0 0 x x 0 0 0 x x 0 0 0 x x
x x 0 x x 0 x 0 x x 0 0 x x x 0 0 0 x x 0 0 0 0 x
rra
Figura 5.2: Eliminación gaussiana y su representación como un grafo. Efecto del reorde-
namiento.

La orden x=a\b realiza todo el proceso anterior de forma automática si a es sparse.


Sin embargo en la forma que lo hemos expuesto podemos resolver reiteradamente
sistemas de ecuaciones con la misma matriz de coeficientes al disponer de la de-
scomposición LU ó LL> .

Queda más allá de los contenidos de este curso explicar cómo funcionan los algorit-
mos implementados en symrcm y symmmd. Se puede señalar no obstante que ambos
do
se basan en identificar la estructura de una matriz con la de un grafo no dirigido,
donde dos nodos i y j están conectados si y sólo si a(i,j)6=0. El proceso de elim-
inación gaussiana se ve como la eliminación sistemática de nodos y la creación de
nuevos enlaces entre los nodos restantes. Concretamente, si hacemos un cero con la
fila i en la fila j, aparecen nuevos enlaces entre los nodos que estaban unidos con el
nodo i y los conectados con j. El problema se reescribe ahora en términos de retirar
los nodos en el orden adecuado de forma que se minimice el número de nuevos ejes
creados (Figura 5.2).

Los gráficos de la Figura 5.1 han sido creados a través del siguiente fichero script.
r
% Calculamos la matriz de elementos finitos para
% un problema sobre un dominio en forma de L

[p,e,t]=initmesh(’lshapeg’,’Hmax’,0.2); % malla inicial

75
5.2 Métodos iterativos para sistemas lineales LECCIÓN II

[p,e,t]=refinemesh(’lshapeg’,p,e,t); % refinamiento
[a,b]=assempde(’lshapeb’,p,e,t,1,0,1);
% a es la matriz (sparse) y b el termino independiente

% Primera fila de dibujos


[l,u]=lu(a,0); % no pivotaje
Bo
figure(1)
subplot(331); spy(a); title(’matriz original’)
subplot(332); spy(l); title(’matriz L’)
subplot(333); spy(u); title(’matriz U’)

% Segunda fila de dibujos


p=symrcm(a); % reordenamiento filas y columnas
[l,u]=lu(a(p,p),0);
figure(1)
subplot(334); spy(a(p,p)); title(’matriz permutada con symrcm’)
subplot(335); spy(l); title(’matriz L’)
subplot(336); spy(u); title(’matriz U’)
rra
% Tercera fila de dibujos
p=symmmd(a); % reordenamiento filas y columnas
[l,u]=lu(a(p,p),0);
figure(1)
subplot(337); spy(a(p,p)); title(’matriz permutada con symmmd’)
subplot(338); spy(l); title(’matriz L’)
subplot(339); spy(u); title(’matriz U’)
do
5.2. Métodos iterativos para sistemas lineales
Cuando un sistema de ecuaciones lineales es de tamaño moderado4 , casi nadie duda
en utilizar el método de Gauss en alguna de sus múltiples variantes (incluidas las de-
scomposiciones matriciales). Sin embargo, la utilización de métodos iterativos se torna
imprescindible en problemas con matrices grandes, especialmente si son sparse, donde el
método de Gauss presenta las siguientes dificultades:

Es caro: O(4n3 /3) operaciones


r
Es destructivo: retoca la matriz del sistema, y esto puede tener consecuencias muy
poco deseables, como hemos visto con matrices sparse. Además requieren en muchas
ocasiones guardar una copia de la matriz.
4
Es difı́cil definir qué se entiende por tamaño moderado. Ciertamente, tamaños enormes en la década
de los años 70 son ahora perfectamente manejables en un pequeño PC.

76
LECCIÓN II Capı́tulo 5. Matrices sparse en Matematicas. Metodos iterativos

Para obtener una solución hace falta realizar todo el proceso: en pasos intermedios
no se dispone de ninguna aproximación de la solución.

Los métodos iterativos se introducen como un intento de salvar estas dificultades.


Bo
5.2.1. Definición
Esencialmente, un método iterativo toma un sistema lineal

Ax = b

y construye una sucesión de vectores de forma que

xm → x, cuando m → ∞.

La forma de construir esta sucesión depende, obviamente de la matriz A, del término


independiente y de cómo se arranque el método numérico (vector inicial).
Existen multitud de esquemas diferentes pero la mayorı́a comparten las siguientes
rra
desventajas:

No siempre convergen en un número razonable de iteraciones, y en muchas ocasiones


ni siquiera convergen.

Los resultados teóricos sobre convergencia son a menudo pobres. Esto es, en general
existe convergencia en situaciones mucho más generales de lo que la teorı́a predice.
Además, chequear estas hipótesis puede resultar tan costoso como resolver el mismo
sistema.

El último punto merece cierto comentario. Los sistemas lineales provienen en general
de problemas fı́sicos de los que se dispone de información a priori, entre las que se pueden
do
encontrar las hipótesis que aseguran la convergencia de un método iterativo. Por ejemplo,
se puede saber que una matriz es definida positiva, y no hay necesidad por tanto de hacer
esta comprobación.
Por contra, los métodos iterativos tienen las siguientes e importantes ventajas:

Son métodos no destructivos. No modifican la matriz del sistema y, en general,


precisan sólo multiplicar por la matriz del sistema o por partes de ella.

Suelen ser más estables frente a los errores de redondeo5 .


r
Se dispone en cada paso de una aproximación de la solución.
5
Carl Friedrich Gauss, que introdujo un método precursor del método conocido actualmente como
método de Gauss–Seidel, comentaba en una carta a su colega Christian Ludwig que los cálculos se
podı́an realizar aún cuando “se estuviese medio dormido” o “pensando en cosas más importantes”. No
hay que olvidar que en su época todos los cálculos se hacı́an a mano. En nuestros dı́as, se plantea el
mismo problema con los errores de redondeo.

77
5.2 Métodos iterativos para sistemas lineales LECCIÓN II

5.2.2. Detalles sobre la implementación


En un método iterativo no podemos esperar calcular la solución exacta, sino hallar
una aproximación con una tolerancia prefijada. Por tanto debemos fijar un criterio de
parada que dé por terminado el método cuando la solución se considere suficientemente
buena. Esto no es grave. Los sistemas de ecuaciones lineales suelen provenir de métodos
Bo
que calculan soluciones aproximadas de problemas fı́sicos e ingenieriles. No tiene pues
sentido obcecarse en calcular la solución exacta de un problema aproximado.
Ası́ hemos de elegir un criterio de parada que termine la ejecución cuando la solución
es suficientemente buena. Una posibilidad es medir la diferencia entre dos iteraciones
consecutivas
kxm+1 − xm k
en alguna norma que queda a elección del programador o del usuario. Si la diferencia es
pequeña, se considera que estamos cerca de la solución y se finaliza el método.
De nuevo nos encontramos con el problema de definir pequeño. Por ejemplo, una
diferencia de 1.4 entre dos iteraciones puede ser grande si la solución tiene un tamaño
kxk ≈ 10−1 o pequeña si kxk ≈ 1010 .
Por ello se puede hacer un promedio entre el error absoluto y el relativo. Concreta-
rra
mente, si x e y son dos iteraciones consecutivas, se puede fijar el criterio
01 aux=norm(x-y); % norma 2 entre x e y
02 if (aux<eps1+eps2*norm(x))
03 disp(’Convergencia alcanzada...’
04 ..........
05 end
En la lı́nea 02 tenemos en cuenta tanto el error absoluto (eps1) como el error relativo
(eps2). Estos valores son parámetros que fijan el criterio de parada y pueden ser dados
por el usuario.
Otros criterios se basan en calcular r = b−Ax y calcular el tamaño. Es decir, medimos
cuánto le falta a x para ser solución del sistema. El vector r recibe el nombre de residuo.
do
Nos encontramos de nuevo con dos componentes del residuo, el primero relacionado
con su tamaño relativo, con respecto al término independiente, y otra absoluta. Ambos
se pueden controlar con
01 aux=norm(b-a*x); % residuo
02 if (aux<eps1+eps2*norm(b))
03 disp(’Convergencia alcanzada...’
04 ..........
05 end
Este criterio puede ser preferible si se dispone ya del residuo y no hay que calcularlo ex
r
profeso. En muchos casos se toma simplemente eps1= 0.
Por otro lado, y desde un punto de vista computacional, debemos evitar que el método
entre en un bucle infinito. Es decir, fijar un número máximo de iteraciones de forma que
si se supera, se termine el método con un mensaje de error6 . Que un residuo sea pequeño
6
Existe otro problema: que la solución crezca de forma que supere la cantidad máxima representable
en coma flotante (overflow). Matlab devolverı́a inf o -inf.

78
LECCIÓN II Capı́tulo 5. Matrices sparse en Matematicas. Metodos iterativos

o que dos iteraciones consecutivas cercanas indiquen proximidad a la solución exacta no


siempre es cierto, pero suele ser muy buena señal.

5.2.3. Métodos iterativos clásicos


El estudio y desarrollo de los métodos iterativos clásicos, también denominados afines
Bo
por su forma de construcción, surgió con fuerza en los años 50, aunque el origen de alguno
de ellos se remonta al siglo XIX. El desarrollo de estos métodos fue paralelo al desarrollo
de los ordenadores y vino muy condicionado por el tipo de problemas que se deseaban
resolver. Estos problemas eran principalmente los provenientes de ecuaciones en derivadas
parciales que daban lugar a matrices grandes y sparse. El uso de los métodos iterativos
afines en nuestros dı́as es menos habitual, habiendo sido superados por los métodos de tipo
Krylov de los que el Gradiente Conjugado es sin lugar a dudas el representante más pop-
ular. De hecho, los métodos clásicos se utilizan en la actualidad como precondicionadores
de los métodos más modernos y potentes, es decir, como un preproceso que acelera la
convergencia de los mismos. Sin embargo su simplicidad y el modo que tienen de ilustrar
el diseño y funcionamiento de un método iterativo fundamentan su exposición en estos
apuntes.
rra
Conocimientos previos
Comenzaremos introduciendo algunas normas vectoriales que nos servirán para medir
el tamaño de los vectores y matrices. Dado un vector

x := (x1 , x2 , . . . , xn )> ∈ Rn

consideramos las normas


q
kxk1 := |x1 | + |x2 | + . . . + |xn |, kxk2 := x21 + x22 + . . . + x2n ,
kxk∞ := máx |xi |.
i=1,...,n
do
Es fácil ver que efectivamente las tres expresiones definen una norma en Rn . Las relaciones
entre ellas vienen dadas por las cotas
√ √
kxk2 ≤ kxk1 ≤ nkxk2 , kxk∞ ≤ kxk1 ≤ nkxk∞ , kxk∞ ≤ kxk2 ≤ nkxk∞ .

Observa que sin embargo estas constantes de equivalencia dependen de n. Todas ellas
están implementadas en Matlab, como ya se vio en la Sección 4.1.2.
Cada norma vectorial define a su vez una norma sobre las matrices

kAk = sup kAxk


kxk=1
r
denominada norma matricial inducida. En la expresión anterior sup es el supremo
sobre todos los vectores de norma 1, que es de hecho un máximo (el supremo se alcanza).
Se puede comprobar que
n
X n
X
kAk1 = máx |aij |, kAk∞ = máx |aij |.
j=1,...,n i=1,...,n
i=1 j=1

79
5.2 Métodos iterativos para sistemas lineales LECCIÓN II

La norma k · k2 tiene una expresión más complicada que dificulta su cálculo práctico. En
concreto p
kAk2 = ρ(A> A)
donde ρ(B), denominado radio espectral, denota el mayor de los valores absolutos de
los valores propios de B (ver Lección IV). Si A es simétrica, se tiene simplemente que
Bo
kAk2 = ρ(A).
En cualquier caso, el comando norm de Matlab aplicado a matrices devuelve las corre-
spondientes normas matriciales:

>> norm(a,1) % norma 1


>> norm(a,inf) % norma infinito
>> norm(a,2) % norma 2. Vale tambien norm(a)

Una norma vectorial y su norma matricial inducida se relacionan mediante

kAxk ≤ kAk kxk .


| {z } |{z} |{z}
norma vectorial norma matricial norma vectorial
rra
Es decir, kAk mide el máximo alargamiento que multiplicar por A puede producir en un
vector medido en la norma k · k.

Definición y condiciones de convergencia


Los métodos iterativos lineales (o basados en iteraciones afines) comienzan consideran-
do una partición de A tal que
A=M −N
con M invertible. Ası́, si x es solución de Ax = b,

M x = N x + b.
do
El método iterativo consiste en

Tomar x0 una aproximación de la solución. Si no se conoce se puede tomar por


ejemplo el vector nulo.

Resolver en cada paso m


M xm+1 = N xm + b. (5.1)

Es fácil ver que si la sucesión construida en (5.1) converge a algún x, entonces el vector
es la solución del sistema. Aún es más, se comprueba fácilmente que
r
xm+k+1 − x = (M −1 N )(xm+k − x) = . . . = (M −1 N )k (xm+1 − x).

Denotando por B = M −1 N se tiene el siguiente resultado

Teorema 5.1 El método iterativo converge si y sólo si existe k tal que kB k k < 1.

80
LECCIÓN II Capı́tulo 5. Matrices sparse en Matematicas. Metodos iterativos

Observa que en el resultado anterior no se especifica la norma utilizada. Otro detalle al


que a veces se presta poca atención es que la convergencia del método ocurre sea cuál sea
x0 , es decir, independientemente de cómo se arranque el método y de cuál sea el término
independiente. Claramente si se tiene una estimación buena de la solución el método
convergerá en menos iteraciones, pero no es una condición imprescindible para asegurar
la convergencia7 .
Bo
No es difı́cil ver que
ρ(B) ≤ kBk
para cualquier norma inducida, y por tanto8

ρ(B) = (ρ(B k ))1/k ≤ (kB k k)1/k ∀k ∈ N.

Es más, se puede probar que, de nuevo para toda norma inducida,

lı́m kB k k1/k = ρ(B)


k→∞

Por tanto se concluye que una condición equivalente de convergencia es que todos
los valores propios de B = M −1 N tengan valor absoluto menor estrictamente que 1.
rra
Teorema 5.2 El método iterativo converge si y sólo si ρ(B) < 1.

Los resultados anteriores pueden utilizarse para probar que

kxm+1 − xk ≤ C(m)ρ(B)m kx1 − x0 k

para todo m ≥ m0 y donde C(m) ≥ 1, con C(m) → 1 cuando m → ∞. La cantidad ρ(B)


recibe en ocasiones el nombre de velocidad asintótica de convergencia. La estimación
anterior justifica esta denominación dado que mide la reducción media del error esperada
en cada iteración.
do
Nota. Si M = A entonces N = 0, por tanto B = 0 y trivialmente

ρ(B) = 0.

Es decir, hay convergencia en una única iteración. Esta iteración consiste en resolver
directamente el sistema de ecuaciones.
En general, uno asegura la convergencia cuando M recoge la información más impor-
tante de A, de forma que N = M − A tenga un tamaño pequeño comparado con M . Por
otro lado, se debe tener en cuenta la definición del método (5.1) y que por tanto en cada
r
iteración hay que resolver un sistema de ecuaciones. Ası́, interesa que M sea sencilla desde
el punto de vista de la resolución del sistema lineal (por ejemplo, diagonal, triangular,...)
y que simultáneamente recoja la mayor información posible de A. 
7
Esta propiedad se pierde cuando se resuelven ecuaciones y sistemas no lineales. En este caso, los
métodos numéricos convergen sólo si se arranca suficientemente cerca de la solución.
8
Si λ es valor propio de B, λ2 lo es de A2 .

81
5.2 Métodos iterativos para sistemas lineales LECCIÓN II

Métodos de Jacobi, de Gauss–Seidel y de relajación de Young


Sea el sistema Ax = b donde
 
a11 a12 . . . a1n
 a21 a22 . . . a2n 
A=
 
.. .. .. .. 
. . 
Bo
 . .
an1 an2 . . . ann

La familia de métodos que vamos a exponer se basa en considerar la siguiente descom-


posición de A
A=D−L−U
donde
     
a11 0 0 ··· 0 0 −a12 · · · −a1n
 a22   −a21 0 ··· 0   0 0 · · · −a2n 
D = , L =  , U =  .
     
.. .. .. .. .. .. .. .. ..
 .   . . . .   . . . . 
ann −an1 −an2 · · · 0 0 0 ··· 0
rra
El método de Jacobi consiste en tomar en la definición del método iterativo M = D
y N = L + U , es decir,
Dxm+1 = (L + U )xm + b.
Para calcular xm+1 hay que resolver por tanto un sistema diagonal cuyo coste es despre-
ciable. Visto componente a componente, tenemos que si
h i>
(m) (m)
xm = x1 , x2 , . . . , x(m)
n ∈ Rn

entonces
(m+1) 1h X (m)
i
xi = bi − aij xj , i = 1, . . . , n.
aii j6=i
do
Para algunos tipos especiales de matrices se sabe que el método converge e incluso se
dispone de información sobre la velocidad de convergencia.
Una matriz es estrictamente diagonal dominante por filas si
X
|aii | > |aij |, ∀i
j6=i

y por columnas si X
|ajj | > |aij |, ∀j.
i6=j
r
Teorema 5.3 Si la matriz es estrictamente diagonal dominante por filas o columnas el méto-
do de Jacobi converge.

Ejercicio 5.1 (matemático) Probar el teorema anterior. ¿Cuándo convergerá más rápido?
(Ayuda. Construir la matriz B = D−1 (L + U ). Probar que kBk∞ < 1 si es dominante por filas
ó kBk1 < 1 si es dominante por columnas. Aplicando el Teorema 5.2, se deduce el resultado.)

82
LECCIÓN II Capı́tulo 5. Matrices sparse en Matematicas. Metodos iterativos

Para dar una descripción del método de Jacobi en pseudocódigo fijamos

x = aproximación inicial, mmax = número máximo de iteraciones,


eps1 = tolerancia absoluta, eps2 = tolerancia relativa,

y tomamos como criterio de parada la norma euclı́dea de la diferencia entre dos iteraciones
sucesivas del método. La elección de la norma es libre, queda a elección del programador
Bo
(podı́amos tomar por ejemplo la norma 2 o la norma infinito).
Una primera versión de nuestro algoritmo es la siguiente

Jacobi

01 for m=1:mmax
02 error=0; y=x
03 for i=1:n
 n
X 
04 x i = bi − aij yj /aii
j=1
j6=i

05 end
rra
06 if kx − yk2 <eps1+eps2*norm(x)
07 return
08 end
09 end
10 disp(’numero máximo de iteraciones alcanzado’)
11 return

Ejercicio 5.2 Implementa el método de Jacobi en Matlab.


do
Solución. Empezaremos fijando la cabecera que contendrá la ayuda de la función. Nos
va a servir de qué estructura vamos a dar a la entrada y salida de datos. Dicho esto, la
implementación de este método que proponemos es la siguiente

01 % JACOBI
02 %
03 % X = JACOBI(A,B) aplica el metodo de Jacobi para la
04 % resolucion del sistema AX=B
05 %
06 %[X,IT]= JACOBI(A,B) devuelve en IT el numero de
r
07 % iteraciones calculadas
08 %
09 %[X,IT]= JACOBI(A,B,ITMAX) ITMAX es el numero max. de iteraciones
10 %
11 %[X,IT]= JACOBI(A,B,ITMAX,... EPS1,EPS2 son las tolerancias
12 % EPS1,EPS2 absoluta y relativa

83
5.2 Métodos iterativos para sistemas lineales LECCIÓN II

13 %
14 %[X,IT]= JACOBI(A,B,ITMAX,...
15 % EPS1,EPS2,X0) arranca el metodo con X0
16 %
17 function [x, varargout]=jacobi(a,b,varargin)
18
Bo
19 % valores por defecto
20 n=length(a); mmax=100;
21 eps1=1e-4; % tolerancia absoluta
22 eps2=1e-4; % tolerancia relativa
23 x=zeros(n,1);
24 if nargin>2
25 mmax=varargin{1};
26 end
27 if nargin>3
28 eps1=varargin{2};
29 end
30 if nargin>4
rra
31 eps2=varargin{3};
32 end
33 if nargin>5
34 x(:)=varargin{4}; %x es un vector columna
35 end
36
37 % Metodo de Jacobi
38
39 for m=1:mmax
40 error=0;
41 y=x;
42 for i=1:n
do
43 v=[1:i-1 i+1:n];
44 x(i)=(b(i)-a(i,v)*y(v))/a(i,i);
45 end
46 error=norm(x-y); % otras normas con norm(x-y,1),norm(x-y,inf)
47 if (error<eps1+eps2*norm(x))
48 break
49 end
50 end
51 if (m==mmax)
52 disp(’numero maximo de iteraciones sobrepasado’)
r
53 end
54
55 %salida
56
57 if (nargout>1)
58 varargout{1}=m;

84
LECCIÓN II Capı́tulo 5. Matrices sparse en Matematicas. Metodos iterativos

59 end
60 return

Recuerda que el comando break, utilizado en la lı́nea 48 provoca la salida automática


del bucle, dando por finalizado la ejecución del método y pasando a la parte del código
encargada de devolver los resultados obtenidos.
Bo


Ejercicio 5.3 Programa una nueva opción de salida que devuelva un vector error de lon-
gitud m − 1 de forma que error(m) sea la diferencia entre xm y xm+1 .

Observa que el código realmente dedicado al método de Jacobi se reduce a apenas diez
lı́neas (39-50) con el resto de la subrutina dedicada al control del algoritmo y a la salida
y entrada de datos. Se observa además que la lı́nea 43 permite implementar en una única
lı́nea (44) el producto de la lı́nea 04 del pseudocódigo.
El código anterior, sin embargo, es optimizable. El ejercicio siguiente ahonda en un
aspecto en particular

Ejercicio 5.4 Otra forma alternativa de implementar el método es reemplazar las lı́neas
rra
42-45 por el producto

x=(b-a*y+d.*y)./d

o bien

x=y+(b-a*y)./d

donde d es un vector columna que contiene la diagonal de la matriz. Observa que realizamos
operaciones de más (multiplicamos por la diagonal para luego restar su contribución), pero
el costo es despreciable y la operación es ahora puramente matricial. Implementa esta nueva
forma y comprueba el resultado. ¿Obtienes mejoras en el redimiento del método9 ?
do
El método de Gauss–Seidel10 consiste en tomar M = D − L y N = U , es decir

(D − L)xm+1 = U xm + b. (5.2)

Para calcular xm+1 hay que resolver un sistema, en este caso triangular. Repasando con
cuidado las operaciones, observamos que
i−1 n
(m+1) 1h X (m+1)
X (m)
i
xi = bi − aij xj − aij xj , i = 1, . . . , n.
aii j=1 j=i+1

9
r
Deberás probar con matrices grandes. La orden rand te puede servir para ese fin. Una forma de
asegurar la convergencia es generar matrices estrictamente diagonal dominantes. ¿Cómo se puede hacer
esto?.
10
El nombre de este algorimo es muy curioso. Según diversos autores (ej. George E. Forsythe ó Gerard
Meurant), Carl Friedrich Gauss no diseñó exactamente este método y Philipp Ludwig von Seidel, que lo
estudió a finales del siglo XIX, desaconsejaba su uso. Gauss desarrolló un método muy similar cuando
trataba de resolver un problema de geodesia que llevaba a un sistema lineal que no era compatible
determinado.

85
5.2 Métodos iterativos para sistemas lineales LECCIÓN II

Escrito en forma algorı́tmica,


Gauss–Seidel

01 for m=1:mmax
02 error=0; y=x
Bo
03 for i=1:n
 i−1
X n
X 
04 x i = bi − aij xj − aij yj /aii
j=1 j=i+1
05 end
06 if kx − yk<eps1+eps2*norm(x)
07 return
08 end
09 end
10 disp(’numero máximo de iteraciones alcanzado’)
11 return
rra
Ası́ pues, la única diferencia con el método de Jacobi es que Gauss–Seidel procede a
utilizar la nueva componente calculada xi tan pronto es posible mientras que Jacobi sólo
la utiliza en la nueva iteración. Es por ello que Gauss–Seidel es (casi siempre) superior a
Jacobi. No hay razones matemáticas que permitan apoyar esta impresión. De hecho existen
matrices para las que Jacobi converge y Gauss–Seidel diverge, aunque hace falta construir
un ejemplo ad hoc, no es fácil encontrar tal ejemplo, para comprobar esta afirmación.
Desde un punto de vista práctico, si Jacobi converge es altamente probable que lo haga
también Gauss–Seidel y generalmente, éste lo hará en menos iteraciones.

Teorema 5.4 El método de Gauss–Seidel converge si


do
la matriz es estrictamente diagonal dominante por filas o columnas;
o

la matriz es simétrica definida positiva.

Ejercicio 5.5 Programa el método de Gauss–Seidel modificando de forma apropiada la fun-


ción del Ejercicio 5.2.

Ejercicio 5.6 De manera similar a lo que se propuso en el Ejercicio 5.4, podemos implementar
la parte central del método de Gauss–Seidel mediante
r
x=l\(b-u*y)

o bien con el doble número de operaciones con

x=y+l\(b-a*y)

donde

86
LECCIÓN II Capı́tulo 5. Matrices sparse en Matematicas. Metodos iterativos

l=tril(a,0); u=triu(a,1);

Implementa el método resultante. ¿Qué ventajas y desventajas observas en cada de estas


implementaciones?.
(Ayuda: recuerda los comandos diag, triu y tril de la Sección 4.1.3)
Bo
Ejercicio 5.7 El método de Gauss–Seidel tiene una curiosa asimetrı́a: la primera componente
de cada xm+1 se calcula utilizando los valores de la anterior iteración xm , mientras que la última
componente utiliza todas las componentes de la nueva iteración xm+1 . Se puede plantear el
método de Gauss–Seidel inverso que es el que resulta de intercambiar los papeles de L y U en
(5.2). Ahora la situación es justamente la recı́proca. ¿Mejora la velocidad de convergencia del
método?

Ejercicio 5.8 El método de Gauss–Seidel simetrizado o cı́clico trata de solventar la asimetrı́a


señalada en el ejercicio anterior. Consiste en encajar dos iteraciones, una con Gauss–Seidel y
otra con el método de Gauss–Seidel inverso. Es decir, dado xm , se aplica un paso del método
de Gauss–Seidel para obtener un nuevo vector xm+1/2 . Seguidamente se calcula un paso del
método Gauss–Seidel inverso y ası́se obtiene la nueva aproximación xm+1 .
rra
Implementa este método. ¿Se reduce el número de iteraciones necesarias para alcanzar la
convergencia? ¿Y el costo por iteración? ¿Te parece rentable esta aproximación?.

El último representante de esta familia de métodos clásicos que estudiaremos es el


método de relajación de Young. Introducido y estudiado independientemente por
David M. Young (en su tesis doctoral) y Stanley P. Frankel sobre 1950, es una simple
modificación del método de Gauss–Seidel que trataba, como buena parte de los métodos
propuestos en estos años, de acelerar la convergencia de los métodos de Gauss–Seidel y
Jacobi.
La modificación propuesta consiste en realizar un promedio sobre la aproximación que
proporcionarı́a Gauss–Seidel y la iteración anterior.
Concretamente, la expresión es
do
i−1 n
(m+1) (m) ωh X (m+1)
X (m)
i
xi = (1 − ω)xi + bi − aij xj − aij xj , i = 1, . . . , n.
aii j=1 j=i+1

Si ω = 1 recuperamos el método de Gauss–Seidel. El objetivo es escoger ω adecuadamente


para acelerar la convergencia del método.
No es fácil encontrar el valor óptimo de ω, aunque necesariamente ω ∈ (0, 2) pues en
caso contrario el método diverge.
Si la matriz es simétrica definida positiva o tridiagonal el método de relajación converge
para cualquier ω ∈ (0, 2). También converge si es estrictamente diagonal dominante (por
r
filas o columnas). Sin embargo, salvo para matrices tridiagonales, poco se puede decir
acerca de la elección óptima del parámetro ω, y aún en este caso, la determinación exacta
del parámetro óptimo exige resolver un problema bastante complicado.
Desde un punto de vista práctico, el parámetro se estima mediante ensayo–error. De
forma algo sorprendente, en problemas prácticos es muy habitual que ω > 1. De ahı́ el
nombre que se le da a veces de Sobrerrelajación (overrelaxed).

87
5.2 Métodos iterativos para sistemas lineales LECCIÓN II

Por último, aunque no sea inmediato, se puede comprobar que este método encaja en
el marco anterior, sin más que tomar
1 1−ω
M= D − L, N= D+U
ω ω
Ejercicio 5.9 Implementa el método de relajación de Young a partir del método de Gauss–
Bo
Seidel. Incluye como nuevo argumento de entrada el parámetro ω. Un posible valor por defecto
podrı́a ser ω = 1 con lo que tendrı́amos el método de Gauss–Seidel.

Ejercicio 5.10 De nuevo, la parte central del método de relajación se puede implementar
en la forma

x=y+m\(b-a*y)

donde m es una matriz adecuada. ¿Cuál es esa matriz?.

5.2.4. Métodos de tipo gradiente


Comenzaremos recordando algunos conceptos e introduciendo algunas notaciones que
rra
facilitarán la exposición de los métodos de tipo gradiente.
Recordemos que todos los vectores se consideran como vectores columna. Dada A una
matriz simétrica definida positiva, la operación que a cada par de vectores x, y le
asigna el número real
x> Ay
es un producto escalar, esto es, cumple las propiedades que definen un producto escalar11 :

1. (αx + βy)> Az = αx> Az + βy> Az, ∀α, β ∈ R, ∀x, y, z ∈ Rn ;

2. x> Ay = y> Ax, ∀x, y ∈ Rn (por ser A simétrica);

3. x> Ax > 0, si x 6= 0 (por ser A definida positiva).


do
En particular, si In es la identidad n × n,

x> In y = x> y

es simplemente el producto escalar habitual en Rn de x e y. Denotaremos

x⊥y ⇐⇒ x> y = 0

y diremos en este caso que x e y son ortogonales. La misma notación se puede extender
al producto definido por A, de forma que
r
x ⊥A y ⇐⇒ x> Ay = 0

y en este caso x e y se dicen A−ortogonales.


11
Es interesante observar cuántas propiedades del producto escalar euclı́deo (el habitual en Rn ) depen-
den únicamente de que se cumplan estas tres propiedades y por tanto son extensibles a estos casos más
generales.

88
LECCIÓN II Capı́tulo 5. Matrices sparse en Matematicas. Metodos iterativos

La norma asociada al producto escalar anterior se conoce como norma de energı́a


y su expresión viene dada, obviamente, por

kxkA := x> Ax.

Todas las normas son equivalentes en Rn , pero para esta norma se tiene además la esti-
mación
Bo
λn kxk2 ≤ kxkA ≤ λ1 kxk2
donde λ1 ≥ λ2 ≥ .... ≥ λn > 0 son los valores propios, todos reales por ser A simétrica y
positivos por ser definida positiva. La cantidad
λ1
κ(A) = ,
λn
que será relevante en lo que sigue, es el condicionamiento de la matriz12 . Obviamente,
κ(A) ≥ 1.
Construimos la función
F (x) = 12 x> Ax − x> b
conocida como funcional de energı́a. Tras unos simples cálculos, se comprueba que
rra
∇F = Ax − b.

Por tanto, el único posible extremo de F es la solución de Ax − b = 0. Además, como la


matriz hessiana de F es la propia matriz A, que es definida positiva, este extremo será un
mı́nimo. Hemos llegado por tanto a la siguiente conclusión:
resolver Ax = b es equivalente a encontrar el mı́nimo de F
En esta observación se basan los métodos de descenso: en lugar de resolver el sistema de
ecuaciones Ax = b, nos preocupamos en buscar el mı́nimo de F . Es esencial que A sea
definida positiva para que estos argumentos sean válidos.
do
Métodos de descenso. Aspectos generales
La idea de estos métodos es sencilla. Dado un valor inicial consiste en ir moviéndose
en trayectorias zigzagueantes hasta alcanzar el mı́nimo. Concretamente, dada una aprox-
imación, fijamos una dirección de desplazamiento, calculamos cuanto nos movemos, de-
scender en el lenguaje habitual, y nos desplazamos a un nuevo punto.
De esta forma construimos una sucesión xm que deberı́a converger a x, siguiendo estos
pasos.
Calcular una dirección de descenso dm .
r
Descender una cantidad ξm , tomando como nueva aproximación

xm+1 = xm + ξm dm .
12
El condicionamiento se define también para matrices arbitrarias reemplazando los valores propios por
los denominados valores singulares, o más en general, definiéndolo como el producto de la norma de A
por la norma de su inversa. En general el condicionamiento de la matriz mide la sensibilidad del sistema
de ecuaciones lineales asociado a variaciones del término independiente.

89
5.2 Métodos iterativos para sistemas lineales LECCIÓN II

Se procede ası́ hasta que hay convergencia.


Dos aspectos determinan el método: qué dirección se toma y cuánto se desciende. Tanto
en el método del Gradiente como en el método del Gradiente Conjugado, que veremos a
continuación, se toma ξm de forma que

F (xm+1 ) = mı́n F (xm + α dm )


Bo
α∈R

es decir, se trata de minimizar, una vez escogida la dirección de descenso dm , el funcional


de energı́a. Definiendo
g(α) = F (xm + α dm )
podemos comprobar que

g 0 (α) = α d> >


m Adm − dm (b − Axm )
| {z }
rm

y por tanto la cantidad de descenso viene dada por


rra
r>
m dm
ξm := >
, (5.3)
dm Adm

(obtenido al imponer g 0 (α) = 0). El vector rm = b − Axm es el residuo de xm , que ya


ha surgido en estas notas. Se puede probar fácilmente que

rm+1 = b − Axm+1 = b − Axm − ξm Adm = rm − ξm Adm .

En consecuencia, el residuo en pasos sucesivos satisface una relación similar a la que


cumple xm . Sin embargo, este tipo de recurrencia puede verse afectada por errores de
redondeo, por lo que en ocasiones el residuo se recalcula cada cierto número de iteraciones
de acuerdo a su definición para cancelar cualquier error de redondeo.
do
El algoritmo resultante es el siguiente:

Método de descenso

01 x0 inicial, r0 = b0 − Ax0
02 for m=0:mmax
03 Escoger dm
r > dm
04 ξm := >m
dm Adm
05 xm+1 = xm + ξm dm
r
06 rm+1 = rm − ξm Adm
07 end

Claramente, la lı́nea 03 queda pendiente y en última medida define el método.

90
LECCIÓN II Capı́tulo 5. Matrices sparse en Matematicas. Metodos iterativos

Método del Gradiente


Dado que −∇F (xm ) = b − Axm = rm , la dirección de máximo descenso es la del
residuo. Por tanto, ésta parece una buena elección para dm . El método ası́ definido es el
método del gradiente.
Bo
Método del Gradiente

01 x0 inicial; r0 = b − Ax0 ;
02 for m=0:mmax
03 pm = Arm
r>m rm
04 ξm = >
r m pm
05 xm+1 = xm + ξm rm
06 rm+1 = rm − ξm pm
07 if krm+1 k ≤ epskbk
08 break
09 end
rra
10 end

En el paso 06 estamos calculando el residuo de la solución. El criterio de parada se


toma ahora a partir del residuo. En concreto hemos escogido el basado en el tamaño
relativo del residuo (epskbk). La norma que utilizamos es la euclı́dea, que es connatural
al método.

Ejercicio 5.11 Programa el Método del Gradiente.

Solución. Una posible implementación del método es la que sigue


do
01 % GRADIENTE
02 %
03 % X = GRADIENTE(A,B) Aplica el met. del gradiente para
04 % la resolucion del sistema AX=B
05 %
06 % X = GRADIENTE(A,B,ITMAX) ITMAX: numero max. de iteraciones
07 %
08 % X = GRADIENTE(A,B,ITMAX... EPS tolerancia relativa
09 % EPS)
r
10 %
11 % X = GRADIENTE(A,B,ITMAX... X0 es el valor inicial
12 % EPS, X0)
13 %
14 %[X,IT] = GRADIENTE(A,B,ITMAX... Devuelve en IT el numero de
15 % EPS,XO) iteraciones calculadas

91
5.2 Métodos iterativos para sistemas lineales LECCIÓN II

16
17 %[X,IT,R]= GRADIENTE(A,B,ITMAX) R es un historial del metodo:
18 % EPS,XO) R(i) es el residuo en el paso i
19
20 function [x,varargout]= gradiente(a,b,varargin);
21
Bo
22 n=length(a); x=zeros(n,1); mmax=40;
23 tol=1e-6;
24
25 if nargin>2
26 mmax=varargin{1};
27 end
28 if nargin>3
29 tol=varargin{2};
30 end
31 if (nargin>4)
32 x=varargin{4};
33 end
rra
34
35 r=b-a*x; res(1)=dot(r,r); aux=norm(b);
36 for m=1:mmax
37 p=a*r;
38 xi=res(m)/dot(r,p);
39 x=x+xi*r;
40 r=r-xi*p;
41 res(m+1)=dot(r,r); % guardamos los residuos
42 if (sqrt(res(m+1))<tol*aux);
43 break
44 end
45 end
do
46
47 if (m==mmax)
48 disp(’numero maximo de iteraciones sobrepasado’)
49 end
50 if nargout>1
51 varargout{1}=m;
52 end
53 if nargout>2
54 varargout{2}=sqrt(res(:));
55 end
r
56 return

El vector res guarda el residuo en cada iteración para ası́ tener un historial de como
ha ido la convergencia.
Prueba el método con un sistema donde la matriz sea simétrica definida positiva (nota:
para toda matriz B, B > B es simétrica (semi) definida positiva.)

92
LECCIÓN II Capı́tulo 5. Matrices sparse en Matematicas. Metodos iterativos


La gráfica mostrada en la Figura 5.3 se ha construido utilizando las instrucciones

>> n=40;a=rand(n,n); a=a*a’; %% a es sim\’{e}trica definida positiva


>> x=ones(n,1); b=a*x;
>> [x,it,r]=gradiente(a,b,100,1e-5);
Bo
>> semilogy(r)

Hemos utilizado una escala logarı́tmica para medir la norma del residuo. Observa su fuerte
comportamiento oscilatorio.

4 Residuo
10

3
10

2
10

1
rra
10

0
10

−1
10

−2
10
0 10 20 30 40 50 60 70
Iteraciones

Figura 5.3: Historial del residuo para el método del Gradiente.

Ejercicio 5.12 En este ejercicio tratamos de nuevo aspectos de la implementación en Mat-


do
lab. Concretamente, ¿qué pasa si el usuario desea especificar el vector de arranque (x0 en
la notación del método) pero desea dejar el número máximo de iteraciones y la tolerancia
por defecto?. Como estándar en Matlab, se envı́a vacı́o ([ ]), de forma que los argumentos
intermedios se ignoran. Por ejemplo,

>> x=gradiente(a,b,[],1e-5)

especificarı́a la tolerancia pero no el número máximo de iteraciones. Implementa las modifi-


caciones necesarias en el programa anterior para que la función soporte este estándar.
(Ayuda: La función isempty puede resultarte útil.)
r
Breves notas sobre el estudio del Método del Gradiente
La clave del análisis es la relación

F (xm+1 ) − F (x) = 21 (xm+1 − x)> A(xm+1 − x) = 12 k xm+1 − x k2A


| {z }
em+1

93
5.2 Métodos iterativos para sistemas lineales LECCIÓN II

donde claramente em+1 es el error entre la solución exacta y la numérica medido en la


norma de energı́a de A. Por tanto, como F (xm+1 ) ≤ F (xm ),

kem+1 kA ≤ kem kA

luego en cada iteración hay una reducción del error en la norma de energı́a. Sin embargo,
Bo
en ningún caso implica que el residuo se reduzca en cada iteración, como bien podemos
comprobar en la Figura 5.3. Aún es más, de la elección hecha de ξm se sigue que

F (xm+1 ) := mı́n F (xm + α rm )


α∈R

y por tanto
h i
kem+1 kA ≤ mı́n kx − xm − α rm kA = mı́n kem − αAem kA ≤ mı́n kI − αAkA kem kA .
α∈R α∈R α∈R

Observa que hemos utilizado la cota kM xkA ≤ kM kA kxkA , caracterı́stica de toda norma
vectorial y su norma matricial inducida.
rra
Proposición 5.5 Sean λ1 y λn el mayor y menor valor propio de A. Entonces

λ1 − λ n
mı́n kI − αAkA = mı́n kI − αAk2 = < 1.
α∈R α∈R λ1 + λ n

La convergencia se escribe de forma muy cómoda en términos del condicionamiento


de la matriz κ(A) = λλn1 , deduciendo la expresión

κ(A) − 1
kem+1 kA ≤ kem kA .
κ(A) + 1

Es inmediato observar que


do
El factor de reducción del error es siempre menor que uno, luego hay convergencia
para toda A simétrica definida positiva.

Si κ(A) >> 1, la convergencia puede ser muy lenta.

Ejercicio 5.13 (puramente matemático) Se puede probar que dada A simétrica definida
positiva existe B simétrica definida positiva tal que BB > = B 2 = A, conocida como raı́z
cuadrada de A. Utilizando este resultado prueba la identidad

kI − αAkA = kI − αAk2
r
utilizada en la Proposición 5.5.
(Ayuda: Observa que kxkA = kBxk2 . Utiliza ahora que

kI − αAkA = sup k(I − αA)xkA = sup kB(I − αA)B −1 (Bx)k2


kxkA =1 kBxk=1

y completa la demostración).

94
LECCIÓN II Capı́tulo 5. Matrices sparse en Matematicas. Metodos iterativos

Ejercicio 5.14 (demostración de la Proposición 5.5) Para toda matriz simétrica C


se cumple que
kCk2 = máx |λj |
j

con λj el valor propio j−ésimo. Por tanto


Bo
kI − αAkA = kI − αAk2 = máx |1 − αλj |.
j

Define gc (α) = |1 − c α| y traza la gráfica de estas funciones para varios valores de c. Deduce
que α = 2/(λ1 + λn ) es el valor que hace mı́nimo kI − αAk2 y que para este valor,

λ1 − λ n
kI − αAk2 = .
λ1 + λn

(Ayuda: al dibujar gc (α) para diferentes valores de c obtendrás obtendrás algo similar a esto
rra
1

0.5

0
0 1 2 3 4 5
α

¿Cuáles son las gráficas de los valores extremos?)


do
El Gradiente Conjugado
El método del Gradiente Conjugado trata de resolver alguna de las dificultades obser-
vadas con el método del Gradiente, como por ejemplo el comportamiento oscilatorio del
residuo.
Observemos que en un método de descenso, y por la elección de ξm hecha en (5.3),

r> > >


m+1 dm = rm dm − ξm dm Adm = 0,

por lo que rm+1 ⊥ dm . Esto es, en un método de descenso el residuo del paso m + 1 es
r
ortogonal a la dirección de descenso anterior.
Sin embargo, en general ya no es cierto que

rm+1 ⊥ dm−1 (5.4)

y por tanto se pierde esta propiedad de ortogonalidad.

95
5.2 Métodos iterativos para sistemas lineales LECCIÓN II

Una forma de evitar, o de mitigar, el aspecto oscilante del método del Gradiente, es
exigir que la dirección de descenso dm satisfaga (5.4). Es decir, tomamos

rm+1 = rm − ξm Adm ,

y concluimos que
Bo
d>
m−1 rm+1 = 0 ⇐⇒ dm−1 ⊥ Adm ⇐⇒ dm−1 ⊥A dm .

En vista de lo anterior optamos por tomar como dirección de descenso una perturbación
de la dirección natural rm (el residuo) en la dirección del descenso anterior (dm−1 ) que
satisfaga la propiedad de ortogonalidad anterior. Es decir, tomamos

dm = rm + τm dm−1

con τm adecuado. Exigiendo que se satisfaga (5.4) deducimos que

r>
m Adm−1
dm ⊥A dm−1 ⇐⇒ r> >
m Adm−1 + τm dm−1 Adm−1 = 0 ⇐⇒ τm = − >
.
dm−1 Adm−1
rra
Como elección inicial de la dirección de descenso tomamos simplemente r0 , el residuo
de la aproximación inicial. Con todo esto, la primera versión del método del Gradiente
Conjugado es la que sigue

Gradiente Conjugado - Primera versión

01 x0 inicial; r0 = b − Ax0 ; d0 = r0 ;
02 for m=0:mmax
03 pm = Adm
r>
m dm
04 ξm =
do
d>
m pm

05 xm+1 = xm + ξm dm
06 rm+1 = rm − ξm pm
07 if krm+1 k ≤ epskbk
08 break
09 end
r > pm
10 τm+1 = − m+1
d>m pm
11 dm+1 = rm+1 + τm+1 dm
12 end
r
13 disp(’Numero maximo de iteraciones alcanzado’)

Como puede verse, las modificaciones sobre el método del Gradiente son mı́nimas
y están concentradas en las lı́neas 04, 10 y 11. En cuanto al número de operaciones,

96
LECCIÓN II Capı́tulo 5. Matrices sparse en Matematicas. Metodos iterativos

coincide con las del método del Gradiente: en cada paso es necesario calcular un producto
matriz–vector (lı́nea 03) y tres productos escalares (04 y 10).
Listaremos a continuación algunas propiedades entre los residuos y las direcciones de
descenso que permiten dar una expresión distinta del método, y deducir alguna de las
propiedades de convergencia.
Bo
Lema 5.6 Para todo m ≥ 0
r> >
m dm = r m r m .

Por tanto
r>
m rm
ξm = .
d>
m Adm

Demostración. Como rm ⊥ dm−1 ,


r> > >
m dm = rm rm + τm rm dm−1 . (5.5)
| {z }
=0

El segundo resultado es inmediato de la definición de ξm . 


Lema 5.7 Para todo m ≥ 0 se satisfacen las siguientes relaciones
rra
i) dm+1 ⊥A dm .
ii) rm+1 ⊥ dm , rm+1 ⊥ dm−1 .
iii) rm+1 ⊥ rm .
Demostración. Los puntos i) y ii) ya se han probado. Para probar iii) basta comprobar
que
r> > > > > >
m+1 rm = rm rm − ξm dm Arm = rm rm − ξm dm Adm + ξm τm dm Adm−1
| {z }
=0
= r>
m rm − ξm d>
m Adm .
do
El resultado es ahora una consecuencia del Lema 5.6. 
Lema 5.8 Para todo m ≥ 0
r> rm+1
τm+1 := m+1
>
.
rm rm
Demostración. Como
1
−Adm = (rm+1 − rm ),
ξm
se tiene
r>
m+1 Adm 1 r>
m+1 (rm+1 − rm ) 1 r>
m+1 rm+1 r>
m+1 rm+1
τm+1 = − = = =
r
>
dm Adm ξm >
dm Adm >
ξm dm Adm r>
m rm

donde hemos utilizado que rm+1 ⊥ rm , y en el último paso, la expresión alternativa de


ξm . 
Los Lemas 5.6 y 5.8 dan expresiones más simples de los parámetros ξm y τm . De hecho
más económicas, dado que r>m rm es conocido del paso anterior y por tanto no es preciso
calcularlo de nuevo. En total dos productos escalares por iteración.

97
5.2 Métodos iterativos para sistemas lineales LECCIÓN II

Ejercicio 5.15 Modifica el algoritmo del Gradiente Conjugado con las nuevas expresiones
de ξm y τm . Observa que podemos evitar en esta versión un producto escalar por iteración.

El resultado sorprendente, y que descubre parte de las buenas propiedades del Gradi-
ente Conjugado, es que estas propiedades de ortogonalidad se extienden a todo el conjunto
de residuos y direcciones generados en los pasos anteriores.
Bo
Lema 5.9 Para todo m ≤ n
i) dm ⊥A d` , ∀` ≤ m − 1;
ii) rm+1 ⊥ d` , ∀` ≤ m;
iii) rm+1 ⊥ r` , ` ≤ m.

La tercera propiedad implica en particular la convergencia del Gradiente Conjugado en


aritmética exacta en a lo sumo n pasos dado que no puede haber n+1 vectores ortogonales
en Rn y por tanto rn+1 = 0. Sin embargo, en aplicaciones prácticas puede requerir más
de n iteraciones por los errores introducidos por la precisión de la máquina.
rra
Ejercicio 5.16 Modifica el programa gradiente para implementar en una función de nom-
bre gradconjugado el método del Gradiente Conjugado.

Hemos ejecutado como antes


>> n=40;a=rand(n,n); a=a*a’; x=ones(n,1); b=a*x;
>> [x,it,r]=gradconjugado(a,b,100,1e-5);
>> semilogy(r)
y hemos desplegado en la Figura 5.4 las normas de los residuos en cada paso. Como se

4
Residuo
10
do
3
10

2
10

1
10

0
10

−1
10

−2
10
0 2 4 6 8 10 12 14
r
Iteraciones

Figura 5.4: Historial del residuo para el método del Gradiente Conjugado

puede comprobar la convergencia es más rápida y hemos reducido notablemente el molesto


comportamiento oscilatorio del residuo.

98
LECCIÓN II Capı́tulo 5. Matrices sparse en Matematicas. Metodos iterativos

Análisis del método

En esta sección probaremos el Lema 5.9. El lector más interesado en la implementación


del método puede saltar esta sección sin mayor problema. Animamos, no obstante, a
su lectura pues ilustra un conjunto de técnicas habituales en otras familias de métodos
iterativos. Además sirve de ejemplo que demostrar el buen funcionamiento de un esquema
Bo
numérico más elaborado, generalmente obtenido mediante modificaciones intuitivas de
algoritmos más simples, puede requerir un análisis nada trivial. Tampoco es extraña la
situación contraria: un método puede fallar por razones no inmediatamente comprensibles.
En la demostración juega un papel muy importante el subespacio

Km (A, r0 ) := Rhr0 , Ar0 , . . . , Am r0 i

esto es, el subespacio formado por todas las combinaciones lineales

α0 r0 + α1 Ar1 + . . . + αm Am r0 , αi ∈ R.

Estos subespacios reciben el nombre de subespacios de Krylov y son clave en multitud


rra
de métodos numéricos para la resolución de sistemas lineales. Antes de proseguir haremos
unos simples comentarios:

1. El subespacio tiene a lo sumo dimensión m + 1.

2. Si q ∈ Km (A, r0 ), entonces Aq ∈ Km+1 (A, r0 ). Es decir, AKm (A, r0 ) ⊂ Km+1 (A, r0 ).

3. Si Km (A, r0 ) = Km+1 (A, r0 ), entonces Km (A, r0 ) = Km+1 (A, r0 ) = Km+2 (A, r0 ) = ...

4. Es fácil comprobar que rm , dm ∈ Km (A, r0 ).


do
La demostración del Lema 5.9 se llevará a cabo por inducción sobre m. Para m = 0 es
un simple ejercicio de comprobación (en este caso r0 = d0 y por tanto ii) y iii) coinciden).
Supongamos pues que el resultado está probado para m. Concretamente, supongamos que
para m

i) dm ⊥A d` , ∀` ≤ m − 1 y {d0 , d1 , . . . , dm } es una base de Km (A, r0 ).

ii) rm+1 ⊥ d` , ∀` ≤ m.

iii) rm+1 ⊥ r` , ` ≤ m y {r0 , r1 , . . . , rm+1 } es una base ortogonal de Km+1 (A, r0 ).


r
Veamos que los puntos i)–iii) se satisfacen entonces para m + 1.

i) dm+1 ⊥A d` , ∀` ≤ m:

99
5.2 Métodos iterativos para sistemas lineales LECCIÓN II

Este resultado está probado ya para ` = m. Para ` ≤ m − 1, utilizamos que

dm+1 = rm+1 + τm+1 dm .

Por tanto, basta probar que

rm+1 ⊥A r` , dm ⊥A d` .
Bo
El segundo es ya conocido (hipótesis de inducción). Por otro lado

rm+1 ⊥A r` ⇐⇒ rm+1 ⊥ Ar` .

Como Ar` ∈ K`+1 (A, r0 ) y una base de este subespacio es {r0 , r1 , . . . , r`+1 } ⊂,
concluimos que
Ar` = α0 r0 + α1 r1 + . . . + α`+1 r`+1
con αj ∈ R adecuados. El resultado se sigue ahora de iii) puesto que rm+1 ⊥ rk ,
para todo k ≤ m.
Por último si dm+1 6= 0 entonces {d0 , . . . , dm+1 } es una base de Km+1 (A, r0 ) por
ser A−ortogonales y por tanto linealmente independientes. 
rra
ii) rm+2 ⊥ d` , ∀` ≤ m + 1

Para ` = m, m + 1 es cierto por construcción (véase Lema 5.7). Para el resto de


valores ` ≤ m − 1, utilizamos

rm+2 = rm+1 − ξm+1 Adm+1 .

Por inducción, rm+1 ⊥ d` , mientras que para el otro término observamos que

(Adm+1 ) ⊥ d` ⇐⇒ dm+1 ⊥A d` ,
do
y ésto es lo que acabamos de probar en el apartado anterior. 

iii) rm+2 ⊥ r` , ∀` ≤ m + 1.

Tomemos ` ≤ m. Entonces

rm+2 ⊥ r` ⇐⇒ (rm+1 − ξm+1 Adm+1 ) ⊥ r` ⇐⇒ (Adm+1 ) ⊥ r`


⇐⇒ (dm+1 ) ⊥A r` .

donde hemos aplicado la hipótesis de inducción en el segundo paso. Ahora, como


r` ⊂ K` (A, r0 ), por el punto i) podemos escribir
r
r` = β0 d0 + β1 d1 + . . . + β` d` . (5.6)

El resultado se sigue de la propiedad i) ya que dm+1 ⊥A dk para k ≤ m. Final-


mente, si rm+1 6= 0 entonces {r0 , . . . , rm+1 } es una base de Km+1 (A, r0 ) por ser
ortogonales. 

100
LECCIÓN II Capı́tulo 5. Matrices sparse en Matematicas. Metodos iterativos

Un examen más cuidadoso de la demostración anterior comprueba que ésta falla en el


caso de que en un paso rm+1 ó dm+1 sean nulos. En cualquiera de estos casos

Km (A, r0 ) = Km+1 (A, r0 ).

Ahora bien esto sucede si y sólo si ha habido convergencia en el paso m (si dm+1 = 0 y
Bo
por tanto rm = 0) o en el paso m + 1 (si rm+1 = 0). Esto es, si la dirección de descenso es
la nula simplemente es porque ya hemos alcanzado la solución, y viceversa, si el residuo
es nulo, la dirección de descenso para la siguiente iteración es la nula.

Notas finales
El Gradiente Conjugado fue propuesto por Magnus R. Hestenes y Eduard Stiefel en
1952. Lo más curioso es que el método fue desarrollado de forma independiente por estos
dos autores. Según cuenta Marvin Stein13 , un estudiante postdoctoral en aquellos años que
programó el algoritmo por primera vez para Hestenes, Stiefel coincidió con Hestenes en
una conferencia en UCLA (University of California, Los Angeles) y le comentó a grandes
trazos el método en el que estaba trabajando. Stiefel estaba impresionado sobre las buenas
rra
propiedades que mostraba este método hasta que revisando las tarjetas perforadas que
contenı́an el programa implementado cayó en la cuenta de que se trataba del mismo
método sobre el que independiente él estaba trabajando14 .
Hemos visto que el método del Gradiente Conjugado es un método directo, en tanto
en cuanto da la solución en un número finito de pasos, concretamente n, el número de filas
de la matriz. Sin embargo, se programa como un método iterativo, de forma que se busca
la convergencia en muchas menos iteraciones. En cada iteración se tiene la estimación
p !m
κ(A) − 1
kem+1 kA ≤ 2 p ke0 kA
κ(A) + 1

donde de nuevo em := xm − x es el error en el paso m−ésimo y e0 el error inicial.


do
El resultado anterior es algo incompleto pero sirve para hacer patente la sensibilidad
del método ante el condicionamiento de una matriz que, aunque menor que en el caso del
método del Gradiente (por la raı́z cuadrada), sigue siendo importante. Si la matriz tiene
un condicionamiento moderado, el método del Gradiente Conjugado dará una solución
aceptable en unas pocas iteraciones. Sin embargo, esto no suele ser un caso habitual. Las
matrices que surgen en la resolución de ecuaciones en derivadas parciales, por ejemplo
elementos o volúmenes finitos, suelen ser, además de matrices sparse, mal condicionadas,
por lo que el método del Gradiente Conjugado requiere de bastantes iteraciones15 .
Estas razones hicieron que el Gradiente Conjugado se tomara como un método más,
sin concederle especial relevancia y confundiéndose con la multitud de métodos para la
r
resolución de sistemas de ecuaciones lineales que iban surgiendo a su alrededor. Esta
13
Anécdota recogida por Yousef Saada y Henk A. van der Vorstb en “Iterative solution of linear systems
in the 20th century” publicado en “Journal of Computational and Applied Mathematics” en el año 2000.
14
Esta coincidencia no es de todas formas un caso aislado en las Ciencias en general y en las Matemáticas
en particular. En ocasiones parece como si las ideas estuviesen flotando en el ambiente a la espera de que
alguien diera el paso final de plasmarlas.
15
O(n1/3 ) en problemas en 3D, O(n1/2 ) en 2D es un comportamiento tı́pico.

101
5.2 Métodos iterativos para sistemas lineales LECCIÓN II

situación se prolongó durante casi 20 años hasta que las ideas del precondicionamien-
to cambiaron radicalmente esta situación y encumbraron al Gradiente Conjugado a su
posición actual16 .
El precondicionamiento consiste, a grandes rasgos, en cambiar el sistema por uno
equivalente17
Bo
−1 −> −1
Ax = b, L
| AL {z } y = L
| {z b}, x = L−> y
B c

y aplicar el método al sistema By = c. Para su implementación basta con conocer simple-


mente la matriz producto M = LL> que recibe el nombre de precondicionador de A. En
general, la matriz L−1 AL−> no se construye, porque el producto por el precondicionador
hace que se pierdan algunas de las buenas propiedades de la matriz original. Ahora bien,
y he aquı́ la ventaja del método, sólo necesitamos calcular productos por M −1 , que
se reducen sistemas lineales con M como matriz de coeficientes. Obviamente, y de forma
similar a como procedı́amos con la descomposición de Cholesky, esto equivale resolver dos
sistemas lineales con L y L> . La buena noticia es que es posible construir matrices para
las que estos sistemas son fáciles de resolver. Por ejemplo, L puede ser sparse y triangular.
rra
El método del Gradiente Conjugado rara vez se programa sin precondicionar. De
hecho, el comando de Matlab con el Gradiente Conjugado implementado es pcg de
preconditioned conjugate gradient.
En última medida, el éxito del Gradiente Conjugado originó el nacimiento de una
familia entera de métodos, los conocidos como métodos de Krylov, que trataban de
extender las buenas propiedades del método a matrices más generales. Por ejemplo, BiCG,
BiCGSTAB, CGS, QMR, GMRES, MINRES, etc. Algunos de estos métodos requieren
que la matriz sea simétrica y otros son válidos para matrices arbitrarias.
Un precondicionador universal, es válido en muchos casos, es la descomposición de
Cholesky incompleta. Va más allá de los contenidos de este curso describir detalladamente
en qué consiste pero podemos dar una idea. Se trata de, grosso modo, aplicar el método
de Cholesky pero restringiendo la creación de nuevas entradas. El resultado es una matriz
L tal que LL> ≈ A en algún sentido. Por tanto, L−1 AL−> ≈ In y su condicionamiento
do
es moderado, o al menos mejor que el de A. En Matlab se encuentra implementada en
el comando cholinc. El siguiente ejercicio ilustra el efecto del precondicionamiento en la
convergencia del Gradiente Conjugado y con ello trata de convencer de la necesidad de
utilizarlo en la resolución de (muy) grandes sistemas de ecuaciones.

Ejercicio 5.17 Las siguientes instrucciones


>> [p,e,t]=initmesh(’lshapeg’,’Hmax’,0.05);
>> [a,b]=assempde(’lshapeb’,p,e,t,1,0,1);
devuelven en a una matriz sparse simétrica definida positiva proveniente de resolver la ecuación
r
de Poisson (una ecuación en derivadas parciales) por el método de elementos finitos en un
16
La American Mathematic Society lo sitúo entre los diez algoritmos más relevantes del siglo XX, junto
con, por ejemplo, la Transformada Rápida de Fourier (FFT) o el algoritmo QR para el cálculo de valores
y vectores propios.
17
Utilizamos la notación L−> = (L−1 )> , es decir invertir y trasponer (o equivalentemente, trasponer e
invertir).

102
LECCIÓN II Capı́tulo 5. Matrices sparse en Matematicas. Metodos iterativos

0 Metodo del gradiente


10
sin precondicionar
precondicionado
−1
10
Bo
−2
10

−3
10

−4
10
Residuo
−5
10

−6
10

−7
10

−8
10
0 50 100 150 200 250
Iteraciones
rra
Figura 5.5: Efecto del en el Gradiente Conjugado.

dominio en forma de ‘L’. La matriz tiene aproximadamente 2100 filas con 14500 elementos no
nulos18 .
Con el comando spy se puede ver la forma de a, su tamaño y el número de entradas
no nulas. Aplica el comando pcg que contiene implementado el Gradiente Conjugado. Por
ejemplo, con
>>[x,flag, relres,iter,resvec] = pcg(a,b,1e-7,100);
aplicas el método con una tolerancia relativa de 10−7 y un número máximo de 100 iteraciones.
En relres se recoge el residuo relativo de la solución calculada (kb − Axk/kbk), en resvec
do
un historial del residuo en cada paso y en flag una variable que informa sobre qué ha sucedido
en la aplicación del método. Ası́ flag==1 indica que se ha alcanzado el número máximo de
iteraciones sin convergencia, mientras que si flag==0 entonces ha habido convergencia. Para
ver el historial de la convergencia del método se puede ejecutar
>> semilogy(resvec);
Observa que es necesario o aumentar el número de iteraciones máximas o disminuir la tolerancia
para obtener convergencia.
A continuación vamos a utilizar un precondicionador muy sencillo basado en la descom-
posición de Cholesky incompleta. Teclea
r
>> R=cholinc(a,’0’);
De nuevo, con los comandos habituales puedes ver tanto la forma como el número de entradas
no nulas de R.
Modificando las instrucciones anteriores con
18
Por cierto, el logo de Matlab es la solución de un problema de este tipo.

103
5.2 Métodos iterativos para sistemas lineales LECCIÓN II

>>[x2,flag2, relres2,iter2,resvec2] = pcg(a,b,[],100,R’,R);

estás aplicando el método del Gradiente Conjugado precondicionado con R> R. ¿Disminuye el
número de iteraciones? (ver iter2). ¿Y el tiempo de cálculo?. ¿Puedes ser ahora más exigente
con la tolerancia?.
Bo
Ejercicio 5.18 Con la orden helpwin lee la ayuda que proporciona Matlab para pcg. ¿Qué otros
métodos iterativos están implementados?. Consulta también la ayuda de cholinc y luinc.
rra
do
r
104
Bo
Lección III
rra
Funciones como argumento. Recursividad
Fórmulas de cuadratura. FFT
do
r
105
r
do
rra
Bo
Introducción
Bo
Hobbes clearly proves that every creature
Lives in a state of war by nature;
So naturalists observe a flea
Has smaller fleas that on him prey,
And these have smaller still to bite’em,
And so proceed ad infinitum.

Swift, Poetry: a Rhapsody


rra
En esta lección abordaremos dos nuevos aspectos de Matlab: el envı́o de funciones
como argumentos de otras funciones y la recursividad, esto es, la habilidad de que las
funciones se llamen a sı́ mismas. Además mostraremos una forma alternativa de definir
funciones en la ventana de comandos.
En la segunda parte hablaremos de las reglas de cuadratura clásicas para la aproxi-
mación de integrales y veremos una implementación sencilla de un método de integración
adaptativa. Finalizaremos con la transformada discreta de Fourier, y su cálculo medi-
ante la transformada rápida de Fourier (FFT). La implementación de estos algoritmos
servirá de ilustración de las estrategias de recursividad, que sirven para obtener un código
simple y legible.
do
r
107
r
do
rra

108
Bo
Capı́tulo 6
Bo
Matlab: Funciones como argumentos.
Recursividad

6.1. Funciones inline


En la sección 3.2 de la Lección I mostramos la definición de funciones mediante ficheros
rra
de texto (con extensión *.m). Existe una forma alternativa de introducir funciones en
Matlab que puede utilizarse directamente en la lı́nea de comandos o en el código de una
función. Por ejemplo,

>> f=inline(’exp(-x)*sin(x)’,’x’);

define la función f (x) = e−x sen(x). Para evaluar se procede igual

>> f(2)

ans =
do
0.1231

A efectos prácticos, inline es equivalente a editar una función con nombre “f” y a escribir
el correspondiente código. La definición queda en memoria pero una vez cerrada la sesión
de Matlab (esto es, al salir del programa) la función se pierde. Ésta es pues una importante
desventaja frente la funciones basada en m-files1 . Sin embargo puede resultar útil para
tareas sencillas tanto en el modo comando como en el código de una subrutina.
Nada impide definir funciones con más argumentos,

>> g=inline(’x*cos(y)-y*cos(x)’,’x’,’y’);
r
Los últimos argumentos del comando inline definen las variables de la función. Si no se
especifican, Matlab trata de reconocer cuáles son las variables y las ordena alfabeticamente:
1
En el menú, seleccionando File → Save workspace as se pueden grabar las variables y funciones
utilizadas en la sesión actual de Matlab. Otra posibilidad es utilizar la orden save indicando que queremos
grabar f . En cualquier caso, ambas opciones no son muy naturales.

109
6.1 Funciones inline LECCIÓN III

>> g=inline(’x^2*cos(y)-y*cos(x)*z’);
>> g

g =

Inline function:
Bo
g(x,y,z) = x^2*cos(y)-y*cos(x)*z

De todas formas, expresar todas las variables explı́citamente puede aclarar y facilitar la
lectura, además de especificar el orden de las variables en la definición de la función:

>> f=inline(’x*cos(k*x)’)

f =

Inline function:
f(k,x) = x*cos(k*x)
rra
>> f=inline(’x*cos(k*x)’,’x’,’k’)

f =

Inline function:
f(x,k) = x*cos(k*x)

Las funciones anteriores no están vectorizadas, es decir, al aplicarlas sobre un vector o


matriz no actúan elemento a elemento. Para ello, deberı́a escribirse

>> g = inline(’x.^2.*cos(y)-y.*cos(x).*z’);
>> g([0 pi 0],[pi 0 0], [0 0 pi]) % funcion vectorizada
do
ans =

0 9.8696 0

Otra forma, más sencilla, es introducir la función de la forma habitual y pedir luego a
Matlab que la prepare para su aplicación a vectores. El comando dedicado a esta tarea es
vectorize:

>> g = inline(’x^2*cos(y)-y*cos(x)*z’) % funcion sin vectorizar

g =
r
Inline function:
g(x,y,z) = x^2*cos(y)-y*cos(x)*z

>> g= vectorize(g)

110
LECCIÓN III Capı́tulo 6. Matlab: Funciones como argumentos. Recursividad

g =

Inline function:
g(x,y,z) = x.^2.*cos(y)-y.*cos(x).*z
Observa que tras la aplicación de este comando, Matlab redefine la función añadiendo “.”
Bo
en los sitios adecuados.

6.2. Funciones como argumentos


Es frecuente que en programación más avanzada se requiera que las funciones trabajen
sobre funciones. Por ejemplo, podemos plantearnos implementar una función que realice
la siguiente tarea
dada una función de una variable y dos valores dibujar la función entre
esos valores
En este caso, uno de los argumentos es la función a dibujar. Veamos cómo se ha
implementado
rra
01 % MIPLOT
02 %
03 % MIPLOT(F,A,B) Dibuja la funcion F entre A y B
04 % MIPLOT(F,A,B,N) Toma N puntos entre A y B
05 %
06
07 function miplot(f,a,b,varargin)
08
09 if nargin<3
10 disp(’argumentos insuficientes’)
11 end
do
12
13 if nargin>3
14 n=varargin{1};
15 else
16 n=200;
17 end
18
19 x=linspace(a,b,n); % vector con n puntos entre a y b
20 y=feval(f,x); % f debe estar vectorizada
21 plot(x,y)
22 return
r
En la lı́nea 07, f recoge la función argumento, mientras que en 20 se procede a evaluar
ésta mediante
feval
Para enviar la función existen dos posibilidades:

111
6.2 Funciones como argumentos LECCIÓN III

Si enviamos una función inline, basta con insertar su nombre

>> fun=vectorize(inline(’exp(-x)*cos(4*x)’));
>> miplot(fun,0,2*pi,200)

Si la función es propia de Matlab o está implementada en un fichero m-file en la


Bo
carpeta de trabajo (o en alguna accesible), podemos
• utilizar “@”2
>> miplot(@sin,0,2*pi,200)
• indicar el nombre de la función entre comillas
>> miplot(’sin’,0,2*pi,200)

Nota. La función plot dibuja el vector y versus x. Concretamente, por defecto construye
el polı́gono con vértices(x(i),y(i)). Si se toma un número suficiente de puntos esto basta
para obtener una buena gráfica. Este comando es una de las salidas gráficas más simples de
Matlab y admite una amplia variedad de argumentos opcionales que controlan el aspecto
rra
final del dibujo. En una lección posterior (Lección V) veremos este comando y otros
relacionados con las salidas gráficas. 

Ejercicio 6.1 Modificar el programa miplot para que en caso de no recibir los argumentos
a y b los pida por pantalla.
(Ayuda. La orden input lee datos por pantalla tras mostrar un mensaje. Necesitarás que ahora a
y b pasen a ser argumentos opcionales.)

Ejercicio 6.2 Lee la ayuda de Matlab sobre plot. Ensaya diferentes variantes, observa como
se puede cambiar de forma sencilla tanto la forma de la gráfica (lı́nea continua, lı́nea a trozos,
raya-punto, sólo puntos,...), el color,...
do
6.2.1. Recursividad
Un aspecto ya habitual en muchos lenguajes de programación es la recursividad, es
decir, la habilidad de que una función se llame a sı́ misma. Es habitual su utilización
cuando se programan estrategias de tipo divide y vencerás, que consiste, a grandes trazos,
en dividir un problema en problemas iguales pero de menores dimensiones.
Quizás el ejemplo más sencillo (y clásico) se basa en la función factorial.

n! = n · (n − 1) · · · 1.

De una manera simple, podemos definir de forma recursiva


r

n · (n − 1)!, si n > 0,
n! =
1, si n = 0.
Su implementación en Matlab es ahora tan sencilla como sigue
2
Matlab recomienda esta forma. El operador @ accede al handle de la función que es la referencia que
tiene Matlab de la función. Para mayor información, ver helpwin function handle.

112
LECCIÓN III Capı́tulo 6. Matlab: Funciones como argumentos. Recursividad

01 % FACT
02 %
03 % FACT(N) devuelve n!
04 %
05
06 function f=fact(n)
Bo
07
08 if (n<0)
09 disp(’error. Argumento inapropiado’);
10 f=[]; % devolvemos el vacio
11 elseif (n==0)
12 f=1;
13 else
14 f=fact(n-1)*n; % llamada a fact con n-1
15 end
16 return

Obviamente, ésta no es la forma más apropiada de programar la función factorial


rra
que en Matlab se encuentra implementada en una función con el mismo nombre3 . Es
más, abusar de este tipo de programación suele generar código poco eficiente. Además el
control que debe hace el ordenador de las sucesivas llamadas puede dar lugar a un costo
en memoria elevado. Sin embargo es cierto que el código resultante suele ser bastante más
simple.
do
r
3
Tienes de hecho acceso al código, basta con ejecutar edit factorial.

113
6.2 Funciones como argumentos LECCIÓN III
Bo
rra
do
r
114
Capı́tulo 7
Bo
Fórmulas de cuadratura.
Transformada rápida de Fourier

7.1. Fórmulas de cuadratura


Un problema ya clásico es la aproximación de una integral
rra
Z b
f (s) ds
a

cuyo cálculo no se puede llevar a cabo por medios analı́ticos o bien porque conlleva un
costo elevado. Este tipo de problemas se ha planteado desde la antigüedad, con algunas
referencias que se remontan a las Matemáticas clásicas en el cálculo de áreas y volúmenes
de figuras curvas. Quizás éste sea el origen de la denominación de fórmula de cuadratura
a cualquier expresión que aproxime una integral definida.
La propia definición de integral1 se fórmula actualmente en términos del lı́mite de
fórmulas de cuadratura, concretamente fórmulas del rectángulo. El Análisis Numérico
trata de analizar no sólo la convergencia de estas fórmulas y otras que se puedan plantear,
do
sino especialmente la calidad de estas aproximaciones estimando el error que comenten.
En última medida, el uso local de estimaciones del error permiten dilucidar qué zonas
del intervalo de integración concentran el error cometido por nuestra fórmula y por tanto
donde debemos concentrar nuestro esfuerzo para reducir el error cometido. Obtenemos
ası́ un método adaptativo, no rı́gido, que reconoce las dificultades del problema y se adapta
a él.
En esta sección esbozaremos estas ideas recurriendo siempre a casos sencillos e ideas
intuitivas y dejando la teorı́a en el mı́nimo imprescindible.

7.1.1. Primeras nociones


r
Desde una óptica completamente ingenua, y a la vista de la gráfica de la función por
integrar, podemos plantear su aproximación por una suma de áreas de rectángulos que
aproximen el área total que define f (Figura 7.1)2 . A este tipo de aproximaciones se les
1
Hablamos de la integral de Rienmann.
2
Esta aproximación está, de hecho, detrás de la definición de la integral de Rienmann.

115
7.1 Fórmulas de cuadratura LECCIÓN III

conoce como reglas del rectángulo. Queda por elegir el punto que al evaluar define la
altura de cada rectángulo. Las elecciones más sencillas son tomar el extremo inferior de
cada subintervalo, el extremo superior o, la a priori más lógica, tomar el punto medio.
Bo
0.6

0.5

0.4

0.3

0.2

0.1

-0.1

-0.2
0 0.5 1 1.5 2 2.5

0.6 0.6
partición Particion
0.5 Regla del punto medio 0.5 Regla del trapecio
0.4 0.4
rra
0.3 0.3

0.2 0.2

0.1 0.1

0 0

-0.1 -0.1

-0.2 -0.2
0 0.5 1 1.5 2 2.5 0 0.5 1 1.5 2 2.5

Figura 7.1: Reglas de cuadratura: punto medio y trapecio

Si, por simplicidad, nos limitamos a trabajar con particiones uniformes, es decir, a
do
construir rectángulos con igual base, las fórmulas anteriores se pueden exponer de forma
simple: en primer lugar introducimos la malla

b−a
n ∈ N, h = , xj = a + hj, xj+1/2 = a + h(j + 1/2)
n
o partición asociada. Las reglas quedan ahora de la siguiente forma
n−1
X
Q1 (f, h) := h f (xj ) (Punto inferior),
j=0
n
r
X
Q2 (f, h) := h f (xj ), (Punto superior)
j=1
n−1
X
Qpm (f, h) := h f (xj+1/2 ), (Punto medio)
j=0

Es difı́cil escapar a la sensación de que la regla del punto medio goza de mejores

116
LECCIÓN III Capı́tulo 7. Fórmulas de cuadratura. FFT

propiedades que las que definen el resto de elecciones3 . Esta impresión es correcta, como
veremos más adelante.
Un análisis algo más profundo nos descubre la regla del trapecio como una mejor
manera de aproximar la integral (ver de nuevo la Figura 7.1). En este caso la integral se
aproxima como suma del área de trapecios, como su propio nombre indica. Es un simple
ejercicio comprobar que la regla obedece a la siguiente fórmula
Bo
h1 n−1
X 1 i
Qtr (f, h) := h f (x0 ) + f (xj ) + f (xn ) , (Regla del trapecio).
2 j=1
2

Parecerı́a evidente que esta aproximación es mejor que la de las fórmulas de rectángulo
que hemos visto. Esta impresión es sólo parcialmente correcta: de hecho la regla del punto
medio es ligeramente mejor que la regla del trapecio, como veremos más adelante.
En cualquier caso, la regla del trapecio sugiere que podemos desarrollar fórmulas más
complejas sobre cada subintervalo [xi , xi+1 ] para luego construir con ellas, simplemente
sumándolas, una fórmula en todo el intervalo [a, b]. Es por ello que a las reglas del rectángu-
lo y trapecio se les llama reglas compuestas, mientras reglas que no implican subdividir
el intervalo de integración en intervalos más pequeños se las conoce como reglas simples.
rra
Ejercicio 7.1 Implementa en Matlab la regla del punto medio.

Solución. Observemos primero que necesitamos cuatro argumentos de entrada:


Función a integrar f.

Puntos inicial y final del intervalo a,b.

Número de divisiones del intervalo n.


Una vez leı́dos estos datos podemos calcular h, la distancia entre dos puntos consecu-
tivos, construir un vector con los puntos donde hay que evaluar f , evaluar la función en
do
esos puntos (un nuevo vector de valores), sumar el vector y multiplicar por h.
El programa podrı́a ser ası́
01 % PUNTOMEDIO
02 %
03 % PUNTOMEDIO(F,A,B,N) devuelve el valor aproximado de la
04 % integral de F entre A y B con la
05 % regla del punto medio con N puntos
06 % F debe estar vectorizada
07
08 function s=puntomedio(f,a,b,n)
r
09
10 h=(b-a)/n;
3
Quizás por razones de simetrı́a. La intuición es una arma poderosa en todas las Ciencias y en las
Matemáticas en particular. Sin embargo en el Análisis Numérico puede llevar a confusiones e impresiones
erróneas. En ocasiones los métodos numéricos funcionan o fallan por razones que escapan a la pura
intuición. De todos modos, no por ello se debe desdeñar, sino manejarla con algo de cuidado.

117
7.1 Fórmulas de cuadratura LECCIÓN III

11 x=linspace(a+h/2,b-h/2,n); % calculamos puntos por evaluar


12 y=feval(f,x); % evaluamos f en esos puntos
13 s=h*sum(y); % aplicamos regla


Bo
Ejercicio 7.2 Implementa en Matlab la regla del trapecio.

Ejercicio 7.3 Tomando un número de puntos suficientemente alto y siempre que la función
sea regular (sea derivable un número suficiente de veces) puedes tomar ese valor como el
resultado exacto de la integral. Con un ejemplo arbitrario compara los resultados de la regla
del punto medio y la regla del trapecio.

Nota. Existe una cuestión, algo tonta, sobre el parámetro n. Lo habitual es tomar n de
forma que h = (b − a)/n sea la distancia entre los puntos que se evalúan para construir
la regla de cuadratura. Esta elección hace que en la regla del punto medio la función se
evalúe en n puntos mientras que en la regla del trapecio, se haga en n + 1 puntos. En
cualquier caso, y adelantándonos a lo que sigue, el parámetro relevante es precisamente
rra
h. 

7.1.2. Reglas simples


Tanto la regla del punto medio como la del trapecio se basan en interpolar la función
por un polinomio de grado 0 (constante) y grado 1 (una recta) sobre cada subintervalo
e integrar dicho polinomio. Esto es, si c es el punto medio de (a, b), la regla del punto
medio consiste en reemplazar la función por la constante, polinomio de grado 0, que pasa
por (c, f (c)) y aproximar la integral de f por la de dicha constante:
Z b Z b
f (s)ds ≈ f (c)ds = f (c)(b − a).
a a
do
Análogamente, la regla del trapecio se basa en aproximar la función por una recta p1 (s),
polinomio de grado 1, que pase por (a, f (a)) y (b, f (b)) y luego dar como resultado aprox-
imado de la integral la de p1 (s):
Z b Z bh
b−s s−a i b−a
f (s)ds ≈ f (a) + f (b) ds = [f (a) + f (b)] .
a a |b − a {z b − a } 2
p1 (s)

El estudio del error de las fórmulas anteriores queda ası́ reducido a las propiedades de
aproximación de los polinomios de grado 0 y 1 correspondientes.
r
Proposición 7.1 Existen ξ1 , ξ2 ∈ [a, b] tales que
Z b
1 00
f (s) ds − (b − a)f (c) = f (ξ1 )(b − a)3 ,
a 24
Z b
b−a   1
f (s) ds − f (a) + f (b) = − f 00 (ξ2 )(b − a)3 .
a 2 12

118
LECCIÓN III Capı́tulo 7. Fórmulas de cuadratura. FFT

Obviamente, nada se dice sobre cuáles son los puntos ξ1 , ξ2 , puesto que conocer esos
puntos en cada caso serı́a equivalente a conocer la integral para cualquier función arbi-
traria. Es remarcable que ambas fórmulas son exactas para polinomios de grado 1 (porque
en tal caso f 00 = 0) y que el error que se puede esperar de la fórmula del punto medio es
la mitad que el de la fórmula del trapecio y además con signo opuesto4 .
Siguiendo con estas ideas, podemos avanzar un paso más trabajando con polinomios
Bo
de grado dos. Denotando por Pn (x) los polinomios de grado n, procedemos como sigue

Construir p ∈ P2 (x) tal que (c = (a + b)/2)

p2 (a) = f (a), p2 (c) = f (c), p2 (b) = f (b).

Dar como aproximación


Z b Z b
f (s) ds ≈ p2 (s) ds.
a a
rra
a c b

Figura 7.2: Regla de Simpson


do
En la terminologı́a habitual se habla de una regla de precisión 2. La fórmula que
ası́ obtenemos viene dada por
b
b − a
Z 
f (s) ds ≈ f (a) + 4f (c) + f (b) . (7.1)
a 6

Esta regla de cuadratura recibe el nombre de regla de Simpson y es una de las más
utilizadas en la práctica. A primera vista se puede esperar que dé el valor exacto de la
integral para polinomios de grado de 2, puesto que ası́ se ha impuesto en la definición.
r
Sin embargo tiene un grado de precisión adicional fruto de la disposición simétrica de los
puntos de evaluación (es decir, del hecho de que c sea el punto medio de [a, b]), lo que lleva
a que la fórmula sea exacta para polinomios de grado 3. Esto es, la regla de Simpson
tiene precisión 3:
4
Salvando el hecho de que en principio ξ1 6= ξ2 . Un análisis más elaborado permite probar que esta
conclusión es esencialmente cierta.

119
7.1 Fórmulas de cuadratura LECCIÓN III

Proposición 7.2 Existe ξ3 ∈ [a, b] tal que


Z b
b − a  1 (4)
f (s) ds − f (a) + 4f (c) + f (b) = − f (ξ3 )(b − a)5 .
a 6 2880
En general, tenemos la siguiente estrategia para construir reglas de mayor precisión:
Bo
Tomar n ∈ N, h = (b − a)/n, xj = a + jh con j = 0, . . . , n (n + 1 puntos).

Construir un polinomio pn ∈ Pn (x) tal que

pj (xj ) = f (xj ).

Aproximar Z b Z b
f (s) ds ≈ pn (s) ds.
a a

Las fórmulas ası́ obtenidas reciben el nombre de fórmulas de Newton-Cotes cerradas5 . Las
fórmulas de Newton-Cotes abiertas se definen de forma similar pero tomando
rra
b−a
xj+1/2 = a + (j + 1/2)h, j = 0, . . . , n, h= .
n
Se denominan reglas abiertas porque ni a ni b se evalúan para aproximar la integral.
Sin embargo no es conveniente recurrir a estas fórmulas de cuadratura porque conforme
aumenta el número de puntos, las fórmulas tienden a ser más inestables numéricamente.
En lugar de ello, se utilizan fórmulas compuestas, como las del rectángulo o trapecio,
definidas a partir de fórmulas simples de pocos puntos. Volveremos a ello en próximos
apartados.

Ejercicio 7.4 (Matemático) Deducir los coeficientes de la regla de Simpson expuestos en


(7.1).
(Ayuda: Todo polinomio de grado 2 se puede escribir en la forma p2 (s) = α1 (s − b)(s − c) +
do
α2 (s − a)(s − c) + α3 (s − a)(s − b). ¿Cuánto valen α1 , α2 , α3 si exigimos que p2 (a) = f (a),
p2 (b) = f (b), p2 (c) = f (c)?. Integra p2 (x) y deduce la regla. Ten en cuenta que c = (a + b)/2.)

Ejercicio 7.5 Otra forma equivalente de definir y calcular las fórmulas de Newton-Cotes es
exigir que la fórmula de cuadratura integre a los polinomios de máximo grado. En el caso de
la fórmula de Simpson, bastarı́a con partir de
b−a
xj = a + jh, j = 0, 1, 2, con h = ,
2
definir
b
r
Z
f (s) ds ≈ ω0 f (x0 ) + ω1 f (x1 ) + ω2 f (x2 ).
a

y exigir que la fórmula sea exacta para f = 1, s, s2 . Calcula ası́ los pesos de la fórmula de
Simpson.
5
El hecho de que Isaac Newton aparezca ligado a estas ideas da una pista sobre la fecha a la que se
remontan estas técnicas.

120
LECCIÓN III Capı́tulo 7. Fórmulas de cuadratura. FFT

Ejercicio 7.6 Siguiendo las ideas del ejercicio anterior, podemos deducir las fórmulas con
más puntos. Para facilitar el estudio realizamos el cambio de variables
Z b
b−a n
Z
f (s) ds = f (a + ht) dt
a n 0
Bo
Se introduce a continuación la regla de cuadratura en [0, n]
Z n  
g(t) dt ≈ n ω0 g(0) + ω1 g(1) + . . . + ωn g(n) .
0

Los pesos se determinan sin más que exigir que sea exacta para polinomios6 , de grado n en t.
Llegamos por tanto a las condiciones
Z n
g(t) dt = n(ω0 g(0) + ω1 g(1) + . . . + ωn g(n)), g ∈ {1, t, . . . , tn }.
0

Esta forma directa de abordar el problema nos conduce al sistema


   
rra
ω 1

1 1 1 ··· 1 0
 0 1 2 ··· n  ω   n/2 
 1  
2

ω n /3

 0 1 4 · · · n2   2  = 
 
.

  . .
 . . . . . . . . . . . . . . . . .   ..  
   .. 

n n
0 1 2 ··· n ωn nn /(n + 1)

Implementa una función que reciba como argumento n y devuelva los pesos de la fórmula de
Newton-Cotes cerrada de n + 1 puntos7 .

Solución. Recordemos en primer lugar que los vectores en Matlab se numeran a partir
de 1, lo que exige desplazar todos los ı́ndices una unidad. Dicho esto, una implementación
de la solución de este ejercicio es como sigue
do
01 % PESOSNEWTONCOTES
02 %
03 % V=PESONEWTONCOTES(N) devuelve en V los pesos de la
04 % formula de Newton-Cotes cerrada
05 % de N+1 puntos.
06 %
07 % Esto es, la integral de f en [a,b] se aproxima por
08 %
09 % (b-a)*(w(1)*f(x(1))+w(2)*f(x(2))+...+w(n+1)*f(x(n+1)))
r
10 %
11 % donde x(i)=a+(i-1)*(b-a)/n i=1,...,n+1,
12
6
observa que el cambio de variable lleva polinomios de grado n a polinomios de grado n
7
La matriz del sistema recibe el nombre de Matriz de Vandermonde. Desafortunadamente es una
matriz muy mal condicionada que da problemas en su resolución para n moderado. Ello es consecuencia
de que la base de monomios no es buena elección como base de los polinomios.

121
7.1 Fórmulas de cuadratura LECCIÓN III

13 function w=pesosnewtoncotes(n)
14
15 r=0:n;
16 c=1; m=ones(1,n+1);
17 for i=1:n
18 m=[m; r.^i]; % construimos matriz del sistema
Bo
19 c=[c; n^(i)/(i+1)]; % construimos el termino independiente
20 end
21
22 w=m\c;
23 return


Con diferentes valores de n hemos obtenido los siguientes resultados
1 2 3 4 5 6 7 8 9 10
1/2 1/6 1/8 7/90 19/288 41/840 322/7409 248/7109 177/5551 94/3503
1/2 2/3 3/8 16/45 25/96 9/35 337/1628 578/2783 458/2607 2431/13693
rra
1/6 3/8 2/15 25/144 9/28 49/64 −111/3391 27/224 −410/5059
1/8 16/45 25/144 34/105 585/3382 97/262 451/2089 722/1587
7/90 25/96 9/28 585/3382 −454/2835 282/4373 −406/933
19/288 9/35 49/64 97/262 282/4373 783/1097
41/84 337/1628 −111/3391 451/2089 −406/933
429/9871 578/2783 27/224 722/1587
248/7109 458/2607 −351/4331
177/5551 2284/12865
94/3503
Se puede comprobar que aparecen pesos negativos a partir de n = 8. Es decir, la fórmula
de cuadratura puede dar valores negativos para una función positiva. Esta inestabilidad se
vuelve más acusada conforme n → ∞. De hecho es muy probable que a partir de n ≈ 10
do
la resolución del sistema lineal de Vandermonde de resultados muy poco fiables dado el
mal condicionamiento de la matriz8 . En cuanto a los pesos, éstos se pueden calcular de
forma más estable sin más que elegir una base adecuada de los polinomios de n.
La fórmula para n = 3 se suele denominar en la literatura, por razones obvias, regla
de 3/8. El grado de precisión de estas reglas (es decir, el grado de los polinomios para
los que las fórmulas dan la integral exacta) es n ó n + 1 dependiendo si n es impar o par
respectivamente.
Ejercicio 7.7 Implementa una función que devuelva los pesos para las fórmulas de Newton-
Cotes abiertas.
r
7.1.3. Retorno a las reglas compuestas
En la sección precedente indicamos que el uso de fórmulas de cuadratura simple con
un número de puntos elevados equidistribuidos no es recomendable dado que exhiben
8
Se puede atenuar este mal condicionamiento utilizando la descomposición QR (ver Lección IV) para
resolver el sistema lineal

122
LECCIÓN III Capı́tulo 7. Fórmulas de cuadratura. FFT

una gran inestabilidad numérica. Este hecho está ı́ntimamente con la inestabilidad de la
interpolación numérica en estos nodos, tema al que volveremos más adelante (Lección V).
Una alternativa que proporciona mejores resultados, y que es muy sencilla de imple-
mentar, es volver a las fórmulas de cuadratura compuestas, dividiendo el intervalo original
en varios subintervalos y aplicar en cada uno de ellos una fórmula de cuadratura simple.
Por ejemplo la regla del trapecio es la fórmula de cuadratura compuesta obtenida al dividir
Bo
el intervalo de integración en n subintervalos y aplicar en cada uno de ellos la fórmula de
Newton-Cotes cerrada de dos puntos:
Z b
b−a
f (s) ds ≈ (f (a) + f (b)).
a 2
Deduciremos a continuación la regla compuesta de Simpson. Tomemos en primer lugar
n subintervalos, con lo que habremos de evaluar en 2n + 1 puntos. Definiendo h = (b −
a)/(2n), xi = a+ih (i = 0, . . . , 2n) aplicaremos la regla de Simpson simple sobre [x2i , x2i+2 ]
(longitud 2h). Aparecen ası́ tres términos diferentes:
Los puntos x0 (= a) y x2n (= b) son extremos de un único subintervalo.
Los puntos x2j , j = 1, . . . , n − 1, que son extremo superior de un subintervalo e
rra
inferior del siguiente ([x2j−2 , x2j ] y [x2j , x2j+2 ]).
Los puntos x2j−1 que son puntos interiores de los subintervalos ([x2j−2 , x2j ]).
La fórmula que obtenemos es
h1 n n−1
4X 2X 1 i
Qsp (f, h) := h f (x0 ) + f (x2j−1 ) + f (x2j ) + f (x2n ) . (7.2)
3 3 j=1 3 j=1 3

La siguiente proposición informa sobre el comportamiento de las tres fórmulas com-


puestas hasta ahora
Proposición 7.3 Existen ξ1 , ξ2 , ξ3 ∈ [a, b] tales que
Z b
h2 00
do
Qpm (f, h) − f (s) ds = f (ξ1 )(b − a),
a 24
Z b
h2
Qtr (f, h) − f (s) ds = − f 00 (ξ2 )(b − a),
a 12
Z b
h4 (4)
Qsp (f, h) − f (s) ds = − f (ξ3 )(b − a).
a 180
A la luz de este resultado se concluye que el error se divide por cuatro cuando h se
divide por dos para las fórmulas del punto medio y trapecio, y por dieciséis en el caso de la
fórmula de Simpson. Se dice entonces que las fórmulas tienen orden de convergencia
2 en los dos primeros casos y orden 4 para la regla de Simpson.
r
Esencialmente, el resultado anterior informa de cómo mejora la aproximación de la
fórmula cuando aumentamos el esfuerzo computacional. Comprobamos que hay una clara
ventaja de la regla de Simpson respecto a la regla del punto medio y del trapecio. No
obstante, se observa que es necesario que la función tenga derivada cuarta continua para
alcanzar orden 4. En caso de que la función no sea tan regular, es esperable que la regla
de Simpson pierda orden.

123
7.1 Fórmulas de cuadratura LECCIÓN III

Ejercicio 7.8 Deducir que la fórmula compuesta de Simpson viene efectivamente dada por
(7.2). Programar en una función la regla de Simpson compuesta, siguiendo las directrices
marcadas en el Ejercicio 7.1.

Ejercicio 7.9 Se trata de observar experimentalmente el orden de convergencia de las reglas


del punto medio, trapecio y de Simpson, programadas en los ejercicios 7.1, 7.2 y 7.8 mediante
Bo
una baterı́a de experimentos.
Para ello, definimos una función mediante inline:

>> f=inline(’x*cos(x)’); f=vectorize(f);

La integral exacta se puede calcular tomando un número muy elevado de puntos (por ejem-
plo n = 10000) con la regla de Simpson, que es la de mayor precisión. Mide el error para
diferentes valores de n y observa como decrece el error. Una buena elección podrı́a ser
n = 10, 20, 40, 80, ..., esto es, multiplicando por 2 el número de puntos. Deberı́as observar que
para funciones suaves el error se divide por 4 o por 16, según la regla que se aplique.
Testa los programas con los siguientes ejemplos
rra
i) f1 (x) = x cos(x) en [0, π]

ii) f2 (x) = xe−x en [0, 3]

iii) f3 (x) = x log(x) en [1, 2] y en [0, 2]9

iv) f4 (x) = cos2 (x) en [0, π/2], en [0, π] y en [0, 2π].

Un fichero script te puede venir bien para este ejercicio. ¿Qué observas con las reglas del
trapecio y del punto medio en el último caso?.
do
Nota. En esta serie de experimentos se observa que la regla de Simpson no alcanza el
orden que la teorı́a predice en el ejemplo iii) sobre el intervalo [0, 2]. Ello es debido a que
las derivadas de la función tienen una singularidad en el origen.
Menos simple de explicar
R 2π es la superconvergencia (convergencia mejor de lo esperado)
2
que se observa para 0 cos (x) (punto iv)).Esto es consecuencia de que el integrando,
además de regular, es π−periódico y se está integrando en un múltiplo de su intervalo
de periodicidad. En una sección posterior daremos una explicación a este fenómeno tan
sorprendente. 
r
Ejercicio 7.10 Implementa la regla compuesta de 3/8, la siguiente a la regla de Simpson, que
aparecı́a en el Ejercicio 7.6. Compara los resultados con la regla de Simpson. ¿Qué observas?
9
En este caso, evaluar en 0 es una singularidad de tipo 0 · ∞. En realidad el lı́mite cuando x → 0 es
cero, que se puede tomar como valor de f (0). Una forma de evitar este problema es aplicar la fórmula en
[, 2] con  << 1, por ejemplo,  = 10−16 . Esta breve discrepancia en el extremo de integración no afecta
al resultado.

124
LECCIÓN III Capı́tulo 7. Fórmulas de cuadratura. FFT

7.1.4. Reglas gaussianas


En el estudio de las fórmulas de Newton-Cotes vimos que los pesos estaban escogidos
de manera que la fórmula tuviese grado máximo de precisión aunque la elección de los
nodos, es decir, de los puntos en los que se evalúa la función, estaba fijada a priori.
Podemos plantearnos ahora hacer de la posición de los nodos una variable más del
Bo
problema. Para ello, y con objeto de simplificar el análisis, nos situamos en el intervalo
[−1, 1] y buscamos la fórmula de mayor precisión de dos puntos:

ω1 , ω2 , ξ1 , ξ2 ∈ R
Z 1
ω1 p(ξ1 ) + ω2 p(ξ2 ) = p(s) ds, p ∈ {1, s, s2 , s3 }
−1

Es decir, tenemos cuatro incógnitas, ξ1 , ξ2 (los nodos de la fórmula) y ω1 , ω2 (los pesos),


y exigimos que la fórmula integre de forma exacta a polinomios de grado 3. En principio
el problema está bien planteado10 .
Es un ejercicio ilustrativo resolver el sistema no lineal

ω1 + ω2 = 2,
rra




 ω1 ξ1 + ω2 ξ2 = 0,



 ω1 ξ12 + ω2 ξ22 = 23 ,


ω1 ξ13 + ω2 ξ23 = 0.

La solución a dicho sistema es


√ √
3 3
ω1 = ω2 = 1, ξ1 = − , ξ2 = .
3 3
En resumen, una elección de los nodos nada obvia define una regla de dos puntos
con mejores propiedades de convergencia que, por ejemplo, la regla del trapecio11 .
do
Podemos proceder de la misma forma y dada una regla de cuadratura de n nodos
exigir que ésta integre de forma exacta a polinomios de grado 2n − 1. Dada la dificultad
del sistema no lineal resultante, patente ya con n = 2, se deduce que el problema debe
ser atacado desde un punto de vista muy diferente.
Existe una teorı́a ya clásica que demuestra que
existe una única regla de cuadratura que cumpla esas condiciones;
los pesos ωi son siempre positivos.
El segundo punto es importante, pues asegura que los pesos no puedan crecer sin
r
control dado que al ser positivos y al integrar de forma exacta a las constantes, ω1 + . . . +
ωn = 2, situación que no se daba en las fórmulas de Newton-Cotes.
10
Tenemos cuatro ecuaciones con cuatro incógnitas. Sin embargo el sistema es no lineal luego la teorı́a
clásica de sistemas lineales no es aplicable. Podrı́amos tener cuatro soluciones, siete soluciones, infinitas
soluciones o ninguna solución...
11
Este resultado le resultó ya muy chocante a Carl Friedrich Gauss, que fue el primero en notar que
una distribución nada lógica de los nodos definı́a una fórmula de cuadratura de mayor grado de precisión.

125
7.1 Fórmulas de cuadratura LECCIÓN III

La teorı́a va más allá puesto que es constructiva: da una forma de calcular la fórmula
(nodos y pesos) mucho más eficiente. En concreto, los nodos de la fórmula de cuadratura
son las raı́ces de una familia de polinomios, los polinomios de Legendre, que se encuentra
tabulada en multitud de textos cientı́ficos. Los pesos ωi se pueden calcular a continuación
resolviendo un simple sistema lineal. En la Tabla 7.1 se pueden ver los coeficientes de
las primeras reglas gaussianas. Observa que la disposición simétrica de los nodos en el
Bo
intervalo [−1, 1] y de los pesos asociados.

n ξi ωi
n=1
0 2
n=2 √
−√ 3/3 1
3/3 1
n=3
−0.774596669 0.555555556
0.0 0.888888889
rra
0.774596669 0.555555556
n=4
−0.861136312 0.347854845
−0.339981044 0.652145155
0.339981044 0.652145155
0.861136312 0.34785484
n=5
−0.906179846 0.236926885
−0.538469310 0.478628670
0.0 0.568888889
0.538469310 0.478628670
0.906179846 0.236926885
do
Cuadro 7.1: Primeras fórmulas gaussianas

Ejercicio 7.11 (Reglas gaussianas en un intervalo arbitrario) Las fórmulas gaus-


sianas se dan en el intervalo de referencia [−1, 1] por comodidad. ¿Cómo se aplicarı́an en un
intervalo [a, b]?.

7.1.5. Extrapolación de Richardson


r
La extrapolación de Richardson es una estrategia que permite acelerar la velocidad de
convergencia de un método numérico bajo determinadas condiciones.
Nos centraremos en esta sección en la descripción de esta técnica aplicada a la fórmula
del trapecio. El método resultante se conoce como método de Romberg.

126
LECCIÓN III Capı́tulo 7. Fórmulas de cuadratura. FFT

Proposición 7.4 Existe una sucesión de números (b2j )j tales que para f suficientemente
regular
Z b m
X h i
2j (2j−1) (2j−1)
f (s) ds − Qtr (f, h) = b2j h f (b) − f (a) + O(h2m+2 ).
a j=1
Bo
El sı́mbolo de Landau O(hM ) indica una cantidad que es menor que una constante
multiplicada por hM y con dicha constante independiente de h. En otras palabras, es
equivalente a escribir
Z b m
X h i
2j (2j−1) (2j−1)

f (s) ds − Qtr (f, h) − b2j h f (b) − f (a) ≤ Cm h2m+2
a j=1

donde Cm depende de m y de la derivada m + 1 de f pero no de h.


Denotando por
Z b h i
I= f (s) ds, α0 (h) = Qtr (f, h) c2j := b2j f (2j−1) (b) − f (2j−1) (a)
a
rra
se observa que para h y h/2 se dispone de los desarrollos
m
X
I = α0 (h) + c2j h2j + O(h2m+2 ),
j=1
m
X
I = α0 (h/2) + 1
c h2j
4j 2j
+ O(h2m+2 ).
j=1

Multiplicando la segunda ecuación por 4, restando la primera y despejando I obtenemos


m
4α0 (h/2) − α0 (h) X 1 1
− 1 c2j h2j + O(h2m+2 ).

I= + 3 4j−1
| 3
{z } j=1 | {z }
(1)
c2j
do
α1 (h)

(1)
En particular observamos que c2 = 0, esto es hemos cancelado el primer término del
desarrollo, por lo que
m
X (1)
I = α1 (h) + c2j h2j + O(h2m+2 ). (7.3)
j=2

Como consecuencia

I − α1 (h) = O(h4 ) |I − α1 (h)| ≤ C4 h4 .




Por tanto α1 (h) es una aproximación de la integral con orden 4. Es más, α1 (h) cumple de
r
nuevo un resultado similar al de la proposición anterior (ver (7.3)), por lo que podemos
repetir el mismo argumento y definir12
16α1 (h/2) − α1 (h)
α2 (h) = .
15
12
α1 (h/2) se ha obtenido igual partiendo de α0 (h/2) y α0 (h/4)

127
7.1 Fórmulas de cuadratura LECCIÓN III

Paso 0 Paso 1 Paso 2 Paso 3

α0 (h) / α1 (h) / α2 (h) / α3 (h)


c nn n6 nn n6 nnn6
o nnn nnn nnn
nnnn nnnn nnnn
Bo
n nnn nnn nnn
v α0 (h/2) / α1 (h/2) / α2 (h/2)
e nn6 nn6
r nn nnn nn nnn
nn nn
g nnn nnn
e / α1 (h/4)
n α0 (h/4)
n n 6
c n nnn
i nnn
a  nnn
α0 (h/8)

Figura 7.3: Diagrama del método de Romberg

Es fácil ver que nuevamente I − α2 (h) tiene un desarrollo del error que comienza con
rra
h6 puesto que este combinación ha cancelado el primer término que aparecı́a con α1 (h).
Como consecuencia, α2 (h) da una aproximación de la integral de orden 6. En general se
pueden definir
22j αj (h/2) − αj (h)
αj+1 (h) = .
22j − 1
Cada una ellas satisfaciendo
|I − αj (h)| ≤ Cj h2j+2 ,
donde Cj es independiente de h pero de j o de f . Observa que la convergencia sólo se
asegura para j fijo y h → 0.
Su ventaja más palpable es que únicamente requiere aproximaciones de la integral
obtenidas con una fórmula de cuadratura sencilla. Combinando resultados para valores
do
distintos de h se obtiene una mejora sustancial en la aproximación de la integral. Aquı́ nos
hemos centrado en la fórmula del trapecio, pero se pueden adaptar a la fórmula del punto
medio o a la de Simpson. Es más, estrategias de este tipo se aplican en diversa áreas del
Análisis Numérico. Para ello, es esencial contar con un resultado del tipo enunciado en la
Proposición 7.4. La extrapolación sigue el sencillo diagrama de la Figura 7.3

Nota. Los resultados expuestos en esta sección, y en concreto la Proposición 7.4, expli-
can por qué la fórmula del trapecio converge mejor de lo esperado para funciones regulares
y periódicas cuando se integra en un intervalo de periodicidad. Observa que en este caso
f (2j−1) (b) = f (2j−1) (a) y por tanto no hay términos en hm para ningún m. Esto es, el
r
orden de convergencia es m para cualquier m, o lo que es lo mismo
Z b
f (s)ds − Qtr (f, h) ≤ Cm hm , ∀m ∈ N


a

donde Cm que depende de la derivada m-ésima de f (y por tanto de m) pero no de h. Con


ello se consigue una convergencia muy rápida a la integral y bastarán unos pocos puntos

128
LECCIÓN III Capı́tulo 7. Fórmulas de cuadratura. FFT

para calcular la integral con una precisión muy fina.


En la terminologı́a habitual en Análisis Numérico se dice que el método tiene un orden
de convergencia superalgebraico. Es posible probar que bajo condiciones algo más fuertes
que la existencia de todas la derivadas13
Z b
f (s)ds − Q (f, h) ≤ Cr−n
Bo

tr
a

con r > 1 y C independiente de r y de n, con lo que el orden es de hecho exponencial. 

Ejercicio 7.12 Comprueba que si aplicas un paso de extrapolación a la fórmula del trapecio
compuesta obtienes el método de Simpson.

Ejercicio 7.13 Implementa la extrapolación de Richardson, según el siguiente prototipo de


función

01 % RICHARDSON
02 %
03 % V= RICHARDSON(F,A,B,N,M) Aplica la formula del trapecio con
rra
04 N, 2*N,4*N,..., 2^(M-1)*N puntos
05 Construye la matriz de extrapolacion
06 V M x M donde V(:,i) es el resultado
07 de aplicar el paso i-1 de Richardson.

Ejercicio 7.14 Existe una forma más general de definir la extrapolación. Para ello precisamos
que las sucesivas h decrezcan de una forma proporcional

α0 (h), α0 (rh), α0 (r2 h), . . . , α0 (rn h).

En el caso expuesto, r = 1/2. ¿Cómo se adapta la extrapolación para otras elecciones de


r ∈ (0, 1)?.
do
7.1.6. Integración adaptativa
Las fórmulas anteriores adolecen de un importante defecto: todas asumen que el com-
portamiento de la función es más o menos uniforme en todo el intervalo de integración.
La situación usual es que la función tenga zonas donde varı́a de forma brusca y zonas
donde su comportamiento sea considerablemente más suave. Intuitivamente, se entiende
que las primeras zonas son las más problemáticas. El siguiente paso en cualquier algorit-
mo numérico es diseñar métodos adaptativos. Estos esquemas reconocen aquellas zonas
que requieren mayor trabajo (refinar, en la terminologı́a habitual) y aquéllas donde basta
r
unas pocas evaluaciones para obtener una aproximación suficientemente buena.
Para abordar esta tarea debemos disponer en primer lugar de un buen estimador
del error, esto es, de un postproceso que nos de información sobre el error que estamos
cometiendo y que ası́ permita dilucidar qué partes del intervalo de integración requieren
mayor esfuerzo y cuáles no.
13
Concretamente que la función sea analı́tica

129
7.1 Fórmulas de cuadratura LECCIÓN III
Bo
Zona regular Zona Irregular Zona regular

Figura 7.4: Integración adaptativa

A continuación expondremos una implementación muy sencilla de una integración


rra
adaptativa basada en la regla de Simpson. El estimador se basa en comparar el resultado
obtenido, en cada subintervalo, por la regla de Simpson simple, y la compuesta con dos
subintervalos.
Dado que la regla de Simpson se obtiene de la regla del trapecio utilizando un único
paso de extrapolación (Ejercicio 7.12), obtenemos de (7.3)
Z b
h 
(1)
f (s) ds − f (a) + 4f (c) + f (b) = c2 h4 + O(h6 ) (7.4)
a |6 {z }
Q1 (f )
Z b (1)
h  c
f (s) ds − f (a) + 4f (d) + 2f (c) + 4f (e) + f (b) = 2 h4 + O(h6 ) (7.5)
a |12 16
do
{z }
Q2 (f )

donde h = (b − a), c es el punto medio de (a, b), d y e, los puntos medios de (a, c) y (c, b).
(1)
El término dominante del error, para h suficientemente pequeño, es c2 h4 de forma que
Z b
(1)
f (s) ds − Q1 (f ) ≈ c2j h4 .
a

A priori este término no puede ser calculado, pero puede ser despejado de (7.4) y (7.5),
sin más que sustraer a la primera identidad la segunda. Ası́ obtenemos
r
1
 (1) 4
Q2 (f ) − Q1 (f ) ≈ 1 − 16 c2j h

y por tanto Z b
16 (1)
(Q2 (f ) − Q1 (f )) ≈ c2j h4 ≈ f (s) ds − Q1 (f ) .
15 a
| {z }
error

130
LECCIÓN III Capı́tulo 7. Fórmulas de cuadratura. FFT

La idea de nuestro esquema adaptativo es la que sigue: dado un intervalo [a, b] y una
tolerancia ε

Calculamos Q2 (f ) y Q1 (f ) como antes, y



16
est = (Q1 (f ) − Q2 (f ))
Bo
15

Si est < ε el resultado se considera bueno y se devuelve Q2 (f );

Si est > ε se aplica el argumento anterior en los subintervalos [a, c] y en [c, b] con
una tolerancia de /2 y se devuelve como integral la que calculada en [a, c] y en [c, b]

Hay por lo tanto un proceso de subdivisión de los intervalos, de manera que la única
forma, en este estado inicial, de que un subintervalo no se divida es que la integral se
calcule dentro de la tolerancia prefijada. Obviamente el algoritmo anterior se programa
de forma natural de manera recursiva.
El papel fundamental lo juega una función, que podrı́a seguir el siguiente prototipo
rra
simpsonadaptativo(f,a,c,b,fa,fc,fb,integ,tol)

donde f es la función a integrar, a y b son los extremos de integración, c el punto medio,


fa, fb y fc los valores de f en a, b y c, integ es el resultado de aplicar la regla de Simpson
en [a,b] y tol la tolerancia con la que se pide la integral. Se procede entonces siguiendo
los siguientes pasos

1. Se toma h=(b-a), d=(a+c)/2, e=(c+b)/2 y se calcula fd = f (d) y fe = f (e)

2. Se calcula
do
integ21 = h/12*(fa + 4fd + fc) integ22 = h/12*(fc + 4fe + fb)
integ2 = integ21 + integ22

3. Se calcula el estimador

16
est = (integ − integ2)

15

4. Si est<tol entonces integ = integ2 y se hace return.


r
5. Si est>tol entonces se calcula

integ21 = simpsonadatativo(f, a, d, c, fa, fd, fc, integ21, tol/2)


integ22 = simpsonadatativo(f, c, e, b, fc, fe, fb, integ22, tol/2)
integ = integ21 + integ22.

131
7.1 Fórmulas de cuadratura LECCIÓN III

Si hemos seguido el esquema anterior y nos vemos forzados a dividir en dos subinter-
valos, habremos evaluado ya f en a, c y en su punto medio d y en c, b y el correspondiente
punto medio e. También se habrá calculado la regla de Simpson en estos intervalos. Es por
ello que enviamos todos estos valores en las llamadas de la función simpsonadaptativo,
dado que generalmente la operación más costosa es precisamente evaluar la función.
Notemos que se ha optado por devolver como aproximación de la integral Q2 (f ), en
Bo
lugar de Q1 (f )14 . Otra variante es devolver
16Q2 (f ) − Q1 (f )
15
que es el primer paso de extrapolación de Simpson (o el segundo del trapecio, de acuerdo
al problema 7.2).
La forma más simple de implementar el proceso anterior es introduciendo una función
de cabecera que prepare los datos iniciales: recibe la función, el intervalo de integración y
la tolerancia solicitada, y calcula para arrancar la subrutina simpsonadaptativo el punto
medio c, los valores de f en a, b y c y el resultado de aplicar la regla de Simpson simple
en [a, b]. Por ejemplo
rra
01 % SIMPSONRECURSIVO
02 %
03 % INTEG= SIMPSONRECURSIVO (F,A,B,TOL)
04 %
05 % Devuelve una aproximacion de la integral mediante
06 % una integracion adaptativa basada en la regla de Simpson
07 % con tolerancia TOL
08
09 function integ=simpsonrecursivo(f,a,b,tol)
10
11 c=(a+b)/2;
12 fa=feval(f,a);
13 fb=feval(f,b);
do
14 fc=feval(f,c);
15 integ=(b-a)*(fa+4*fb+fc)/6; %regla de Simpson
16 integ=simpsonadaptativo(f,a,c,b,fa,fc,fb,integ,tol);
17 return
Resta por programar la función simpsonadaptativo, trabajo que proponemos al lec-
tor.
Ejercicio 7.15 Implementa la regla de Simpson adaptativa.
Ejercicio 7.16 El método tal como está programado puede entrar en un bucle infinito si no
r
se consigue integrar con la tolerancia exigida en las sucesivas subdivisiones de un intervalo.
Para evitar este problema hacemos que el programa lleve control del número de veces que ha
subdividido un intervalo. La función puede seguir la siguiente sintaxis
14
Casi nadie dudarı́a en esta elección. Es decir, es esperable que Q2 (f ) sea mejor que Q1 (f ), ası́ que ¿por
qué no devolver lo mejor que se tiene?. Matemáticamente, sin embargo, el estimador del error controla
el error de Q1 (f ) y no de Q2 (f ).

132
LECCIÓN III Capı́tulo 7. Fórmulas de cuadratura. FFT

1.5
Bo
1

0.5

0
0 0.2 0.4 0.6 0.8 1 1.2 1.4 1.6 1.8 2


rra
Figura 7.5: Integración adaptativa de x

[integ,subd2]=simpsonadaptativo(f,a,c,b,fa,fc,fb,integ,tol,subd)

donde subd2=subd+1. Si subd2 > subdmax se devuelve un mensaje de error, se deja de


subdividir y se continua la ejecución del programa devolviendo el último valor calculado. El
parámetro subdmax puede dejarse como un valor por defecto que puede modificarse si el usuario
especifica otro valor. Es decir, entra a formar parte de un conjunto variable de argumentos de
entrada.
Implementa el método resultante.

Ejercicio 7.17 Por último podemos llevar un control sobre los puntos que hemos evaluado.
do
Para ello basta utilizar

[integ,subd2,x2]=simpsonadaptativo(f,a,c,b,fa,fc,fb,integ,tol,subd,x)

con x2=[x d e] donde d y e son los puntos medios de [a,c] y [c,b] respectivamente.
Implementa el método resultante.
(Ayuda: si al final se desea que los puntos x2 estén ordenados se puede aplicar la instrucción
sort(x2) que devuelve el vector con sus componentes ordenadas de menor a mayor.)

Nota final
r
De un estimador se suele hablar de dos conceptos bien importantes: confiabilidad y
eficiencia. Un estimador es confiable si efectivamente el error está por debajo de lo que el
estimador calcula. Por contra, es eficiente si el estimador aproxima bien el error cometido.
Nuestro estimador, en general, es poco eficiente: el error real suele estar muy por debajo de
la cantidad que nos devuelve el√estimador, especialmente si el intervalo de integración es
grande. Por ejemplo, para f = x e integrando en [0, 2], se observa que con una tolerancia

133
7.2 Transformada rápida de Fourier LECCIÓN III

Adaptativa Pto. medio Trapecio Simpson

tol Error neval Error Error Error


10−1 8.91e−03 7 8.01e−3 −3.67e−2 −1.01e−2
10−2 1.41e−04 15 2.70e−3 −1.06e−2 −3.59e−3
Bo
10−3 1.57e−06 29 1.03e−3 −3.81e−3 −1.40e−3
10−4 2.12e−07 47 5.01e−4 −1.82e−3 −6.90e−4
10−5 8.48e−09 77 2.45e−4 −8.67e−4 −3.33e−4
10−6 2.64e−10 133 1.09e−4 −3.81e−4 −1.36e−4
10−7 8.27e−12 233 4.73e−5 −1.64e−4 −6.41e−5
10−8 2.25e−13 421 1.96e−5 −6.76e−5 −2.65e−5

R2√
Cuadro 7.2: Resultados numéricos para 0 x dx. Tolerancia exigida (tol), número de
evaluaciones (neval) y error cometido (Error). Comparativa con las reglas del punto medio,
del trapecio y de Simpson con h fijo y el mismo número de evaluaciones
rra
de 10−5 el error real cometido por el método adaptativo es 8.48 · 10−9 , un error 1000 veces
menor en magnitud. Una forma de corregir este problema es, una vez que se ha decidido
dividir el intervalo de integración en dos subintervalos, no exigir una tolerancia tol/2 en
cada uno de ellos, sino utilizar r ∗ tol con r ∈ [1/2, 1]. Matlab utiliza de hecho r = 1.
Matlab cuenta con algunas funciones encargadas de la integración numérica:

quad quadl dblquad triplequad

Las dos últimas aplican reglas de cuadratura para integrales dobles y triples respectiva-
mente.
El comando quad implementa esencialmente el método de Simpson recursivo que
hemos visto en esta sección. Por otro lado, quadl utiliza una regla de orden mayor que
da mejores resultados si el integrando es más regular.
do
El código de estas funciones está abierto, luego se puede editar para ver los detalles
de su implementación.

7.2. Transformada rápida de Fourier


La transformada rápida de Fourier, o FFT, según sus siglas en inglés15 , es una her-
ramienta muy potente en el análisis de señales periódicas y cuyas aplicaciones se han
extendido a aspectos muy diferentes del Cálculo Numérico.
Existen diversas formas de introducir la FFT. Hemos escogido la interpretación que
r
relaciona la transformada de Fourier discreta con los coeficientes de Fourier para enlazar
seguidamente con algunas aplicaciones.
15
El nombre correcto serı́a transformada discreta rápida de Fourier, para distinguirla de la transformada
de Fourier continua. Sus siglas en inglés, FFT, podrı́an entonces provenir de Fast Fourier Transform o
Finite Fourier transform. De acuerdo a lo anterior, las siglas más adecuadas serı́an FFFT (Fast Finite
Fourier transform), pero nadie utiliza esta nomenclatura, seguramente por el exceso de Fs)

134
LECCIÓN III Capı́tulo 7. Fórmulas de cuadratura. FFT

Parte de esta sección, especialmente la referente a la transformada rápida de Fourier,


se ha obtenido del libro Numerical Computing with Matlab, de Cleve Moler.

7.2.1. Transformada de Fourier discreta


Nota En esta sección seguiremos la notación de Euler
Bo
exp(iθ) = eiθ = cos θ + i sen θ, θ ∈ R,

donde i es la unidad imaginaria. 


Dada una función 1–periódica, ésta se puede expresar en forma de serie de Fourier
X
f (θ) = fb(m) exp(2πimθ), θ∈R (7.6)
m∈Z

donde fb(m) es el coeficiente m-ésimo de Fourier


1
rra
Z
fb(m) = f (θ) exp(−2πimθ)dθ, m ∈ Z.
0

La convergencia de la serie es un asunto algo delicado16 , pero si la función tiene, por


ejemplo, derivada continua, la convergencia de la serie es uniforme:
s
X
máx f (θ) − fb(m) exp(2πimθ)| → 0, cuando r, s → ∞,

θ∈[0,1]
m=−r

lo que en particular justifica alguna de las manipulaciones que haremos a continuación.


La identidad (7.6) se interpreta en el sentido de que la función original f es suma
infinita de unas frecuencias fundamentales. Observa que para cada m,
do
exp(2πimθ),

es una función 1/m-periódica, o dicho de otra forma, su periodo es 1/m (ver la Figura
7.6).
Además se tiene la relación
Z 1 ∞
X
2
|f (θ)| dθ = |fb(m)|2 (7.7)
0 m=−∞
r
que se interpreta como que la energı́a de función original f es igual a la energı́a del vector
infinito (. . . , fb(−2), fb(−1), fb(0), fb(1), fb(2), . . .)> .
16
Mucho se ha escrito sobre esto. En cualquier caso hay que especificar en qué sentido converge la
serie. El sitio más adecuado, matemáticamente hablando, es el espacio de las funciones cuyo cuadrado
es integrable, que se denota por L2 (0, 1). Fı́sicamente se interpreta como el espacio de las señales cuya
energı́a es finita.

135
7.2 Transformada rápida de Fourier LECCIÓN III

Parte Real e Imaginaria de exp(2π i mθ) para m=1,2,3


Freq.1 periodo 1
1.5 Freq 2 periodo 1/2
Freq 3 periodo 1/3
Bo
1

0.5

-0.5

-1

-0.2 0 0.2 0.4 0.6 0.8 1 1.2


rra
Figura 7.6: Primeras exponenciales trigonométricas.

Nota. Utilizando la definición de la exponencial trigonométrica, podemos expresar



X ∞
X
f = fb(0) + (fb(m) + fb(−m)) cos(2πm · ) + i(fb(m) − fb(−m)) sen(2πm · ) (7.8)
| {z } | {z }
m=1 =: αm m=1
=: βm
donde αm y βm se pueden calcular de forma alternativa mediante
do
Z 1 Z 1
αm = 2 f (θ) cos(2πmθ) dθ, βm = 2 f (θ) sen(2πmθ) dθ.
0 0

La expresión (7.8) puede resultar más atractiva que (7.6), especialmente si la función es
real puesto que implica trabajar únicamente con cantidades reales, sin parte imaginaria.
Sin embargo, tanto el análisis como una notación más compacta animan a utilizar la
exponencial compleja. Aún es más, en lo que sigue podemos suponer que las funciones
son complejas (devuelven valores en C) y por tanto se cubre este caso de forma muy
natural. 
Desde un punto de vista práctico, es poco habitual que se pueda (o que se proceda a)
r
evaluar la función en cualquier punto. En lugar de ello se dispone de un muestreo es decir,
del valor de la función en una serie de puntos uniformemente distribuidos. Ası́ definimos
j
xj = N
, j = 0, . . . , N − 1,
se evalúa
yj := f (xj ) , j = 0, . . . , N − 1

136
LECCIÓN III Capı́tulo 7. Fórmulas de cuadratura. FFT

y se construye el vector  
y0
 y1 
y= .
 
..
 . 
yN −1
Bo
La primera cuestión es
¿Es posible recuperar los coeficientes de Fourier de f a partir de y?
La respuesta obvia es no: si tomamos una cantidad finita de información es imposible
recuperar (salvo en casos triviales) los coeficientes de Fourier, que en última media son la
función y, por tanto, conllevan una cantidad infinita de información.
Ahora bien, la situación es muy diferente si disponemos de información a priori sobre
la función f . Si una función periódica f es regular podemos probar que
fb(k) → 0, |k| → ∞
y de hecho de una forma muy rápida (ver Ejercicio 7.18), por lo que unos pocos coeficientes
pueden ser suficientes para reconstruir la función de forma muy aproximada.
rra
Para calcular estos coeficientes utilizamos la regla del trapecio, que como hemos visto
en la sección anterior converge muy rápidos para funciones regulares y periódicas. Todo
lo anterior nos conduce a
Z 1
f (k) :=
b f (θ)exp(−2πikθ) dθ
0
f (1) = f (0) = y0
1 h1
N
X −1
1 i ↓
≈ f (0) + f ( Nj ) exp(− 2πijk
N
) + f (1) =
N 2 j=1
2
N −1
1 X
= yj ω jk
N j=0
do
donde
ω := exp − 2πi

N
.
Lo anterior sugiere construir
N −1
1 X
Yk := yj ω jk
N j=0

como una aproximación de fb(k). El vector


 
y0
y1
r
 
Y=
 
.. 
 . 
yN −1
recibe el nombre de transformada discreta de Fourier de y que denotaremos por
F y = Y. Por tanto F : CN → CN , es decir, transforma vectores de números (en principio)
complejos en vectores complejos.

137
7.2 Transformada rápida de Fourier LECCIÓN III

Ejercicio 7.18 Sea f es periódica con derivada primera continua,


Z 1 θ=1
1
f (k) :=
b f (θ) exp(−2πikθ) dθ = − f (θ) exp(−2πikθ)
0 2πki θ=0
| {z }
=0
Z 1
1
Bo
+ f 0 (θ) exp(−2πikθ) dθ.
2πki 0

Demostrar entonces que


C
|fb(k)| ≤
k
donde C es independiente de k. ¿De qué depende C?. Prueba reiterando este argumento que
si f es más regular el decrecimiento de fb(k) es más acusado.

Para estudiar la relación entre transformada de Fourier continua y discreta precisamos


del siguiente lema

Lema 7.5 Para todo k ∈ Z


rra
N −1
(
1 X 1, k = `N para algún ` ∈ Z,
exp − 2πijk

N
=
N j=0 0, en caso contrario.

Demostración. Tomemos como antes


ω := exp − 2πi

N
.
Entonces, la suma anterior es simplemente
N −1 N −1
1 X jk 1 X k j
ω = (ω ) .
N j=0 N j=0

Si k = `N , es decir, si k es un múltiplo de N , ω k = exp(−2πi`) = 1 y la suma anterior es


do
1. En caso contrario, teniendo en cuenta que
1 − rm
1 + r + r2 + . . . + rm−1 =
1−r
obtenemos que
N −1
1 X k j 1 1 − (ω k )N 1 1 − (ω N )k
(ω ) = = .
N j=0 N 1 − ωk N 1 − ωk

Ahora, como ω N = 1, se sigue que la suma anterior es nula. 


Utilizando el desarrollo en Fourier de f e intercambiando el orden de los sumatorios17
r
podemos escribir
N −1 N −1 N −1
1 X 1 X 1 X b hX  i
jk 2πijk
exp 2πi(m−k)j

Yk := yj ω = f (xj ) exp − N = f (m) N
.
N j=0 N j=0 N m∈Z j=0

17
Manipulaciones que deben siempre justificarse y que son válidas si, por ejemplo, la función tiene
derivada primera continua.

138
LECCIÓN III Capı́tulo 7. Fórmulas de cuadratura. FFT

Por el lema anterior,


N −1 
X 
2πi(m−k)j
 1, si m = k + `N ,
exp N
=
0, en caso contrario,
j=0

por lo que
Bo
1 Xb
Yk = f (k + mN ).
N m∈Z
De esta forma, Yk recoge no sólo el coeficiente k−ésimo de Fourier, sino contribuciones en
frecuencias más altas, cuya distancia al coeficiente k dista un múltiplo de N .
Llegado a este punto, conviene recordar que el decreciemiento rápido a cero de los
coeficientes de Fourier cuando |k| → ∞ sugiere que Yk aproxima bien al coeficiente
de Fourier más próximo a cero y la aproximación mejora muy rápidamente cuando
N → ∞. Es decir,
 X

 f
b (k)+ fb(k + mN ), si 0 ≤ k ≤ N2

m6=0



 | {z }
rra

pequeño


Yk = X (7.9)
N
f (k − N )+ f (k + mN ), si 2 < k < N .

 b b




 m6 = 0

 | {z }

pequeño

A la operación que a cada Y le asocia el vector original y se conoce como transfor-


mada inversa de Fourier discreta y se denota

F −1 Y = y.

Con argumentos similares a los utilizados anteriormente se puede ver que


N −1
do
X
2πijk

yk := Yj exp N
,
j=0

obteniéndose ası́ una expresión muy similar a la transformada de Fourier. En particular,


concluimos que F −1 existe y está bien definida.

Nota. En el marco continuo, tenı́amos que


Z 1 X
fb(m) = f (θ) exp(−2πimθ) dθ, f (θ) = fb(m) exp(2πimθ).
0 m∈Z
r
Obsérvese el paralelismo entre la Transformada de Fourier Discreta, y la integral de la
expresión superior (la primera es la aproximación discreta de la segunda) y la inversa de
la Transformada de Fourier Discreta con la serie de Fourier.

Ejercicio 7.19 Prueba la expresión dada para la inversa de la transformada discreta de


Fourier.

139
7.2 Transformada rápida de Fourier LECCIÓN III

Ejercicio 7.20 Dado que vamos a calcular aproximaciones de los coeficientes centrales de
Fourier, podrı́amos plantearnos definir
N
X −1
Yek = yj ω jk , −N/2 < k ≤ N/2
j=0
Bo
¿Sabrı́as ver qué relación hay entre Yek e Yk ?.

7.2.2. Cálculo de la transformada de Fourier Discreta


Es fácil dar una expresión matricial de la transformada de Fourier discreta en términos
de la matriz
 
1 1 1 ··· 1
 1 ω ω2 · · · ω N −1 
· · · ω 2(N −1) 
 2

ω4 ω = exp − 2πi

W :=  1 ω , N
 ............................... 
2
1 ω N −1 ω 2(N −1) · · · ω (N −1)
rra
Con esta matriz, la relación entre y y su transformada Y se escribe simplemente
1
Y = Fy = W y.
N
Análogamente,
y = F −1 Y = W ∗ Y
donde W ∗ es la matriz adjunta
 
1 1 1 ··· 1
2 N −1
 1 ω ω ··· ω 
do

· · · ω 2(N −1) ω = ω −1 = exp
 2 4
 2πi

W = 1 ω
 ω ,
 N
 ............................... 
2
1 ω N −1 ω 2(N −1) · · · ω (N −1)

La matriz W es una matriz de tipo Vandermonde, que ya surgido anteriormente.


Además es casi ortogonal:
W ∗ W = N IN
donde IN la matriz identidad de orden N .
En resumen, la transformada discreta de Fourier, y su transformada inversa, se reducen
a calcular un producto matriz-vector. El costo, en una implementación directa, conlleva
r
la construcción de la matriz y realizar el producto. Sólo el producto tiene un costo de
orden O(2N 2 ) operaciones (sumas y productos).

Ejercicio 7.21 Construye la matriz W ∗ .

Ejercicio 7.22 Implementa la transformada discreta de Fourier.

140
LECCIÓN III Capı́tulo 7. Fórmulas de cuadratura. FFT

Solución. Esta es una implementación que evita construir la matriz W . En su lugar


calcula sucesivamente las filas, la multiplica por y para hallar el correspondiente coeficiente
y calcula la siguiente fila. De esta forma se reduce la memoria utilizada pero no el número
de operaciones
01 % FT
Bo
02 %
03 % Y=ft(y) devuelve la transformada de Fourier discreta
04 % la implementacion es la directa
05
06 function Y = ft(y)
07
08 y=y(:); % y es columna ahora
09 n=length(y);
10 w=exp(-i*2*pi*(0:n-1)/n);
11 W=ones(1,n);
12 Y=zeros(n,1);
13 for j=1:n
rra
14 Y(j)=W*y;
15 W=W.*w
16 end
17 Y=Y/n;
18 return
Ejercicio 7.23 Implementa la transformada inversa de Fourier.

Notas finales
Si f es real,
Re fb(k) = Re fb(−k), Im fb(k) = −Im fb(−k).
Esta simetrı́a se extiende a la transformada discreta: si y es real
do
Im y0 = 0, Re yk = Re yN −k , Im yk = −Im yN −k , k = 1, . . . , N − 1.
De esta forma, si ignoramos la primera componente, la parte real de Y, respectivamente
imaginaria, es simétrico, respectivamente antisimétrico, respecto al punto N/2. Este punto
se conoce como el punto de Nyquist.
Otra analogı́a con el marco continuo es que la transformada discreta de Fourier preser-
va, salvo constante multiplicativa, la norma k · k2 del vector original, esto es, su energı́a.
Concretamente (comparar con (7.7))
1 1 1 1
kYk22 = Y∗ Y = (W y)∗ (W y) = 2 y∗ W ∗ W y = y∗ y = kyk22 . (7.10)
r
N 2 N N N
Hay una falta de consenso en la definición de Transformada de Fourier discreta.
Nosotros hemos tomado como definición de la transformada y de su inversa las dadas
por
N −1 N −1
1 X X
Yk := jk
yj ω , yk := Yj ω −jk , ω = exp(− 2πi
N
).
N j=0 j=0

141
7.2 Transformada rápida de Fourier LECCIÓN III

En Matlab, la transformada de Fourier y su inversa están implementadas en fft e ifft.


La definición que se toma es ligeramente diferente
N −1 N −1
X 1 X
Yk := jk
yj ω , yk := Yj ω −jk , ω = exp(− 2πi
N
).
j=0
N j=0
Bo

En otros textos se multiplica por 1/ N en ambos sumatorios con el fin de dar un aspecto
más uniforme (en este caso la norma 2 del vector y de su transformada coinciden). En
cualquier caso, la diferencia entre las diferentes transformadas es simplemente el producto
por una potencia de N .
Todo lo desarrollado en esta sección es perfectamente aplicable a funciones periódicas
con distintos periodos, sin más que aplicar un cambio de variables y transformarla en
1−periódica.

7.2.3. Aplicaciones a la eliminación de ruido


Una de las primeras aplicaciones surge en el análisis de señales y fenómenos periódicos.
Vamos a mostrar un (muy) simple ejemplo en la eliminación de ruido de una señal periódi-
rra
ca. Suponemos que la señal, dada por una función regular y suave, es perturbada por un
ruido que puede ser modelizado por una variable aleatoria que sigue una distribución
uniforme.
Como la señal original es regular, sus coeficientes de Fourier decrecen rápidamente
a cero. En particular, la función puede ser aproximada por una suma parcial con unas
pocas exponenciales trigonométricas. Dicho de otra forma, la función tiene unas pocas
frecuencias importantes mientras que el resto tiene una aportación despreciable.
Tomemos por ejemplo una señal dada por la función

f (x) := cos(cos(12πx)) sen(2πx)

En la Figura 7.7 se muestra la función y sus coeficientes de Fourier, que decrecen rápida-
do
mente a cero. También se muestra una evaluación en 64 puntos (un muestreo) uniforme-
mente distribuidos y la transformada de Fourier discreta resultante. Obsérvese la relación
entre transformada discreta de Fourier y los coeficientes de Fourier mostrada en (7.7).
En el campo discreto, tenemos un ruido r y el vector transformada de Fourier discreta
R = F r. Visto en el campo transformado, esta perturbación tiene un tamaño, relacionado
con la amplitud del ruido y con el número de puntos que se han tomado de muestra. Dado
el comportamiento altamente irregular, es esperable que las contribuciones en todas las
frecuencias sean similares. Pero
1
kRk22 = krk22 ≤ máx |rj |.
N j=0,...,N −1
r
Por tanto, si el ruido tiene un valor máximo controlado, las componentes del vector trans-
formado tienden a cero cuando N → ∞. De hecho es esperable que este decrecimiento
sea uniforme en todas las componentes, es decir,
1
Rj ≈ √
N

142
LECCIÓN III Capı́tulo 7. Fórmulas de cuadratura. FFT

Señal continua con un muestreo de 64 puntos


1 1

0.5 0.5
Bo
0 0

-0.5 -0.5

-1 -1
0 0.2 0.4 0.6 0.8 1 0 0.2 0.4 0.6 0.8 1

Coef. Fourier (en valor absoluto) FT de la señal discreta (valor abs.)


0.4
0.4

0.3
0.3

0.2 0.2
rra
0.1 0.1

0 0
-40 -20 0 20 40 0 10 20 30 40 50 60

Figura 7.7: Coeficientes de Fourier y transformada discreta de Fourier

Ahora, si consideramos la influencia de este ruido sobre una señal y, tenemos la señal
perturbada y e = y + r. Se trata ahora de eliminar ese ruido observando la transformada
Y.
e
La estrategia que planteamos es la siguiente. En el caso de que Yej sea grande, pode-
do
mos aceptar este coeficiente dado que el error relativo es pequeño. Por contra, si Yej es
pequeño, el error relativo que hemos introducido es tal que la información ha quedado
irremediablemente contaminada y por tanto debemos desecharla.
Lo anterior sugiere una forma de depurar la señala, partiendo de un nuevo vector Z
(
0 si |Yek | es pequeño,
Zk = (7.11)
Yek en otro caso.
Con la información que nos queda, reconstruimos la señal discreta original y mediante
F −1 Z. Ası́ tenemos el siguiente diagrama
r
+ ruido F (7.11) F −1
y −→ y
e −→ Y
e −→ Z −→ z.

Al final de proceso, z es (deberı́a ser) mejor aproximación de y que la señal perturbada


y
e.
En la Figuras 7.9 se muestran los resultados obtenidos con n = 64 y n = 256. Se puede
observar como la señal es filtrada eliminando gran parte del ruido introducido.

143
7.2 Transformada rápida de Fourier LECCIÓN III

0.08 0.015

0.06
0.01
Bo
0.04
0.005
0.02

0 0
10 20 30 40 10 20 30 40
-3
x 10
0.08 8

0.06 6

0.04 4
rra
0.02 2

0 0
50 100 150 50 100 150

Figura 7.8: Ruido en un conjunto de puntos (40 arriba, 160 abajo) y su transformada
discreta

7.2.4. Transformada rápida de Fourier


La importancia del análisis de Fourier, y por ende de la transformada discreta de
do
Fourier, fue cobrando fuerza a lo largo del siglo XX y muchos aspectos siguen demandando
este tipo de técnicas en el siglo actual.
Pronto surgieron problemas que requerı́an calcular la transformada de Fourier de mil-
lones de elementos, lo que colocaba el problema más allá de la potencia de los ordenadores
de la época y los de un futuro previsible18 . En cualquier caso duplicar N , el número de
elementos de y, requerirı́a multiplicar por cuatro la potencia del ordenador. Siguiendo el
progreso de la informática, esto significarı́a una espera de 36 meses19 .
18
Hemos mostrado algunas aplicaciones simples de la transformada de Fourier que son esencialmente
unidimensionales (una señal periódica). Existen aplicaciones que exigen trabajar ya con señales bidimen-
r
sionales. En ese caso, duplicar la precisión con la que se trabaja implica multiplicar por 4 la dimensión
del problema y por 16 la complejidad computacional del algoritmo que hemos visto. Problemas en más
dimensiones y con números muy elevados de variables no son extraños.
19
La ley de Moore formulada por Gordon Moore cofundador de Intel en 1965 es un ejemplo de una
ley empı́rica que se viene satisfaciendo con asombrosa regularidad en los últimos cuarenta años. Esta ley
establece que la potencia de cálculo y la capacidad de almacenamiento se multiplica por 2 cada 18 meses.
De forma paralela han surgido otras versiones de la ley de Moore que establecen comportamientos de
crecimiento exponencial en el mundo de la informática.

144
LECCIÓN III Capı́tulo 7. Fórmulas de cuadratura. FFT

Señal con ruido


64 puntos FT (en valor absoluto)
1
0.4

0.35
0.5
0.3
Bo
0.25
0 0.2

0.15

-0.5 0.1

0.05

-1 0
0 0.2 0.4 0.6 0.8 1 0 10 20 30 40 50 60

Truncacion de la FT Señal filtrada


1
0.4

0.35
0.5
0.3

0.25
0
rra
0.2

0.15

0.1 -0.5

0.05

0 -1
0 10 20 30 40 50 60 0 0.2 0.4 0.6 0.8 1

Señal con ruido


256 puntos FT (en valor absoluto)
1
0.4

0.35
0.5
0.3

0.25
0 0.2
do
0.15

-0.5 0.1

0.05

-1 0
0 0.2 0.4 0.6 0.8 1 0 50 100 150 200 250

Truncacion de la FT Señal filtrada


1
0.4

0.35
0.5
0.3

0.25

0.2 0

0.15
r
0.1 -0.5

0.05

0 -1
0 50 100 150 200 250 0 0.2 0.4 0.6 0.8 1

Figura 7.9: Filtrado del ruido

145
7.2 Transformada rápida de Fourier LECCIÓN III

En 1965, Jim Cooley, investigador ligado a IBM y John Tukey, de la Universidad de


Princeton mostraron una forma sencilla de programar la transformada de Fourier discreta
que reducı́a drásticamente el número de operaciones.
La idea de partida del algoritmo es considerar el caso N = 2m. Entonces denotando
ω1 := ω 2
Bo
se tiene que
ω 2jk = (ω 2 )kj = ω1jk .
De esta forma, si 0 ≤ k ≤ M − 1 = N/2 − 1
N −1 M −1 M −1
1 X jk 1 X 2jk 1 X
Yk = yj ω = y2j ω + y2j+1 ω (2j+1)k
N j=0 N j=0 N j=0
| {z } | {z }
Pares Impares
N = 2M M −1 M −1
↓ 1h 1 X 1 X i
= y2j ω1jk + ω k y2j+1 ω1jk
2 M j=0 M j=0
rra
1 h
(0) (1)
i
=: Yk + ω k Yk . (7.12)
2
(0) (1)
Notemos que Yk e Yk son el resultado de aplicar la transformada de Fourier disc-
reta a los vectores (y0 , y2 , . . . , y2M −2 )> y a (y1 , y3 , . . . , y2M −1 )> respectivamente, que son
vectores de longitud M = N/2.
Si M ≤ k ≤ N − 1 la relación cambia levemente. Para ello, escribamos k = M + κ,
donde ahora 0 ≤ κ ≤ M − 1. Entonces
N −1 M −1 M −1
1 X jk 1 X 2jk 1 X
Yk = yj ω = y2j ω + y2j+1 ω (2j+1)k
N j=0 N j=0 N j=0
M −1 M −1
1h 1 X 1 X i
= y2j ω1jM ω1jκ + ω M ω κ y2j+1 ω1jκ .
do
2 M j=0 M j=0

Dado que
ω M = exp(−πi) = −1, ω1M = 1;
se deduce que
1  (0)
Yκ − ω κ Yκ(1) .

Yk = (7.13)
2
v
Denotando por w el vector resultado de enlazar los vectores v y w, las identidades
(7.12) y (7.13) se puede escribir en notación vectorial
r
 
1 Y(0) + ω. ∗ Y(1)
Y= (7.14)
2 Y(0) − ω. ∗ Y(1)
donde Y(0) e Y(1) son las transformadas de Fourier de los vectores (y0 , y2 , . . . , y2M −2 )> y
(y1 , y3 , . . . , y2M −1 )> ,
ω = (ω 0 , ω 1 , . . . , ω M −1 )> , ω := exp(− 2πi
N
), (7.15)

146
LECCIÓN III Capı́tulo 7. Fórmulas de cuadratura. FFT

y “.*” denota el producto elemento a elemento entre las componentes de los vectores.
En cuando al número de operaciones, si f (N ) es el número de multiplicaciones, se
comprueba que el total de productos es el de dos transformadas de longitud N/2 más N
productos realizados al combinar dichas transformadas. En resumen,

f (N ) = 2f (N/2) + N.
Bo
Nada nos impide aplicar de forma reiterada el algoritmo anterior para calcular Y(0) e
Y(1) si M es divisible por 2 (o lo que es lo mismo, que N sea divisible por 4). De forma
natural, se puede programar el método de forma recursiva.
El caso óptimo del algoritmo en la versión anterior se da cuando N = 2p . El algoritmo
queda de la siguiente forma

FFT

N =length(y)
if N==1
rra
Y=y
else
Y(0) := FFT(y(0 : 2 : N − 2)) % Parte ‘‘par’’
Y(1) := FFT(y(1 : 2 : N − 1)) % Parte ‘‘impar’’
ω = exp(−2πi/N )
ω := [ω 0 , ω 1 , . . . , ω N/2−1 ]>
Y(0 : N/2 − 1) = (Y(0) + ω. ∗ Y(1) )/2
Y(N/2 : N − 1) = (Y(0) − ω. ∗ Y(1) )/2
end

En tal caso, se puede comprobar que el número de productos es


do
f (N ) = 2p (p + 1) = N (log2 (N ) + 1)

que debe compararse con el N 2 esperable de la implementación directa. De ahı́ viene el


nombre de Transformada Rápida de Fourier.

Ejercicio 7.24 Implementa la transformada rápida de Fourier.

Ayuda. No utilices fft como nombre de esta función, dado que éste es el comando de
Matlab para el cálculo de la transformada rápida de Fourier. Entrando ya en programa, en
r
primer lugar podemos plantearnos cómo se va a devolver el resultado, si como un vector
fila o como un vector columna. Para ello, la primera instrucción de nuestra subrutina
podrı́a ser

y=y(:); Y=y;

si se quiere trabajar sólo con columnas, o

147
7.2 Transformada rápida de Fourier LECCIÓN III

y=y(:).’; Y=y;
si se desea implementar para filas. Fı́jate que ya hemos introducido el vector que va a
guardar la transformada de Fourier y que sus dimensiones coinciden con las del vector y.
Llegado a este punto, hay que tener cuidado al programar el producto
ω. ∗ Y(1)
Bo
para que los vectores implicados, ω e Y(1) tengan igual dimensión.
Si el vector tiene un número par de elementos, la transformada se calcula a partir de
la transformada de los vectores
y(1 : 2 : n) −→ (y0 , y2 , . . . , yn−2 )> , (Y(0) )
y(2 : 2 : n) −→ (y1 , y3 , . . . , yn−1 )> , (Y(1) )
de acuerdo con el algoritmo (véase también (7.14) y (7.15)).
Cuando el número de entradas de y no sea una potencia de 2 se puede utilizar el primer
algoritmo que dimos (ejercicio 7.22). De esta manera tendrı́amos la siguiente estructura
y=y(:); n=length(y);
rra
if mod(n,2)==0
...... % expresion RECURSIVA en terminos de dos transformadas
......
else % no es divisible por 2
...... % Algoritmo del ejercicio 7.22
end
En las lı́neas anteriores, mod(m,n) devuelve el resto de la división de m entre n y sirve
para comprobar si el número de entradas es par o impar.
Ejercicio 7.25 Implementa una función recursiva que devuelva el número de operaciones
para el cálculo de la FFT. Utilı́zala para obtener una tabla con el número de operaciones para
algunos valores altos de N . Compara con el número de operaciones requerido en la versión
do
inicial del algoritmo dada antes.

Solución. Ésta es una forma simple de implementar la función


01 % OPERACIONESFFT(N)
02 %
03 % M=OPERACIONESFFT(N)
04 %
05 % M es el numero de operaciones de la FFT
06
07 function M=operacionesFFT(N)
r
08
09 if mod(N,2)==1
10 M=N^2;
11 else
12 M=operacionesFFT(N/2)*2+N;
13 end

148
LECCIÓN III Capı́tulo 7. Fórmulas de cuadratura. FFT


Hemos testado la función con 219 y 219 − 1 que es primo. Éste es el resultado

>> format rat


>> operacionesfft(2^19) %(2^19 approx 500.000)
Bo
ans=

10485760

>> operacionesfft(2^19-1)

ans =

274876858369

Observa que el número de operaciones efectuadas se reduce en un factor de 26000 si


rra
aumentamos en uno el número de elementos.

Ejercicio 7.26 Implementa la Inversa de la Transformada Discreta de Fourier con nombre


InvTrRaFourier.

Ejercicio 7.27 En este ejercicio observaremos la dependencia de la FFT implementada en


Matlab respecto del número de entradas del vector. Para ello, utilizaremos de nuevo los valores
219 − 1 y 219 propuesto anteriormente. Define dos vectores y1 y y2 con 219 − 1 y 219 com-
ponentes respectivamente, por ejemplo, mediante la orden rand. Aplica fft(y1) y fft(y2)
y comprueba el tiempo que tarda en cada caso. ¿Sabrı́as explicar por qué se reduce el tiempo
de cálculo?.
do
Nota final

Las implementaciones comerciales de la FFT son ciertamente más complicadas que


lo que hemos visto. En realidad, los métodos recursivos son menos eficientes que las
implementaciones directas, que no hacen uso de la recursividad.
En lugar de ello se opta por una programación directa, más refinada. No sólo se
descompone la transformada en dos de longitud mitad de la original, como se ha mostrado
en este algoritmo, sino que además se intenta dividir por los primeros números primos 2,
3, 5, 7,... reduciéndola a dos, tres, cinco o siete transformadas y ası́ sucesivamente. Incluso
r
el caso de números primos se realiza de forma más óptima que el algoritmo (ingenuo) del
ejercicio 7.22.
Los comandos en Matlab que devuelven la transformada de Fourier y su inversa son fft
e ifft. Puede consultarse la ayuda para ver algunos detalles sobre su funcionamiento e
implementación. Existen otras transformadas ligadas a ésta. Por ejemplo, la transformada
del coseno y la del seno, también implementadas en Matlab (dct, idct, dst y idst). .

149
7.2 Transformada rápida de Fourier LECCIÓN III

La FFT y el producto de números enteros


Dados dos vectores
u = (u0 , u1 , . . . , ur )> , v = (v0 , v1 , . . . , vs )>
se define el vector convolución u ∗ v al vector de r + s + 1 componentes cuya entrada k
Bo
viene dada por
mı́n{k,r}
X X
(u ∗ v)k := u` v j = u` vk−` , (k = 0, . . . , r + s). (7.16)
`+j=k `=máx{0,k−s}

Es fácil comprobar que la convolución, también llamado producto de convolución, es


conmutativo. Esta operación es simplemente el producto de polinomios. En efecto, si
consideramos los polinomios
u0 + u 1 x + . . . + u r x r , v0 + v1 x + . . . + vs xs
entonces el coeficiente en xk del polinomios producto viene dado precisamente por (7.16).
Una propiedad interesante de la transformada de Fourier discreta es que convierte la
convolución de dos vectores en producto de transformadas. Tomemos N = r + s. Si u y
rra
v se insertan en Rn+1 rellenando con ceros
u = (u0 , u1 , . . . , ur , 0, . . . , 0 )> , v = (v0 , v1 , . . . , vs , 0, . . . , 0 )
| {z } | {z }
N − r = s ceros N − s = r ceros
tenemos que
F (u ∗ v) = N (F (u). ∗ F (v)),
donde la operación anterior es el producto elemento a elemento entre los vectores. Ası́, una
forma rápida de calcular la convolución de los dos vectores es seguir el siguiente algoritmo
Calcular U = F (u), V = F (v)
Multiplicar W = N U. ∗ V
do
Devolver F −1 (W)
Si N = r + s es una potencia de 2 entonces el número de operaciones es del orden de
O(n log2 (N )), comparado con 2N 2 que tiene la implementación más directa.
Una de las aplicaciones más simples del cálculo de productos de convolución está en
el producto de números enteros. Por ejemplo,

6031 → 1 + 3 · 10 + 0 · 102 + 6 · 103
1234 → 4 + 3 · 10 + 2 · 102 + 1 · 103

⇒ 6031 × 1234 = 4 + 15 · 101 + 11 · 102 + 31 · 103 + 21 · 104 + 12 · 105 + 6 · 106
= 7442254.
r
Es decir, se trata simplemente del producto de polinomios con “10” jugando el papel de
“x”, o equivalentemente, la convolución entre dos vectores:

6031 → (1, 3, 0, 6, 0, 0, 0, 0) =: u
⇒ u ∗ v = (4, 15, 11, 31, 21, 12, 6)>
1234 → (4, 3, 2, 1, 0, 0, 0, 0) =: v
Por tanto, la FFT nos ofrece una forma muy rápida de multiplicar dos números enteros.

150
LECCIÓN III Capı́tulo 7. Fórmulas de cuadratura. FFT

Ejercicio 7.28 Implementa una función que calcule el producto de dos números enteros con
la transformada de Fourier de acuerdo al siguiente prototipo
% MULTIPLICACION
%
%
Bo
% P=MULTIPLICACION(A,B) Devuelve el producto de A por B
%
% A,B deben ser arrays de caracteres
% P es un array de caracteres con el
% producto A*B
%
Ayuda. Para que el método sea realmente eficiente necesitamos que los vectores sobre los
que se va a aplicar la transformada de Fourier tengan longitud una potencia de 2. Para
ello podemos insertar más ceros de los inicialmente previstos de forma que N sea una
potencia20 de 2.
Para disponer de una precisión en principio ilimitada, introduciremos los números
que deseamos multiplicar en una cadena de caracteres y haremos la salida en el mismo
rra
formato. Para su implementación necesitaremos manejarnos con la conversión entre los
diversos formatos de datos.
Una cadena o string es simplemente un vector de caracteres y ası́ lo maneja Matlab:
>> p=’esto es una prueba’

ans=

esto es una prueba

>> p(3)
do
ans=

>> p(6:9)

ans =

es u
Hará falta transformar un vector de caracteres a un vector de números y viceversa. Para
r
ello se puede utilizar los comandos str2num, num2str(STRing-to-NUMeric y NUMeric-
to-STRing).
Una vez que tengamos el vector de números hay que darle la vuelta al vector, de forma
que
’1234’ [4 3 2 1].
20
¿Qué hace log2(ceil(r+s))?

151
7.2 Transformada rápida de Fourier LECCIÓN III

Por último una vez multiplicados hay un paso de acarreo, es decir, un resultado de forma
que

[4 15 11 31 21 12 6] 4 + 15 · 101 + 11 · 102 + 31 · 103 + 21 · 104 + 12 · 105 + 6 · 106

debe transformarse en su representación decimal


Bo
4 + 5 · 101 + 2 · 102 + 2 · 103 + 4 · 104 + 4 · 105 + 7 · 106 = 744224.

Nota. ¿Para qué preocuparse en multiplicar números enteros? Es decir, no parece haber
una necesidad acuciente de diseñar algorimos para multiplicar números de centenares o
miles de cifras. Una aplicación sorprendente proviene del mundo de cifrado de mensajes.
El sistema de cifrado más popular actualmente es el RSA, propuesto por los matemáticos21
Ron Rivest, Adin Shamir y Len Adleman en 1977, está basado en el conocido Teorema
Pequeño de Fermat22 . Este teorema, muy simple, tiene que ver con los restos de la división
por números primos. El mensaje que se desea enviar se convierte en un número entero,
más o menos largo. El cifrado y descifrado del mensaje se basa en calcular restos de di-
visiones por el producto de dos números primos muy grandes. La seguridad del sistema
rra
depende directamente del tamaño de estos primos: mayor tamaño es mayor seguridad.
Ello hace que se requiera calcular productos y divisiones de números enteros enormes de
forma rápida y eficiente23 . 

Nota. La convolución está implementada en Matlab mediante el comando conv. La


forma de calcular es esencialmente la expuesta en esta sección. 
do
r
21
El nombre del algoritmo son las iniciales de sus apellidos.
22
Nada que ver con el Último Teorema de Fermat, cuya demostración tuvo que esperar cuatro siglos.
23
Para una información más detallada, mı́rese por ejemplo http://en.wikipedia.org/wiki/Rsa.

152
Bo
Lección IV

Cálculo simbólico, arrays y celdas en Matlab.


rra
Valores y vectores propios. Google.
do
r
153
r
do
rra
Bo
Introducción
Bo
La physique ne nous donne pas seulement
l’occasion de résoudre des problèmes... elle
nous fait pressentir la solution

Henri Poincaré
En la primera parte de esta lección trataremos diversos aspectos instrumentales de
Matlab, como el manejo de polinomios, arrays multidimensionales (tensores) y vectores de
celdas. Daremos además algunos esbozos sobre la manipulación de expresiones simbólicas.
rra
Aunque en este campo Matlab no es comparable a otros manipuladores simbólicos como
Maple o Mathematica, puede resultar en muchos casos suficiente.
En la segunda parte trataremos el cálculo de valores y vectores propios de Matlab.
Volvemos por tanto a incidir en el manejo de vectores y matrices, y en ese sentido es un
recordatorio de lo que vimos en las Lecciones 1 y 2. Con el fin de aliviar el peso teórico de
la parte matemática, terminaremos con un capı́tulo fundamentalmente divulgativo sobre
Google y su algoritmo de evaluación de páginas web Pageranktm .
do
r
155
r
do
rra
Bo
Capı́tulo 8
Bo
Matlab: Cálculo simbólico y
estructuras de datos.

8.1. Polinomios y cálculo simbólico


Los polinomios constituyen las funciones más simples en Matemáticas y computa-
rra
cionalmente son importantes habida cuenta que contienen en su estructura las operaciones
básicas en un ordenador. En esta sección veremos como maneja Matlab un polinomio y
nos servirá de preparación para la sección siguiente donde veremos someramente la toolbox
de cálculo simbólico.

8.1.1. Polinomios
Matlab maneja un polinomio identificándolo simplemente con un vector de números
(en principio) reales. Concretamente, el vector fila (an , . . . , a0 )> corresponde al polinomio
an xn + an−1 xn−1 + . . . + a0 . Si algún coeficiente es nulo, debe incluirse. Por ejemplo, el
vector (1, 0, 2)> representa el polinomio x2 + 2. Sumar y restar dos polinomios se reduce
ası́ a sumar y restar dos vectores, salvando el problema de que ambos deben tener el
do
mismo grado:
>> p=[2 0 1]; % 2*x^2+1
>> q=[-1 1 -1 0 1]; % -x^4+x^3-x^2+1
>> p+q % ERROR!!
??? Error using ==> plus
Matrix dimensions must agree.

>> p=[0 0 2 0 1]; % dos coeficientes mas


>> p+q % ahora OK!
r
ans=

-1 1 1 0 2
El producto y división de polinomios están implementados respectivamente en los coman-
dos conv y deconv

157
8.1 Polinomios y cálculo simbólico LECCIÓN IV

>> p=[2 0 1]; q=[-1 1 -1 0 1];


>> conv(p,q)

ans =

-2 2 -3 1 1 0 1
Bo
>> deconv(q,p)

ans=
-0.5000 0.5000 -0.2500
Ejercicio 8.1 Implementa una función que calcule la suma de dos polinomios, su producto,
cociente y resto según el siguiente prototipo
01 OPERACIONESPOL(P1,P2)
02
03 [S,R,C,P]= OPERACIONESPOL(P1,P2) S, R, C y P son la suma, resta
04 cociente y producto de P1 y P2
rra
(Ayuda: P1 y P2 deben ser de la misma longitud. ¿Qué hace la instrucción
p1=[zeros(1,length(p2)-length(p1)) p2]
cuando length(p2)>length(p1)? Comprueba que también es válida cuando length(p2)<length(p1).
¿Qué hace entonces?.)
El comando polyval se encarga de la evaluación de un polinomio:
>> p=[1 0 0 1 0 3]; %definimos el polinomio x^5+x^2+3
>> polyval(p,2) %evaluamos en x=2

ans =
do
39

>> polyval(p,[1 2 3]) %vectorizado

ans =

5 39 255

Raı́ces de polinomios
Las raı́ces de un polinomio p son las soluciones de la ecuación p(x) = 0. El Teorema
r
Fundamental del Álgebra1 afirma que un polinomio de grado n tiene exactamente n raı́ces
en C (alguna puede estar repetida).
1
Demostrado por primera vez por Carl Friedrich Gauss en 1799 (a los 22 años) en su tesis doctoral.
Gauss ha salido repetidamente en estas lecciones y en campos muy distintos, desde las Matemáticas más
aplicadas a las más puras. Quizás ahora se comprenda mejor por qué recibió el sobrenombre de“prı́ncipe
de las Matemáticas”.

158
LECCIÓN IV Capı́tulo 8. Matlab: Cálculo simbólico y estructuras de datos.

En Matlab podemos utilizar roots para calcular de forma aproximada las raı́ces de un
polinomio:

>> pol=[2 -3 -17 30]; % 2*x^2-3*x^2-17*x+30


>> roots(pol)
Bo
ans =

-3.0000
2.5000
2.0000

>> pol2=[1 -2 2 -1];


>> roots(pol2).’ % un par complejas!!

ans =

1.0000 0.5000 + 0.8660i 0.5000 - 0.8660i


rra
Recı́procamente, dado un vector que contenga las raı́ces, podemos crear un polinomio
mónico (el coeficiente que acompaña a la mayor potencia de x es 1) cuyas raı́ces sean las
dadas:

>> poly([-3 5/2 2])

ans =

1 -3/2 -17/2 15

El comando poly puede emplearse también para construir el polinomio caracterı́stico de


una matriz cuadrada A, es decir, el polinomio
do
det(A − xI)

donde I es la matriz identidad de orden n. Por ejemplo,

>> A=[3 -2 2;-1 2 2;-1 1 3];


>> p=poly(A) %pol caract. (monico)

p =

1 -8 19 -12
r
>> roots(p).’

ans =

4 3 1

159
8.1 Polinomios y cálculo simbólico LECCIÓN IV

En la segunda parte de esta lección nos centraremos en los métodos numéricos para el
cálculo de las raı́ces de estos polinomios2 .

Nota. Un problema clásico3 es la determinación de las raı́ces de un polinomio. La


ecuación de segundo grado aparece más o menos resuelta en las Matemáticas antiguas:
Bo
babilónicas, griegas, hindúes y árabes. Es un hecho muy resaltable que no existı́a una
fórmula para la solución como la como la que conocemos hoy en dı́a, sino que los autores
describı́an diversas ecuaciones, habitualmente con ejemplos concretos, para luego explicar
cómo se procedı́a a resolverlas4 a menudo con razonamientos geométricos que excluı́an
cualquier resultado negativo. Fue en las matemáticas hindúes donde las raı́ces negativas
fueron consideradas como válidas.
Las matemáticas italianas primero y europeas después retoman a partir del siglo XV
las ecuaciones polinómicas. Nicolo Fontana Tartaglia, Girolamo Cardano, François Viète,
René Descartes, Gottfried Wilhelm von Leibniz, Joseph-Louis Lagrange y Leonhard Euler
entre otros matemáticos de menor renombre, estudiaron la resolución por radicales de
ecuaciones polinómicas de tercer y cuarto grado con un resultado final satisfactorio: se
consiguió dar con fórmulas que proporcionaban las raı́ces de un polinomio de grado 4. Sin
rra
embargo fueron incapaces de encontrar una fórmula para la ecuación general de quinto
grado. La cuestión quedó zanjada de forma sorprendente: Niels Henrik Abel probó en 1824
(a los 22 años) que no existı́a un fórmula que diera las raı́ces de cualquier polinomio de
grado 5 mediante la aplicación de radicales5 tomando raı́ces enésimas. En última medida,
se habı́a llegado a la conclusión de que era imposible la resolución exacta de ecuaciones
polinómicas de grado mayor o igual que cinco. El estudio de cuándo una ecuación se podı́a
resolver mediante radicales fue iniciado por Evariste Galois6 .
Otro asunto muy diferente es la resolución numérica del problema. Se dispone de una
familia de métodos para la resolución de problemas no lineales generales (es decir, para
ecuaciones de la forma f (x) = 0 donde f es una función cualquiera, no necesariamente
polinómica) como los métodos de Newton-Raphson, secante, regula–falsi, etc. Sin em-
bargo, dadas las particulares propiedades de los polinomios, hay métodos especialmente
do
diseñados para tal fin. Algunos métodos clásicos son los de Bairstow y el de Bernoulli. En
los últimos años el cálculo de las raı́ces de un polinomio ha quedado reducido al cálculo
2
Las raı́ces son los valores propios de la matriz A.
3
La información de estas lı́neas se ha extraı́do de la web “MacTutor History of Mathematics
Archive” de la Universidad de St. Andrews (Escocia). La dirección electrónica es http://turnbull.mcs.st-
and.ac.uk/history/
4
al-Khwarizm clasificó y explicó cómo resolver ecuaciones de segundo grado en 6 tomos. El desarrollo
del Álgebra y la manipulación simbólica de expresiones ha conseguido que este problema pueda ser
planteado en nuestros dı́as a un alumno de primaria.
5
Paolo Ruffini habı́a dado una demostración no del todo correcta en 1799.
6
r
Galois y Abel comparten algunas caracterı́sticas en común, ambos murieron jovenes (Abel a los 29
años y Galois a los 21) con buena parte de su trabajo ignorado por la comunidad matemática. La muerte
de Galois es todavı́a más sorprendente. Francés y republicano convencido, llegó a estar en prisión por ello,
murió en un duelo en 1832 en los años convulsos posteriores a la revolución francesa, aunque no está claro
si éste fue por motivos polı́ticos o de otra ı́ndole. En la noche anterior al duelo escribirı́a en el margen de
unas notas sobre las que trabaja: “Falta algo para completar la demostración. No tengo tiempo.”. Esta
frase ha cimentado la, probablemente exagerada, leyenda de que paso la noche escribiendo Matemáticas.
Su trabajo fue rescatado del olvido por Joseph Liouville 11 años después.

160
LECCIÓN IV Capı́tulo 8. Matlab: Cálculo simbólico y estructuras de datos.

de los valores propios de una matriz, simplemente construyendo la matriz compañera7

−an−1 −an−2 · · · −a1 −a0


 
 1 0 ··· 0 0 
..
 
xn + an−1 xn−1 + . . . a0 0 1 . 0 0 
 

 .. .. .. .. 
Bo
 . . . . 
0 0 ··· 1 0

Al cálculo de los valores propios de una matriz volveremos en la segunda parte de esta
lección. 

8.2. Procesador simbólico


Retomando el hilo de la sección anterior, otra forma de operar con polinomios es de
manera simbólica. Para ello podemos proceder del siguiente modo:
rra
>> syms x %define x como variable simbolica
>> (x^4+x^2-1)+(2*x^3+4*x^2+3) %suma de polinomios

ans =

x^4+5*x^2+2+2*x^3

>> expand((x^4+x^2-1)*(2*x^3+4*x^2+3)) %expande el producto

ans =

2*x^7+4*x^6+2*x^5+7*x^4-2*x^3-x^2-3
do
Observa con atención la primera instrucción. Con syms, declaramos x con una variable
simbólica y por tanto susceptible de entrar en expresiones y manipulaciones algebraicas.
Las órdenes anteriores pueden aplicarse sobre funciones cualesquiera, no necesaria-
mente polinómicas:

>> syms x y
>> expand(cos(x+y))

ans=
r
cos(x)*cos(y)-sin(x)*sin(y)

Podemos llevar a cabo operaciones de cálculo básico tales como la integración o la


derivación:
7
De hecho, ası́ procede roots.

161
8.2 Procesador simbólico LECCIÓN IV

>> diff(x*cos(x^2)) %derivada

ans =

cos(x^2)-2*x^2*sin(x^2)
Bo
>> diff(x^4+x^2-1,3) %tercera derivada

ans =

-24*x^2*cos(x^2)-6*sin(x^2)+8*x^4*sin(x^2)

>> int(exp(x)*cos(4*x),x) %integral indefinida

ans =

1/17*exp(x)*cos(4*x)+4/17*exp(x)*sin(4*x)
rra
>> int(exp(x)*cos(4*x),x,0,pi) %integral definida

ans =

1/17*exp(pi)-1/17
De forma similar se pueden calcular lı́mites (limit), sumar series (symsum),
>> sym k;
>> symsum(1/k^2,k,1,inf)

ans=
do
1/6*pi^2
hacer desarrollos de Taylor (taylor) o transformadas integrales como las de Fourier o
Laplace (fourier, ifourier, laplace e ilaplace)
Observa como los resultados son sı́mbolos y no números. En cualquier caso, el comando
vpa procede a evaluar con la precisión solicitada (si es posible)
>> vpa( 1/17*exp(pi)-1/17) % 32 cifras por defecto

ans=

1.3023936842811332237346277906909
r
>> vpa( 1/17*exp(pi)-1/17,64) % ahora con 64 cifras

ans=

1.3023936842811332237346277906908653676509857177734375000

162
LECCIÓN IV Capı́tulo 8. Matlab: Cálculo simbólico y estructuras de datos.

Nota. La derivación e integración de un polinomio se puede hacer también con polyder


y polyint que trabaja directamente sobre el vector que almacena el polinomio, es decir,
no es simbólico:
>> polyder([1 4 2]) % derivada de x^2+4*x-2
Bo
ans=

2 4


Ejercicio 8.2 Los siguientes comandos inciden en la simplificación y manipulación de expre-


siones
simplify factor expand collect simple
Consulta la ayuda de Matlab y aplı́calos sobre diferentes expresiones algebraicas susceptibles
de ser simplificadas.
rra
Para la resolución de ecuaciones y sistemas de ecuaciones mediante métodos simbólicos,
con las limitaciones que esto implica, podemos utilizar el comando solve:
>> solve(’x*log(x^2+4*x-4)=0’)

ans =

0
1
-5
Cuando el término independiente es cero puede omitirse:
>> solve(’x*log(x^2+4*x-4)’)
do
De forma análoga, dsolve busca las soluciones de ecuaciones y sistemas diferenciales:
>> dsolve(’D3y-D2y-2*Dy-cos(s)’,’s’) % y’’’-y’’-2y’-cos(s)=0

ans =

-3/10*sin(s)+1/10*cos(s)+C1+C2*exp(2*s)+C3*exp(-s)

>> dsolve(’D3y-D2y-2*Dy-cos(s)’,’y(0)=1’,’Dy(0)=2’, ’D2y(0)=3’,’s’)


r
ans =

-3/10*sin(s)+1/10*cos(s)+1/2+9/10*exp(2*s)-1/2*exp(-s)

Ejercicio 8.3 Utiliza solve para hallar las cuatro raı́ces de la ecuación de cuarto grado
x4 + ax3 + bx2 + cx + d.

163
8.3 Tensores LECCIÓN IV

Nota. Matlab es un programa más enfocado al cálculo numérico que al simbólico. Cier-
tamente los resultados son presentados de una forma que estéticamente no es comparable
a Mathematica o Maple. Sin embargo se puede acceder a cualquier instrucción de Maple
luego a priori todo lo que se puede hacer con este procesador se puede hacer con Matlab.
Para llamar a un comando de Maple se utiliza el comando maple, mientras que a la ayuda
correspondiente se accede con mhelp. 
Bo
8.3. Tensores
Ya hemos hablado en múltiples ocasiones de la gran potencia que posee Matlab para
realizar cálculos matriciales8 y su habilidad en el manejo de grandes cantidades de memo-
ria. Estas habilidades se extienden a la manipulación de arrays multidimensionales, que
matemáticamente se puede identificar con tensores. Un tensor es simplemente una matriz
multidimensional, esto es, si una matriz se puede interpretar como una tabla de números,
un tensor (o array) tridimensional es simplemente un conjunto de números desplegados
en 3D en forma de paralelogramo. Ası́
rra
>> a=zeros(1,3,2)

a(:,:,1) =

0 0 0

a(:,:,2) =

0 0 0

define un array de una fila, tres columnas y dos alturas. Abandonaremos en lo que sigue
este sı́mil geométrico pues aporta poco. Se puede declarar un tensor simplemente dando
do
sus valores

>> a2(:,:,1)=[1 2 3;4 5 6]

a2 =

1 2 3
4 5 6

>> a2(:,:,2)=[7 8 9;10 11 12]


r
a2(:,:,1) =

1 2 3
4 5 6
8
Recuerda Matlab = Matrix laboratory

164
LECCIÓN IV Capı́tulo 8. Matlab: Cálculo simbólico y estructuras de datos.

a2(:,:,2) =

7 8 9
10 11 12
Bo
>> size(a)

ans =

2 3 2

>> length(a) %maximo de las dimensiones

ans =

3
rra
Observa la diferencia
>> a1=a(1,:,:)

a1(:,:,1) =

1 2 3

a1(:,:,2) =

7 8 9
do
>> a2=a(:,1,:)

a2(:,:,1) =

1
4

a2(:,:,2) =

7
r
10

>> a3=a(:,:,1)

a3 =

165
8.3 Tensores LECCIÓN IV

1 2 3
4 5 6
Por tanto, de las variables que acabamos de definir únicamente a3 es una matriz propia-
mente dicha.
La forma de operar con tensores es básicamente la misma que con vectores y matrices.
Por ejemplo:
Bo
>> b=a+ones(2,3,2)

b(:,:,1) =

2 3 4
5 6 7

b(:,:,2) =

8 9 10
11 12 13
rra
>> b(:,2:3,2)=[-1 -2;-3 -4]

b(:,:,1) =

2 3 4
3 3 3

b(:,:,2) =

8 -1 -2
3 -3 -4
do
>> b(:)’ % como se guarda en memoria...

ans =

2 3 3 3 4 3 8 3 -1 -3 -2 -4

Ejemplo. Mediante las siguientes ordenes calculamos las cinco primeras potencias de
la matriz a y las almacenamos en una variable tridimensional b:
r
a=[1 2;3 4];
b(:,:,1)=a;
for i=2:5
b(:,:,i)=b(:,:,i-1)*a; %b(:,:,i) guarda a^i
end


166
LECCIÓN IV Capı́tulo 8. Matlab: Cálculo simbólico y estructuras de datos.

Las funciones que operan sobre escalares, tales como sin, cos, etc., funcionan con
tensores exactamente del mismo modo que con vectores o matrices, realizando las opera-
ciones elemento a elemento. Si se aplica una función de las que operan sobre los elementos
de un tensor como por ejemplo búsqueda de máximos o mı́nimos (max, min) o la suma y
producto (sum, prod), devuelve un tensor de una dimensión menos, resultado de realizar
la operación sobre la primera dimensión:
Bo
>> a=zeros(2,3,2);
>> a(:,:,1)=[1 2 8; 4 5 6]; a(:,:,2)=[6 2 14; 3 5 1]

a(:,:,1) =

1 2 8
4 5 6

a(:,:,2) =
rra
6 2 14
3 5 1

>> max(a) % 1x3x2

ans(:,:,1) =

4 5 8

ans(:,:,2) =

6 5 14
do
>> max(max(a)) % 1x1x2

ans(:,:,1) =

ans(:,:,2) =

14
r
>> max(max(max(a))) % 1x1x1, un numero

ans =

167
8.4 Vectores de celdas LECCIÓN IV

8.4. Vectores de celdas


Aunque los tensores añaden mayor flexibilidad a las matrices y vectores, siguen siendo
estructuras rı́gidas (todas las entradas deben ser números reales, a(1,:,:,:) debe tener
la misma dimensión que a(2,:,:,:),...).
Matlab cuenta con una estructura que probablemente sea el paradigma de la flexibilidad
Bo
en tanto en cuanto permite guardar casi cualquier tipo de dato. Es, por ası́ decirlo, un
“cajón de sastre”. Este tipo de estructura se denomina vector (matriz o tensor) de celdas
o cell array. Ya nos hemos encontrado con esta estructura cuando vimos el diseño de
funciones cuyo número de parámetros de entrada y/o salida era variable. Las variables
varargin y varargout son realmente vectores de celdas que contenı́an distintos tipos de
datos a los que se accedı́a mediante llaves. Un vector de celdas se maneja del mismo. A
modo de ejemplo podemos crear un vector de celdas simplemente asignando valores
>> celda={7,[1 2 3;4 5 6],’una cadena de caracteres’,inline(’x+y’)};
>> whos celda
Name Size Bytes Class
rra
celda 1x4 1214 cell array

Grand total is 95 elements using 1214 bytes


que es equivalente a dar cada una de sus componentes
>> celda{1}=7;
>> celda{2}=[1 2 3;4 5 6];
>> celda{3}=’una cadena de caracteres’;
>> celda{4}=inline(’x+y’);
También se puede proceder, con pequeñas diferencias de sintaxis, de la siguiente forma
>> celda(1)={7};
do
>> celda(2)={[1 2 3;4 5 6]};
Fı́jate en la disposición de las llaves en los dos ejemplos anteriores. En cualquier caso, una
vez definido el vector podemos acceder a cada una de sus componentes indicando entre
llaves su posición
>> celda{1}

ans =

7
r
>> celda{4}([1 2 4], [2 1 1/2]) % funcion!!

ans =

3.0000 3.0000 4.5000

168
LECCIÓN IV Capı́tulo 8. Matlab: Cálculo simbólico y estructuras de datos.

o visualizar todas ellas mediante

>> celldisp(celda)

celda{1} =
Bo
7

celda{2} =

1 2 3
4 5 6

celda{3} =

una cadena de caracteres

celda{4} =
rra
Inline function:
(x,y) = x+y

Este tipo de estructura, aunque muy flexible a la hora de almacenar información, es


sin embargo manejada con menor eficiencia por Matlab, por lo que debe hacerse un uso
mesurado de ella. Los comandos varargin y varargout proporcionan un buen ejemplo
de una utilización apropiada de esta estructura.

Ejercicio 8.4 Otra manera de agrupar distintos tipos de datos es utilizar estructuras (“struct”).
Una estructura es un tipo de dato del que luego se pueden asignar campos distintos. Por ejem-
plo, la estructura Libro podrı́a contener los campos Titulo y Autor que serı́an cadenas de
caracteres y A~noPublicacion y NumeroPaginas que serı́an números.
do
Utiliza la ayuda de Matlab para averiguar cómo pueden definirse estos tipos de datos
mediante la orden struct.
r
169
8.4 Vectores de celdas LECCIÓN IV
Bo
rra
do
r
170
Capı́tulo 9
Bo
Cálculo numérico de valores y
vectores propios.

9.1. Introducción
El estudio de los valores y vectores propios de una matriz surge ligado a una gran
rra
cantidad de problemas que se plantean en ámbitos de muy diversa ı́ndole, tales como la
Ingenierı́a, Fı́sica, Economı́a, Estadı́stica o Biologı́a. Algunos ejemplos los encontramos
en el cálculo de los modos de vibración de algunas estructuras, el estudio de la evolución
de sistemas dinámicos, compresión de datos, el análisis de redes (grafos),...
El problema que abordamos es el siguiente: dada una matriz A de tamaño n × n
queremos encontrar los escalares λ y vectores v 6= 0 que cumplan

Av = λv.

Se dice entonces que λ es un valor propio de A y que v es un vector propio asociado


a λ. Se trata por tanto de buscar las direcciones invariantes bajo los productos por la
matriz.
do
Equivalentemente, los valores propios de A son aquellos valores λ para los que el
sistema lineal homogéneo
(A − λI)v = 0,
tiene soluciones no nulas, y estas soluciones son los vectores propios asociados a λ. Esta
expresión nos da una manera de calcular λ: los valores propios son los valores, reales o
complejos, para los que A − λI no es invertible, o equivalente, para los que det(A − λI)=0.
Concluimos de esta manera que los valores propios son las raı́ces del polinomio

p(λ) := det(A − λI) = 0.


r
conocido como polinomio caracterı́stico. Dado que p(λ) tiene grado n, habrá exactamente
n valores propios (aunque alguno de ellos puede estar repetido o ser complejo).
Históricamente los métodos numéricos comenzaron trabajando sobre el polinomio car-
acterı́stico para hallar los valores propios, pero pronto se comprobó que este camino no
era el más indicado. Uno de los hechos que motivaron este abandono radicaba en la in-
estabilidad numérica:

171
9.1 Introducción LECCIÓN IV

Las raı́ces de un polinomio son muy sensibles a variaciones en sus coeficientes;

El polinomio a su vez puede ser muy sensible a las entradas de la matriz.

En vista de lo anterior se planteó el problema original: ¿son los valores y vectores propios
sensibles a pequeñas modificaciones de las entradas de la matriz?. Afortunadamente para
matrices simétricas se tiene la ansiada estabilidad: pequeñas variaciones en A, producto
Bo
por ejemplo de errores de medida o errores de redondeo, dan lugar a pequeñas modifica-
ciones en los valores propios1 . Para matrices arbitrarias este resultado dista mucho de ser
cierto, las condiciones para asegurar la estabilidad son más complicadas, y podemos en-
contrarnos con lo que en la terminologı́a habitual se denomina, matrices mal condicionadas
para el cálculo de valores propios.

Ejemplo Estas lı́neas muestran la sensibilidad de una matriz muy simple ante una
pequeña variación en una entrada.

>> a=[149 50 154;-537 -180 -546;27 9 25];


>> p= poly(a)
rra
p =

1.0000 6.0000 11.0000 6.0000

>> roots(p).’

ans =

-3.0000 -2.0000 -1.0000

>> b=[149 50 154;-537 -180.01 -546;27 9 25];


>> q=poly(b)
do
ans =

1.0000 6.0100 9.2600 1.6700

>> roots(q).’

ans=

-3.5019 -2.3008 -0.2073


r


Ejercicio 9.1 Repite el ejemplo anterior con diferentes matrices simétricas y observa como
el resultado es más estable.
1
Probado por primera vez por Hermann Weyl en 1911 en un área totalmente distinta.

172
LECCIÓN IV Capı́tulo 9. Cálculo numérico de valores y vectores propios.

Nota. Éste y otros detalles no eran conocidos en los inicios del cálculo cientı́fico. James
Hardy Wilkinson relata la siguiente anécdota2 . Cuando estaba programando en uno de los
primeros ordenadores electrónicos el método de Newton para la resolución de ecuaciones
no lineales, decidió testarlo con el siguiente polinomio
(x − 20)(x − 19) · · · (x − 1).
Bo
El método fallaba de forma reiterada, a pesar de las sucesivas revisiones del código, hasta
que Wilkinson cayó en la cuenta de que el error no radicaba en su programa sino que
las raı́ces eran tan sensibles numéricamente que se veı́an afectadas por los errores de
redondeo. Wilkinson demostró que al cambiar el coeficiente de x19 en p, que es −210,
por −210 − 2−23 , las raı́ces 16 y 17 se transforman3 en el par complejo 16.73 ±2.81i.
El polinomio en cuestión pasó a la historia del Numérico con el nombre de “el pérfido
polinomio de Wilkinson”. 

9.2. Matrices semejantes


Dos matrices A y B son semejantes si existe una matriz P invertible tal que
rra
B = P AP −1 .
En este caso,
det(B − λI) = det(P AP −1 − λI) = det(P (A − λI)P −1 ) =

= det(P ) det(A − λI) det(P −1 ) = det(A − λI),


es decir, A y B tienen el mismo polinomio caracterı́stico y por tanto los mismos valores
propios.
Este resultado sugiere una estrategia para encontrar los valores propios de A: buscar
matrices semejantes para las que el cálculo de los valores propios sea sencillo. En particular,
cuando B es triangular sus valores propios son simplemente los elementos diagonales.
do
Si podemos tomar los n vectores propios linealmente independientes, la matriz P :=
[v1 |v2 | . . . |vn ] (su i–ésima columna es el vector vi ) es invertible. Entonces
AP = P D ⇐⇒ P −1 AP = D,
donde D es una matriz diagonal con los valores propios sobre la diagonal. Si una matriz
es semejante a una matriz diagonal se dice que es diagonalizable.
Particularmente interesante es el caso en que P se puede tomar además ortogonal.
Esto es, P −1 = P > , y por tanto
P > AP = D.
r
Las matrices ortogonales son muy estables numéricamente y posibilitan el diseño de méto-
dos más robustos frente a errores de redondeo.
2
Recogida por D. Kincaid y W. Cheney en su excelente libro “Análisis Numérico: Las Matemáticas
del Cálculo Cientı́fico.” Addison-Wesley, 1994.
3
¿Cómo asumir que las raı́ces de un polinomio tan sencillo fueran imposibles de aproximar por un
ordenador? Wilkinson dirı́a después “Speaking for myself I regard it as the most traumatic experience in
my career as a numerical analyst”

173
9.3 Método de potencias LECCIÓN IV

Teorema 9.1 Si A es simétrica, existe Q ortogonal tal que Q> AQ = D con D diagonal con
los valores propios de A. En particular, los valores propios de una matriz simétrica son todos
reales.

En las Secciones 9.4 y 9.5 de esta lección se estudiarán dos métodos basados en trans-
formaciones de semejanza (producto por matrices ortogonales) que tratan de llevar una
Bo
matriz simétrica a una forma diagonal como forma de calcular los valores propios. Estos
métodos se pueden adaptar, con más o menos éxito, a matrices arbitrarias llevando en
este caso la matriz a una forma triangular o cuasitriangular.

9.3. Método de potencias


En esta sección presentaremos el método de potencias y algunas variantes del mismo
que proporcionan un valor propio de la matriz. Estos métodos combinados con técnicas
de deflación, que consisten en construir una nueva matriz con los mismos valores propios
que la original salvo el ya el calculado, permiten calcular unos pocos valores propios.
rra
9.3.1. Descripción del método
Asumiremos para empezar que la matriz A tiene un valor propio dominante, es decir,
sus valores propios pueden ordenarse en la forma

|λ1 | > |λ2 | ≥ |λ3 | ≥ . . . ≥ |λn |.

Supongamos además que tenemos una base formada por vectores propios, esto es pode-
mos tomar {vi }ni=1 vectores propios linealmente independientes (la matriz A es por tanto
diagonalizable). Entonces, cualquier vector x0 puede escribirse en la forma
n
X
x0 = αi vi
do
i=1

con αi adecuados. Multiplicando reiteradamente por A obtenemos


n   m  m 
m
X λ2 λn
A x0 = αi λm
i vi = λm
1 α1 v1 + α2 v2 + . . . + αn vn . (9.1)
i=1
λ1 λ1

Entonces, si α1 6= 0 y m es grande

xm := Am x0 ≈ λm
1 α1 v1 ,
r
es decir, xm tiende a apuntar en la dirección del vector propio asociado al valor propio
de mayor módulo (en el lenguaje habitual se habla del valor propio dominante). El valor
propio λ1 se puede calcular, entre otras posibilidades, mediante el conocido cociente de
Rayleigh:
(m) x> Axm x> xm+1
λ1 := m 2 = m 2 ≈ λ1 .
kxm k kxm k

174
LECCIÓN IV Capı́tulo 9. Cálculo numérico de valores y vectores propios.

Proposición 9.2 Bajo las hipótesis anteriores


  m 
(m) λ1
λ1 = λ1 + O λ2
.

Si además A es simétrica   2m 


(m) λ1
λ1 = λ1 + O .
Bo
λ2

Basado en estas ideas surge el método de potencias, que simplemente consiste en


multiplicar un vector inicial por las potencias sucesivas de la matriz A. Para evitar que
los vectores xm tengan componentes muy grandes o muy pequeñas se genera una sucesión
de vectores normalizados, es decir, una vez multiplicado por A se procede a dividir por
su norma.
El algoritmo es el siguiente:

Método de potencias

01 x0 6= 0 vector inicial
rra
x0
02 y0 =
kx0 k2
03 for m=1:mmax
04 xm = Aym−1
>
05 λ(m) = ym−1 xm
xm
06 ym =
kxm k2
07 if kym − ym−1 k2 < eps
08 return
09 end
10 end
do
La lı́nea 06 es simplemente el cociente de Rayleigh que, como la norma escogida para
normalizar es la euclı́dea, adopta esta expresión más sencilla.
Hemos elegido como criterio de parada la diferencia entre dos vectores consecutivos.
Otra posible elección es
|λ(m) − λ(m−1) | < eps |λ(m) |.

Ejercicio 9.2 Programa el método de potencias


r
Solución. He aquı́ una implementación del método.

01 %POTENCIAS
02 %
03 %LB=POTENCIAS(A) Devuelve en LB una aproximacion del

175
9.3 Método de potencias LECCIÓN IV

04 % mayor valor propio de A calculado


05 % por el metodo de potencias
06 %
07 %[LB,V]=POTENCIAS(A) V es el vector propio
08 %
09 %[LB,V,NITER]=POTENCIAS(A) NITER son las iteraciones calculadas
Bo
10 %
11 % LB=POTENCIAS(A,MMAX) MMAX No. maximo de iteraciones n
12 %
13 % LB=POTENCIAS(A,MMAX,EPS) EPS es el criterio de parada
14 %
15 % LB=POTENCIAS(A,MMAX,EPS,V0) V0 vector inicial para la iteracion
16
17 function [lb,x,m]=potencias(a,varargin);
18
19 n=length(a);
20 if nargin>1 & ~isempty(varargin{1})
21 mmax=varargin{1};
rra
22 else
23 mmax=n*2;
24 end
25 if nargin>2 & ~isempty(varargin{2})
26 eps=varargin{2};
27 else
28 eps=1e-6;
29 end
30 if nargin>3 & ~isempty(varargin{3})
31 y=varargin{3};
32 else
33 y=rand(n,1);
do
34 end
35 y=y/norm(y);
36
37 for m=1:mmax
38 x=a*y;
39 lb=y’*x;
40 x=x/norm(x);
41 if norm(x-y)<eps
42 return
43 end
r
44 y=x;
45 end
46 disp(’numero maximo de iteraciones superado’)
Observa la utilización de isempty que permite que el usuario especifique alguno de
los parámetros, ignorando los anteriores sin más que utilizar el vacı́o []. Por ejemplo, la
siguiente llamada es válida:

176
LECCIÓN IV Capı́tulo 9. Cálculo numérico de valores y vectores propios.

>> [lb,v]=potencias(a,[],[],v0); % especifico el vector inicial

Ejercicio 9.3 Compara la velocidad de convergencia y el número de iteraciones requerido


Bo
para distintas tolerancias y vectores iniciales al tomar las matrices
     
−1 −3 0 −1 −3 0 −1 4 −2
A= 4 9 4 , B =  −3 9 4 , C= 4 9 −1  .
−2 −1 5 0 4 5 −2 −1 5

Nota. Cuando no se conoce una aproximación del vector propio asociado al valor propio
dominante, se suele iniciar el algoritmo partiendo de un vector generado aleatoriamente.
Podrı́a ocurrir que para el vector inicial α1 = 0, pero la probabilidad de que se dé este
problema es (prácticamente) nula. En este caso, si |λ2 | > |λ3 |, salvo por errores de re-
dondeo4 , el método proporcionará el valor propio subdominante λ2 y su vector propio
asociado normalizado.
rra
No es necesario que la matriz sea diagonalizable para que el método de potencias
converja. Tampoco que el subespacio asociado al valor propio dominante esté generado
por un único vector. En este caso, que sólo puede darse si λ1 es un valor propio repetido, el
método puede converger a distintos vectores propios normalizados dependiendo del vector
inicial considerado.
Si |λ1 | = |λ2 |, es decir, λ1 = ±λ2 ó λ1 y λ2 son números complejos conjugados, entonces
el método de potencias falla. 

Ejercicio 9.4 Consideremos la matriz


 
0 0 0 −24
 1 0 0 50 
A= 
do
 0 1 0 −35 
0 0 1 10

cuyos valores propios son 1, 2, 3 y 4.

1. Aplicar el método de potencias a la matriz A partiendo de un vector aleatorio y del


vector (−20, 33, −15, 2)> .

2. Sabiendo que v1 = (−24, 26, −9, 1)> y v2 = (−12, 19, −8, 1)> son vectores propios
asociados a los valores propios 1 y 2 respectivamente, ¿qué crees que ocurrirá si se toma
como vector inicial v1 − 3v2 = (12, −31, 15, −2)> ?
r
3. Observa para distintas tolerancias la diferencia entre partir del vector del apartado an-
terior y de (12, −31, 15, −2.0001)> .
4
El efecto de los errores de redondeo se traduce en una componente no nula en la dirección de v1 ,
incluso aunque el vector inicial no la tuviese. Se podrı́a decir que éste es uno de los pocos casos en los
que los errores de redondeo nos pueden ayudar.

177
9.3 Método de potencias LECCIÓN IV

Ejercicio 9.5 En este ejercicio vamos a comprobar que el cálculo de los valores propios
utilizando el polinomio caracterı́stico no es el camino correcto. Teclea las instrucciones en un
fichero script
n=50;
d=1/n:1/n:1; [q,r]=qr(rand(n));
Bo
a=q’*d*q;
En a tenemos una matriz simétrica con valores propios5 {0.02, 0.04, 006, . . . , 1}. Se trata de
que apliques potencias para calcular el valor propio dominante y compares el resultado con el
que obtienes al calcular las raı́ces del polinomio caracterı́stico.
Compara los resultados. Cambia el valor de n y observa el efecto que tiene en matrices
cada vez más grandes.

9.3.2. Variantes del método de potencias


Método de la potencia inversa
Si A es invertible y v es un vector propio asociado a un valor propio λ (que será distinto
rra
de cero), entonces,
Av = λv ⇐⇒ A−1 v = λ−1 v.
Es decir, λ−1 es un valor propio de la matriz inversa y v es un vector propio asociado.
Por tanto podemos aplicar el método de potencias a la matriz A−1 para calcular el menor
valor propio en valor absoluto de A.
En lugar de calcular el producto xm = A−1 ym−1 (lı́nea 04 en el método de potencias)
resolveremos en cada iteración el sistema6

Axm = ym−1 .

Disponemos para ello de una galerı́a amplia de métodos vistos en las Lecciones I y II.
Notemos además que en cada iteración se tiene que resolver un sistema cuya matriz
es siempre la misma, ası́ que si optamos por un método directo podemos calcular la
do
factorización LU una única vez, fuera del bucle for (lı́neas 03--10), y resolver de forma
reiterada los dos sistemas triangulares. Si por contra se opta por un método iterativo,
podemos arrancar el esquema utilizando xm−1 , la aproximación del vector propio calculada
en la iteración anterior.

Ejercicio 9.6 Programa a partir del Ejercicio 9.2 el algoritmo de la potencia inversa.

Método de potencias desplazado


Si λ es un valor propio de A, entonces λ − α es un valor propio de A − αI y (λ − α)−1
r
lo es de (A − αI)−1 . Por tanto, si aplicamos el método de potencias a la matriz

A − αI
5
El comando qr descompone A = QR con Q ortogonal y R triangular. Por tanto los valores propios
de Q> AQ coinciden con los de A. La Sección 9.5.1 está dedicada al cálculo de esta descomposición.
6
Recuerda que invertir una matriz para multiplicarla posteriormente por un vector es mucho más
costoso que resolver el sistema correspondiente.

178
LECCIÓN IV Capı́tulo 9. Cálculo numérico de valores y vectores propios.

donde α es una constante conocida, podemos obtener el valor propio de A más alejado
de α. Más interesante desde el punto de vista práctico es aplicar el método de potencias
a (A − αI)−1 , que nos proporcionará el valor propio de A más próximo a α.

Ejercicio 9.7 Modifica el programa del Ejercicio 9.6 para implementar el método de poten-
Bo
cias desplazado. Los argumentos obligatorios de entrada serán ahora A y alpha.

Comentarios finales

El método de potencias tiene una ventaja evidente: su simplicidad. Ni siquiera nece-


sitamos la matriz en sı́, sólo saber multiplicar por ella.
El algoritmo de la potencia desplazada se puede utilizar para el cálculo de un vector
propio si se conoce λ, el valor propio asociado. Basta para ello aplicar el método con
α = λ +  con  << 1. Puede plantearse si esto tiene efectos perniciosos habida cuenta
de que A − αI está muy cerca de ser singular. Wilkinson probó sin embargo que el efecto
de esta inestabilidad se da precisamente en la dirección del vector propio, que a fin de
rra
cuentas es lo que nos interesa.
Se puede sugerir una versión alternativa del método de potencias desplazada consis-
tente en tomar un α nuevo en cada iteración, por ejemplo el último valor calculado λ(m) .
Aunque esto acelera enormemente la convergencia del método, dispara el costo por it-
eración, ya que en cada paso hay que resolver un sistema lineal nuevo, por lo que salvo
en contados casos no es recomendable.
Si se conoce un valor propio λ de una matriz A de tamaño n, puede construirse una
nueva matriz de tamaño n − 1 que tiene exactamente los mismos valores propios que A
salvo λ. Podrı́a aplicarse ahora el método de potencias (o cualquiera de sus variantes) a la
nueva matriz para determinar un nuevo valor propio de A. Este tipo de técnica, en la que
no entraremos en estos apuntes, se conoce como deflación. Debemos señalar que mediante
esta técnica los errores de redondeo se van acumulando, de modo que sólo es factible para
do
calcular unos cuantos valores propios. El número final depende obviamente de la propia
matriz y de la precisión con que se van calculando los valores propios.

9.4. Método de Jacobi


En esta sección estudiaremos un método que nos proporcionará todos los valores pro-
pios de una matriz simétrica (todos son reales) mediante un esquema iterativo basado
en transformaciones de semejanza.
r
9.4.1. Descripción del método
El método de Jacobi transforma en cada paso una matriz simétrica A en otra semejante
con estructura más diagonal mediante el producto a izquierda y derecha por matrices
apropiadas. Una matriz de Givens, también llamada de rotación, es una matriz de la

179
9.4 Método de Jacobi LECCIÓN IV

forma  
1
..
.
 
 
cos α sin α  ← fila p
 

1
 
 

Rpq (α) =  .. 
.
Bo

 

 1 


 − sin α cos α  ← fila q


 ... 

1
↑ ↑
(9.2)
col. p col. q
Es fácil ver que son ortogonales, es decir, Rpq (α)−1 = Rpq (α)> .
Mediante
>
A1 := Rpq ARpq
rra
(p, q y α adecuados) vamos a anular el mayor elemento extradiagonal de A. Esta operación
(1)
sólo afecta a las filas y columnas p, q de A. Concretamente, si denotamos por aij las
entradas de A1 ,

a(1)
pq = (aqq − app ) cos α sen α + apq (cos2 α − sen2 α) =

1
= (aqq − app ) sen(2α) + apq cos(2α).
2
Por tanto, el ángulo α debe tomarse de modo que

 cos(2α) = 0,
 si aqq = app ,
2apq
do
 tan(2α) =
 , en caso contrario.
aqq − app

Para calcular cos α y sen α evitando el uso de un arcotangente se recurre a algunas


manipulaciones trigonométricas que prueban que si7

aqq − app sign(θ)


θ := , t := √ ,
2apq |θ| + θ2 + 1

entonces
1 t
cos α = √ , sen α = √ .
t2 + 1 t2 + 1
r
Cuando aqq = app tomamos

1 −sign(aqq )
cos α = √ , sen αm = √ .
2 2
7
sign (z) es el signo de z, −1 si z es negativo, 1 en caso contrario.

180
LECCIÓN IV Capı́tulo 9. Cálculo numérico de valores y vectores propios.

El método ya se vislumbra en este estado: se trata de repetir el mismo argumento


con A1 para obtener una segunda matriz A2 resultado de cancelar el mayor elemento
extradiagonal de A1 . De esta forma, reiterando este proceso llegamos a una sucesión de
matrices Am que cumplen
 
λ1
Bo
 λ2 
Am −→ D :=  , cuando m → ∞.
 
 . . . 
λn

Además, definiendo Qm := Rp1 q1 (α1 )Rp2 q2 (α2 ) . . . Rpm qm (αm ), donde Rpk ,qk es la matriz
utilizada en el paso k−ésimo

Q−1
m AQm = Am −→ D.

Por tanto, las columnas de Qm son las aproximaciones (ortonormales) de los vectores
propios correspondientes.
El siguiente teorema prueba la convergencia de este método. Para ello necesitamos la
rra
llamada norma de Frobenius8
n
hX i1/2
2
kAkF := |ai,j |
i,j=1

Teorema 9.3 Sea Am la matriz en la iteración m, Dm su diagonal y Bm := Am − Dm .


Entonces
kAm kF = kAm+1 kF , kBm+1 k2F = kBm k2 − 2|a(m)
pm qm |
2

El resultado dice en primer lugar que la norma de Frobenius de una matriz no cambia
cuando se multiplica a izquierda y derecha por las matrices Rpq (α), una de ellas traspuesta.
De hecho se preserva cuando se multiplica, a izquierda y derecha, por matrices ortogonales
do
arbitrarias. El segundo resultado dice algo más: el peso de los elementos extradiagonales
disminuye en cada paso según el elemento cancelado. Esto asegura la convergencia del
proceso hasta obtener una matriz diagonal.
En la práctica, el proceso se interrumpe cuando los elementos que están fuera de la
diagonal son suficientemente pequeños. En concreto, se suele tomar el siguiente criterio
de parada
n
!1/2
X (m)
|a(m)
pm qm | < eps |aii |2 .
i=1
r
Fı́jate que las matrices Am y Am+1 sólo difieren en las filas y columnas pm y qm . A
efectos prácticos no será necesario formar las matrices de rotación ya que basta conocer
los valores de cos αm y de sen αm para construir Am+1 a partir de Am .

Ejercicio 9.8 Implementa el método de Jacobi.


8
En Matlab serı́a norm(a(:)) o norm(a,’fro’).

181
9.4 Método de Jacobi LECCIÓN IV

Solución. La parte central del programa se puede implementar con las siguientes lı́neas
01 % JACOBI
02 %
03 % D=JACOBI(A) Aplica el metodo de Jacobi a A y devuelve
04 % en D los valores propios; A debe ser
05 % simetrica
Bo
06 %
07 % [D,Q]= JACOBI(A) Q es ortogonal con Q’A Q=D
08 %
09 % [D,Q,NITER]= JACOBI(A) NITER Numero de iteraciones calculadas
10 %
11 % D=JACOBI(A,NMAX) NMAX numero maximo de iteraciones
12 %
13 % D=JACOBI(A,NMAX) NMAX numero maximo de iteraciones
14 %
11 % D=JACOBI(A,NMAX,EPS) EPS es el criterio de parada
12
13 function [d,Q,m]= jacobi(a,varargin)
rra
14
15 n=length(a);
16 if nargin>1 & ~isempty(varargin{1})
17 mmax=varargin{1};
18 else
19 mmax=n^2;
20 end
21
22 if nargin>2 & ~isempty(varargin{2})
23 eps=varargin{2};
24 else
25 eps=1e-5;
do
26 end
27
28 Q=eye(n);
29 for m=1:mmax
30 d=diag(a);
31 %Calculo del mayor elemento extradiagonal
32 [max1,p]=max(abs(a-diag(d)));
33 [max2,q]=max(max1);
34 p=p(q);
35 if max2<eps*norm(d)
r
36 return % convergencia
37 end
38 %calculo sen y cos
39 if abs(a(q,q)-a(p,p))<eps
40 c=1/sqrt(2);
41 s=-c*sign(a(p,q));

182
LECCIÓN IV Capı́tulo 9. Cálculo numérico de valores y vectores propios.

42 else
43 theta=(a(q,q)-a(p,p))/(2*a(p,q));
44 t=sign(theta)/(abs(theta)+sqrt(theta^2+1));
45 c=1/sqrt(t^2+1);
46 s=c*t;
47 end
Bo
48 r=[c s ;-s c];
49 %La rotacion solo afecta a las filas y col. p y q
50 a([p q],:)=r’*a([p q],:);
51 a(:,[p q])=a(:,[p q])*r;
52 Q(:,[p q])=Q(:,[p q])*r; % guardamos Q
53 end
54 disp(’numero maximo de iteraciones sobrepasado’);
55 return

Observa bien las lı́neas 32-33 que sirven para encontrar la posición del máximo elemento
extradiagonal.

rra
9.4.2. Variantes del método de Jacobi
Aunque el método de Jacobi ofrece la posibilidad de calcular de forma rápida todos
los valores propios, tiene una convergencia lenta incluso para matrices de tamaño mod-
erado. Vamos a introducir algunas mejoras desde el punto de vista computacional, que
no matemático. Concretamente vamos a realizar una pequeña modificación que aunque
eleva el número de iteraciones necesarias para converger (peor desde el punto de vista
matemático) cada iteración se ejecuta en menos tiempo, de forma que al final se consigue
reducir el tiempo de cálculo (mejora computacional).
Para ello vamos a identificar primero dónde se nos va el tiempo de cálculo. Con este
fin utilizaremos una de las herramientas más útiles en Matlab: profile.
do
Comenzamos creando una matriz simétrica de tamaño moderado:

>> a=rand(120); a=a+a’;

y activamos el profile de Matlab con

>> profile on

Ahora Matlab va a llevar un control sobre el tiempo que consume cada lı́nea de código9 .
A continuación ejecuta el programa jacobi para a con un número máximo de iteraciones
r
suficientemente alto de forma que asegures convergencia. La instrucción

>> profile report

despliega un informe donde puedes ver el tiempo que ha consumido cada parte del pro-
grama. Se observa claramente que las lı́neas más costosas son aquéllas empleadas en la
búsqueda del máximo elemento extradiagonal (observa la Figura 9.1). Es precisamente

183
9.4 Método de Jacobi LECCIÓN IV

MATLAB Profile Report: Function Details


Bo
jacobi C:/Documents and Settings/Víctor/Escritorio/LibroMatlab/jacobi.m
Time: 14.75100000 s (100.0%)
Calls: 1
Self time: 14.75100000 s (100.0%)

Function: Time Calls Time/call


jacobi 14.75100000 1 14.75100000

Parent functions:
none
rra
Child functions:
none

99% of the total time in this function was spent on the following lines:

33: for m=1:mmax


0.07643962 1% 34: d=diag(a);
35: %Calculo del mayor elemento extradiagonal
13.37100000 91% 36: [max1,p]=max(abs(a-diag(d)));
0.26000000 2% 37: [max2,q]=max(max1);
38: p=p(q);
0.07000000 0% 39: if max2<eps*norm(d)
40: return % convergencia
do
42: %calculo sen y cos
0.09000000 1% 43: if abs(a(q,q)-a(p,p))<eps
44: c=1/sqrt(2);

51: end
0.10819591 1% 52: r0=[c s ;-s c];
53: %La rotacion solo afecta a las filas y col. p y q
0.31000000 2% 54: a([p q],:)=r0'*a([p q],:);
0.12000000 1% 55: a(:,[p q])=a(:,[p q])*r0;
0.17000000 1% 56: r(:,[p q])=r(:,[p q])*r0; % guardamos r
r
0.05000000 0% 57: end

Figura 9.1: Profile aplicado al método de Jacobi.

184
LECCIÓN IV Capı́tulo 9. Cálculo numérico de valores y vectores propios.

en estas lı́neas donde debemos proponer nuestra mejora, reemplazando la búsqueda por
algún proceso más económico.
La variante que proponemos es la siguiente: recorreremos uno por uno todos los el-
ementos situados debajo de la diagonal (como la matriz es simétrica esto es suficiente).
Si el tamaño de un elemento es pequeño, no hacemos nada y pasamos al siguiente. Si es
grande, se procede anularlo. Para dilucidar si es grande o pequeño compararı́amos con
Bo
el tamaño de la diagonal de forma semejante a como se hace en el programa original
(lı́nea 09). Una vez recorridos todos los elementos, esto es, una vez realizado un barrido
en la terminologı́a habitual, volvemos a empezar. Cada cierto número de iteraciones, por
ejemplo tras cada barrido, podemos medir el tamaño de los elementos extradiagonales que
quedan para ver si se da por finalizada la ejecución del programa. Si comprobamos que
hay todavı́a elementos diagonales muy grandes, empezamos de nuevo.

Ejercicio 9.9 Implementa la modificación sugerida en el párrafo de arriba. Ejecuta el profile


de Matlab y compara tiempos de ejecución con el programa original. ¿Qué observas?. Fı́jate
también en el número de iteraciones que necesita para converger. ¿Qué te parece?.

Nota. La instrucción profile es muy útil a la hora de depurar código dado que permite
rra
controlar qué partes del programa vale la pena optimizar y cuáles no. La instrucción tiene
varios argumentos opcionales y comandos relacionados que puedes consultar en la ayuda.
Los comandos tic y toc son más simples pero proporcionan menos información. El
primero activa el reloj y el segundo nos informa sobre el tiempo trascurrido desde que se
ejecutó tic. 

9.5. Método QR de Francis


El método QR y sus variantes son sin lugar a dudas la elección más apropiada para el
cálculo de todos los valores propios de una matriz llena.
El método es muy fácil de entender y sencillo de implementar. Sin embargo, es difı́cil
do
de comprender por qué funciona (el análisis no es nada trivial).
Ya hemos visto descomposiciones matriciales del tipo A = LU con L (permutación
de) triangular inferior con 1s en la diagonal y U triangular superior. Una descomposición
alternativa es
A = QR
con Q ortogonal (Q> = Q−1 ) y R triangular superior. Esta descomposición siempre existe
y puede ser calculada de varias formas distintas.
El método QR de Francis consiste en grosso modo construir una sucesión de matrices
Am (A0 = A) procediendo como sigue
r
Am = Qm Rm (factorizar) Am+1 := Rm+1 Qm+1 (construir)

Para una matriz simétrica el algoritmo converge prácticamente en todos los casos a una
matriz diagonal con los valores propios. Más adelante detallaremos el algoritmo y cómo se
9
Tener activada esta opción resta algo de velocidad a los programas puesto que parte de Matlab
está ocupada en autorevisarse. Con profile off desconectas este control.

185
9.5 Método QR de Francis LECCIÓN IV

puede mejorar su implementación. En cualquier caso queda claro que antes de entrar en
materia debemos hablar con algo de profundidad de la descomposición QR de una matriz.
Ejercicio 9.10 Probar que todas las matrices Am son semejantes y por tanto comparten los
mismos valores propios.
Bo
9.5.1. Factorización QR
Quizás la forma más sencilla de calcular la descomposición es aquélla ligada al algo-
ritmo de Gram-Schmidt. Este algoritmo, uno de los clásicos en Álgebra Lineal, se utiliza
para hallar una base ortogonal de un subespacio partir de una base (o sistema generador)
dada. Las operaciones, una vez reescritas adecuadamente se pueden expresar de la forma
A = QR
donde las columnas de A son los vectores originales, las colunas de Q son los vectores
ortonormales que generan el mismo subespacio que los vectores columna de A y R es una
matriz triangular superior que indica cómo se transforma la base original en la nueva base
ortonormal. La descomposición tiene sentido para matrices rectangulares y en este caso
las dimensiones de A y Q coinciden (si A, es m × n, también lo es Q y R es n × n).
rra
Este algoritmo es, sin embargo, muy inestable numéricamente y rara vez se utiliza en
la práctica10 .
Existen caminos distintos que nos conducen a la descomposición QR. Los dos métodos
más utilizados se basan en transformar la matriz original en una triangular superior mul-
tiplicando a izquierda por matrices ortogonales, ya sean rotaciones como las que aparecen
en el algoritmo de Jacobi (matrices de Givens), o matrices (reflexiones) de Householder.

Factorización QR con Matrices de Householder


Una matriz de Householder viene dada por
Q = I − 2 u u> , con kuk2 =1,
do
donde u es un vector columna n × 1 e I es la matriz identidad de tamaño n. Observa que
efectivamente es una matriz, ya que u u> es n × n.
Es muy sencillo comprobar que es simétrica (Q> = Q) y que Q> Q = I, y por tanto
Q−1 = Q.
La factorización QR mediante transformaciones de Householder se basa en la siguiente
propiedad
Proposición 9.4 Dado un vector columna x, si tomamos α = ±kxk2 y definimos
x − α e1
u := , donde e1 = (1, 0, . . . , 0)> ,
kx − α e1 k2
r
Q := I − 2 u u> ,
entonces
Qx = (α, 0, . . . , 0)> .
10
Existe el algoritmo de Gram-Schmit modificado que dota de algo más de estabilidad al método
original.

186
LECCIÓN IV Capı́tulo 9. Cálculo numérico de valores y vectores propios.

Generalmente se suele escoger α con el signo opuesto al de la primera componente de x


para que kuk2 no sea demasiado pequeña.
Para obtener una descomposición A = QR podemos proceder del siguiente modo:
1. Construimos la matriz de Householder Q1 como en la proposición anterior tomando
como vector x la primera columna de A. Entonces
Bo
α1 ∗ . . . ∗
 
 
Q1 A =  0. (9.3)
 

 .. A2 
0
2. Repetimos el proceso con la matriz A2 que es (n − 1) × (n − 1) para construir la
matriz de Householder Q∗2 tal que
α2 ∗ . . . ∗
 
 
∗  0
Q2 A2 =  . . (9.4)

 .. A3 
0
rra
Ahora basta considerar
1 0 ... 0
 
 
Q2 = 
 0 
(9.5)
.. 
 . Q∗2 
0
que cumple  
α1 ∗ ∗ . . . ∗
 0 α ∗ ... ∗ 
 2 
 
Q2 Q1 A = 
 0 0


 . .
 .. ..

A3
do

0 0
3. En el k–ésimo paso se construyen las matrices Q∗k y Qk :
αk ∗ . . . ∗
 
" #
  Ik−1
Q∗k Ak =  0. , Qk := ,
 
 .. Ak+1  Q∗k
0
donde Ik−1 es la matriz identidad de tamaño k − 1.
r
Después de n − 1 pasos obtenemos la descomposición
Qn−1 · · · Q1 A = R, con R triangular superior.
Definiendo Q := Q1 · · · Qn−1 , tenemos que Q−1 = Q−1 −1
n−1 · · · Q1 = Qn−1 · · · Q1 . Por tanto,

A = QR con Q ortogonal y R triangular superior.


Ejercicio 9.11 Implementa la descomposición QR con matrices de Householder

187
9.5 Método QR de Francis LECCIÓN IV

Solución. He aquı́ una implementación del método

01 % [Q,R]=QRHOUSEHOLDER(A) Calcula Q ortogonal y R triangular


02 % superior tales que A=QR.
03 %
04 % El algoritmo esta basado en las matrices de Householder
Bo
05 %
06 function [q,r]=QRhouseholder(a)
07
08 n=length(a)
09 q=eye(n);
10 r=a;
11 for k=1:n
12 u=r(k:n,k); %primera columna
13 alpha=-sign(u(1))*norm(u);
14 u=u-alpha*[1;zeros(length(u)-1,1)];
15 u=u/norm(u);
16 qhouse=eye(length(u))-2*u*u’;
rra
17 r(k:n,k:n)=qhouse*r(k:n,k:n);
18 q(:,k:n)=r(:,k:n)*qhouse;
19 end
20 return

Observa la manipulación simple de los bloques de a, q y r.




Ejercicio 9.12 Adapta el programa para calcular la factorización QR de matrices rectangu-


lares, es decir, matrices generales de m filas y n columnas.
(Ayuda: el for de la lı́nea 11 es ahora for k=1:min([m,n]). El resto de cambios son inmediatos
sin más que tener en cuenta los tamaños de las matrices implicadas.)
do
Si Q = I − 2 u u> es n × n y B n × m, entonces el producto QB puede calcularse como

QB = (I − 2 u u> )B = B − 2u(u> B). (9.6)

Es decir, en ningún momento se requiere construir la matriz Q y únicamente necesitamos


realizar dos productos matriz-vector. El número de operaciones del producto QB es ahora
nm mientras que en la implementación inicial el costo era n2 m. De forma análoga se puede
calcular el producto BQ con B m × n también en mn operaciones.

Ejercicio 9.13 Implementa la factorización QR utilizando las indicaciones previas. Compara


r
con algún ejemplo la reducción del tiempo de cálculo.

Factorización QR con matrices de Givens


La factorización QR de una matriz se puede obtener también utilizando matrices de
rotación, es decir, matrices de la forma (9.2). Esta alternativa es especialmente interesante
si la matriz tiene sus elementos no nulos concentrados entorno a la diagonal. Para matrices

188
LECCIÓN IV Capı́tulo 9. Cálculo numérico de valores y vectores propios.

llenas el tiempo de cálculo es prácticamente el doble comparado con el requerido al utilizar


matrices de Householder.
Es muy fácil comprobar que para crear un cero en la posición (p, q) al multiplicarla a
izquierda por una matriz de Givens Rp,q (α) basta elegir α de modo que
aqq −apq
cos α = p 2 , sin α = p .
Bo
aqq + a2pq a2qq + a2pq

Notemos que las matrices Rpq (α)A y A sólo difieren en las filas p y q.
El método consistirá entonces en ir transformado la matriz original (de tamaño n) en
una matriz triangular superior del siguiente modo: en primer lugar se hacen ceros en las
posiciones de la primera columna por debajo del elemento de la diagonal multiplicando
por n − 1 matrices como (9.2), de modo que
 
∗ ∗ ... ∗
 0 ∗ ... ∗ 
A1 := R1n (α1n ) . . . R13 (α13 )R12 (α12 ) A =  .. .. ..  .
 
| {z }  . . . 
Q1 0 ∗ ... ∗
rra
Obviamente Q1 es una matriz ortogonal por ser producto de matrices ortogonales. En el
siguiente paso haremos ceros en la segunda columna por debajo de la diagonal y ası́ suce-
sivamente. Fı́jate que los elementos nulos de las columnas anteriores se preservan en los
sucesivos pasos.

Ejercicio 9.14 Implementa la factorización QR utilizando matrices de Givens.

Solución. Podemos definir la siguiente función:

01 % QRGIVENS
02 %
03 % [Q,R]=QRGIVENS(A) Calcula Q ortogonal y R triangular
do
04 % superior cumpliendo A=QR
05 %
06 % Utiliza el algoritmo basado en matrices de Givens
07 %
08
09
10 function [q,r]=QRGivens(a)
11 n=length(a);
12 q=eye(n);
13
r
14
15 for j=1:n-1
16 for i=j+1:n
17 if a(i,j)~=0
18 aux=sqrt(a(j,j)^2+a(i,j)^2);
19 c=a(j,j)/aux;

189
9.5 Método QR de Francis LECCIÓN IV

20 s=-a(i,j)/aux;
21 Rot=[c s; -s c];
22 %solo cambian las filas i y j
23 a([i j],:)=Rot*a([i j],:);
24 q([i j],:)=Rot*q([i j],:);
25 end
Bo
26 end
27 end
28 q=q’;
29 r=a;
30 return

Ejercicio 9.15 Adapta el método para trabajar con matrices rectangulares.

Ejercicio 9.16 Compara el tiempo de cálculo requerido al utilizar matrices de Householder


rra
y de Givens, con matrices llenas y matrices tridiagonales.
(Ayuda: Recuerda los comandos tic y toc.)

Factorización QR con Matlab


En Matlab podemos obtener una factorización QR mediante el comando qr. Por ejem-
plo,

>> a=rand(4);
>> [q,r]=qr(a)

q =
do
-0.3685 0.7147 -0.2407 -0.5436
-0.7715 -0.4099 0.4388 -0.2102
-0.3858 -0.2967 -0.8391 0.2429
-0.3466 0.4829 0.2131 0.7754

r =

-1.2078 -1.0282 -0.7184 -1.1168


0 0.6539 0.5720 0.3849
0 0 -0.6839 -0.4834
r
0 0 0 -0.0530

La matriz a no tiene por qué ser cuadrada:

>> a=rand(3,2);
>> [q2,r2]=qr(a)

190
LECCIÓN IV Capı́tulo 9. Cálculo numérico de valores y vectores propios.

q2 =

-0.6815 0.6346 -0.3644


-0.6680 -0.7428 -0.0444
-0.2989 0.2132 0.9302
Bo
r2 =

-1.3726 -0.7532
0 0.5993
0 0

Comentarios sobre la descomposición QR


Si A es m × n, y Q, R es la descomposición dada por Householder o Givens11 , tomando
(con notación de Matlab)

Q1 = Q(:, 1 : m), R1 = R(1 : m, :),


rra
entonces R1 es cuadrada, Q1 tiene las columnas ortonormales y A = Q1 R1 .
La factorización QR se puede utilizar para resolver sistemas lineales compatibles inde-
terminados mediante la aproximación por mı́nimos cuadrados. Especı́ficamente, se trata
de asignar como solución de Ax = b la dada por

A> Ax = A> b.

Este sistema de ecuaciones recibe el nombre de ecuaciones normales. Se prueba en-


tonces que, bajo la hipótesis de que las columnas de A sean linealmente independientes,
la solución anterior cumple

kb − Axk2 < kb − Azk2 , ∀z ∈ Rn .


do
Esto es, minimiza el residuo. En la práctica no se construyen las ecuaciones normales,
sino que utilizando la descomposición QR, el problema se reduce a

R1> Q> Q R x = R1> Q>


1 b, ⇔ R1> R1 x = R1> Q>
1 b, ⇔ R1 x = Q>
1 b.
| 1{z }1 1
I
Recuerda que R1 es triangular y que por tanto, la resolución del último sistema es trivial.
En particular este método puede aplicarse a un sistema compatible determinado y
resolver ası́ sistemas de ecuaciones lineales. El método resultante es más caro que el
método de Gauss, ya que realiza el doble número de operaciones, pero tiene una ventaja
r
muy importante: es estable numéricamente y no hace falta realizar ninguna estrategia de
pivotaje12 .
11
Ya hemos indicado en los Ejercicios 9.12 y 9.15 que estos métodos pueden aplicarse a matrices
rectangulares generales.
12
La razón de esta estabilidad se puede vislumbrar intuitivamente: como Q es ortogonal, todas las
entradas están entre 0 y 1.

191
9.5 Método QR de Francis LECCIÓN IV

Otra aplicación de la factorización QR es el cálculo del rango de una matriz. Concre-


tamente, el rango de A coincide con el número de filas de R distintas de cero. Asumiendo
que estamos trabajando con un rango numérico, examinaremos cuántas filas son clara-
mente distintas de cero. Esto merece un comentario: casi cualquier perturbación de una
matriz que no tenga rango máximo da una matriz que si lo tiene. Por esto, numérica-
mente, las matrices tienen (casi) siempre rango máximo. Sin embargo, el hecho de estar
Bo
muy cerca de una matriz que no tenga rango máximo tiene consecuencia perniciosas en
muchas aplicaciones numéricas.

Ejercicio 9.17 Implementa la resolución de sistemas lineales por mı́nimos cuadrados.

Ejercicio 9.18 Introduce la siguiente matriz en Matlab


 
11 13
A=
22π 26π

Calcula el determinante en Matlab y deduce cuál es su rango. Calcula la descomposición QR.


¿Qué rango le asignarı́as a A?.
rra
9.5.2. Método QR de Francis
Retomamos el método QR de Francis para matrices simétricas. El algoritmo es sim-
plemente el siguiente:

Método QR de Francis

A = A1 matriz inicial
for k=1:mmax
Descomponer Ak = Qk Rk
Calcular Ak+1 := Rk Qk
do
Dk+1 =diag(Ak+1 )
Xn−1 Xn n
X
(k+1) 2 (k+1)
if ( |aij | < eps |aii |2 )
j=1 i=j+1 i=1
return
end
end

El algoritmo finaliza cuando el tamaño de los elementos por debajo de la diagonal


r
principal es pequeño respecto de los elementos diagonales, es decir, cuando consideramos
que la matriz es prácticamente triangular.
Para matrices simétricas, que es el caso que de momento nos ocupa, el método converge
salvo en situaciones algo extrañas a una matriz diagonal con los valores propios. Un hecho
sorprendente es que además los valores propios aparecen ordenados en la diagonal de
mayor a menor módulo.

192
LECCIÓN IV Capı́tulo 9. Cálculo numérico de valores y vectores propios.

Ejercicio 9.19 ¿Qué modificación harı́as del algoritmo anterior para que también devolviera
los vectores propios?.

Ejercicio 9.20 Implementa el algoritmo QR de Francis utilizando cualquiera de las descom-


posiciones QR vistas.
Ayuda: ¿Qué calculamos mediante las órdenes tril(a,-1) y norm(a,’fro’)?
Bo
Si A no es simétrica pero es diagonalizable, el método converge, también bajo condi-
ciones muy generales a una matriz quasitriangular, es decir, a una matriz de la forma
 
D1 . . . . . . . . . . . .
 D2 . . . . . . . . 
T = , donde Dj es 1 × 1 o 2 × 2.
 
 . .. ..  . 
Dm

Los valores propios de A son exactamente los valores propios de estos bloques 2 × 2.
De hecho cada par de valores propios complejos conjugados genera un bloque Dj de
orden 2. En particular, si la matriz tiene únicamente valores propios reales, la matriz T
rra
es triangular. Si trabajamos con aritmética compleja entonces la matriz T es triangular
superior. Éste es el conocido Teorema de Schur.

Ejercicio 9.21 Adapta el método QR a matrices no simétricas. Observa que deberás cambiar
el criterio de parada.

Ejercicio 9.22 Aplica el método QR a distintas matrices (simétricas, no simétricas, con


todos los valores propios reales o con alguno complejo) para observar cómo es la matriz lı́mite
resultante en cada caso.

Nota. La descomposición de Schur, tanto real como compleja, se puede calcular en


Matlab con schur. 
do
9.5.3. Comentarios adicionales
Técnicas de aceleración
Una matriz es de Hessenberg si tiene la forma
 
∗ ... ... ∗
.. 
 ∗ . 

 . 
H=  0 ..
,

 . . .. 
 .. . . . . .
r
. 
0 ... 0 ∗ ∗

es decir, si todos los elementos por debajo de la subdiagonal principal son nulos.
Toda matriz se puede llevar a forma de Hessemberg mediante producto a izquierda y
derecha por matrices ortogonales. Si además la matriz original es simétrica, la matriz de
Hessenberg correspondiente es de hecho tridiagonal simétrica.

193
9.5 Método QR de Francis LECCIÓN IV

Trabajar sobre una matriz de Hessemberg tiene importantes ventajas. En primer lugar,
la factorización QR es mucho más económica: si utilizamos matrices de Givens únicamente
debemos preocuparnos de cancelar los elementos situados en la subdiagonal inferior. Es
más, si H es Hessemberg (respectivamente tridiagonal simétrica), y H = QR, entonces la
matriz RQ es de nuevo de Hessemberg (respectivamente tridiagonal simétrica). En el caso
de matrices tridiagonales hay claramente una reducción en las necesidades de memoria
Bo
del método pues sólo requerimos guardar tres diagonales de la matriz durante todo el
proceso.
El método QR no se programa en la práctica tal como lo hemos presentado. Se recurre
a dos tipos de estrategias que aceleran enormemente la velocidad de convergencia. La
primera es la traslación. Utilizando la notación de la Sección 9.5.2, se tratarı́a de en
lugar de factorizar la matriz Am , descomponer

Am − αm I = Qm Rm ,

para posteriormente definir


Am+1 := αm I + Rm Qm .
rra
Es trivial comprobar que Am y Am+1 son semejantes, por lo que tendrán los mismos
valores propios. Una elección adecuada de αm consigue acelerar la convergencia en zonas
determinadas de la matriz. Por ejemplo, si A simétrica se puede conseguir que en pocas
iteraciones  
 Bn−1 0 
Am →  .
0 λn
En este caso, λn es un valor propio, se guarda en memoria y se empieza a trabajar con Bn−1
que es de orden n − 1. Este tipo de técnica se denomina deflacción. Existen algoritmos
que permiten seguir la pista a los vectores propios, relacionando los vectores propios de
Am con los de Bn−1 .
do
Apéndice: reducción a la forma de Hessenberg
Disponemos ya de las herramientas necesarias para implementar la reducción a forma
de Hessenberg de una matriz. Para ello, consideremos la siguiente partición de A

b>
 
α
A= ,
c A1
r
donde b y c son vectores columna de n − 1 componentes y A1 es (n − 1) × (n − 1).
Tomemos H1 una matriz de Householder n − 1 × n − 1, que especificaremos más adelante,
y construyamos
 
1 0
H :=  .
0 H1

194
LECCIÓN IV Capı́tulo 9. Cálculo numérico de valores y vectores propios.

Entonces
b> H 1
 
β
HAH =  .
H1 c H 1 A1 H 1

Si H1 se toma ahora de forma que H1 c = αe1 , se consigue cancelar todos los elementos
de la primera columna situados por debajo de la subdiagonal inferior. Es más, si A es
Bo
simétrica, b = c y por tanto en la primera fila de HAH sólo los dos primeros elementos
son no nulos.
A continuación se procede a trabajar con la matriz H1 A1 H1 de forma similar a como
se hizo en la Sección 9.5.1.

Nota. En Matlab la función hess reduce una matriz a forma de Hessenberg. Puede
utilizarse de las siguientes maneras:

>>H=hess(A); %H es una matriz de Hessenberg semejante a A


>>[P,H] = hess(A); %Ademas P ortogonal tal que A = P*H*P’


rra
9.6. Valores y vectores propios en Matlab
Para determinar todos los valores y vectores propios de una matriz podemos utilizar
el comando eig. Esta función es de hecho una compilación de funciones que se aplican
dependiendo de la forma de la matriz. Este comando también sirve para resolver el prob-
lema de valores propios generalizados: dadas dos matrices cuadradas A y B encontrar
escalares λ y vectores v 6= 0 tales que

Av = λBv.

En ocasiones requerimos unos pocos valores propios. El comando eigs, proporciona


do
los valores propios más relevantes, siendo el propio usuario el que especifique si éstos son
los mayores o menores en valor absoluto, los de mayor o menor parte real,etc. La ayuda
de Matlab es bastante extensa y desde aquı́ animamos a su consulta. Como detalle curioso
este comando se puede llamar de forma que uno de los argumentos sea una función que
devuelva el producto por la matriz. Es decir, sólo necesita saber multiplicar por la matriz
y por tanto no es necesario disponer de ella13 . El uso de este comando es indispensable
en matrices sparse no simétricas dado que, aún reduciéndola a forma de Hessenberg, las
necesidades de memoria son gigantescas14 . Para este tipo de problemas se utilizan otros
tipos de métodos no relacionados con QR.
Asociado al cálculo de valores propios, se encuentra el cálculo de los valores singulares,
r
esto es, buscar P y Q ortogonales de forma que

P > AQ = D,
13
Puede resultar extraño, pero en muchas aplicaciones prácticas es más fácil hallar el producto de un
vector por la matriz que construirla explı́citamente.
14
La descomposición QR destroza la estructura sparse de una matriz.

195
9.7 Notas históricas LECCIÓN IV

donde D es una matriz diagonal con elementos no negativos. Las entradas de D son los
valores singulares, mientras que las columnas de P y Q contienen los vectores singulares
asociados. Esta descomposición existe aún cuando A es rectangular. El comando que cal-
cula esta descomposición en Matlab es svd. El algoritmo más utilizado para este problema
es una variante del método QR conocido como Algoritmo de Golub-Kaham.
Bo
9.7. Notas históricas15
El problema del cálculo numérico de los valores propios de una matriz puede remon-
tarse a los trabajos de Carl Jacobi quien utilizó el método del mismo nombre en 1846.
No existe un origen claro del método de potencias, sino que parece haber surgido
de forma simultánea en diversos ambientes. El método de la potencia desplazada fue
introducido por Helmut Wielandt en 1944, quien sugirió también algunas técnicas de
deflacción para, combinadas con el método de potencias, obtener varios valores propios
de la matriz.
En 1958, Heinz Rutishause propuso un precursor del método QR, el método LU. El
método descomponı́a la matriz en la forma LU , para posteriormente construir U L. Se
rra
trataba de aplicar de forma simultánea el método de potencias y para evitar que to-
das las direcciones degeneran hacia la dirección dominante, se hacı́a una descomposición
LU que aseguraba la independencia de los vectores. Desgraciadamente, el método era
inestable numéricamente salvo para algunos casos particulares. J. G. F. Francis y V. N.
Kublanovskaya propusieron independientemente en 1961 reemplazar la descomposición
LU por la QR dando origen al método que hemos visto. El trabajo de Francis era más
completo y sugerı́a ya de hecho la reducción a forma de Hessenberg, la deflación y estrate-
gias de desplazamiento.
El cálculo estable de la descomposición QR tuvo que esperar a los años 1950, cuando
Wallace Givens y Alstom S. Householder propusieron sus métodos en 1954 y 1958 re-
spectivamente. Householder también en 1958 y Wilkinson en 1960 estudiaron los aspectos
numéricos de la reducción de una matriz a su forma de Hessenberg.
do
9.8. Google16
Google17 ha pasado a ser en su corta vida uno de los referentes mundiales de Internet.
Su sistema de búsqueda de páginas en la red ofrece en general unos resultados bastante
precisos. Una de las claves de su sistema es su método de evaluación de las páginas,
denominado Pageranktm . Este sistema evalúa las páginas web según el número de enlaces
que permiten llegar a ella.
r
15
Las fuentes de esta sección se han obtenido principalmente del artı́culo Eigenvalue computation in
the 20th Century (Gene H. Golub y Henk A. van der Vorst, publicado en Journal of Computational and
Applied Mathematics 123 y Matrix Algorithms Volume II: Eigensystems, de G.W. Stewart.
16
Este capı́tulo se ha extraı́do esencialmente del libro Numerical Computing de Cleve Moler, disponible
en http://www.mathworks.com/moler/
17
Por si algún despistado todavı́a no conoce su dirección electrónica, visı́tese http://www.google.es,
http://www.google.com y muchos más...

196
LECCIÓN IV Capı́tulo 9. Cálculo numérico de valores y vectores propios.
Bo
Figura 9.2: Una web muy sencilla.

Concretamente, la cuestión sobre la que se basa este sistema de evaluación es la que


sigue:
Si una persona navega de forma continuada durante un largo periodo de tiempo,
¿cúal es la probabilidad de que llegue a una página web determinada?
Esta probabilidad es la que se utiliza para evaluar las páginas. A priori hay dos formas
rra
de llegar a una página:

i) a través de un enlace desde otra página (probabilidad p),

ii) directamente (probabilidad (1 − p)).

Un valor habitual es p = 0.85.


En la figura 9.2 vemos un (muy) simple ejemplo de una web representada como un
grafo dirigido. Una flecha de i a j indica que la página i tiene un enlace (un link) a la
página j.
En este ejemplo n = 6 es el número de páginas que cuenta con 9 enlaces. Este grafo
se puede representar matemáticamente mediante la matriz 6 × 6
do
 
0 0 1 0 0 0
 1 0 0 1 1 0 
 
 0 1 0 0 0 0 
G = (gij ) = 
 0 0 1 0 0 0 

 
 0 0 0 1 0 1 
0 0 0 1 0 0

donde
gij = 1, si llegamos a i desde j.
De forma natural G es sparse, puesto que con n páginas uno puede esperar que el número
r
de enlaces sea del orden de O(n) (esto es, proporcional al número de páginas) y no del
orden O(n2 ) que se corresponderı́a con una matriz llena.
Sea
n
X
cj = gij (número de enlaces que salen de j).
i=1

197
9.8 Google LECCIÓN IV

Entonces la probabilidad de llegar a i si estamos en j es

gij 1−p
p +
cj n }
| {z
|{z}
Siguiendo un enlace desde j Tecleando la dirección
Bo
Esta información se puede recoger en la matriz A de tamaño n × n cuyas componentes
vienen dadas por
gij 1 − p
aij = p + .
cj n
Esta matriz no es sparse, pero se puede escribir

e + 1 − p en e>
pG n
n
donde geij = gij /cj y en es la matriz columna 1 × n
 >
en = 1 1 ··· 1 .
rra
De esta forma se puede almacenar la matriz A sin necesidad de requerir grandes cantidades
de memoria. Es más, el producto por cualquier vector se puede calcular con

e + 1 − p en e> x = p G
Ax = p Gx x./c +
1−p
(en · x) en .
n
n |{z} n | {z }
Div. elem. a elem. Prod. escalar

(0)
Si denotamos por xj la probabilidad de estar en la página web j en un instante inicial,
entonces la probabilidad de llegar a la página web i en el paso primero es
n
X (0) (1)
aij xj =: xi
do
j=1

y por tanto  
(1)    (0) 
x1 a11 a12 · · · a1n x1
(1)  (0)
x2   a21 a22 · · · a2n   x2
    
=  = Ax0 .
 
··· ..................  ···
 
  
(1)
xn an1 an2 · · · ann (0)
xn
De esta forma, denotando por
(m) (m) >
xm = (x1 , x2 , . . . , x(m)
r
n )

a las probabilidades de estar en una página web determinada en el paso m, obtenemos la


relación
xm+1 = Axm .
La idea es hacer evolucionar el sistema hasta que se estabilice.

198
LECCIÓN IV Capı́tulo 9. Cálculo numérico de valores y vectores propios.

Proposición 9.5 Existe un único x de componentes no negativas tal que


n
X
>
x = Ax, x en = xi = 1.
i=1

Además, comenzando con x0 cuyas componentes sean positivas y sumen uno,


Bo
x = lı́m xm .
m

El resultado dice, en palabras llanas, que la probabilidad de que estemos en una página
web (esto es, x), después de navegar una cantidad suficiente de tiempo18 es independiente
de cómo hemos empezado (es decir, de x0 ). Matemáticamente hablando, dice que existe
un único vector propio asociado al valor propio 1 de componentes positivas con kxk1 = 1
y que además la sucesión xm converge a x independientemente del vector inicial escogido.
Observa que la sucesión de vectores xm son el resultado de aplicar el método de potencias
a la matriz A (sin normalizar respecto de k · k2 ) y que por su forma particular19 siempre
que se parta de un vector inicial cumpliendo los requisitos de la proposición tendremos
que xm ≥ 0 y kxm k1 = 1.
rra
Aquı́ vemos una forma completamente directa de programar este cálculo

01 % PAGERANK(G)
02 %
03 % PAGERANK(G) Calcula el indice de impacto de una WEB dada
04 % por el grafo G
05 % El grafo tiene que ser conexo, es decir, no puede haber nodos
06 % separados del resto
07
08 function y=pagerank(g)
09
10 p=0.85; % probabilidad de llegar a traves de un enlace
do
11 eps=0.0001; % criterio de parada
12 nmax=1000; % numero maximo de iteraciones
13 n=length(g);
14 x=1/n*ones(n,1); % vector inicial
15 for j=1:nmax
16 y=producto(g,x,p);
17 if norm(x-y)<eps
18 disp(’convergencia’)
19 return
20 end
r
21 x=y;
22 x=x/sum(x);
23 end
18
Ciertamente, podrı́amos tener que dedicar muchas horas...
19
La matriz A cumple que todas sus entradas son positivas y que la suma de los elementos de cada fila
es 1. Una matriz de esta forma se denomina matriz de Markov. Teóricamente se sabe que el valor propio
dominante de estas matrices es siempre 1.

199
9.8 Google LECCIÓN IV

24 disp(’Convergencia no alcanzada’)
25 return
26
27 % Y= PRODUCTO(G,X,P)
28 % calcula el producto a*x
29 % notese que la matriz no llega a construirse
Bo
30
31 function y=producto(g,x,p)
32 c=sum(g);
33 c=c(:);
34 x=x(:);
35 n=length(x);
36 en=ones(n,1);
37 y=p*g*(x./c)+(1-p)/n*en*(en’*x);
38 return

Nota. Aplicando la función pagerank al ejemplo de la Figura 9.2, obtenemos este re-
sultado
rra
x = [0.1370 0.2806 0.2636 0.1370 0.1181 0.0638]>
Por orden de preferencia nos encontramos los nodos
2, 3, 1 y 4, 5, 6.
A pesar de que el nodo 3 sólo se enlaza a través del 2, la importancia de este nodo influye
en su buena puntuación.
En problemas reales, las matrices son enormes, en Febrero de 2006 google habı́a cat-
alogado 9.680.000.000 páginas20 . Después de la evaluación hay que hacer un filtrado de
acuerdo a las palabras clave con las que se hace la búsqueda.
Es posible hacer subir la evaluación de una página mediante la creación de páginas web
que se enlacen entre ellas y especialmente sobre una. Este tipo de técnicas, denominada
google bombing ha sido utilizado reiteradas veces por objetivos de diversa naturaleza,
do
económicos, polı́ticos, de protesta.... Los algoritmos del buscador tratan de detectar este
tipo de trampas y reconstruir la evaluación para que sea más imparcial. 

Nota histórica
Google fue fundado en 1995 por Sergey Brin y y Larry Page, el primero ingeniero
eléctrico y el segundo licenciado en matemáticas y que contaban entonces con 23 y 24
años. El nombre proviene del número 10100 que, aunque no oficialmente, se llama Googol21
El ambiente desenfadado y el origen matemático del buscador tuvo un curioso reflejo
en la primera oferta pública de acciones que tuvo lugar a principios del 2004. Brin y Page
r
sacaron al mercado una participación de la compañı́a cuyo valor era 2.718.281.828$, el
número e con 10 cifras decimales22 .
20
Basta hacer la búsqueda de una palabra inexistente precedida de un “-” para obtener el número de
páginas catalogadas.
21
Ası́ lo denomino el matemático Edward Kasner. En inglés existe la palabra goggles que son unas gafas
de natación (?).
22
Muy pocos se dieron cuenta de este “guiño”. Se hizo de nuevo palpable la escasa cultura cientı́fica

200
LECCIÓN IV Capı́tulo 9. Cálculo numérico de valores y vectores propios.
Bo
rra
do
r
en general y matemática en particular del mundo periodı́stico.

201
9.8 Google LECCIÓN IV
Bo
rra
do
r
202
Bo
Lección V
rra
Salidas gráficas en Matlab. Interpolación
do
r
203
r
do
rra
Bo
Introducción
Bo
...but it had no pictures or conversations in it,
“and what is the use of a book,” thought Alice
“without pictures or conversation?”

Lewis Carroll, Alice in Wonderland


Trataremos en este proyecto uno de los aspectos más potentes de Matlab: las salidas
gráficas. Ciertamente exponer con cierto detalle todo lo relacionado con este campo es
una tarea ardua y extensa. Sin embargo, y éste es nuestro objetivo, sı́ es asumible alcanzar
rra
un conocimiento base de forma que sea el usuario quien, con la ayuda de Matlab o con
manuales especı́ficos, profundice en los aspectos puntuales que necesite.
En la segunda parte estudiaremos el problema de la interpolación polinómica como
una buena piedra de toque para testar las salidas gráficas. Como aspectos relacionados
hablaremos someramente de la interpolación por splines y las curvas Bézier, que nos
ofrecen un ejemplo muy sencillo de las Matemáticas aplicadas al diseño gráfico.
do
r
205
r
do
rra
Bo
Capı́tulo 10
Bo
Matlab: Salidas gráficas en Matlab

10.1. Dibujos bidimensionales


10.1.1. El comando plot
Ya hemos observado que los comandos de Matlab cuentan con varios niveles de manip-
rra
ulación. Los niveles iniciales son básicos y por tanto fáciles de utilizar. El acceso a niveles
finos exige trabajar con argumentos nuevos, más instrucciones y el manejo de una sintaxis
más complicada.
Esta caracterı́stica se destaca más, si cabe, en los comandos relacionados con las salidas
gráficas. Es por ello que, empezando por la instrucción plot, recorreremos los diferentes
niveles de forma gradual. No trataremos el nivel superior, que conlleva un control absoluto
del dibujo, dado que requerirı́a una exposición demasiada larga. Lo que aquı́ expondremos
es suficiente en un 99 % de los casos, y en última medida, se puede acceder a todos los
aspectos de un dibujo desde la ventana gráfica a golpe de ratón.

Primer nivel
El primer comando que trataremos es plot. Es una instrucción muy versátil y la más
do
indicada para dibujar gráficas de funciones y curvas en el plano. Su sintaxis básica es
>> plot(x,y)
que dibuja el vector y versus el vector x. Más en concreto une los puntos (x(i), y(i))
mediante segmentos. Tomando un número suficientemente elevado de puntos trazamos
con ello una gráfica suave, sin esquinas visibles.
Al ejecutar este comando se abre una ventana, figure en el vocabulario de Matlab,
donde se traza la correspondiente figura.
Si y es real, plot(y) toma x=1:n donde n es la longitud de y. Si, por otro lado, y es
un vector de números complejos, dibuja la parte imaginaria versus la parte real. Es decir,
r
es equivalente a plot(real(y),imag(y)).
Ejercicio 10.1 ¿Qué hacen las siguientes lı́neas de código?
>> clear i
>> t=linspace(0,2*pi,9);
>> plot(exp(i*t));

207
10.1 Dibujos bidimensionales LECCIÓN V
Bo
rra
Figura 10.1: Ventana gráfica.

¿Te parece natural? ¿Qué observas con la escala? ¿Qué sucede si se ejecuta axis equal?.
¿Como dibujarı́as una circunferencia?.

Segundo nivel
El comando además acepta una serie de argumentos que, entre otras cosas, permiten
do
controlar el color, el tipo de marcas sobre los puntos (x(i), y(i)) y el formato de las
lı́neas que los unen. Ası́, en su aspecto más general,

plot(x,y,S)

dibuja y versus x, con S una cadena de caracteres que se construye con1

b azul . punto - linea ’solida’


g verde o circulo : punteado
r rojo x equis -. punto-linea
c cian + cruz -- linea-linea
r
m magenta * estrella
y amarillo s cuadrado
k negro d diamante
v triangulo (hacia abajo)
^ triangulo (arriba)
1
Traducido directamente de la ayuda de Matlab.

208
LECCIÓN V Capı́tulo 10. Matlab: Salidas gráficas en Matlab

< triangulo (izquierda)


> triangulo (derecha)
p estrella pentagonal
h estrella hexagonal

La primera columna especifica el color utilizado, la segunda la marca sobre cada punto y
Bo
la tercera el patrón que siguen las lı́neas utilizadas para unir los puntos.
Por ejemplo el siguiente fichero script

x=linspace(0,4,100);
y=exp(-x).*cos(2*pi*x);
figure(1); plot(x,y,’.’)
figure(2); plot(x,y,’r-.’)
figure(3); plot(x,y,’sm--’)
figure(4); plot(x,y,’hg’)
figure(5); plot(x,y,’kv:’)

genera (tras el reordenamiento manual de las ventanas) la pantalla mostrada en la Figura


rra
10.2.
El comando figure abre una ventana gráfica asignándole un número. Si la ventana
ya está abierta, la coloca como la ventana de salida por defecto. En particular, figure
permite manejarse con varias ventanas de forma simultánea.
Para superponer varios dibujos sobre una misma ventana podemos

Utilizar plot de la siguiente forma2

>> plot(x1,y1,x2,y2,x3,y3,x4,y4)

mediante el cual dibujaremos y1 vs. x1, y2 vs. x2, etc., o si queremos dar un formato
personalizado a cada dibujo podemos usar
do
>> plot(x1,y1,’r-’,x2,y2,’b:’,x3,y3,’m-.’,x4,y4,’k--’)

Utilizar la instrucción hold on que activa la superposición en pantalla. Por ejemplo,

>> hold on %activamos superposicion


>> plot(x1,y1,’r-’)
>> plot(x2,y2,’r:’)
>> plot(x3,y3,’m.-’)
r
>> plot(x4,y4,’k--’)

Esta opción es más versátil dado que permite superponer gráficas construidas con
diferentes comandos. La superposición se desconecta con hold off, de forma que
un nuevo dibujo borrará los anteriores.
2
Se asignan distintos colores a cada una de las gráficas de forma automática.

209
10.1 Dibujos bidimensionales LECCIÓN V
Bo
rra
Figura 10.2: Ventana gráfica.

Tercer nivel
Ya en un tercer nivel, se pueden acceder a detalles concretos del dibujo, como el tamaño
y color de las marcas, la anchura de la lı́nea, etc. Las diferentes opciones llevan nombres
nemotécnicos que facilitan su memorización3 . Destacamos entre las más importantes
do
color: color de la lı́nea.

LineWidth: anchura de la lı́nea.

Marker: selecciona la marca que se coloca en los puntos evaluados

MarkerEdgeColor: color del borde de las marcas

MarkerFaceColor: color de la marca


r
MarkerSize: tamaño de la marca

Para especificar un color, se puede utilizar uno de estos caracteres {b, g, r, c, m, y, k} o


bien un vector con tres componentes con valores entre 0 y 1 que especifica un color según
3
nemotécnicos en inglés, of course.

210
LECCIÓN V Capı́tulo 10. Matlab: Salidas gráficas en Matlab

el estándar RGB4 .
Por ejemplo

>>x=0.01:0.2:2; y=sin(x)./x;
>>plot(x,y,’o-.’,’color’,[0.2 0.4 0.6],’linewidth’,2,...
’markeredgecolor’,’k’,’markerfacecolor’,[0.9 0.6 0.4],...
Bo
’markersize’,9)

Ejercicio 10.2 Dibuja las funciones seno y coseno en [−2π, 2π], la primera en rojo y la
segunda en azul. El ancho de lı́nea debe ser de dos puntos y deben seguir dos estilos diferentes,
a tu elección.
Puedes empaquetar las instrucciones en un fichero script. Será más cómodo para editar y
cambiar lo que desees.

La ventana gráfica

Las propiedades anteriores se pueden editar directamente en la ventana gráfica. Para


rra
ello, hay que seleccionar edit plot (véase la Figura 10.3) y pulsar sobre la gráfica con
un doble click. Se desplegará una ventana adicional con varias pestañas que informan y
permiten modificar las diferentes caracterı́sticas del objeto. Si se procede igual sobre el
fondo de la pantalla controlaremos más aspectos del propio entorno, como la escala, el ratio
entre el eje OX y OY, las marcas sobre los ejes..., aspectos que trataremos seguidamente.
No entraremos a explicar estos detalles en profundidad. Éste es un buen ejemplo
donde la prueba, la experimentación y el ensayo–error permiten aprender mejor y más
rápidamente que cualquier manual que podamos redactar.
La ventaja principal de trabajar a través de comandos es que podemos dotar de un as-
pecto determinado a nuestros dibujos sin necesidad de retocarlos en cada paso y para cada
ejemplo. Esto es especialmente importante si necesitamos un número elevado de gráficas
o bien necesitamos rehacerlas constantemente. En contrapartida deberemos manejar una
do
mayor galerı́a de instrucciones.

Ejercicio 10.3 Ejecuta

>> t=linspace(-2*pi, 2*pi,200);


>> y1=cos(t);
>> y2=sin(t);
>> plot(t,y1,t,y2)

Desde la ventana gráfica modifica su aspecto para que tenga el que le habı́as dado en el
r
Ejercicio 10.2.

4
Red, Green, Blue. Crea un color añadiendo partes de rojo, verde y azul (de 0 a 1) especificado por
un vector de tres componentes.

211
10.1 Dibujos bidimensionales LECCIÓN V
Bo
rra
do
r
Figura 10.3: Edición de un dibujo.

212
LECCIÓN V Capı́tulo 10. Matlab: Salidas gráficas en Matlab

10.1.2. Comandos asociados a plot


Hay una serie de comandos que controlan el entorno donde se despliega la gráfica.
Entre los más elementales (o al menos, más fáciles de utilizar), podemos destacar:

clf: borra la ventana actual (figure) de gráficos.


Bo
cla: borra el axes actual. El axes es la parte de la ventana utilizada para
dibujar. Una ventana puede contener varios axes (véase el comando
subplot tratado más adelante).

hold: hold on permite que sucesivas gráficas se vayan solapando; hold off
desconecta esta opción (es la que está por defecto).

axis: un comando algo complejo. Puede controlar entre otros detalles el ratio
entre los ejes OX y OY, la parte del dibujo que se muestra por pantalla,
las coordenadas utilizadas, el ajuste del marco al dibujo...

xlim, ylim: especifican los lı́mites del dibujo. Se puedn utilizar para centrar el
rra
dibujo.

grid: grid on muestra una malla en pantalla; grid off la desconecta.

legend: despliega una leyenda, esto es, un cuadro explicativo sobre las gráficas
presentes.

text: añade un texto en las coordenadas especificadas.

xlabel, ylabel: añade tı́tulos (etiquetas) a los ejes OX y OY.

title: coloca un tı́tulo en la cabecera del dibujo.

whitebg: asigna un color al fondo del dibujo.


do
A modo de ejemplo, el siguiente conjunto de instrucciones (empaquetado en un fichero
script) despliega las gráficas mostradas en la Figura 10.4

figure(1) % desplegamos ventana 1


clf % borramos todo
x=linspace(0,5,100);
f=inline(’exp(-n*x).*cos(x)’,’n’,’x’); % funciones vectorizadas
hold on % solapamiento de graficas
y=f(1/3,x);
r
plot(x,y,’k--’,’linewidth’,2)
y=f(1,x);
plot(x,y,’r-.’,’linewidth’,2)
y=f(3,x);
plot(x,y,’:’,’color’,[0.0,0.0,0.5],’linewidth’,2)
y=f(9,x);

213
10.1 Dibujos bidimensionales LECCIÓN V

plot(x,y,’-’,’color’,[0.0,0.3,0.0],’linewidth’,2)
grid on % desplegamos la red
xlim([-0.5,6]), ylim([-0.25,0.5]) % rango de los graficos
xlabel(’Eje OX’,’fontname’, ’Comic Sans Ms’, ’fontsize’,12)
ylabel(’Eje OY’,’fontname’, ’Comic Sans Ms’, ’fontsize’,12)
title(’Algunas graficas de funciones’,...
Bo
’fontsize’,16,’fontname’,’Times new roman’)
legend(’exp(-x/3).*cos(x)’, ’exp(-x).*cos(x)’,...
’exp(-3x)*cos(x)’, ’exp(-9x).*cos(x)’);

Algunas graficas de funciones


0.5
exp(-x/3).*cos(x/3)
exp(-x).*cos(x)
exp(-3x)*cos(3x)
0.4 exp(-9x).*cos(9x)
rra
0.3

0.2
Eje OY

0.1

-0.1

-0.2

0 1 2 3 4 5 6
Eje OX
do
Figura 10.4: Una muestra de dibujos.

Nota. En el comando title hemos utilizado los atributos fontname y fontsize para
especificar la fuente y su tamaño utilizada en el tı́tulo. Otros atributos son

fontweight: los valores posibles son light, normal, demi, bold. Especifica el trazo
r
de los caracteres, desde fino (light) hasta negrita (bold).

fontangle: sus valores son normal, italic u oblique. Fija la inclinación de la fuente.

rotate: especifica el ángulo con el que se escribe el texto. El valor por defecto, 0, es
la escritura horizontal, mientras que con 90 se escribe el texto en vertical.

214
LECCIÓN V Capı́tulo 10. Matlab: Salidas gráficas en Matlab

Estos atributos están disponibles para cualquier comando que se ocupe de desplegar
textos en la pantalla gráfica. Por ejemplo, xlabel, ylabel, title,...
Quizás lo más difı́cil sea saber qué fuentes tenemos instaladas y su correspondiente
nombre. La solución más sencilla a esta cuestión es ir a la venta gráfica, y editar las
caracterı́sticas del dibujo5 . Allı́ podremos ver qué fuentes están a nuestra disposición y su
nombre correspondiente. 
Bo
Ejercicio 10.4 En este ejercicio trataremos de visualizar el efecto del comando axis con
diferentes opciones sobre el aspecto final de un dibujo.
Teclea
>> clf
>> x = 0:.025:pi/2; plot(x,tan(x),’-ro’)
La función tangente presenta una ası́ntota vertical6 en π/2. Teclea los siguientes comandos y
observa el aspecto final de la figura.
>> axis equal
>> axis image
rra
>> axis normal % vuelta al formato original
>> axis([0 pi/2 0 5]) % especificamos el rango de salida
>> axis tight
¿Podrı́as decir qué hace cada comando?.

10.1.3. Comandos get y set


Los comandos get y set permiten acceder y cambiar los atributos de cualquier gráfica.
Todo objeto gráfico, desde una simple curva hasta la propia ventana donde se despliega
el dibujo tiene asociado un puntero, un handle al que se encuentra enlazado. Los valores
de cada uno de los parámetros se pueden visualizar (get) y editar (set) desde la lı́nea de
comandos o desde una función.
do
Nos limitaremos de momento a dar unas ideas a grandes trazos para el comando plot.
Ejecuta
>> x=0:0.01:pi;
>> h=plot(x,x.*cos(4*x));
La variable h es un puntero que enlaza con el dibujo desplegado sobre la ventana. Ahora
se puede recabar información sobre éste:
>> get(h,’linestyle’)
r
ans =

-
5
Seleccionar editar dibujo, doble click sobre el fondo, seleccionar la pestaña style e ir al menú desple-
gable font name
6
Tiende a infinito.

215
10.1 Dibujos bidimensionales LECCIÓN V

>> get(h,’marker’)

ans =

none
Bo
>> get(h,’linewidth’)

ans =

0.5000
Las órdenes anteriores nos informan de que el dibujo se ha trazado con lı́nea continua, sin
ninguna marca y con anchura de lı́nea 0.5.
Con set podemos cambiar cualquiera de estos atributos
>> set(h,’linewidth’,2)
>> set(h,’color’,[0.5 0.6 0.2])
rra
>> set(h,’linestyle’,’-.’)
de forma que la gráfica pasa a tener una anchura de 2 puntos, cambia el color y el estilo
ahora es punto-raya.
Si se ejecuta get(h) podemos visualizar todos los atributos del objeto gráfico:
>> get(h)
Color = [0.5 0.6 0.2]
EraseMode = normal
LineStyle = -.
LineWidth = [2]
Marker = none
MarkerSize = [6]
do
MarkerEdgeColor = auto
MarkerFaceColor = none
XData = [ (1 by 315) double array]
YData = [ (1 by 315) double array]
ZData = []

BeingDeleted = off
ButtonDownFcn =
Children = []
Clipping = on
r
CreateFcn =
DeleteFcn =
BusyAction = queue
HandleVisibility = on
HitTest = on
Interruptible = on

216
LECCIÓN V Capı́tulo 10. Matlab: Salidas gráficas en Matlab

Parent = [101.001]
Selected = off
SelectionHighlight = on
Tag =
Type = line
UIContextMenu = []
Bo
UserData = []
Visible = on

De forma similar
h= legend(’x*cos(x)’);
devuelve en h, después de desplegar la leyenda correspondiente en el dibujo, una variable
que permite a continuación la manipulación de muchas de sus propiedades. Para ello se
utiliza la instrucción set
>> set(h,’fontsize’,11,’fontname’,’arial’,’fontangle’,...
rra
’oblique’,’color’,[0.8 0.8 0.8])
cambia alguno de los atributos de la leyenda, como la fuente y su tamaño, la inclinación
y el color de fondo.
Otro ejemplo lo da el siguiente código:
01 x=linspace(0,4,1000);
02 y=x.*log(x);
03 figure(1);
04 clf % borramos
05 plot(x,y,’--’,’linewidth’,3);
06 h2=gca; % accedemos al handle de la grafica
07 set(h2,’xtick’,[0 0.25 0.5 1 2 4],’fontsize’,16,’ygrid’,...
do
08 ’off’,’xgrid’,’on’,’linewidth’,2,’gridlinestyle’,’-.’)
09 title(’x*log(x)’,’fontangle’,’oblique’,’fontname’,...
10 ’Comic Sans ms ’,’fontweight’,’bold’,’fontsize’,20)
que accede a la estructura de la gráfica (gca), que esencialmente es el marco donde de-
splegamos los dibujos. Las lı́neas 07-08 edita los atributos xtick, que señala los puntos
donde se colocan las marcas en el eje OX, la fuente utilizada en el dibujo, activa la malla
únicamente en la dirección OX, especifica la anchura de la lı́nes y el patrón que sigue. El
resultado se puede ver en la Figura 10.5.
Todas las propiedades anteriores se pueden modificar más fácilmente en la ventana
gráfica. Su manejo es fácil e intuitivo (seleccionar, doble click, botón derecho del ratón....).
r
Con helpwin line y helpwin axes obtenemos la información de las diferentes op-
ciones para la instrucción plot (y similares) y para la figura.
Finalmente gca y gcf devuelven el puntero al axis y figure utilizado en ese momento
(get current axis y get current figure). Si quieres ver todos sus atributos, ejecuta
>> get(gca), get(gcf)

217
10.1 Dibujos bidimensionales LECCIÓN V

x log(x)
6

5
Bo
4

-1
0 0.25 0.5 1 2 4
rra
Figura 10.5: Modificación del entorno del dibujo.

Un ejemplo de caracterı́sticas más avanzadas


Es posible asignar a un objeto gráfico funciones que se ejecuten al realizar alguna
acción, como cuando se crean (útil especialmente si se redibuja constantemente) o cuando
se seleccione con el ratón.
Por ejemplo con
t=linspace(-6*pi,6*pi,200);
h=plot(t,sin(t)./t);
do
orden=’v=get(h,’’color’’); set(h,’’color’’,v([3 1 2]))’;
set(h,’ButtonDownFcn’,orden)
asignamos al dibujo la siguiente propiedad: cuando se pulse encima de él con el ratón, se
ejecutará la instrucción dada en orden:
>> v=get(h,’color’); set(h,’color’,v([3 1 2]))’;
La variable orden es simplemente una cadena de caracteres con esta instrucción. Observa
como se repite ’ precisamente para insertar este carácter y evitar ası́ la confusión con el
sı́mbolo fin de cadena de caracteres.
En última medida, estas caracterı́sticas enlazan con las interfaces gráficas de Mat-
r
lab (gui), donde los objetos gráficos pueden ser menús desplegables, campos de textos,
items,... Matlab dispone de una guı́a para el desarrollo de interfaces gráficos con su tu-
torial correspondiente. Aquı́ no entraremos en la descripción y uso de estas interfaces,
pero animamos al lector a consultar la correspondiente ayuda mediante helpwin guide.
Una vez dentro de la ayuda, aconsejamos seleccionar Go to online doc for guide y
allı́ acceder a Creating GUIs.

218
LECCIÓN V Capı́tulo 10. Matlab: Salidas gráficas en Matlab

10.1.4. El comando subplot


Este comando permite la visualización de diferentes subventanas gráficas (axes) en
una misma ventana. A modo de ejemplo,

subplot(231)
Bo
define en la figure seis zonas para volcar las salidas gráficas dispuestas en 2 × 3 (dos filas,
tres columnas) y accede a la primera de ellas. La numeración es la desplegada en la figura
10.6.

1 2 3
rra
4 5 6

Figura 10.6: Ejemplo de numeración con subplot.

Por ejemplo, las instrucciones

x=linspace(0,2*pi,150);
do
subplot(321)
plot(x,sin(x),’linewidth’,2);
title(’sin(x)’,’fontsize’,14)
axis tight
subplot(322)
plot(x,cos(x),’linewidth’,2);
title(’cos(x)’,’fontsize’,14)
axis tight
subplot(323)
plot(x,sin(2*x),’linewidth’,2);
r
title(’sin(2x)’,’fontsize’,14)
axis tight
subplot(324)
plot(x,cos(2*x),’linewidth’,2);
title(’cos(2x)’,’fontsize’,14)
axis tight

219
10.1 Dibujos bidimensionales LECCIÓN V

subplot(325)
plot(x,sin(4*x),’linewidth’,2);
title(’sin(4x)’,’fontsize’,14)
axis tight
subplot(326)
plot(x,cos(4*x),’linewidth’,2);
Bo
title(’cos(4x)’,’fontsize’,14)
axis tight

crean la Figura 10.7.

10.1.5. Otras salidas gráficas


Señalaremos a continuación otros comandos relacionados con dibujos y gráficas bidi-
mensionales de manejo similar a plot

plotyy: permite mostrar dos dibujos en la misma gráfica con dos ejes
OY a la izquierda y a la derecha.
rra
polar: curvas en polares.
semilogx, semilogy: similar a plot pero utilizando, respectivamente, una escala log-
arı́tmica en el eje OX y en el eje OY.
loglog: escala logarı́tmica en ambos ejes.
stem: dibuja puntos uniéndolos con una linea vertical al eje OX.
stairs: traza una gráfica en forma de escalera.
bar, barh, bar3: despliega gráficas en forma de barras. Muy apropiada para rep-
resentar datos y estadı́sticas (estilo excel).
area: muestra los datos en una gráfica de forma acumulada. El col-
do
or utilizado se controla mediante el comando colormap, cuyo
funcionamiento veremos más adelante.
line: une puntos mediante lı́neas. Es una instrucción de bajo niv-
el cuyo funcionamiento es similar a plot. De hecho, plot se
construye a partir de line.
fill: dibuja polı́gonos cerrados y colorea su interior.
patch: una instrucción también de bajo nivel, construye polı́gonos, o
caras en tres dimensiones y asigna un color a la cara definida.
r
Comandos fáciles de usar
Matlab tiene implementada una serie de comandos, asociados a la toolbox de cálculo
simbólico que vimos en la lección anterior, que permiten dibujar de forma sencilla gráficas
de funciones. No se tiene un control tan completo como con plot pero se compensa con
su fácil uso. En el apartado que nos ocupa (gráficas bidimensionales) son resaltables

220
LECCIÓN V Capı́tulo 10. Matlab: Salidas gráficas en Matlab

sin(x) cos(x)
1
0.5 0.5
0 0
-0.5 -0.5
Bo
0 2 4 6 0 2 4 6

sin(2x) cos(2x)
1
0.5 0.5
0 0
-0.5 -0.5

0 2 4 6 0 2 4 6

sin(4x) cos(4x)
1
0.5 0.5
0 0
rra
-0.5 -0.5

0 2 4 6 0 2 4 6

Figura 10.7: Disposición simultánea de gráficas con subplot.

ezplot ezpolar

La ayuda de Matlab es, en nuestra opinión, suficiente para hacernos con su manejo.

10.2. Gráficas en 3D
do
Comenzaremos con curvas en el espacio para pasar y tratar con mayor profundidad
las superficies en 3D. Hemos decidido incluir en este apartado las instrucciones relativas
a curvas de nivel aunque hablando propiamente son dibujos bidimensionales. Su origen y
su posterior interpretación nos conducen de nuevo al entorno espacial.

10.2.1. El comando plot3


Este comando sirve, grosso modo, para dibujar curvas en el espacio. Su manejo es muy
r
similar a plot, por lo que no nos detendremos demasiado en su explicación. Ésta es su
sintaxis

plot3(x,y,z,opciones)

Las opciones son esencialmente las mismas que aparecı́an en plot. He aquı́ un ejemplo
sencillo

221
10.2 Gráficas en 3D LECCIÓN V

clf
t=linspace(0,8*pi,200);
plot3(t.*cos(t),t.*sin(t),t,’r-’,’linewidth’,2)
grid on % dibujamos la ’malla’
title(’Una curva en espiral...’,’fontsize’,18,’fontname’,...
’Comic Sans MS’,’color’,[0.675 0.000 0.000])
Bo
zlim([0,20])
xlabel(’eje OX’,’fontsize’,14)
ylabel(’eje OY’,’fontsize’,14)
zlabel(’eje OZ’,’fontsize’,14)

cuyo resultado se muestra en la Figura 10.8. Los comandos relacionados con los aspectos

Una curva en espiral...


rra
30

25

20
eje OZ

15

10

0
30
20
30
10 20
0 10
-10 0
do
-10
-20 -20
-30 -30
eje OY eje OX

Figura 10.8: Un dibujo en 3D con plot3.

accesorios del dibujo (axes, title, xlabel, grid...) funcionan exactamente igual. Además
aparecen algunos nuevos cuya utilidad y manejo no deberı́a causar sorpresa:
r
zlabel zlim

Para poder manipular, rotar en 3D, el objeto gráfico basta presionar en la barra de
herramientas en el botón señalado en la Figura 10.9 y mover el ratón sobre el objeto con
el botón pulsado

222
LECCIÓN V Capı́tulo 10. Matlab: Salidas gráficas en Matlab
Bo
Figura 10.9: Icono para rotar los dibujos.

10.2.2. El comando surf


Primer nivel
El comando surf dibuja esencialmente superficies en el espacio. En su forma más
simple se puede identificar con el dibujo de funciones de dos variables en el espacio. En
este caso, el formato es
rra
surf(x,y,z)

donde x e y especifican una malla en el plano y z la altura correspondiente. El color que


se da a cada punto está asignado por defecto según la altura en el eje Z.
Queda pendiente, no obstante, cómo construir una malla. Aunque se puede hacer a
mano (Matlab ofrece en su ayuda información detallada de cómo hacerlo), es mejor utilizar
los comandos propios de Matlab, en este caso, meshgrid. Ası́, si queremos representar una
superficie z = f (x, y) en un dominio rectangular utilizando los puntos de coordenadas
x = (x1 , . . . , xn ) e y = (y1 , . . . , ym ), deberemos generar primero la malla formada por los
puntos (xi , yj ). En Matlab simplemente tenemos que utilizar la orden

[X,Y]=meshgrid(x,y)

que crea las matrices de tamaño m × n


do
   
x 1 . . . xn y 1 . . . y1
X =  ... ..  Y =  ... ..  .
 
.  . 
x 1 . . . xn y m . . . ym

Es decir, las m filas de X son copias del vector x y las n columnas de Y son copias del
vector y. La malla está formada por los puntos (X(i,j),Y(i,j)). Por ejemplo,

>> x=[0 0.33 0.67 1]; y=[-1 0 1];


>> [X,Y]=meshgrid(x,y)
r
X =

0 0.3300 0.6700 1.0000


0 0.3300 0.6700 1.0000
0 0.3300 0.6700 1.0000

223
10.2 Gráficas en 3D LECCIÓN V

Y =

-1 -1 -1 -1
0 0 0 0
1 1 1 1
Bo
Ahora para representar la superficie z = f (x, y) utilizamos la orden surf(X,Y,Z)
donde  
f (x1 , y1 ) . . . f (xn , y1 )
Z = f (X, Y) =  .. ..
.
 
. .
f (x1 , ym ) . . . f (xn , ym )
El dibujo de la Figura 10.10 se ha construido con el siguiente conjunto de instrucciones

>>x=linspace(-2,2,40); y=linspace(-1,1,20);
>>[X,Y]=meshgrid(x,y); Z=X.^2-Y.^2;
>>surf(X,Y,Z)
rra
do
Figura 10.10: Ejemplo de una superficie creada con surf.

Se puede dibujar la superficie y asignar un color según los valores de un cuarto vector
r
(matriz más bien). Desde una interpretación matemática, se tratarı́a de dibujar los valores
de una función sobre una superficie:

>> x=linspace(-3,3,60); y=linspace(-3,3,60);


>> [X,Y]=meshgrid(x,y); Z=X.^2-Y.^2; T=cos(sqrt(X.^2+Y.^2+Z.^2));
>> surf(X,Y,Z,T), colorbar

224
LECCIÓN V Capı́tulo 10. Matlab: Salidas gráficas en Matlab
Bo
Figura 10.11: Otro ejemplo de surf.
rra
despliega la gráfica de la Figura 10.11. El comando colorbar muestra la barra de colores
de la derecha que informa sobre el valor numérico que corresponde a cada color.
También es posible dibujar superficies definidas sobre partes de un rectángulo. Para
ello, cualquier punto cuya coordenada z sea un nan (not a number), no se dibuja. Por
ejemplo

>> x=linspace(-1,1,101); y=x;


>> [X,Y]=meshgrid(x,y);
>> Z=-X.^2-Y.^2;
>> Z(sqrt(X.^2+Y.^2)<0.5)=nan;
do
>> surf(X,Y,Z)

despliega la superficie de la Figura 10.12). La cuarta lı́nea merece un comentario aunque


instrucciones parecidas han sido tratadas ya en la Lección 1. Al hacer la comparación
sqrt(X.^2+Y.^2)<0.5, Matlab devuelve una matriz lógica, de 1s y 0s según el punto
correspondiente esté cerca del cero o no. La instrucción Z(sqrt(X.^2+Y.^2)<0.5)=NaN,

hace que los puntos situados dentro del cı́rculo de radio 1/ 2 (que es donde la expresión
lógica es 1), tomen como valor NaN. De todos modos se observa la deficiente aproximación
de los cuadrados, propios de surf, del cı́rculo interior. Al final de esta lección veremos
una forma más elaborada para trabajar con superficies definidas sobre conjuntos más
r
generales.

Comandos del entorno 3D

Nos limitaremos a hablar de cinco comandos que controlan las propiedades del entorno
3D, aunque éstos no son los únicos disponibles en Matlab:

225
10.2 Gráficas en 3D LECCIÓN V
Bo
rra
Figura 10.12: Utilización de nan en un dibujo.

colorbar: despliega una barra de colores que informa sobre la correspondencia


entre el valor numérico y el color utilizado. Por defecto se despliega
verticalmente a la derecha del dibujo, aunque puede mostrarse horizon-
talmente si ası́ se desea.
colormap: especifica qué colores se van a utilizar en el dibujo (mapa de colores).
Existe un conjunto de formatos predefinidos que listamos a continuación

autumn bone colorcube cool copper flag


gray hot hsv jet lines pink
do
prism spring summer white winter default

Para cambiar a un formato basta ejecutar

>> colormap(’bone’)

Se pueden también definir formatos personalizados, bien mediante la


lı́nea de comandos o desde la propia ventana gráfica.
daspect: controla la relación entre los ejes del dibujo. Baste decir que

daspect([1 1 1])
r
fija que las proporciones de los ejes OX, OY y OZ sean iguales. Es decir,

>> sphere(40); % dibuja una esfera


>> daspect([1 1 1]) % relaciones 1:1:1 en los ejes

muestra la esfera como tal y no como un elipsoide.

226
LECCIÓN V Capı́tulo 10. Matlab: Salidas gráficas en Matlab

pbaspect: similar al anterior pero relacionado con la caja que enmarca el dibujo.
view: especifica el punto desde el que se ve el dibujo. Tiene dos parámetros:

view(az,el)

El primero es el azimuth (ángulo de rotación horizontal) y el segundo


Bo
es el ángulo de elevación vertical. Ambos deben especificarse en grados.
Por defecto en dibujos tridimensionales az = −37.5 y el = 30.

El comando surf: segundo y tercer nivel


En un segundo nivel de utilización del comando anterior podemos acceder a algunas
opciones adicionales entre las que podrı́amos destacar:7

’EdgeAlpha’: se especifica un valor entre 0 y 1 que define la transparencia que


tiene la rejilla o red en el dibujo (con 0 la red es transparente
y por tanto no se ve).
’FaceAlpha’: como la opción anterior pero relativa a las caras.
rra
LineStyle: indica el formato de la rejilla: ’-’, ’--’, ’:’,.... Igual que en
plot. Con ’none’ desaparece del dibujo.

’MeshStyle’ tiene tres opciones posibles both (por defecto), row y column.
Especifica cómo despliega la red: entera, sólo las filas o sólo
columnas, respectivamente.
’EdgeColor’: toma cuatro posible valores: un color (en el formato habitual),
’none’, ’flat’, ’interp’. Especifica qué color utilizar en la
rejilla. Por defecto es negro, pero se puede eliminar la rejil-
la (’none’), se puede utilizar el color marcado por el primer
do
vértice (’flat’) o bien utilizar un color definido por los colores
de los dos vértices de cada eje (’interp’).
’FaceColor’: con los mismos valores que en la opción anterior. La opción
’interp’ fija un color interpolado sobre la cara, eliminan-
do ası́ el aspecto de mosaico que en ocasiones adoptan las
superficies.
’LineWidth’: anchura de las lı́neas utilizadas en el dibujo de la red.
’Marker’: indica qué marca colocar en cada punto del dibujo. Sigue el mis-
mo formato que plot (por defecto no coloca ninguna marca).
r
’MarkerEdgeColor’
’MarkerFaceColor’: igual que en plot.
’MarkerSize’

Por ejemplo, la Figura 10.13 se obtiene con


7
siempre a nuestro juicio...

227
10.2 Gráficas en 3D LECCIÓN V

f=inline(’x^2-y^2’); f=vectorize(f);
x0=linspace(-2,2,6);
y0=linspace(-2,2,4);
[X0,Y0]=meshgrid(x0,y0);
x1=linspace(-2,2,40);
y1=linspace(-2,2,40);
Bo
[X1,Y1]=meshgrid(x1,y1);
hold on % solapamos dos dibujos
surf(X0,Y0,f(X0,Y0),’facecolor’,’none’,’edgecolor’,’k’,...
’marker’,’o’, ’markersize’,6,’MarkerFaceColor’,’k’, ’linewidth’,2);
surf(X1,Y1,f(X1,Y1),’facecolor’,’interp’, ’facealpha’,0.5,...
’edgecolor’,’none’);
colorbar
colormap(’spring’)
rra
do
Figura 10.13: Algunas opciones con surf.

Ejercicio 10.5 Observa las diferencias entre estas dos salidas de la misma superficie
r
>> x=linspace(-2,2,20); y=linspace(-1,1,20);
>> [X,Y]=meshgrid(x,y);
>> figure(1)
>> surf(X,Y,X.^3-Y.^2.*Y,’linestyle’,’none’)
>> figure(2)
>> surf(X,Y,X.^3-Y.^2.*Y,’linestyle’,’none’,’facecolor’,’interp’)

228
LECCIÓN V Capı́tulo 10. Matlab: Salidas gráficas en Matlab

En un tercer nivel de dificultad (y de precisión), se puede manipular el dibujo vı́a el


handle que devuelve, de forma similar a como hacı́amos en plot. Como ejemplo ilustrativo,
>> x1=linspace(-2,2,60); y1=linspace(-2,2,60);
>> [X1,Y1]=meshgrid(x1,y1);
>> h=surf(X1,Y1,exp(-X1.^2-Y1.^2).*cos(pi*(X1.^2-Y1.^2)/2),...
’facecolor’,’interp’,’edgecolor’,’none’);
Bo
devuelve en h, después de dibujar, un puntero al dibujo. Podemos leer una propiedad
determinada mediante get:
>> get(h,’facecolor’)

ans =

interp
o bien ver todas con
>> get(h)
rra
AlphaData = [1]
AlphaDataMapping = scaled
CData = [ (60 by 60) double array]
CDataMapping = scaled
EdgeAlpha = [1]
EdgeColor = none
EraseMode = normal
FaceAlpha = [1]
FaceColor = interp
LineStyle = -
LineWidth = [0.5]
Marker = none
do
MarkerEdgeColor = auto
MarkerFaceColor = none
MarkerSize = [6]
MeshStyle = both
XData = [ (60 by 60) double array]
YData = [ (60 by 60) double array]
ZData = [ (60 by 60) double array]
FaceLighting = flat
EdgeLighting = none
................
r
................
Observarı́amos ası́ algunas de las opciones que hemos comentado y otras muchas más que
no hemos estudiado.
Para cambiar una propiedad utilizamos de nuevo el comando set:
>> set(h, ’edgecolor’,[0.2 0 0],’linewidth’,1);
>> set(h, ’facaalpha’,.5);

229
10.2 Gráficas en 3D LECCIÓN V

Mallados especiales
Con sphere podemos obtener el mallado de una esfera. Puede utilizarse para dibujar
bien una esfera o incluso funciones definidas sobre una superficie esférica. Por ejemplo,
mediante el siguiente fichero script hemos obtenido las representaciones gráficas de la
Figura 10.14.
Bo
[X,Y,Z]=sphere(60);
subplot(121)
surf(X,Y,Z,’facecolor’,[0.4 0.9 0.6])
daspect([1 1 1]) % aspecto [1 1 1]
title(’La esfera’,’fontsize’,14)
subplot(122);
surf(X,Y,Z,16*X.^2.*Y.^3.*Z.^4)
title(’16 X^2 Y^3 Z^4 sobre la esfera’,’fontsize’,14)
colormap(’hot’)
colorbar(’hor’) % barra de colores horizontal
daspect([1 1 1]) % aspecto [1 1 1]
rra
do
r
Figura 10.14: Esferas en 3D.

Comandos similares son ellipsoid (elipsoides) y cylinder (cilindros). Son algo más
flexibles de lo que pueda parecer. Ası́, y aunque parezca paradójico,

230
LECCIÓN V Capı́tulo 10. Matlab: Salidas gráficas en Matlab

>> cylinder(0:0.1:1,40)

dibuja un cono.

Ejercicio 10.6 Lee bien la ayuda de cylinder. ¿Podrı́as dibujar una semiesfera utilizando
este comando?.
Bo
10.2.3. Otros comandos
Comentaremos a continuación otras instrucciones relacionadas con gráficas de objetos
tridimensionales.

pcolor
Proporciona un dibujo bidimensional de una superficie vista desde arriba. Es equiva-
lente a dibujar primero la superficie con la orden surf y posteriormente cambiar el punto
de vista mediante view(0,90). Puedes ver un ejemplo en la Figura 10.15.
rra
do
Figura 10.15: Una superficie con surf y pcolor.
r
contour y contourf
Despliegan las lı́neas de nivel del dibujo. Propiamente generan una gráfica en 2D. La
diferencia entre ellas es que la primera instrucción sólo traza las curvas de nivel mientras
que la segunda colorea el espacio entre ellas.
Es posible añadir un texto sobre cada lı́nea de nivel utilizando clabel. Para ello basta
hacer como en el ejemplo siguiente

231
10.2 Gráficas en 3D LECCIÓN V

>> x1=linspace(-2,2,60); y1=linspace(-2,2,60);


>> [X1,Y1]=meshgrid(x1,y1);
>> f=vectorize(inline(’cos(x^2-y)’));
>> subplot(211) % dos dibujos
>> [c,h]=contour(X1,Y1,f(X1,Y1)); colorbar;
>> clabel(c,h) % Inserta el texto sobre las curvas de nivel
Bo
>> subplot(212)
>> [c,h]=contourf(X1,Y1,f(X1,Y1),5); colorbar % 5 curvas de nivel;
>> clabel(c,h,’fontsize’,12); % cambiamos tamano de la letra

El resultado es el de la Figura 10.16.

2
-0.2
0.60.4 0 .4

-0 -0.-0. 0
0

.8 6 4
0.2
-0 .6 .8

0.6

.2
-0 -0

0.8 0.6
0.2 -0

-0
0. .6 0

0.8
0

1 8 0.4
8

0.
.
4

2
. 6 0.2
.4

04.
0

0.
0.
0 2 0
-0-0.

-0.2

0.06.40.2 0.2 0.6


0.8
.6 4 - 0.02.4
rra
- -
0.6 0
-1 -0 0 -0.4
0.4
-0

-0 .2 2 .4

0 0.4
-0. -0.6

.8
.8

0.2
0.20

-0
-0 .6 -0 . 8 -0.6

-
-0.4
.8 -0
-2 -0.8
-2 -1.5 -1 -0.5 0 0.5 1 1.5 2

2 0.6
0. 6 0.2 -0.2
99 2

0.4
99 0.
0.

0.6
6

1 0.2
-0

0
.5

.5

6
0.
-02
9

-0
.

0 -0.2
-0
99

.2
9

0.2 0 .6
-0.4
-1 0.2 -0.6
-0.0.2

00.2.2
2

-0.8
-0.2
-

-2
-2 -1.5 -1 -0.5 0 0.5 1 1.5 2
do
Figura 10.16: Lı́neas de nivel

surfc y surfl
Ambas son variantes de surf. La primera despliega la superficie y dibuja en el plano
OXY (plano inferior) las curvas de nivel.
La segunda es como surf pero el color que asigna a cada punto viene determinado
por un punto de iluminación exterior. El resultado es el de una superficie de un color
r
determinado iluminado desde un punto

mesh, meshc, meshz y waterfall


Todos ellos dibujan únicamente la malla (rejilla) del dibujo. La segunda además añade
las lı́neas de nivel, de forma semejante a como procedı́a surfc. Finalmente, waterfall es

232
LECCIÓN V Capı́tulo 10. Matlab: Salidas gráficas en Matlab

como mesh pero añade un efecto de caida en los bordes del dibujo8 .

10.2.4. Comandos fáciles de usar


Los comandos
Bo
ezplot3 ezmesh ezmeshc ezsurf ezsurfc
ezcontour ezcontourf

permiten trazar, de forma muy sencilla, curvas y superficies en el espacio. Su sencillez de


uso (consulta la ayuda) queda lastrada con el inconveniente de que apenas se tiene control
sobre el aspecto final.

10.3. Campos vectoriales


Los comandos quiver y quiver3 despliegan en 2D y 3D campos de velocidades. Esto
es, a cada punto se le asigna un vector y se dibuja.
rra
2.5

1.5

0.5

-0.5

-1
do
-1.5

-2

-2.5
-2.5 -2 -1.5 -1 -0.5 0 0.5 1 1.5 2 2.5

Figura 10.17: Campo de velocidades con quiver

Por ejemplo, la Figura 10.17 se ha obtenido con


r
>>x=-2:0.25:2; y=x;
>>[X,Y]=meshgrid(x,y); % malla del cuadrado [-2,2] x [-2,2]
>>ind=logical(zeros(size(X))); % matriz logica de dimensi\’{o}n la de X
>>ind(X.^2+Y.^2<0.5^2)=1; % si (x,y) esta cerca de (0,0) vale 1
>>X(ind)=[]; Y(ind)=[]; % eliminamos estos puntos
8
Es más fácil verlo que explicarlo...

233
10.4 Dibujos sobre dominios mallados en triángulos LECCIÓN V

>>vx=-Y./(X.^2+Y.^2);
>>vy=X./(X.^2+Y.^2); % calculamos vectores
>>h=quiver(X,Y,vx,vy);
>>axis square
Observa que cerca del (0,0) los vectores se hacen muy grandes. Para evitar que esto
Bo
distorsione el dibujo hemos optado por no dibujar los vectores correspondientes a puntos
muy cercanos al origen. Con este fin hemos utilizado una variable (en realidad una matriz)
lógica ind que toma valor uno únicamente si el punto correspondiente (X,Y) está cerca
del origen.
Una vez salvada esta dificultad, hemos procedido a dibujar el campo de velocidades
resultante.
El comando quiver devuelve en realidad dos punteros, uno a las lı́neas y otro a
la cabeza del vector. Sus valores opcionales son similares a los ya vistos en secciones
anteriores.

Ejercicio 10.7 Siguiendo con las instrucciones desplegadas arriba, observa qué sucede si se
ejecuta
rra
set(h(1),’linewidth’,1,’color’,’r’,’linestyle’,’:’)
set(h(2),’color’,’k’)
¿Podrı́as eliminar la punta de los vectores?.

Ejercicio 10.8 Utilizando el comando quiver3, dibuja el campo de velocidades que a cada
punto le asigna el vector (velocidad) dado por
 x y z
−p , −p , −p )
2
x +y +z2 2 2 2
x +y +z 2 x + y2 + z2
2

(Ayuda: el comando meshgrid es también el apropiado para construir mallas en 3D)


do
10.4. Dibujos sobre dominios mallados en triángulos
Los comandos que hemos estudiado a lo largo de la sección precedente están pensados
para dibujar superficies definidas esencialmente sobre una cuadrı́cula. Aunque en muchos
casos esto es suficiente, en otras muchas ocasiones se trabaja con funciones definidas sobre
conjuntos, o dominios en la terminologı́a habitual, mucho más generales.
Una forma muy simple de trabajar con estos dominios es dividirlos en triángulos y
construir la superficie solapando diferentes planos definidos sobre cada triángulo9 . Los
resultados que se obtienen son bastante satisfactorios, puesto que los triángulos son más
flexibles que los cuadriláteros a la hora de adaptarse a los dominios.
r
Esta división en triángulos de un dominio se denomina triangulación o mallado del
dominio. Se dice que un mallado se hace más fino si el tamaño de los triángulos disminuye.
Una triangulación es conforme si la intersección de dos lados cualesquiera del mallado
es o bien vacı́a (los triángulos no se tocan), o un vértice o un lado entero. Es decir no
9
Se utiliza el conocido resultado de que tres puntos no alineados definen un único plano. Es fácil ver
también que la superficie ası́ construida es continua

234
LECCIÓN V Capı́tulo 10. Matlab: Salidas gráficas en Matlab
Bo
Figura 10.18: Triangulación no conforme.

se admite que un lado de un triángulo pueda ser parte de dos lados de dos triángulos
diferentes (véase la Figura 10.18). Por otro lado, una familia de triangulaciones se dice
regular si los triángulos no se aplanan, es decir, los ángulos de los triángulos no se hacen
rra
muy pequeños.
La siguiente cuestión es cómo almacenar la información de una triangulación. Si
optáramos por guardar cada triángulo, con sus correspondientes vértices, guardarı́amos
información redundante. Por ejemplo, un vértice compartido por 6 triángulos serı́a alma-
cenado 6 veces.
En lugar de ello se opta por una estructura más elaborada pero más económica. Se
empieza almacenando las dos coordenadas de los vértices en dos vectores que denotaremos
por x e y. En segundo lugar, apuntamos los vértices que corresponden a cada triángulo.
Esto se hace mediante una matriz, que llamaremos en lo que sigue t, de tres columnas y
número de filas igual al número de triángulos. Para saber los vértices que corresponden
al triángulo i basta leer la correspondiente fila de t y sus coordenadas serán
do
[x(t(i,1)),y(t(i,1))], [x(t(i,2)),y(t(i,2))], [x(t(i,3)),y(t(i,3))]

A modo de ejemplo, el mallado expuesto en la Figura 10.19 se guarda en las siguientes


variables

Triangulos

8 3 16
7 2 15
9 5 21
11 6 20
r
10 1 14
12 4 17
16 9 21
4 8 17
1 7 14
15 11 20

235
10.4 Dibujos sobre dominios mallados en triángulos LECCIÓN V

0.6

0.4
12 6 11
Bo
4 12 4 2
0.2 6
25 10
14
20
8 17 15 2
15 16
0 26
8 20 19 18 22 13 7
13
24 14 18
-0.2 1 16 27 23 9
19
17 7 21 21
5
3 28 1
-0.4 3 11
9 5 10

-0.6
-0.5 0 0.5
rra
Figura 10.19: Ejemplo de triangulación. En el gráfico la numeración de los triángulos se
rodea con un cı́rculo.

5 10 19
6 12 20
14 7 15
2 11 15
17 13 20
18 15 20
3 9 16
do
18 13 19
16 13 17
8 16 17
10 14 19
14 15 18
19 13 21
14 18 19
12 17 20
13 18 20
13 16 21
r
5 19 21

coordenadas:

x y

236
LECCIÓN V Capı́tulo 10. Matlab: Salidas gráficas en Matlab

0.5033 -0.3584
0.5033 0.2378
-0.4967 -0.3584
-0.4967 0.2378
0.0033 -0.4603
0.0033 0.3397
Bo
0.5033 -0.0603
-0.4967 -0.0603
-0.2523 -0.4363
0.2590 -0.4363
0.2590 0.3157
-0.2523 0.3157
-0.0716 -0.1050
0.2924 -0.1866
0.2820 0.0614
-0.2806 -0.1991
-0.2641 0.0537
0.1204 -0.0707
rra
0.0838 -0.2577
0.0113 0.1306
-0.1031 -0.2912

La información anterior es suficiente para construir la malla, la triangulación del do-


minio. Si además se desea construir una superficie definida sobre ese dominio, basta añadir
un vector adicional z de forma que z(j) sea el valor de la función en el nodo j.
do
r
Figura 10.20: Un dominio mallado en triángulos.

237
10.4 Dibujos sobre dominios mallados en triángulos LECCIÓN V

Ésta es una forma ya estándar de definir y trabajar con una triangulación que también
sigue Matlab10 con los comandos trimesh y trisurf.
El primero despliega la malla triangular especificada por t, (la matriz conteniendo los
triángulos), x e y (que dan las coordenadas de los vértices),

trimesh(t,x,y)
Bo
Se puede especificar la coordenada z de los vértices (la altura),

trimesh(t,x,y,z)

con lo que se dibuja la malla 3D correspondiente.


El comando trisurf es similar, pero colorea las caras. Hablando con propiedad, estos
comandos al igual que mesh y surf, representan superficies. Las opciones para manipular
el aspecto final de la superficie son iguales que las de surf, incluyendo las ya vistas
facecolor, facealpha, meshalpha, edgecolor,....

Nota. Un tema nada trivial es la construcción de un mallado sobre un dominio (polig-


onal) dado. Existen multitud de algoritmos que tratan este problema. En principio se
rra
plantea la construcción de una malla gruesa, con pocos triángulos y de área consider-
able, con los triángulos lo más regulares posibles (sin deformar, alargar, en deması́a los
triángulos).
Posteriormente, se trata de refinar la malla, es decir, dividir los triángulos en triángulos
más pequeños hasta que se alcance una precisión adecuada.
Esta idea se esconde detrás de aplicaciones como la interpolación (aproximación de
una función) y especialmente el método de elementos finitos, probablemente del método11
más utilizado en la resolución de problemas de contorno para ecuaciones en derivadas
parciales.
Si se desea información de cómo se puede inicializar un malla en Matlab, ası́ como
sobre el algoritmo utilizado se puede consultar el comando initmesh (incluido el tema de
triangulaciones de Delaunay). Para el refinamiento puedes consultar refinemesh. .
do
Existe otra posibilidad más visual, y por tanto más amigable para empezar a trabajar.
Teclea

>> pdetool

Se cargará un entorno gráfico para la resolución de ecuaciones en derivadas parciales. No


entraremos en este tema por ser demasiado técnico. En lugar de ello, nos centraremos en
la definición de mallados. Una vez dibujado el dominio, y mallado, se puede exportar la
malla a la ventana de comandos en las variables t y p. La primera contiene en las tres
primeras filas los triángulos que componen la triangulación mientras que las coordenadas
de los vértices están guardadas en las dos filas de p. 
r
10
La toolbox pdetool dedicada a la resolución de ecuaciones en derivadas parciales sigue una variante
algo más complicada que la expuesta arriba.
11
Propiamente hablando es una familia de métodos.

238
Capı́tulo 11
Bo
Interpolación. Curvas Bézier

11.1. Interpolación polinómica


Un problema ya clásico es la construcción, o aproximación de una función conocidos
unos pocos valores. Algunas referencias a este tipo de problemas se remontan al manejo de
tablas trigonométricas y posteriormente logarı́tmicas y exponenciales donde unos pocos
rra
valores estaban tabulados y para valores intermedios era necesario un proceso de interpo-
lación. Se habla en este caso de un problema de interpolación de Lagrange. Si además del
valor puntual, añadimos información sobre las derivadas estamos ante una interpolación
de Hermite.
En estos apuntes trataremos principalmente la interpolación polinómica, esto es, la
construcción de polinomios que pasen por unos puntos predeterminados. Daremos tam-
bién unos breves esbozos sobre la interpolación por polinomios trigonométricos y la inter-
polación polinómica a trozos con las funciones spline.

11.1.1. Interpolación polinómica de Lagrange


El problema que queremos resolver es el siguiente
do
Dados un conjunto de n + 1 puntos {(x0 , y0 ), (x1 , y1 ), . . . (xn , yn )}, construir
un polinomio pn de grado n tal que

pn (xj ) = yj , j = 0, . . . , n.

El polinomio pn recibe el nombre de polinomio de interpolación de Lagrange. Ha-


bitualmente, yj son valores de una función f que sólo se puede evaluar en un conjunto
finito de puntos porque o bien en el resto del intervalo es desconocida, o bien es cara
r
computacionalmente de evaluar.
Tenemos una serie de cuestiones pendientes:

¿Se puede construir siempre el polinomio de interpolación pn ?. Y relacionada con


esta cuestión, ¿el polinomio de interpolación es único?.

¿Existen formas óptimas para cálcular este polinomio?.

239
11.1 Interpolación polinómica LECCIÓN V

-9
x 10

4
Bo
3

-1 z6-46*z5+ 884*z4-9088*z3+52736*z2-163840*z+212992
(z-8)4*(4+(z-8)*(2+(z-8))

7.994 7.996 7.998 8 8.002 8.004 8.006


rra
Figura 11.1: Dos formas de escribir y evaluar un polinomio.

¿Cómo aproxima pn a esta función f ?. Este punto es crucial ya que se trata del error
que podemos esperar de nuestra aproximación.

Como cuestión asociada, pero no menos importante, nos deberı́amos plantear

¿Cuál es la mejor forma de evaluar un polinomio?. Es decir, ¿nos interesa el poli-


nomio escrito en la manera tradicional o simplemente poder evaluarlo de forma fácil,
rápida y estable numéricamente?
do
Ejemplo En la Figura 11.1 hemos dibujado los polinomios (z−8)4 (4+(z−8)(2+(z−8)))
y z 6 −46z 5 +884z 4 −9088z 3 +52736z 2 −163840z+212992 en un entorno de 8. Analı́ticamente
son el mismo polinomio pero el resultado de evaluar una u otra expresión puede dar
un resultado muy diferente debido a los errores de redondeo. La primera expresión es
mucho más apropiada desde el punto de vista computacional aunque nosotros estemos
más acostumbrados a escribir los polinomios de la segunda manera.
El algoritmo más estable para evaluar un polinomio es el método de Horner que
está basado a su vez en el método de Ruffini para dividir polinomios. Concretamente
utiliza que el valor de p(a) es el resto de dividir p(z) por z − a . El algoritmo es fácilmente
implementable y tiene un costo reducido.
r
11.1.2. Existencia del polinomio de interpolación
Probaremos la existencia del polinomio de interpolación mediante un razonamiento
directo. Tomemos
Pn 3 pn (x) = a0 + a1 x + a2 x2 + . . . + an xn ,

240
LECCIÓN V Capı́tulo 11. Interpolación. Curvas Bézier

un polinomio de grado n. Obviamente, pn cuenta con n + 1 parámetros libres que son


simplemente sus coeficientes {aj }. Si exigimos que

pn (xj ) = yj , j = 0, . . . , n,

nos encontramos con que los coeficientes satisfacen el sistema lineal


Bo
1 x0 x20 · · · xn0
    
a0 y0
 1 x x2 · · · xn  a1   y1 
 1 1 1    
a2 y2
    
 1 x2 x22 · · · xn2  = . (11.1)
.. ..
    
 ..................
    
 .   . 
1 xn x2n · · · xnn an yn

Por tanto el problema se reduce a la resolución de un sistema de ecuaciones lineales y


la existencia y unicidad del polinomio de interpolación a que el sistema en cuestión sea
compatible determinado.
La matriz del sistema (11.1) es de tipo Vandermonde que nos ha surgido repetidas
rra
veces en estos apuntes1 . Dado que el sistema tiene el mismo número de ecuaciones que
de incógnitas, se tiene que la existencia de solución para cualquier conjunto de
datos es equivalente a la unicidad. Además, la unicidad de solución es equivalente
a que la única solución posible para el término independiente nulo sea el polinomio cero.
Pero esto es inmediato puesto que todo polinomio no nulo de grado n tiene a lo sumo n
raı́ces.
Otra forma de ver la existencia y unicidad es de tipo constructiva. Tomemos

(x − x0 ) · · · (x − xj−1 )(x − xj+1 ) · · · (x − xn ) Y x − xi


Lj (x) := = .
(xj − x0 ) · · · (xj − xj−1 )(xj − xj+1 ) · · · (xj − xn ) i6=j xj − xi

Es fácil ver que Lj ∈ Pn y que además


do

1, i = j,
Lj (xi ) :=
0, i 6= j.

Por tanto,
pn (x) = y0 L0 (x) + y1 L1 (x) + . . . + yn Ln (x)
satisface las condiciones (11.1). Una vez probada la existencia deducimos por los mismos
argumentos la unicidad del polinomio de interpolación.
La fórmula anterior se conoce como fórmula de Lagrange del polinomio de in-
terpolación y la base del espacio de polinomios Pn formada por {Lj }j se denomina base
r
de Lagrange del problema de interpolación.

Ejercicio 11.1 Programar una función que evalúe el polinomio de interpolación según la
fórmula de Lagrange en un conjunto de puntos.
1
Cada columna es el resultado de elevar a una potencia el vector [1 x0 x1 · · · xn ]>

241
11.1 Interpolación polinómica LECCIÓN V

Solución. He aquı́ una posible implementación2


01 % LAGRANGEP
02 %
03 % Y=LAGRANGEP(X0,Y0,X) devuelve en Y el valor del pol. de interp.
04 % que pasa por los puntos (X0,Y0) evaluado
Bo
05 % en x mediante la formula de Lagrange
06 %
07 % X0 y Y0 son dos vectores de la misma longitud, X puede ser un
08 % vector.
09
10 function y=lagrangep(x0,y0,x)
11
12 x0=x0(:).’; y0=y0(:).’; x=x(:).’; % todos vectores filas
13 n=length(x0);
14 if (length(y0)~=n)
15 disp(’ERROR. Long de x0 debe ser igual a Long de y0’)
16 return
rra
17 end
18 y=x*0; % y es un vector nulo de igual dimension que x
19
20 for j=1:n
21 p=ones(size(x));
22 for i=[1:j-1 j+1:n]
23 p=p.*(x-x0(i))./(x0(j)-x0(i));
24 end
25 y=y+p*y0(j);
26 end
27
28 return
do

Hemos testado el programa anterior para interpolar la función exp(sen(6x)) en [0, π]
en diversos puntos uniformemente distribuidos (a igual distancia). El resultado, junto con
el error cometido se muestra en la Figura 11.2.

Ejercicio 11.2 Implementa la construcción del polinomio de interpolación mediante la res-


olución directa del sistema dado en (11.1). ¿Qué observas cuando el grado del polinomio
crece?.
r
11.1.3. Fórmula de Newton
Es fácil comprobar que la fórmula de Lagrange tiene un costo computacional elevado.
Por ello es necesario explorar formas alternativas de construir el polinomio de interpolación
y de proceder a su evaluación.
2
Observa el for de la lı́nea 20

242
LECCIÓN V Capı́tulo 11. Interpolación. Curvas Bézier

2
exp(-x).*sin(6.*x)
1.5 polinomio de grado 5
polinomio de grado 9
polinomio de grado 13
1

0.5
Bo
0

-0.5

-1
0 0.5 1 1.5 2 2.5 3 3.5

Error
1.5

0.5

0
rra
-0.5 polinomio de grado 5
polinomio de grado 9
-1 polinomio de grado 13

-1.5
0 0.5 1 1.5 2 2.5 3 3.5

Figura 11.2: Polinomios de interpolación con diferentes grados y el error cometido.

Observa que la fórmula de Lagrange se basa en tomar como base de Pn la dada por
{L0 (x), L1 (x), . . . , Ln (x)}.
do
En esta base, las coordenadas del polinomio de interpolación son simplemente los valores
que toma la función en los puntos donde se interpola. Es decir, no es necesario resolver
ningún sistema de ecuaciones lineales (la matriz del sistema serı́a la matriz identidad).
El precio que se paga como contrapartida es una evaluación más cara del polinomio de
interpolación.
Podemos explorar otras bases que, aumentando el costo de la resolución del sistema,
ofrezcan fórmulas del polinomio de interpolación cuya evaluación sea menos costosa.
Planteamos ası́ utilizar la base
{1, (x − x0 ), (x − x1 )(x − x0 ), . . . , (x − xn−1 )(x − xn−2 ) · · · (x − x0 )}.
r
Es inmediato probar que es una base de los polinomios de grado n. Dicho de otra forma,
cualquier polinomio de grado n se puede escribir (de forma única) como
α0 + α1 (x − x0 ) + . . . + αn (x − xn−1 )(x − xn−2 ) · · · (x − x0 ). (11.2)
Además el sistema lineal que hay que resolver para obtener los coeficientes αj es ahora tri-
angular superior, por lo que su resolución es prácticamente directa en O(n2 ) operaciones.

243
11.1 Interpolación polinómica LECCIÓN V

Aún es más, si pn (x) interpola a f en n + 1 puntos, añadir un punto más (xn+1 , yn+1 ) es
simplemente corregir el polinomio anterior en la forma siguiente

pn+1 (x) = pn (x) + αn+1 (x − x0 ) · · · (x − xn ), (11.3)

donde
yn+1 − pn (xn+1 )
Bo
αn+1 = . (11.4)
(xn+1 − xn )(xn+1 − xn−1 ) · · · (xn+1 − x0 )
Es decir, el trabajo hecho para calcular el polinomio de interpolación en n + 1 puntos se
puede utilizar si se desea añadir un punto más de interpolación.
Estas identidades se pueden utilizar para calcular el polinomio de interpolación uti-
lizando polinomios intermedios que vayan interpolando en subconjuntos crecientes de
datos. Sin embargo, un análisis algo más detallado nos va a descubrir una manera más
apropiada de calcular los coeficientes del polinomio de interpolación. Siguiendo la no-
tación clásica, consideraremos que los valores yj que deseamos interpolar provienen de
una función f a priori desconocida, es decir,

yj = f (xj ), j = 0, . . . , n.
rra
Escribiremos entonces el polinomio que interpola en {xk , . . . , xk+m } como sigue

f [xk ] + f [xk , xk+1 ](x − xk ) + . . . + f [xk , xk+1 , . . . , xk+m ](x − xk ) · · · (x − xk+m−1 ). (11.5)

La identidad (11.3) justifica el uso de esta notación es correcta. Esto es, el coeficiente
de (x − xk ) · · · (x − xk+r ) no depende de m. Obviamente, si k = 0 y m = n, entonces
recuperaremos el polinomio de interpolación en el conjunto inicial de valores. A estas
alturas f [xk , xk+1 , . . . , xk+r ] son todavı́a simples coeficientes del polinomio de cuyo cálculo
nos ocupamos a continuación. Es inmediato comprobar que si
n o
p interpola en (x , f (x )), (x , f (x )), . . . , (x , f (x )) ,

n 0 0 1 1 n n

n o
do
qn interpola en (x1 , f (x1 )), (x2 , f (x2 )), . . . , (xn+1 , f (xn+1 )) ,

entonces
x − xn+1
pn+1 (x) = qn (x) + (pn (x) − qn (x)), (11.6)
x0 − xn+1
es el polinomio que interpola en los n + 1 puntos
n o
(x0 , f (x0 )), (x1 , f (x1 )), . . . , (xn+1 , f (xn+1 )) .

Detengámonos un momento a examinar el coeficiente director de cada polinomio. El


coeficiente en xn de pn y qn y el de xn+1 de pn+1 son respectivamente
r
f [x0 , . . . , xn ], f [x1 , . . . , xn+1 ] f [x0 , . . . , xn+1 ].

Utilizando (11.6) deducimos que


f [x0 , . . . , xn ] − f [x1 , . . . , xn+1 ]
f [x0 , x1 . . . , xn+1 ] = . (11.7)
x0 − xn+1

244
LECCIÓN V Capı́tulo 11. Interpolación. Curvas Bézier

Como
f [xj ] = f (xj )
(simplemente porque el polinomio de grado 0 que pasa por (xj , f (xj )) es la constante
f (xj )), obtenemos una forma recursiva de calcular los coeficientes del polinomio de in-
terpolación. El algoritmo resultante se puede representar esquemáticamente mediante el
diagrama de la Figura 11.3.
Bo
En la literatura, f [xk , . . . , xk+r ] recibe el nombre de diferencia dividida de order
r, mientras que la forma de escribir el polinomio expuesta en (11.2) y (11.5) recibe el
nombre de fórmula de Newton3 .
Obviamente, a partir de la fórmula de Newton podemos expresar el polinomio que
interpola a f en los puntos {x0 , . . . , xn } en la forma
  
f [x0 ] + (x − x0 ) f [x0 , x1 ] + (x − x1 ) f [x0 , x1 , x2 ] + (x − x2 ) . . .

+(x − xn−1 )f [x0 , x1 , . . . , xn ] , (11.8)

que es mucho más apropiada desde el punto de vista computacional que la forma clásica.
En forma de pseudocódigo podemos proceder del siguiente modo para evaluar el poli-
rra
nomio de interpolación utilizando la fórmula de Newton:
Diferencias divididas

01 x0 , y0 % datos
02 n = length(x0 ) − 1
03 D(:, 0) = y0 ;
04 for j=1:n
05 for i=0:n-j
D(i + 1, j − 1) − D(i, j − 1)
06 D(i, j) =
x0 (i + j) − x0 (i)
07 end
08 end
do
09
10 % Evaluacion del polinomio
11 y=D(0,n)
12 for i=n-1:-1:0
13 y = (x − x0 (i)) ∗ y + D(0, i)
14 end
r
Con la notación anterior
D(i, j) = f [xi , xi+1 , . . . , xi+j ]
de forma que j es el orden de la diferencia e i el nodo donde empieza.
3
De nuevo los nombres utilizados dan idea de la antigüedad de estas técnicas. Newton halló esta forma
de escribir el polinomio cuando estudiaba las fórmulas de cuadratura de Newton-Cotes.

245
11.1 Interpolación polinómica LECCIÓN V

Orden 0 Orden 1 Orden 2 Orden 3

x0 f (x0 ) = f [x0 ] / f [x0 , x1 ] / f [x0 , x1 , x2 ] / f [x0 , x1 , x2 , x3 ]


mm 6 mm6 ll6
mmmmm mmmmm lllll
mmm mmm lll
Bo
mmm mmm lll
x1 f (x1 ) = f [x1 ] / f [x1 , x2 ] / f [x1 , x2 , x3 ]
m 6 6
mm mmm
mmmmm mmmmm
mm mm
mmm mmm
x2 f (x2 ) = f [x2 ] / f [x2 , x3 ]
mmm6
mmm
m mmmm
mm
x3 f (x3 ) = f [x3 ]

Figura 11.3: Estructura del cálculo de las diferencias dividas.

Ejercicio 11.3 Implementa el cálculo del polinomio de interpolación mediante diferencias


rra
divididas.

Solución. Nuestra intención es, si no se especifican valores donde evaluar el polinomio,


que se devuelva el polinomio escrito en forma simbólica. Es decir, declararemos x como
variable simbólica y devolveremos el polinomio en esta variable. Podemos escoger hacerlo
en forma expandida o bien simplemente escrito en la forma anidada. Nosotros hemos
escogido hacerlo en la segunda forma.
Por otro lado y entrando ya en el tema de su implementación, en el algoritmo anterior
todas las entradas de los vectores y matrices implicados se numeran de 0 a n. Hay que tener
en cuenta, como ya hemos hecho repetidas veces, que la numeración en Matlab comienza
necesariamente en 1 y por tanto los vectores y bucles irán de 1 a n+1. Recordemos que
n+1 es la longitud del vector de datos. Aunque en teorı́a renumerar el algoritmo es
do
algo sencillo, hay que hacerlo con cierto cuidado.
Dicho esto, una implementación posible es la siguiente

01 % NEWTONP
02 %
03 % Y= NEWTONP(X0,Y0) devuelve el polinomio que interpola
04 % en (X0,Y0) escrito en forma de Newton
05 %
06 % Y= NEWTONP(X0,Y0,X) devuelve en Y el polinomio interpolante
07 % evaluado en X
r
08
09 function y=newtonp(x0,y0,varargin)
10
11 x0=x0(:).’; y0=y0(:).’; n=length(x0)-1;
12 if (length(y0)~=n+1)
13 disp(’long de x0 debe ser igual long de y0’)

246
LECCIÓN V Capı́tulo 11. Interpolación. Curvas Bézier

14 return
15 end
16 if nargin>2
17 x=varargin{1}; % evaluamos x
18 else
19 syms x; % x es una variable simbolica
Bo
20 end
21 % calculo de las diferencias divididas
22 D=zeros(n+1); % matriz n+1 x n+1 de ceros
23 D(:,1)=y0.’;
24 for j=2:n+1
25 for i=1:n-j+2
26 D(i,j)=(D(i+1,j-1)-D(i,j-1))/(x0(i+j-1)-x0(i));
27 end
28 end
29 % evaluacion del polinomio
30 D=D(1,:); % tomamos las diferencias que vamos a usar
31 y=x.^0.*D(n+1); % asi y tiene la longitud de x
rra
32 for i=n:-1:1
33 y=(x-x0(i)).*y+D(i);
34 end
35 return

Ejercicio 11.4 El bucle interno en las lı́neas 25-27 se puede vectorizar. Hazlo.

Un análisis más detenido muestra que no es necesario definir toda una matriz D sino
que es posible realizar todo el proceso con un vector. Para ello observa que las diferencias
do
D(i, j) con sólo se utilizan dos veces, para construir D(i − 1, j + 1) y D(i, j + 1). Esto se
consigue modificando las lı́neas 03-08 del algoritmo como sigue

Modificación

03 D = y0 ;
04 for j=1:n
05 for i=n:-1:j
D(i) − D(i − 1)
06 D(i) =
r
x0 (i) − x0 (i − j)
07 end
08 end

247
11.1 Interpolación polinómica LECCIÓN V

Observa que las diferencias se sobrescriben en el vector pero de una forma tal que un
valor no es borrado hasta que ya ha sido utilizado. De ahı́ que el bucle en 05 vaya hacia
atrás. Con esta modificación
D(i) =f [x0 , x1 , . . . , xi ].
Ejercicio 11.5 Retoca el programa newtonp según las indicaciones anteriores.
Bo
Ejercicio 11.6 El algoritmo de Neville para la evaluación del polinomio de interpolación se
basa en la identidad (11.6). Dado el punto x donde evaluar el polinomio de interpolación
y partiendo de n + 1 polinomios de grado cero que interpolan los datos ({x0 , x1 , . . . , xn })
procede a calcular el valor que toman en x los polinomios de grado 1 que interpolan en
dos puntos ({{x0 , x1 }, {x1 , x2 }, . . . , {xn−1 , xn }}), seguidamente los de grado 2 interpolantes
en tres puntos, ({{x0 , x1 , x2 }, {x1 , x2 , x3 }, . . . , {xn−2 , xn−1 , xn }}), y ası́ sucesivamente hasta
llegar al polinomio final de grado n.
En todos los casos es la identidad (11.6) la que permite calcular el valor del polinomio de
grado k + 1 en función de dos de grado k. La evaluación se puede representar en forma de
estructura en árbol, muy similar a la que se obtiene para las diferencias divididas. ¿Podrı́as
diseñar y programar este algoritmo?.
rra
Nota. Observa que el método funciona aún cuando los puntos x0 , . . . , xn no estén
ordenados, aunque para una evaluación del polinomio más estable es mejor que ası́ sea.
Además la definición de las diferencias divididas no depende del orden de los puntos
f [x0 , . . . , xi , . . . , xj , . . . xn ] = f [x0 , . . . , xj , . . . , xi , xn ].
De forma alternativa se puede escribir el polinomio de interpolación mediante
f [xn ] + f [xn , xn−1 ](x − xn ) + . . . + f [xn , xn−1 , . . . , x0 ](x − x1 )(x − x2 ) · · · (x − xn ). (11.9)
En este caso se habla de diferencias regresivas, mientras que en el caso que hemos
tratado reciben el nombre de diferencias progresivas. 
Ejercicio 11.7 Modificar los algoritmos anteriores para trabajar con las diferencias regresi-
do
vas.

Interpolación en Matlab
La interpolación polinómica está implementada en Matlab con polyfit. La sintaxis es
>> p=polyfit(x0,y0,n)
donde x0 e y0 son los puntos a interpolar y n es el grado del polinomio utilizado. Si n se
toma igual a length(x0) − 1, devuelve el polinomio de interpolación mientras que para
n menor calcula el polinomio que mejor aproxima a los puntos por mı́nimos cuadrados4 .
Para evaluar el polinomio se recurre a polyval.
r
El algoritmo que utiliza Matlab es el directo, construyendo simplemente la matriz
de Vandermonde y resolviendo el sistema mediante una descomposición QR que es más
estable numéricamente. Sin embargo, con un número (muy) elevado de puntos, la inesta-
bilidad numérica subyacente se hace palpable.
X
4
Es decir, calcular el polinomio de grado n, que minimiza (p(xi ) − yi )2 .
i

248
LECCIÓN V Capı́tulo 11. Interpolación. Curvas Bézier

Ejercicio 11.8 Interpola la función cos(8πx) en [0, 1] con 20,40, 80 y 160 puntos utilizando
el comando polyfit y las funciones lagrangep y newtonp y dibuja el resultado. ¿Qué obser-
vas?.

11.1.4. Análisis del error de interpolación


Bo
El error entre la función y el polinomio de interpolación se puede estudiar utilizan-
do algunas propiedades de las diferencias divididas que detallaremos más adelante. En
cualquier caso, el resultado relevante es el siguiente: si f es la función regular que inter-
polamos en {x0 , x1 , . . . , xn } ⊂ [a, b], entonces el error en cada punto se puede escribir
1
f (x) − pn (x) = f (n+1) (ξx ) (x − x0 )(x − x1 ) · · · (x − xn ) (11.10)
(n + 1)! | {z }
ωn (x)
donde ξx ∈ [a, b] depende de x. Vemos que hay varias contribuciones al error final:
el factor 1/(n + 1)! que tiende rápidamente a 0,
un factor que depende del crecimiento de la derivada n + 1,
rra
un término que depende de la colocación de los nodos de interpolación y que puede
ser muy oscilante.
En vista de lo anterior serı́a fácil concluir que hay convergencia del polinomio de
interpolación a la función si ésta es suave. Dicho de otra manera, función y polinomio se
volverı́an indistinguibles si tomásemos un número elevado de puntos.
Desafortunadamente5 , la conclusión anterior es falsa. Uno de los primeros (con-
tra)ejemplos lo encontró Carl Runge6 a finales del siglo XIX7 . Consistı́a en interpolar la
función
1
f (x) =
1 + 25x2
en el intervalo [−1, 1] en un conjunto uniforme de puntos. El resultado (desastroso) se
do
muestra en la Figura 11.4.
Una forma de reducir el error es controlar la función ωn (x) para que sea lo más pequeña
posible. Ası́, el problema se plantea en los siguientes términos8
¿Qué elección de los nodos {x0 , x1 , . . . , xn } hace que máxx |ωn (x)| sea
mı́nimo?.
5
Y contraintuitivamente. ¿Cómo entender si no que dos funciones regulares que coincidan en un número
cada vez mayor de puntos no acaben siendo muy similares?
6
Matemático alemán de finales del siglo XIX. También es conocido por ser codesarrollador del Método
Runge-Kutta para la resolución de problemas de valor inicial.
7
Éste fue el siglo de la fundamentación de las Matemáticas. Se probó que multitud de resultados que se
r
tenı́an como evidentes eran falsos y fue necesario reconstruir las Matemáticas desde su base. Por ejemplo,
en el mismo siglo se mostró la existencia de funciones no continuas en ningún punto, de funciones continuas
pero no derivables en ningún punto, ası́ como de funciones con un número infinito de máximos y mı́nimos
locales. También se construyeron curvas que rellenaban el plano, curvas cerradas que englobando una área
finita tenı́an una longitud infinita (fractales)... Algunas de estas construcciones, originarias esencialmente
en las Matemáticas puras han encontrado en el siglo XX aplicaciones a problemas de ı́ndole esencialmente
práctico.
8
Un problema min-max: minimizar un máximo.

249
11.1 Interpolación polinómica LECCIÓN V

1.5

0.5

0
Bo
2
-0.5 1./(1+25.*x. )
polinomio de grado 5
polinomio de grado 10
-1
polinomio de grado 15
polinomio de grado 20
-1.5

-2
-1 -0.8 -0.6 -0.4 -0.2 0 0.2 0.4 0.6 0.8 1

Error
4

-1
polinomio de grado 5
polinomio de grado 10
-2
polinomio de grado 15
rra
polinomio de grado 20
-3

-4
-1 -0.8 -0.6 -0.4 -0.2 0 0.2 0.4 0.6 0.8 1

Figura 11.4: Ejemplo de Runge. Polinomio de interpolación y error cometido.

Éste es un problema clásico que fue resuelto por Pafnuty Lvovich Chebyshev9 en
términos de una familia de polinomios conocidos como polinomios de Chebyshev de primer
tipo.
Para un intervalo arbitrario [a, b], la disposición de los n + 1 puntos de interpolación
que minimizan el máxx∈[a,b] |wn (x)| es la dada por los puntos
do
a+b b−a  π kπ 
xk := + cos + , k = 0, . . . , n. (11.11)
2 2 2n + 2 n + 1

Es fácil comprobar que la distribución de puntos no es en medida alguna uniforme sino


que tiende a concentrar puntos en los extremos.
La elección de estos puntos para la interpolación no asegura la convergencia del
polinomio pero sı́ permite controlar mejor uno de los términos que más rápido pueden
crecer con n, con lo que en la práctica se traduce en mejores resultados10 . De hecho con
esta elección,
r
1
máx |ωn (x)| = n
x∈[a,b] 2
9
Matemático ruso del siglo XIX. Estos polinomios surgieron en sus estudios en aproximación de fun-
ciones por polinomios. Chebyshev hizo también importantes contribuciones en Teorı́a de la Probabilidad.
10
Dicho de otra manera, es más difı́cil dar con un ejemplo para el que esta disposición de nodos dé un
polinomio interpolante que no converja a la función original.

250
LECCIÓN V Capı́tulo 11. Interpolación. Curvas Bézier

de forma que ωn (x) → 0 cuando n → ∞ (además esta convergencia es rápida). En la


Figura 11.5 observamos como ahora el polinomio interpolante para el ejemplo de Runge
converge a la función.

2
Bo
1.5

0.5

0
1./(1+25.*x.2)
-0.5
polinomio de grado 5
polinomio de grado 10
-1 polinomio de grado 15
polinomio de grado 20
-1.5

-2
-1 -0.8 -0.6 -0.4 -0.2 0 0.2 0.4 0.6 0.8 1

Error
4

2
rra
1

-1
polinomio de grado 5
-2 polinomio de grado 10
polinomio de grado 15
-3 polinomio de grado 20

-4
-1 -0.8 -0.6 -0.4 -0.2 0 0.2 0.4 0.6 0.8 1

Figura 11.5: Ejemplo de Runge con otros nodos.

Ejercicio 11.9 Elege un intervalo arbitrario [a, b] y crea un fichero script que muestre la
do
disposición de los puntos dados por (11.11). Dibuja los puntos obtenidos para diferentes
valores de n. Dibuja también el polinomio ωn (x). ¿A qué función te recuerda?.

Ejercicio 11.10 (teórico) Se trata de probar una serie de propiedades de las diferencias
divididas de las que finalmente se deduce la estimación del error del polinomio de interpolación
dada en (11.10).
(1) Prueba que f (j) (x) − p(j) (x) se anula en n + 1 − j puntos para j = 0, . . . , n + 1.
(2) Utilizando (1), prueba que existe ξ tal que
f (n) (ξ)
r
f [x0 , . . . , xn ] = .
n!
(3) Fijemos y ∈ [a, b]. Entonces
f (x) = pn (y) + f [x0 , . . . , xn , y](x − x0 )(x − x1 ) · · · (x − xn ).
Utiliza ahora (2) para probar la estimación del error dada en (11.10).

251
11.2 Extensiones adicionales LECCIÓN V

(Ayuda: El Teorema de Rolle establece que si g es derivable en [a, b] con g(a) = g(b) entonces
existe c ∈ (a, b) tal que
g 0 (c) = 0.
Aplicando este resultado, concluimos que existe αj ∈ (xj , xj+1 ) (j = 0, . . . , n − 1) tal que

f 0 (αj ) − p0 (αj ) = 0.
Bo
Se puede aplicar el mismo resultado para probar que existen n − 2 puntos tales que f 00 (βj ) =
p00 (βj ) y ası́ sucesivamente.)

11.2. Extensiones adicionales


11.2.1. Interpolación de Hermite
La interpolación de Hermite incorpora las derivadas como datos adicionales. Concre-
tamente, partimos de este conjunto de datos

(x0 , f (x0 )), . . . , (x0 , f (m0 ) (x0 ))




rra


 (x1 , f (x1 )), . . . , (x1 , f (m1 ) (x1 ))



 ..............................

(xn , f (xn )), . . . , (xn , f (mn ) (xn ))

Observa que estamos asumiendo que no hay huecos en los datos. Esto, si por ejemplo la
derivada de orden 2 es dato, también lo es el valor de la función y su primera derivada.
El número total de datos es

N := (m0 + 1) + (m1 + 1) + · · · + (mn + 1),

por lo que el polinomio deberı́a tener grado N − 1.


El análisis de este problema no tiene mayor dificultad que el ya realizado para la inter-
do
polación polinómica de Lagrange. La clave está en la fuerte relación entre diferencias divi-
didas y derivada, mostrada en el Ejercicio 11.10. Ası́, se hace la siguiente interpretación:

f [ xk , . . . , xk ] := f (m) (xk ).
| {z }
m + 1 veces
La idea es ordenar los nodos y tomarlos repetidos según el número de datos que consid-
eramos en cada punto de forma que tomaremos los N nodos

{x0 , x0 , . . . , x0 , x1 , x1 , . . . , x1 , . . . , xn , xn , . . . , xn .}
| {z } | {z } | {z }
m0 +1 m1 +1 mn +1
r
Las diferencias divididas se definen de nuevo de forma recursiva
 (m)
f (xi )

 , si xi = xi+m ,
m!

f [xi , xi+1 , . . . , xi+m ] :=
 f [xi , x1 , . . . , xi+m−1 ] − f [xi+1 , x1 , . . . , xi+m ] ,

en otro caso,

xi − xm

252
LECCIÓN V Capı́tulo 11. Interpolación. Curvas Bézier

y el polinomio de interpolación se construye exactamente como antes, es decir, utilizando


la fórmula (11.8) con las nuevas definiciones de los nodos y de las diferencias divididas.
El cálculo de las diferencias y la evaluación del polinomio en un punto en el caso de
la interpolación de Hermite puede describirse en lenguaje de pseudocódigo de la siguiente
forma:
Diferencias divididas para la interpolación Hermite
Bo
01 x0 , y0 datos
02 n = length(x0 ) − 1
03 D = y0 ;
04 for j=1:n
05 for i=n:-1:j
06 if x0 (i) == x0 (i − j)
07 D(i) = D(i)/j
08 else
D(i) − D(i − 1)
09 D(i) =
x0 (i) − x0 (i − j)
10 end
rra
11 end
12 end
13
14 % Evaluacion del polinomio
15 y=D(n);
16 for i=n-1:-1:0
17 y = (x − x0 (i)) ∗ y + D(i)
18 end

En este algoritmo la tabla de diferencias divididas se almacena de forma compacta,


como se sugirió en el Ejercicio 11.5. Observa que desde el punto de vista computacional
do
las diferencias con respecto a la interpolación de Lagrange son mı́nimas.
Ejercicio 11.11 Entiende bien el algoritmo anterior. Implementa la interpolación de Hermite
según el siguiente prototipo
01 HERMITEP
02
03 Y=HERMITEP(X0,Y0) Devuelve en Y el polinomio de interpolacion de
04 Hermite X0 debe estar ordenados. Los nodos
05 repetidos se interpretan como derivadas sucesivas
06 en ese punto
r
07
08 Y=HERMITE(X0,Y0,X) Devuelve en Y la evaluacion del polinomio en X
Observa que, una vez implementada esta función,
>> x0=[0 0 0 0 0 0]; y0=[1 1 1 1 1 1];
>> p=hermitep(x0,y0)

253
11.2 Extensiones adicionales LECCIÓN V

devuelve de hecho el polinomio de Taylor de orden 5 de f (x) = exp(x) en el cero. La


orden
>> simple(hermitep(x0,y0))
hace más evidente esta identidad.
Bo
11.2.2. Interpolación de funciones periódicas
Si una función es periódica es natural reemplazar en el problema de interpolación los
polinomios por funciones periódicas sencillas con el mismo periodo. Por simplificar, vamos
a suponer que estamos considerando únicamente funciones 2π–periódicas, aunque las ideas
que a continuación expondremos se extienden fácilmente a funciones con cualquier periodo.
Concretamente, si se trata de funciones 2π–periódicas podemos utilizar
sen(nx), cos(nx), n ∈ N ∪ {0}
para interpolarlas, o bien,
exp(inx), n ∈ Z.
rra
Ambas son equivalentes, como ya vimos en la Lección 3 con la FFT, pero la utilización
de exponenciales complejas facilita tanto el análisis como la manipulación ası́ como la
extensión de la interpolación a funciones complejas
Supongamos que tomamos un número impar 2n+1 de puntos de interpolación equidis-
tantes:
2kπ
xk = , k = 0, . . . , 2n.
2n + 1
El problema queda ası́ definido: calcular
n
X
p2n+1 (x) := αj exp(ijx)
j=−n

tal que
n
do
X  2πijk 
yk = p2n+1 (xk ) = αj exp .
j=−n
2n + 1
La resolución de este problema se puede llevar a cabo con la transformada de Fourier
Discreta, y por tanto es aplicable la FFT.
Ejercicio 11.12 Comprueba que efectivamente se reduce todo a una transforma de Fourier
discreta.
(Ayuda: Observa que
 2πijk   2πi(2n + 1 − j)k 
exp − = exp .
2n + 1 2n + 1
r
Por tanto el problema es equivalente a encontrar αj tales que
n 2n
!
X  2πijk  X  2πijk 
yk = p2n+1 (xk ) = αj exp + α2n+1−j exp .
2n + 1 2n + 1
j=0 j=n+1

Ejercicio 11.13 ¿Qué pasa si se toma un número par de puntos de interpolación?

254
LECCIÓN V Capı́tulo 11. Interpolación. Curvas Bézier

Nota. El interpolante converge a la función bajo hipótesis mucho más débiles que en
el caso no periódico. Por ejemplo, basta con que la función tenga derivada continua. No
existen por tanto fenómenos como el de Runge para funciones periódicas con condiciones
mı́nimas de regularidad. 
Bo
11.2.3. Interpolación polinómica a trozos
Los polinomios tienen un importante inconveniente que desaconseja su utilización para
la interpolación en un número elevado de puntos. La Figura 11.6 ilustra esta problemática
con un problema de interpolación para el que el polinomio correspondiente exhibe un com-
portamiento ciertamente irracional. Ello se debe a que se obliga a que el polinomio sea
prácticamente constante en dos zonas con un salto en medio. El polinomio es excesiva-
mente rı́gido11 que en última medida provoca que éste se rompa.

2
rra
1.5

0.5

0
do
-0.5
0 0.2 0.4 0.6 0.8 1

Figura 11.6: Rigidez polinómica

Como forma de solventar estos problemas se opta por utilizar elementos más compli-
cados pero que sean más flexibles.
Uno de los elementos más populares son los splines. Un spline12 es una función
polinómica a trozos que cuenta con cierta regularidad. Es decir, diferentes polinomios
sobre diferentes subintervalos se unen exigiendo además que la función resultante sea con-
r
tinua y derivable hasta cierto orden. Los representantes más sencillos son las constantes a
11
Es un sı́mil con lo que sucede si se dobla una vara muy rı́gida. El problema al utilizar polinomios es
que basta modificar un sólo dato para que el polinomio se cambie en todo el dominio, en muchas ocasiones
sin ningún control. Sin embargo, en un interpolante uno deberı́a esperar que la modificación de un punto
afectara sólo al entorno de dicho punto.
12
aceptaremos el anglicismo a partir de ahora.

255
11.2 Extensiones adicionales LECCIÓN V

trozos y las poligonales. En este último caso, se trata sencillamente de unir los puntos por
segmentos obteniéndose una curva poligonal. Sin embargo para las constantes a trozos no
podemos exigir continuidad y para las poligonales no podemos exigir derivabilidad en los
puntos de contacto (tiene picos).
Los splines cúbicos son probablemente los más utilizados. Partiendo de una subdivisión
del intervalo a = x0 < x1 < · · · < xn = b, se trata de construir una función sn tal que
Bo
sn (x)|[xi ,xi+1 ] ∈ P3 , i = 0, . . . , n − 1,
es decir, sea un polinomio de grado tres en cada subintervalo, cumpliendo que
sn (xi ) = yi , , i = 0, . . . , n,
esto es, que tome unos valores prefijados en los puntos de interpolación y de modo que
tanto la función sn como sus derivadas primera y segunda sean continuas13 en todo el
intervalo [a, b]. Por tanto tenemos que exigir que
lı́m s(j) (j)
n (x) = lı́m− sn (x), j = 0, 1, 2.
x→x+
j x→xj

La continuidad de la primera derivada preserva la existencia de recta tangente (no hay


picos) y por tanto la velocidad de recorrido de la curva, mientras que con la continuidad
rra
de la derivada segunda garantizamos que curvatura de la curva sea también continua en
todo el dominio de definición.
Dado que tenemos n subintervalos, y cuatro parámetros sobre cada intervalo (sn es un
polinomio de grado 3 en cada intervalo), disponemos de 4n variables. Por contra, los datos
de interpolación fijan n + 1 restricciones y las condiciones de continuidad del spline y de
sus dos primeras derivadas en las interfaces de los subintervalos dan otras 3n condiciones.
En total tenemos
n + 1 + 3(n − 1) = 4n − 2
restricciones, por lo que el problema precisa fijar dos condiciones adicionales para poder
hablar, siquiera plantear, la unicidad del spline.
Estas son algunas de las elecciones habituales
s00n (x0 ) = s00n (xn ) = 0, spline natural.
do
Datos adicionales s0n (x0 ) = y−1 , s0n (xn ) = yn+1 , spline grapado.
Condiciones de periodicidad: si los datos son periódicos se puede imponer s0n (x0 ) =
s0n (xn ), s00n (x0 ) = s00n (xn ), spline periódico.
No nos detendremos a detallar como se prueba la existencia y unicidad de tales splines,
ni la forma de calcularlos. Baste decir que se recurre a técnicas más eficientes, y por tanto
complejas, que la forma directa que se deduce de su definición.
Entre las buenas propiedades de los splines destacamos que convergen a la función si
ésta es continua. Aún es más, si la función f que se interpola es regular (de hecho basta
r
con que su derivada cuarta sea continua)
máx |sn (x) − f (x)| ≤ C máx(xj+1 − xj )4
x j

con C una constante dependiente de f pero independiente de los puntos.


13
Si forzáramos la continuidad de la tercera derivada tendrı́amos globalmente un polinomio de grado
tres.

256
LECCIÓN V Capı́tulo 11. Interpolación. Curvas Bézier

Nota. Los splines tienen un origen muy natural. Existı́a una herramienta de dibujo,
ya anticuada, que recibı́a el nombre de spline, o trazador en castellano. Consistı́a en
una especie de regla hecha de un material flexible que se moldeaba para hacer coincidir
el trazado por una serie de puntos. La curva ası́ trazada es fı́sicamente equivalente a
resolver el problema de construir una curva que pase por una serie de puntos y que
minimice la energı́a elástica. La solución matemática a este problema es un spline natural
Bo
(polinomio cúbico a trozos con derivada segunda nula en los extremos) lo que justifica su
denominación.
Se pueden definir splines de mayor grado, siguiendo exactamente la idea anterior, esto
es, pegando polinomios a trozos y dando la mayor regularidad posible. 

Splines en Matlab
Matlab dispone de dos comandos encargados de esta tarea:
ppval spline
El primero (piecewise polynomial value) evalúa una función polinómica a trozos. Uno
de sus argumentos es la propia estructura de la función según una sintaxis propia de
rra
Matlab. La segunda instrucción devuelve una estructura de este tipo que contiene el spline
que interpola a datos.
A modo de ejemplo, he aquı́ el spline natural que interpola a los datos desplegados en
la Figura 11.714
>> x0=linspace(0,1,21);
>> y0=[zeros(1,6) ones(1,15)];
>> p1=spline(x0,y0); % spline natural
>> x=linspace(0,1,200);
>> h=plot(x0,y0,’o’,x,ppval(p1,x),’r’,’linewidth’,2);
Por otro lado Matlab tiene implementada una serie de funciones para trabajar con
splines más generales en una toolbox. Al ejecutar splinetool podemos acceder a un
do
entorno gráfico donde testar las capacidades de Matlab en este campo.

Ejercicio 11.14 Se plantea el siguiente problema: dada una serie de puntos en el plano
n o
(x0 , y0 ), (x1 , y1 ), . . . , (xn , yn )

construir una curva en paramétricas

x(t) := (x(t), y(t)), t ∈ [0, T ] (11.12)

tal que
r
x(tj ) = (xj , yj ). (11.13)
Una buena elección es utilizar splines. Para ello se trata de calcular dos splines cx(t) y cy(t)
que satisfagan, obviamente,

cx(tj ) = xj , cy(tj ) = yj .
14
Los splines siguen conservando cierta rigidez pero se adaptan mucho mejor a los datos.

257
11.2 Extensiones adicionales LECCIÓN V

1.2

0.8
Bo
0.6

0.4

0.2

-0.2
0 0.2 0.4 0.6 0.8 1
rra
Figura 11.7: Interpolación con splines cúbicos naturales

Tenemos ası́ dos problemas de interpolación desacoplados, esto es, cada uno se resuelve in-
dependiente del otro. Queda como cuestión pendiente la elección de T en (11.12) y de los
puntos tj en (11.13). Una buena elección es tomar
q
hj := (xj+1 − xj )2 + (yj+1 − yj )2 ,

que coincide con la longitud del segmento que une (xj , yj ) y (xj+1 , yj+1 ), y hacer luego

t0 = 0, tk := h0 + h1 + . . . + hk−1 , T = tn .
do
Una vez ya calculados, la curva se dibuja evaluando

x(t) := (cx(t), cy(t)), t ∈ [0, T ].

Implementa un programa que siga este prototipo


01 SPLINE2D
02
03 SPLINE2D(X,Y) Traza una curva en el plano que pasa por
04 (X(i),Y(i)) utilizando splines cubicos
05
r
Ejercicio 11.15 El comando ginput permite introducir los puntos a través del ratón. Lee
bien la ayuda y modifica el programa anterior para que haga posible la lectura de los datos
con el ratón en caso de que se llame a la función sin argumentos.
Entre las posibilidades que ofrece está la de controlar qué tecla o botón del ratón se ha
utilizado.

258
LECCIÓN V Capı́tulo 11. Interpolación. Curvas Bézier

Ayuda. Deduce qué realiza el siguiente código...


x0=[]; y0=[]; n=length(x0);
salir=0;
cla
xlim([0,1]); ylim([0,1])
Bo
while salir==0
[xi,yi,b]=ginput(1);
if b==3 % boton derecho del raton
cla
if n>0 % borramos el ultimo punto
x0(n)=[]; y0(n)=[];
plot(x0,y0,’ro’)
xlim([0,1]); ylim([0,1])
n=n-1;
end
elseif isempty(b) % Se ha pulsado return: finalizamos lectura
salir=1;
rra
elseif b==2 % boton central: finalizamos la lectura
salir=1
else % introducimos el punto
x0=[x0 xi]; y0=[y0 yi];
plot(x0,y0,’o’)
n=n+1;
axis([0 1 0 1])
end
end

Nota. El comando gtext es similar a ginput. Despliega un texto en el punto selec-


cionado con el ratón. 
do
11.3. Curvas Bézier
Las curvas Bézier son curvas en el plano que quedan determinadas por un conjunto
de puntos que marcan su recorrido, aunque estas curvas no pasan necesariamente por
todos los puntos. Éstos forman un polı́gono de control en el siguiente sentido: la curva
está contenida en el polı́gono formado por esos puntos e imita con cierta libertad la
poligonal que dibujan.
La curva se construye utilizando los polinomios de Bernstein de orden n:
r
 
n n j
Bj (t) = t (1 − t)n−j , j = 0, 1, . . . , n.
j
Es un simple ejercicio comprobar que los polinomios cumplen las siguientes propiedades:

{Bjn }nj=0 son una base de Pn . Dicho de otra forma, cualquier polinomio se puede
escribir como una combinación de estos polinomios.

259
11.3 Curvas Bézier LECCIÓN V

n
X
Bjn (t) = 1, ∀t ∈ R.
j=0

A partir de unos puntos

xi = (xi , yi ), con i = 0, . . . , n,
Bo
se construye ahora la curva de Bézier utilizando estos polinomios:
n
X n
X n
X 
S(t) := Bjn (t)xj = Bjn (t)xj , Bjn (t)yj , t ∈ [0, 1].
j=0 j=0 j=0

El parámetro t se mueve de forma que para t = 0 estamos en el punto inicial y para t = 1,


en el final. Nótese que los puntos utilizados para dibujar la curva están ordenados: hay
un punto inicial x0 , uno final xn y a xj le sigue xj+1 ...
Podemos comprobar (véase la Figura 11.8), que la curva se adapta a la forma que mar-
can los puntos. Sin embargo, únicamente podemos garantizar que esta curva pasará por
el primer y último punto ya que S(0) = x0 y S(1) = xn pero en general S(t) 6= xj para
j 6= 0, n.
rra
1 1

0.8 0.8

0.6 0.6

0.4 0.4

0.2 0.2

0 0
do
0 0.2 0.4 0.6 0.8 1 0 0.2 0.4 0.6 0.8 1

1 1

0.8 0.8

0.6 0.6

0.4 0.4
r
0.2 0.2

0 0
0 0.2 0.4 0.6 0.8 1 0 0.2 0.4 0.6 0.8 1

Figura 11.8: Curvas Bézier para algunas configuraciones de puntos.

260
LECCIÓN V Capı́tulo 11. Interpolación. Curvas Bézier

Ejercicio 11.16 Utilizando el código mostrado en el Ejercicio 11.15, programa las curvas
Bézier. Compara con las curvas que definen la interpolación por splines y la polinómica.

Ejercicio 11.17 Implementa la siguiente extensión del programa anterior: permitir que el
usuario seleccione puntos y pueda moverlos o borrarlos (por ejemplo, con el botón derecho del
ratón) y ası́ comprobar la sensibilidad de la curva al polı́gono de control.
Bo
Una sugerencia: una vez leı́dos los puntos, y dibujada la correspondiente curva nos situamos
de nuevo en la ventana gráfica con ginput y leemos la selección hecha por el ratón. Ahora
hay tres opciones

Si pulsamos cerca de un punto, entendemos que hemos seleccionado dicho punto.

• Si se ha pulsado con el botón derecho lo eliminamos del dibujo, redibujamos la


curva y esperamos de nuevo.
• Si pulsamos cerca de un punto con el botón izquierdo entendemos que vamos a
mover ese punto. Esperamos otra selección del ratón (otro ginput), reemplazamos
el punto seleccionado por el nuevo y redibujamos.
rra
Si pulsamos lejos de todos los puntos, entendemos que añadimos un nuevo punto.
Llamémoslo y. En este punto hay un tema no trivial: cómo ordenamos el nuevo punto
y respecto a los puntos anteriores {xj }.

θj
x j+1
xj
do
x j+2

Figura 11.9: Ordenación de nodos para la curva Bézier.

Una forma de determinar15 este orden es medir el ángulo entre los vectores

u=−
x−→
j y, v=−
x−−→
j+1 y
r
y quedarse con aquél para el que ángulo θj sea mayor (véase la Figura 11.9). Para ello,
basta utilizar que
|u · v|
| cos(θj )| = .
kukkvk
15
Gracias a Jon Garcı́a por sugerirnos esta solución.

261
11.3 Curvas Bézier LECCIÓN V

Escogeremos entonces j para que | cos(θj )| sea mı́nimo, y construiremos la curva Bézier
con puntos
{x1 , . . . , xj , y, xj+1 , . . . , xn }
{xj , xj+1 }.
Bo
Nota. Las curvas Bézier fueron introducidas por los ingenieros Pierre Bézier y Paul
de Casteljau, que trabajaban entonces en Renault y Citröen. Concretamente, buscaban
herramientas para el diseño de parachoques de forma que la curva que diera su forma
fuera controlada por una serie de puntos y que tuviera buenas propiedades geométric-
as. Los algoritmos iniciales (todavı́a se utilizan en la práctica hoy en dı́a) seguı́an ideas
muy geométricas16 , y se tardó algún tiempo en darle la forma que hemos mostrado, más
matemática. Como resultado de este estudio surgieron las curvas B-spline, que reemplaz-
aban a los polinomios de Bernstein por splines de grados adecuados. Las curvas B-spline
son más flexibles que las curvas Bézier y en su caso lı́mite incluyen a éstas. Por lo tanto
pueden interpretarse como una generalización de las mismas.
Por otro lado existen formas mucho más eficientes de evaluar y calcular este tipo de
curvas que permiten en última media su implementación en una forma más interactiva,
rra
de forma que el usuario mueva los puntos (cambie el polı́gono de control) y que la curva
se redibuje constantemente. 
do
r
16
La versión original ni siquiera hablaba de polinomios.

262
Bibliografı́a
Bo
[1] Atkinson, K. (1993): Elementary Numerical Analysis. Wiley.
[2] Burden, R.L. y Faires, J.D. (1998): Análisis Numérico. International THOMSON.
[3] Chapman, S.J. (1997): Fortran 90/95 for Scientists and Engineers. McGraw-Hill.
[4] Chapman, S.J. (2002): Matlab Programming for Engineers. Books/Cole.
[5] Cooper, J. (2001): A Matlab Companion for Multivariate Calculus.Academic Press.
rra
[6] Eriksson, K.E., Step, D. y Johnson, C. (2004): Applied Mathematics: body and soul.
Springer Verlag.
[7] Garcı́a de Jalón, J. (2004): Aprenda Matlab 6.5 como si estuviera en primero.
Publicación electrónica, disponible en
http://mat21.etsii.upm.es/ayudainf/aprendainf/varios.htm
[8] Gander, W. y Hřebı́ček, J. (2004): Solving problems in Scientific Computing using
Maple and Matlab. Springer–Verlag.
[9] Golub, G.H. y van Loan, C.F. (1989): Matrix Computations. University Press.
[10] Golub, G.H. y van der Vorst, H. (2000): “Eigenvalue computation in the 20th centu-
ry” en J. Comput. Appl. Math. 123 (2000), 35–65.
do
[11] Greenbaum, A. (1997): Iterative Methods for Linear Systems. SIAM.
[12] Hänmerlin, G. y Hoffmann, K.H. (1991): Numerical Mathematics. Springer–Verlag.
[13] Hanselman, D. y Littlefield, B.R. (2000): Mastering Matlab 6. Prentice Hall.
[14] Higham, D.J. y Higham, N.J. (2005): Matlab guide. SIAM.
[15] Hoffman, J., Johnson, C. y Logg, A. (2004): Dreams of Calculus. Springer.
[16] Infante, J.A. y Rey, J.M. (2002): Métodos numéricos. Teorı́a, problemas y prácticas
r
con Matlab. Anaya.
[17] Kharab, A. y Guenther, R.B. (2001): An Introduction to Numerical Methods: A MAT-
LAB Approach. Chapman & Hall.
[18] Kincaid, D. y Cheney, W. (1994): Análisis numérico. Las matemáticas del cálculo
cientı́fico. Addison–Wesley Iberoamericana.
[19] Kress, R. (1988): Numerical Analysis. Springer Verlag.

[20] The MacTutor History of Mathematics archive, University of St. Andrew,


http://turnbull.mcs.st-and.ac.uk/ history/.

[21] Marchand, P. y Holland, T.O. (2003): Graphics and GUIs with Matlab, tercera edi-
ción. Chapman & Hall/CRC.
Bo
[22] Maron, M.J. (1987): Numerical Analysis. A practical approach. Macmillan.

[23] Mathews, J.H. y Fink, K.(2000): Métodos Numéricos con Matlab. Prentice Hall.

[24] Mathworks, http://www.mathworks.com/products/.

[25] Meurant, G. (1999): Computer solution of Large Linear systems. North Holland.

[26] Moler, C. (2004): Numerical computing with Matlab. SIAM.

[27] Palm, W.J. (2004): Introduction to Matlab 7 for engineers. McGraw-Hill.

[28] Quarteroni, A., Sacco, R. y Salery, F. (2000): Numerical Mathematics. Springer.


rra
[29] Quarteroni, A. y Salery, F. (2003): Scientific computing with Matlab. Springer.

[30] Wikipedia: the free enciclopedy, http://www.wikipedia.org.

[31] Saasd, Y. y van der Vorst, H.A. (2000): “Iterative solution of linear systems in the
20th century” en J. Comput. Appl. Math., 123, 1-33 (2000).

[32] Stewart, G.W. (1996): Afternotes in Numerical Analysis. SIAM.

[33] Stewart, G.W. (2001):Matrix Algorithms: Vol. I. Basic decompositions. SIAM.

[34] Süli, E. y Mayers, D. (2003): An Introduction to Numerical Analysis. Cambridge


University Press.
do
r
264
Índice de figuras
Bo
2.1. Pantalla Principal. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.2. Pantalla de ayuda. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.3. Ayuda con helpwin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
2.4. Ayuda on line. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

4.1. Diagrama de un matriz sparse . . . . . . . . . . . . . . . . . . . . . . . . 64

5.1. Resultado de reordenar las filas y columnas con symrcm y symmmd. . . . . 73


rra
5.2. Eliminación gaussiana y su representación como un grafo. . . . . . . . . . 75
5.3. Historial del residuo para el método del Gradiente. . . . . . . . . . . . . . 93
5.4. Historial del residuo para el método del Gradiente Conjugado . . . . . . . 98
5.5. Efecto del en el Gradiente Conjugado. . . . . . . . . . . . . . . . . . . . . 103

7.1. Reglas de cuadratura: punto medio y trapecio . . . . . . . . . . . . . . . 116


7.2. Regla de Simpson . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
7.3. Diagrama del método de Romberg . . . . . . . . . . . . . . . . . . . . . . 128
7.4. Integración adaptativa . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130

7.5. Integración adaptativa de x . . . . . . . . . . . . . . . . . . . . . . . . 133
7.6. Primeras exponenciales trigonométricas. . . . . . . . . . . . . . . . . . . . 136
7.7. Coeficientes de Fourier y transformada discreta de Fourier . . . . . . . . . 143
do
7.8. Ruido y su Transformada de Fourier Discreta . . . . . . . . . . . . . . . . 144
7.9. Filtrado del ruido . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145

9.1. Profile aplicado al método de Jacobi. . . . . . . . . . . . . . . . . . . . 184


9.2. Una web muy sencilla. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197

10.1. Ventana gráfica. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208


10.2. Ventana gráfica. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210
10.3. Edición de un dibujo. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212
10.4. Una muestra de dibujos. . . . . . . . . . . . . . . . . . . . . . . . . . . . 214
10.5. Modificación del entorno del dibujo. . . . . . . . . . . . . . . . . . . . . . 218
r
10.6. Ejemplo de numeración con subplot. . . . . . . . . . . . . . . . . . . . . 219
10.7. Disposición simultánea de gráficas con subplot. . . . . . . . . . . . . . . 221
10.8. Un dibujo en 3D con plot3. . . . . . . . . . . . . . . . . . . . . . . . . . 222
10.9. Icono para rotar los dibujos. . . . . . . . . . . . . . . . . . . . . . . . . . 223
10.10. Ejemplo de una superficie creada con surf. . . . . . . . . . . . . . . . . . 224
10.11. Otro ejemplo de surf. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225

265
10.12. Utilización de nan en un dibujo. . . . . . . . . . . . . . . . . . . . . . . . 226
10.13. Algunas opciones con surf. . . . . . . . . . . . . . . . . . . . . . . . . . 228
10.14. Esferas en 3D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230
10.15. Una superficie con surf y pcolor. . . . . . . . . . . . . . . . . . . . . . . 231
10.16. Lı́neas de nivel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232
10.17. Campo de velocidades con quiver . . . . . . . . . . . . . . . . . . . . . . 233
Bo
10.18. Triangulación no conforme. . . . . . . . . . . . . . . . . . . . . . . . . . . 235
10.19. Numeración de triángulos . . . . . . . . . . . . . . . . . . . . . . . . . . . 236
10.20. Un dominio mallado en triángulos. . . . . . . . . . . . . . . . . . . . . . . 237

11.1. Dos formas de escribir y evaluar un polinomio. . . . . . . . . . . . . . . . 240


11.2. Polinomios de interpolación con diferentes grados y el error cometido. . . 243
11.3. Estructura del cálculo de las diferencias dividas. . . . . . . . . . . . . . . 246
11.4. Ejemplo de Runge. Polinomio de interpolación y error cometido. . . . . . 250
11.5. Ejemplo de Runge con otros nodos. . . . . . . . . . . . . . . . . . . . . . 251
11.6. Rigidez polinómica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255
11.7. Interpolación con splines cúbicos naturales . . . . . . . . . . . . . . . . . 258
11.8. Curvas Bézier para algunas configuraciones de puntos. . . . . . . . . . . . 260
rra
11.9. Ordenación de nodos para la curva Bézier. . . . . . . . . . . . . . . . . . 261
do
r
266
Índice general
Bo
1. Introducción 1
1.1. ¿Qué es? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.2. ¿Cómo trabaja? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.3. ¿Cómo aprenderemos? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

I Primeros pasos en Matlab.


rra
Métodos directos para sistemas de ecuaciones lineales 5
2. Matlab: Primeros pasos 9
2.1. Entorno de trabajo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.2. Comandos de ayuda . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.3. Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
2.4. Ficheros script y funciones . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
2.4.1. Ficheros script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
2.4.2. Funciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
2.5. Vectores y matrices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
2.5.1. Definición de matrices y vectores . . . . . . . . . . . . . . . . . . . 22
2.5.2. Operaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
do
2.5.3. Detalles adicionales . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
2.5.4. Acceso a partes de matrices . . . . . . . . . . . . . . . . . . . . . . 27
2.6. Bucles y estructuras de decisión . . . . . . . . . . . . . . . . . . . . . . . . 30
2.6.1. Bucles: el comando for . . . . . . . . . . . . . . . . . . . . . . . . . 30
2.6.2. Operadores lógicos y estructuras de decisión . . . . . . . . . . . . . 31

3. Métodos directos para sistemas de ecuaciones lineales 37


3.1. Método de Gauss . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
3.1.1. Método de Gauss sin pivotaje . . . . . . . . . . . . . . . . . . . . . 38
r
3.1.2. Método de Gauss con pivotaje parcial . . . . . . . . . . . . . . . . . 41
3.1.3. Método de Gauss con pivotaje parcial ficticio . . . . . . . . . . . . 43
3.2. Descomposiciones matriciales . . . . . . . . . . . . . . . . . . . . . . . . . 44
3.2.1. Descomposición LU . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
3.2.2. Casos particulares . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
3.2.3. Comandos correspondientes en Matlab . . . . . . . . . . . . . . . . 48

267
II Programación Avanzada. Métodos iterativos 51
4. Matlab: programación avanzada 55
4.1. Retorno a las matrices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
4.1.1. Acceso a partes estructuradas de una matriz . . . . . . . . . . . . . 55
4.1.2. Más operaciones sobre matrices . . . . . . . . . . . . . . . . . . . . 60
Bo
4.1.3. Matrices sparse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
4.2. Argumentos de funciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66

5. Matrices sparse en Matematicas. Metodos iterativos 71


5.1. Método de Gauss para matrices sparse . . . . . . . . . . . . . . . . . . . . 71
5.2. Métodos iterativos para sistemas lineales . . . . . . . . . . . . . . . . . . . 76
5.2.1. Definición . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
5.2.2. Detalles sobre la implementación . . . . . . . . . . . . . . . . . . . 78
5.2.3. Métodos iterativos clásicos . . . . . . . . . . . . . . . . . . . . . . . 79
5.2.4. Métodos de tipo gradiente . . . . . . . . . . . . . . . . . . . . . . . 88
rra
III Funciones como argumento. Recursividad
Fórmulas de cuadratura. FFT 105
6. Matlab: Funciones como argumentos. Recursividad 109
6.1. Funciones inline . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
6.2. Funciones como argumentos . . . . . . . . . . . . . . . . . . . . . . . . . . 111
6.2.1. Recursividad . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112

7. Fórmulas de cuadratura. FFT 115


7.1. Fórmulas de cuadratura . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
7.1.1. Primeras nociones . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
7.1.2. Reglas simples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
7.1.3. Retorno a las reglas compuestas . . . . . . . . . . . . . . . . . . . . 122
do
7.1.4. Reglas gaussianas . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
7.1.5. Extrapolación de Richardson . . . . . . . . . . . . . . . . . . . . . . 126
7.1.6. Integración adaptativa . . . . . . . . . . . . . . . . . . . . . . . . . 129
7.2. Transformada rápida de Fourier . . . . . . . . . . . . . . . . . . . . . . . . 134
7.2.1. Transformada de Fourier discreta . . . . . . . . . . . . . . . . . . . 135
7.2.2. Cálculo de la transformada de Fourier Discreta . . . . . . . . . . . . 140
7.2.3. Aplicaciones a la eliminación de ruido . . . . . . . . . . . . . . . . . 142
7.2.4. Transformada rápida de Fourier . . . . . . . . . . . . . . . . . . . . 144
r
IV Cálculo simbólico, arrays y celdas en Matlab. Valores y
vectores propios. Google. 153
8. Matlab: Cálculo simbólico y estructuras de datos. 157
8.1. Polinomios y cálculo simbólico . . . . . . . . . . . . . . . . . . . . . . . . . 157
8.1.1. Polinomios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157

268
8.2. Procesador simbólico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161
8.3. Tensores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164
8.4. Vectores de celdas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168

9. Cálculo numérico de valores y vectores propios. 171


9.1. Introducción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171
Bo
9.2. Matrices semejantes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173
9.3. Método de potencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174
9.3.1. Descripción del método . . . . . . . . . . . . . . . . . . . . . . . . . 174
9.3.2. Variantes del método de potencias . . . . . . . . . . . . . . . . . . . 178
9.4. Método de Jacobi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179
9.4.1. Descripción del método . . . . . . . . . . . . . . . . . . . . . . . . . 179
9.4.2. Variantes del método de Jacobi . . . . . . . . . . . . . . . . . . . . 183
9.5. Método QR de Francis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185
9.5.1. Factorización QR . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186
9.5.2. Método QR de Francis . . . . . . . . . . . . . . . . . . . . . . . . . 192
9.5.3. Comentarios adicionales . . . . . . . . . . . . . . . . . . . . . . . . 193
9.6. Valores y vectores propios en Matlab . . . . . . . . . . . . . . . . . . . . . 195
rra
9.7. Notas históricas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196
9.8. Google . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196

V Salidas gráficas en Matlab. Interpolación 203


10.Matlab: Salidas gráficas en Matlab 207
10.1. Dibujos bidimensionales . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207
10.1.1. El comando plot . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207
10.1.2. Comandos asociados a plot . . . . . . . . . . . . . . . . . . . . . . 213
10.1.3. Comandos get y set . . . . . . . . . . . . . . . . . . . . . . . . . . 215
10.1.4. El comando subplot . . . . . . . . . . . . . . . . . . . . . . . . . . 219
10.1.5. Otras salidas gráficas . . . . . . . . . . . . . . . . . . . . . . . . . . 220
do
10.2. Gráficas en 3D . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221
10.2.1. El comando plot3 . . . . . . . . . . . . . . . . . . . . . . . . . . . 221
10.2.2. El comando surf . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223
10.2.3. Otros comandos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231
10.2.4. Comandos fáciles de usar . . . . . . . . . . . . . . . . . . . . . . . 233
10.3. Campos vectoriales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233
10.4. Dibujos sobre dominios mallados en triángulos . . . . . . . . . . . . . . . . 234

11.Interpolación. Curvas Bézier 239


11.1. Interpolación polinómica . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239
r
11.1.1. Interpolación polinómica de Lagrange . . . . . . . . . . . . . . . . . 239
11.1.2. Existencia del polinomio de interpolación . . . . . . . . . . . . . . . 240
11.1.3. Fórmula de Newton . . . . . . . . . . . . . . . . . . . . . . . . . . . 242
11.1.4. Análisis del error de interpolación . . . . . . . . . . . . . . . . . . . 249
11.2. Extensiones adicionales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252
11.2.1. Interpolación de Hermite . . . . . . . . . . . . . . . . . . . . . . . . 252

269
11.2.2. Interpolación de funciones periódicas . . . . . . . . . . . . . . . . . 254
11.2.3. Interpolación polinómica a trozos . . . . . . . . . . . . . . . . . . . 255
11.3. Curvas Bézier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259
Bo
rra
do
r
270
Índice de comandos de Matlab
Bo
[], 30 blkdiag, 57
%, 10 break, 31
|, 32 ButtonDownFcn, 216
&, 32
’, 57 celldisp, 167
.’, 58 chol, 49
./, 24 cholinc, 100
/, 24 cla, 211
<, 32 clabel, 230
<=, 32 clear, 18
rra
==, 32 clf, 211
>, 32 collect, 161
>=, 32 colorbar, 223
@, 110 colormap, 223
\, 24 cond, 63
\., 24 continue, 31
~=, 32 contour, 229
: contourf, 229
def. de vectores, 27 conv, 150, 155
selección de submatrices, 28 cos, 10, 15
cosh, 15
abs, 13 cot, 15
do
acos, 15 csc, 15
acosh, 15 cylinder, 228
acot, 15
acsc, 15 daspect, 223
angle, 13 dblquad, 132
ans, 11 dct, 147
area, 218 deconv, 155
asec, 15 det, 24
asin, 15 diag, 55
asinh, 15 dot, 60, 63
r
atan, 15 dsolve, 161
atanh, 15 dst, 147
axis, 211, 213
edit, 19
bar, 218 eig, 193
bar3, 218 eigs, 193
barh, 218 ellipsoid, 228

271
else, 33 hilb, 26
elseif, 34 hold, 207
end
con for, 30 i,j, 13
con if, 33 idct, 147
con while, 35 idst, 147
Bo
en arrays, 35 if, 33
eps, 20 ifft, 147
exp, 15 ifourier, 160
expand, 161 ilaplace, 160
eye, 26 inf, 12
ezcontour, 231 initmesh, 236
ezcontourf, 231 inline, 107
ezmesh, 231 input, 110
ezmeshc, 231 inv, 24
ezplot, 218 invhilb, 26
ezplot3, 231 isempty, 91, 174
ezpolar, 218
rra
laplace, 160
ezsurf, 231
legend, 211
ezsurfc, 231
length, 25
factor, 161 limit, 160
factorial, 111 line, 218
feval, 109 linspace, 27
fft, 147 load, 18
figure, 207 log, 15
fill, 218 log10, 10, 15
fontangle, 212 log2, 15
fontname, 212 logical, 33
fontsize, 212 loglog, 218
do
fontweight, 212 lookfor, 14
for, 30 lu, 49
format, 12
fourier, 160 maple, 162
full, 65 max, 42, 61
function, 20 mesh, 230
meshc, 230
gca, 215 meshgrid, 221
gcf, 215 meshz, 230
get, 213 mhelp, 162
r
ginput, 256 min, 61
grid, 211 mldivide, 25
gtext, 257 mod, 146
mrdivide, 25
help, 14
helpwin, 14 NaN, 12
hess, 193 en dibujos, 223

272
nargin, 66 roots, 157
nargout, 66 rotate, 212
nnz, 65
norm, 62 save, 18
num2str, 149 schur, 191
sec, 15
Bo
ones, 26 semilogx, 218
semilogy, 91, 218
pascal, 26 set, 213
patch, 218 sign, 15
pbaspect, 223 simple, 161
pcg, 100 simplify, 161
pcolor, 229 sin, 10, 14, 15
pdetool, 236 sinh, 15
pi, 12 size, 25
plot, 110, 205 solve, 161
color, 208 spalloc, 65
LineWidth, 208 sparse, 64
rra
Marker, 208 spdiags, 66
MarkerEdgeColor, 208 speye, 66
MarkerFaceColor, 208 sphere, 228
MarkerSize, 208
spline, 255
plot3, 219
splinetool, 255
plotyy, 218
spones, 66
polar, 218
sprand, 66
poly, 157
sprandn, 66
polyder, 161
spy, 65
polyfit, 246
sqrt, 11
polyint, 161
stairs, 218
polyval, 156
stem, 218
do
power, 15
str2num, 149
ppval, 255
subplot, 217
profile, 181
sum, 61
qr, 49, 188 surf, 221
quad, 132 EdgeAlpha, 225
quadl, 132 EdgeColor, 225
quiver, 231 FaceAlpha, 225
quiver3, 231 FaceColor, 225
LineStyle, 225
rank, 63 LineWidth, 225
r
rcond, 63 Marker, 225
realmax, 20 MarkerEdgeColor, 225
realmin, 20 MarkerSize, 225
refinemesh, 236 MeshStyle, 225
reshape, 60 surfc, 230
return, 20 surfl, 230

273
svd, 194
switch, 35
symamd, 72
symmmd, 70
symrcm, 70
symsum, 160
Bo
tan, 15
tanh, 15
taylor, 160
text, 211
tic, 183
title, 211
toc, 183
tril, 55
trimesh, 236
triplequad, 132
trisurf, 236
rra
triu, 55

varargin, 66
varargout, 66
vectorize, 108
view, 223
vpa, 160

waterfall, 230
while, 35
whitebg, 211
who, 17
whos, 17
do
xlabel, 211
xlim, 211

ylabel, 211
ylim, 211

zeros, 23, 26
zlabel, 220
zlim, 220
r
274