Está en la página 1de 75

FORMULARIO BÁSICO

COMANDOS DE SCILAB
A=[1 2 3; 4 5 6] Introducción de una matriz (ejemplo).
A=[1; 2; 3] Introducción de un vector (ejemplo).
A(i,j) Elemento de una matriz A situado en la posición
(i, j)
rref(A) Calcula la forma escalonada reducida de una matriz
A
A\b Si el sistema A~x = ~b es compatible, devuelve una
solución. Si es incompatible devuelve una “solución
por mínimos cuadrados”.
rank(A) Rango de A.
eye(n,n) Matriz identidad n × n.
ones(m,n) Matriz de unos m × n.
zeros(m,n) Matriz de ceros m × n.
kernel(A) Núcleo de la matriz A; devuelve una matriz cuyas
columnas forman una base del núcleo de A.
D=diag(diag(A)) Permite calcular la matriz D de la descomposición
A=L+D+U de una matriz A necesaria para apli-
car los métodos numéricos de resolución de siste-
mas.
L=tril(A)-D Permite calcular la matriz L de la descomposición
anterior.
U=triu(A)-D Permite calcular la matriz U de la descomposición
anterior.
inv(A) Calcula la inversa de una matriz A.
[L,U]=lu(A) Calcula una descomposición LU de A.
det(A) Determinante de A.
norm(u) Norma de un vector ~u.
sum(u) Suma de las componentes de un vector ~u.
for i=1:n sentencias; end; Sintaxis del bucle for.
FÓRMULAS
~xk+1 = D−1 [~b − (L + U)~xk ] Recurrencia del método de Jaco-
bi.
(L + D)~xk+1 = ~b − U~xk Recurrencia del método de
Gauss-Seidel.
~a t ~
x
P royW (~x) = ~a t~a
~a Proyección ortogonal de un vec-
tor ~x sobre la recta W generada
por un vector ~a.
M(S) Matriz cuyas columnas son los
vectores de un conjunto S.
M(S)t M(S)~y = M(S)t~x; P royW (~x) = M(S)~y Proyección ortogonal de un vec-
tor ~x sobre sobre un subespacio
vectorial W = hSi.
PW = M(S)(M(S)t M(S))−1 M(S)t Matriz de proyección.
Práctica 0 de Álgebra
Introducción a Scilab

Índice
1. Introducción 2

2. Introducción de datos en Scilab 2

3. Ayuda 6

4. Cómo guardar y recuperar sesiones 6

5. Operaciones con escalares 7

6. Operaciones con matrices 7


6.1. Operaciones básicas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
6.2. Otras operaciones con matrices . . . . . . . . . . . . . . . . . . . . . . . . . 9
6.3. Operaciones elemento a elemento . . . . . . . . . . . . . . . . . . . . . . . . 9
6.4. Tipos especiales de matrices . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

7. Manipulación interna de matrices 10

8. Polinomios 12

9. Estructuras de decisión y bucle con Scilab 13


9.1. El condicional if . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
9.2. El bucle for . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
9.3. El bucle while . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

10.Funciones con Scilab 15

11.Fin de sesión 16

1
1. Introducción
El programa Scilab trabaja fundamentalmente con matrices de coeficientes reales, complejos
o booleanos. En esta práctica se pretende describir el funcionamiento básico del programa y
todos los aspectos básicos sobre Scilab que los alumnos han de conocer para poder realizar las
prácticas de Matemática Discreta y de Álgebra.
Scilab es un programa libre. En particular, se puede utilizar y distribuir libremente y consultar
y modificar el código fuente en las condiciones de su licencia. El programa se puede descargar
de http://www.scilab.org. Estas prácticas, con ligeras modificaciones, pueden realizarse
con otros programas de sintaxis similar, por ejemplo sistemas libres, como Octave, o sistemas
comerciales como Matlab.
Empezaremos indicando el funcionamiento básico del programa, indicando las diversas ma-
neras de introducir matrices en Scilab y como manipularlas. A continuación describiremos como
realizar con Scilab las principales operaciones matemáticas entre matrices. Terminaremos la
práctica mostrando algunas de las estructuras de decisión y de bucles más habituales en Scilab.
El programa Scilab está disponible para diversas plataformas, entre las cuáles podemos
destacar GNU/Linux, Microsoft Windows y MacOSX.
A lo largo de las diferentes prácticas iremos introduciendo más operadores, comandos y
funciones básicas según las vayamos necesitando y describiremos con más detalle su funcio-
namiento. Únicamente pretendemos dar aquí los principales operadores, comandos y funciones
básicos para poderlos buscar después con más facilidad.
Los ejemplos que se muestran están desarrollados con la versión 4.1.2 de Scilab bajo el
sistema operativo GNU/Linux con un procesador Intel R CoreTM 2 Duo E8400 a 3 GHz. La
ejecución de Scilab en otras plataformas o sistemas operativos pueden dar resultados ligeramente
diferentes, por lo que habrá que prestar atención.
En estos boletines utilizaremos los siguientes convenios tipográficos:
Las instrucciones que se introducen desde el teclado aparecerán en un tipo de letra
mecanográfico en negrita (por ejemplo, entrada).
Los resultados o la salida de Scilab aparecerán en un tipo de letra mecanográfica de grosor
mediano (por ejemplo, salida).
Las expresiones genéricas en la descripción de los comandos de Scilab aparecerán con
letra mecanográfica cursiva (por ejemplo, si aparece nombre =expresión , entenderemos
que nombre y expresión se han de sustituir por las cadenas adecuadas en Scilab).

2. Introducción de datos en Scilab


El programa Scilab se puede ejecutar escribiendo en una línea de comandos
scilab
o, en un entorno gráfico de ventanas, haciendo doble clic (o clic sencillo) sobre el icono corres-
pondiente o buscándolo en el menú adecuado. Aparece una ventana con el siguiente texto:

2
scilab-4.1.2

Copyright (c) 1989-2007


Consortium Scilab (INRIA, ENPC)
-------------------------------------------

Startup execution:
loading initial environment

-->

Si se llama al programa Scilab con la opción -nw, el texto aparece en el terminal, sin ventana
nueva. Esta opción es adecuada si no se necesitan capacidades gráficas o sólo se dispone de un
terminal de texto.
La marca --> nos indica que podemos introducir comandos.
Los vectores se introducen escribiendo ordenadamente sus componentes separadas por una
coma (,) o por un espacio en blanco y cerrando toda la expresión entre corchetes ([ ]). Los
escalares se introducen directamente, sin necesidad de corchetes, y, en el caso de números
decimales, separando la parte entera de la decimal con un punto (.).
Por ejemplo, el escalar a = 2 se introduce tecleando
a=2
y al pulsar la tecla  aparece
-->a=2
a =

2.

-->
El vector ~v = (1, −1, 3) se introduce con
-->v=[1 -1 3]
v =

1. - 1. 3.
o con
-->v=[1,-1,3]
v =

1. - 1. 3.

3
Nota: En algunas versiones del programa aparecen signos de exclamación alrededor de las
matrices.
Una matriz de tipo m × n es una colección de m × n números organizados en m filas y
n columnas. Si A es una matriz, ai,j denota el término que ocupa la fila i y columna j de la
matriz y podemos escribir que A = (ai,j ).
En Scilab, los elementos de una matriz se introducen entre corchetes [ ], escribiendo
ordenadamente los elementos de cada fila separados por comas o por espacios en blanco y
separando las filas por punto y coma (;) o el carácter  (retorno de carro). No hace falta
indicar previamente el tamaño de las matrices.
Por ejemplo, la matriz  
1 2 3
A = 4 5 6
7 8 9
se puede introducir en Scilab como

A=[1 2 3;4 5 6;7 8 9]


o como

A=[1 2 3
4 5 6
7 8 9]
o también como

A=[1 2,3;4 5 6
7 8 9]
Al introducir alguna de estas expresiones y pulsar  se obtiene

A =

1. 2. 3.
4. 5. 6.
7. 8. 9.

Ejemplo 1. Introducir la matriz A del ejemplo anterior. La pantalla de Scilab ha de quedar


aproximadamente como se muestra en la figura 1.

Las instrucciones de Scilab tienen la forma

variable =expresión

o, simplemente,

expresión

4
Figura 1: Introducción de una matriz a Scilab

Los nombres de las variables han de empezar por una letra, seguida de más letras o dígitos,
hasta un máximo de 25 caracteres. Scilab no ejecuta las sentencias hasta que no se pulsa
 . Si una sentencia acaba con punto y coma (;), el resultado no se muestra en la pantalla,
aunque el resultado se almacena en la memoria. Scilab distingue entre mayúsculas y minúsculas.
Naturalmente, no se pueden utilizar otros comandos de Scilab como nombre de variables.
Es posible incluir diversas instrucciones en una misma línea separándolas por una coma (,),
para mostrar los resultados, o por punto y coma (;), para no mostrarlos. De la misma forma, si
una sentencia es muy larga y no cabe en una línea, se puede separar en diversas líneas poniendo
al final de cada línea tres o más puntos (...).
Es posible recordar ordenes anteriores con las teclas de las flechas.
Si una expresión es asignada a una variable, ésta permanece almacenada como una varia-
ble de trabajo durante toda la sesión (o hasta que se le asigne otro valor o se borre con la
instrucción clear, que borra todas las variables, o clear seguido del nombre de una o más
variables para borrarlas). De esta forma, para recuperar esta expresión en cualquier momento,

5
será suficiente escribir el nombre de la variable. Si utilizamos la segunda forma de las instruc-
ciones, el resultado se almacena en la variable ans. Eso nos permite recuperar el resultado de
la operación inmediatamente anterior si no lo hemos asignado a otra variable.
Los comandos who y whos nos indican cuáles son las variables del entorno de trabajo.
Los comentarios se introducen precedidos de los caracteres // (dos barras) fuera de una
cadena. Todo lo que haya detrás no se ejecuta.

3. Ayuda
Podemos encontrar ayuda sobre cualquiera de los comandos o funciones de Scilab escribiendo
help o, si se usa Scilab en un entorno gráfico, pinchando con el ratón sobre el botón Help.
También podemos encontrar ayuda sobre un comando específico tecleando
help comando

4. Cómo guardar y recuperar sesiones


Es posible guardar todas las variables del entorno de trabajo con el comando save. Por
ejemplo,

-->save('fichero.dat')

guarda todas las variables en el fichero fichero.dat, mientras que

-->save('fichero.dat',A,b,c)

guarda las variables A, b y c en el fichero. Para recuperar el contenido de los ficheros, se utiliza
el comando load con la sintaxis

-->load('fichero.dat','A','b','c')

Para guardar el contenido de una sesión de trabajo, se usa el comando diary:

-->diary('fichero.txt')

empieza la grabación de toda la sesión de trabajo en el fichero de texto fichero.txt. Para


concluir la grabación utilizaremos

-->diary(0)

Si el fichero ya existe previamente se borrará. Por eso hay que prestar mucha atención al escribir
el nombre del fichero. Una buena estrategia es incluir la fecha (y, si es necesario, la hora) en el
nombre del fichero. Por ejemplo,

-->diary('md221010.txt');

6
5. Operaciones con escalares
Scilab es capaz de trabajar con escalares reales y complejos. Para trabajar con números
decimales, la parte entera y la decimal se separan mediante un punto (.). Las operaciones
suma, resta y multiplicación se hacen con los operadores +, - y *, respectivamente. La potencia
de un escalar a a un escalar p la escribiremos a ˆ p . Las raíces cuadradas se pueden calcular
también con el operador sqrt. Las raíces de otros índices se pueden
√ representar como potencias
de exponentes fraccionarios, como por ejemplo 2ˆ (1/3) para 3 2. Para la división hay dos
operadores, / y \. Por ejemplo, a /b quiere decir a dividido entre b , mientras que a \b quiere
decir b dividido entre a .
La jerarquía de los operadores mencionados es la habitual: de mayor (el último en ejecución)
a menor (el primero en ejecución) es la siguiente:

+ - * / \ ˆ

Para variar el orden de ejecución utilizaremos los paréntesis.


p
Ejemplo 2. Calculemos con Scilab el valor de la expresión 2x3 y + y 5 z, con x = 1,5, y = 3,7,
z = 9.
Primero introducimos las variables

-->x=1.5; y=3.7; z=9;

Seguidamente, introducimos la expresión:

-->2*x^3*y+sqrt(y^5*z)
ans =

103.97472

El resultado es 103,97472.

6. Operaciones con matrices


Seguidamente mostraremos como se ejecutan con Scilab las operaciones matriciales habitua-
les y otras que serán útiles para algunas prácticas. Como los vectores no son más que matrices
con una única fila, las operaciones que se describan serán también válidas para vectores.

6.1. Operaciones básicas


Suma y resta de matrices: Para sumar dos matrices utilizaremos el operador + y para res-
tarlas el operador -. Las dos matrices han de tener el mismo tamaño (es decir, el mismo
número de filas y de columnas). Si se pretende sumar o restar matrices que no tienen el
mismo tamaño, Scilab nos indicará que hemos cometido un error.

7
Producto de un escalar por una matriz: Se realiza con el operador *.

Producto de matrices: Se realiza también con el operador *. El número de columnas de la


primera matriz ha de coincidir con el número de filas de la segunda matriz. Si se pretende
multiplicar dos matrices que no satisfacen esta condición, se obtiene un mensaje de error.

Potencia de una matriz: Para calcular el producto de una matriz A por ella misma n veces,
utilizaremos el operador ˆ . Por ejemplo, Aˆ n. Si la matriz no es cuadrada, Scilab nos dará
un mensaje de error.

Ejemplo 3. A continuación mostramos cálculos con matrices.

-->X=[1 2;3 -1]


X =

1. 2.
3. - 1.

-->Y=[0 1]
Y =

0. 1.

-->X*Y
!--error 10
inconsistent multiplication

-->X+Y
!--error 8
inconsistent addition

-->X-Y
!--error 9
inconsistent subtraction

-->Y*X
ans =

3. - 1.

8
6.2. Otras operaciones con matrices
Inversa de una matriz: Scilab calcula la inversa de una matriz cuadrada (si existe) con la
función inv(). Si la matriz introducida no tiene inversa, aparecerá un mensaje de error. En
las prácticas de Álgebra Lineal estudiaremos el funcionamiento detallado de esta función.

Traspuesta de una matriz: La matriz traspuesta de una matriz dada es la matriz obtenida
intercambiando filas por columnas. Scilab la calcula con el operador apóstrofo (’), por
ejemplo, A'.

6.3. Operaciones elemento a elemento


En algunas ocasiones puede ser útil realizar operaciones con matrices elemento a elemento
que no corresponden a ninguna operación matemática entre matrices. Mostraremos a continua-
ción alguna de estas operaciones.

Suma de un escalar a todos los elementos de una matriz: Se ejecuta poniendo el ope-
rador + entre la matriz y el escalar. Por ejemplo, A+1 es la matriz que se obtiene cuando
sumamos 1 a cada elemento de la matriz A.

Producto y cociente elemento a elemento: Para multiplicar elemento a elemento se usa


el operador «.*». Por ejemplo, A.*B. Hace falta que las matrices sean del mismo tamaño
para poder hacer esta operación. Análogamente podemos calcular cocientes de matrices
elemento a elemento con el operador «./».1

Potencia elemento a elemento: Para elevar a un número todos los elementos de una matriz
se utiliza el operador «.ˆ ». La matriz puede ser de cualquier tamaño y el exponente,
cualquier número.

6.4. Tipos especiales de matrices


En Scilab hay implementadas unas cuantas matrices especiales. Por ejemplo, zeros(m ,n )
es la matriz nula de m filas y n columnas, ones(m ,n ) es la matriz de m filas y n columnas
formada toda por unos y eye(m ,n ) es la matriz de tamaño m filas y n columnas que tiene
unos en la diagonal y ceros en el resto de las posiciones (cuando m =n , es la matriz identidad
de orden n, In ). Análogamente, si mat es una matriz, zeros(mat ), ones(mat ) y eye(mat )
devuelven las matrices de las mismas dimensiones que mat formadas, respectivamente, por
zeros, unos, y unos en la diagonal y ceros en el resto de posiciones.
1
Este último operador se puede utilizar, por ejemplo, para dividir un número entre todos los elementos de
una matriz. En este caso, si el primer número es un entero, puede ser necesario separarlo del operador con
un espacio (por ejemplo, 1 ./A) o ponerle el punto decimal (1../A) porque 1./A se interpretaría como el
cociente entre el número real 1. y la matriz A.

9
7. Manipulación interna de matrices
Supongamos que tenemos introducida una matriz A en nuestra sesión de Scilab y queremos
cambiar el elemento que ocupa la fila i y la columna j por el valor expresión . Entonces
utilizaremos la orden

A (i ,j )=expresión

Esta acción modifica la matriz A. Por tanto, si no queremos perder la matriz A original podemos
copiarla a otra matriz, haciendo por ejemplo

-->B=A

y efectuando después la modificación a la matriz B, por ejemplo,

-->B(2,3)=10

Si los índices son más grandes que el tamaño de la matriz, Scilab añade filas o columnas
suficientes para acomodar los nuevos elementos. También conviene tener en cuenta que Scilab
identifica las matrices 1 × 1 con los escalares.
Scilab permite introducir matrices definidas por bloques. Supongamos que A i B son matrices
con el mismo número de filas, podemos construir la matriz

C= A B

obtenida poniendo las columnas de B a la derecha de las de A. Esta matriz se introduce en


Scilab escribiendo

-->[A,B]

-->[A B]

Análogamente, si A y B son dos matrices con el mismo número de columnas, podemos construir
la matriz  
A
D=
B
poniendo las filas de B debajo de las filas de A. Esta matriz se introduciría en la forma

-->[A;B]

o como

-->[A
--> B]

De la misma manera, podemos añadir a una matriz A m × n una nueva fila escribiendo

10
-->[A; [a1 a2 ... an]]
y una nueva columna escribiendo
-->[A,[a1;a2; ...; am]]
Esta manera de trabajar por bloques es válida para cualquier número de matrices siempre que
los números de filas y de columnas sean compatibles.
Ejemplo 4. Consideremos las matrices
   
1 2 3 7 8 2
A = 4 5 6 , B = 4 1 6 .
7 8 9 0 0 1

-->A=[1 2 3
--> 4 5 6
--> 7 8 9]
A =

1. 2. 3.
4. 5. 6.
7. 8. 9.

-->B=[7 8 2
--> 4 1 6
--> 0 0 1]
B =

7. 8. 2.
4. 1. 6.
0. 0. 1.

-->C=[A,B]
C =

1. 2. 3. 7. 8. 2.
4. 5. 6. 4. 1. 6.
7. 8. 9. 0. 0. 1.

-->D=[A;B]
D =

1. 2. 3.
4. 5. 6.

11
7. 8. 9.
7. 8. 2.
4. 1. 6.
0. 0. 1.

Una vez introducida una matriz matriz , es posible trabajar con submatrices extraídas de
ella, usando expresiones como las siguientes:
matriz (i ,j ) para el elemento que ocupa la posición fila i y columna j de matriz ,
matriz (:,j ) para la columna j de matriz ,
matriz (i ,:) para la fila i de matriz ,
matriz (r :s ,:) para la submatriz formada por las filas entre la r y la s de matriz ,
matriz (:,r :s ) para la submatriz formada por las columnas entre la r y la s de
matriz ,
matriz ([r s ],:) para la submatriz formada por las filas r y s de matriz , y
matriz (:,[r s ]) para la submatriz formada por las columnas r y s de matriz .
Observemos que estas expresiones también nos permiten hacer modificaciones en una matriz
que ya ha sido introducida. Así, por ejemplo, si queremos modificar la fila i de matriz ,
podemos escribir matriz (i ,:)=nueva fila y el programa nos devolverá la matriz matriz
modificada. Hay que tener en cuenta que las dimensiones de la submatriz y la nueva matriz han
de ser compatibles. Por otra parte, podemos asignar a todos los elementos de una submatriz
un mismo elemento con la misma sintaxis.
Como antes, hay que tomar precauciones si no queremos perder la matriz inicial.

8. Polinomios
Para definir una variable polinómica en la indeterminada s, podemos definir la variable s en
la forma
-->s=poly(0,"s")
s =

-->p=3+4*s+s^2
p =

2
3 + 4s + s

12
Las raíces de una polinomio se calculan con la función roots. Para el polinomio p que
hemos introducido tendríamos

-->roots(p)
ans =

- 1.
- 3.

Para evaluar un polinomio en un valor concreto utilizaremos la función horner. Por ejemplo

-->horner(p,2)
ans =

15.

En las prácticas de Álgebra Lineal trabajaremos con polinomios.

9. Estructuras de decisión y bucle con Scilab


Scilab es un lenguaje de programación en el que es posible utilizar instrucciones condicionales
y ejecutar diversos bucles. Para referencia futura describimos algunas de estas instrucciones.
Todas estas instrucciones acaban con la palabra reservada end.

9.1. El condicional if
La instrucción if se utiliza para evaluar una expresión lógica y ejecutar una serie de ins-
trucciones si la expresión es verdadera.
La sintaxis es:

if condición then instrucciones


elseif condición then instrucciones
...
else instrucciones
end
donde las partes elseif y else son opcionales, y puede haber más de una cláusula elseif.
La palabra then puede ser sustituida por un retorno de carro o una coma y ha de encontrarse
siempre en la misma línea que el correspondiente comando if o elseif.
Si la condición de la línea con if es verdadera, se ejecutan las instrucciones siguientes.
En otro caso, se ejecuta la primera de las series de instrucciones elseif para las cuales la
condición sea verdadera, y, si ninguna de ellas es verdadera, se ejecutan las instrucciones de la
cláusula else.
Presentamos un ejemplo sencillo.

13
-->x=-4; if x<0 then r=-x,elseif x==0 then r=0,else r=x,end
r =

4.

-->x=5; if x<0 then r=-x,elseif x==0 then r=0,else r=x,end


r =

5.

Scilab también dispone del comando select/case que puede ser una alternativa útil cuan-
do una expresión sólo puede tomar un pequeño numero de valores interesantes. Para más
información, teclear help select en Scilab.

9.2. El bucle for


El bucle for se utiliza para ejecutar unas instrucciones para todas las columnas de una
matriz. Su sintaxis es

for variable =expresión do instrucción, ... instrucción ,end


Aquí expresión suele ser una matriz y las órdenes se ejecutan para todas las columnas de la
matriz. Los formatos habituales para esta expresión son

comienzo :paso :fin

comienzo :fin

Ejemplo 5. Con el siguiente ejemplo podemos escribir los cuadrados de los números impares
entre 1 y 9:

-->for x=1:2:9 do [x,x^2],end


ans =

1. 1.
ans =

3. 9.
ans =

5. 25.
ans =

14
7. 49.
ans =

9. 81.
Con la siguiente instrucción calculamos la suma de los cuadrados de los 10 primeros números
naturales. Usar punto y coma en vez de coma evita la escritura de todos los valores intermedios.
-->suma=0;for x=1:10 do suma=suma+x^2;end;suma
suma =

385.

9.3. El bucle while


Este bucle se utiliza para ejecutar unas instrucciones mientras una cierta expresión booleana
sea verdadera. Su sintaxis es
while condición do instrucciones ,...[,else instrucciones ], end
La palabra do puede sustituirse por then, por una coma o por un salto de línea. La palabra
do o then tienen que encontrarse en la misma línea que while. La cláusula else se ejecuta
cuando condición deja de ser verdadera.

10. Funciones con Scilab


Ya hemos visto algunas funciones como zeros o ones, que permiten construir objetos de
Scilab a partir de sus parámetros o argumentos. La sintaxis de una función de Scilab es
función (arg1 , arg2 ...)
para dar un resultado, o
[var1 , var2 ...]=función (arg1 , arg2 ...)
para funciones que devuelven diversos resultados, asignados a las variables var1 , var2 ...
Para definir una función en Scilab podemos usar las palabras clave function i endfun-
ction. Su sintaxis es
function argssalida =nombrefunción (argsentrada )
instrucciones
endfunction
donde argsentrada es una lista de identificadores de variables que se asignarán ordenadamen-
te a los parámetros y argssalida es un identificador o una lista de identificadores de variables
separados por comas i cerrados entre corchetes. La lista de instrucciones ha de contener asig-
naciones de estas variables para calcular el resultado.
Por ejemplo, la siguiente función calcula el cuadrado de un número dado:

15
-->function y=cuadrado(x)
-->y=x*x
-->endfunction

-->z=cuadrado(3)
z =

9.

Como vemos, el argumento de salida es y y el de entrada es x. El valor de la función es el


valor de y cuando acaba la definición de la función después de sustituir el parámetro x por el
argumento utilizado.
La siguiente función admite dos parámetros, x e y, y devuelve dos resultados, que corres-
ponden a la suma y a la diferencia de sus argumentos:

-->function [suma, dif]=sumadif(x,y)


--> suma=x+y
--> dif=x-y
-->endfunction

-->[m,n]=sumadif(5,3)
n =

2.
m =

8.

Observemos que la variable m queda asignada a la suma de los dos números y la variable n
queda asignada a la diferencia entre los dos números.
Suele ser interesante almacenar una o varias funciones en un fichero de texto, con el fin de
poderlas usar en diversas sesiones. Para ejecutar todas las instrucciones (no solo definiciones
de funciones) de un fichero de texto fichero.sci , podemos usar el comando exec:

-->exec('fichero.sci ')

La versión gráfica del programa Scilab incluye un editor de ficheros, al que se puede acceder
desde el menú, que permite la ejecución del código que se seleccione.

11. Fin de sesión


Para terminar la sesión de Scilab se introduce la instrucción exit. Si se trabaja en un
entorno de ventanas, también se puede salir cerrando la ventana de Scilab.

16
Práctica 1
Resolución de sistemas de ecuaciones lineales: métodos
directos

Índice
1. Operaciones elementales por filas 1

2. Forma escalonada reducida de una matriz 3

3. Resolución de sistemas lineales con el operador \ 3


3.1. Descripción del operador \ . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
3.2. Solución general de un sistema utilizando \ y kernel . . . . . . . . . . . . . . 6

4. Redes de flujo 9

1. Operaciones elementales por filas


Sabemos que hay tres tipos de operaciones elementales por filas:
1. Intercambio de filas: una fila de la matriz se puede intercambiar con otra.

2. Multiplicación de una fila: cada elemento de una fila puede ser multiplicado por una
constante no nula.

3. Suma de una fila: una fila puede ser sustituida por la suma de esta fila y un múltiplo de
otra fila.
Los comandos de Scilab que se pueden utilizar para efectuar estas operaciones elementales
en una matriz A son los siguientes:

1. Intercambio de filas aplicado a las filas i y j:

A ([i , j ],:) = A ([j , i ],:)

2. La fila i-ésima se multiplica por p:

1
A (i ,:) = p*A (i ,:)

3. La fila i se cambia por la suma de la fila i y p veces la fila j:

A (i ,:) = A (i ,:) + p *A (j ,:)

Ejemplo 1. Consideramos la siguiente matriz


 
0 −2 3 9
A = −4 6 0 −4
2 −5 5 17

Efectuaremos, utilizando Scilab, las siguientes operaciones elementales:


1. intercambiamos las filas 1 y 3,

2. multiplicamos por 1/2 la segunda fila,

3. sumamos la primera fila a la segunda.


La secuencia de comandos utilizados y las salidas obtenidas son:

-->A=[0 -2 3 9;-4 6 0 -4;2 -5 5 17]


A =

0. - 2. 3. 9.
- 4. 6. 0. - 4.
2. - 5. 5. 17.

-->B=A;

-->B([1,3],:)=B([3,1],:)
B =

2. - 5. 5. 17.
- 4. 6. 0. - 4.
0. - 2. 3. 9.

-->C=B;

-->C(2,:)=(1/2)*C(2,:)
C =

2. - 5. 5. 17.

2
- 2. 3. 0. - 2.
0. - 2. 3. 9.

-->D(2,:)=D(2,:)+D(1,:)
D =

2. - 5. 5. 17.
0. - 2. 5. 15.
0. - 2. 3. 9.

2. Forma escalonada reducida de una matriz


La función rref proporciona la forma escalonada reducida de una matriz cualquiera. Veamos
un ejemplo.
Ejemplo 2. Consideramos el sistema de ecuaciones lineales

−2y +3z = 9 
−4x +6y = −4
2x −5y +5z = 17

cuya matriz ampliada es la del ejemplo 1. Calculamos ahora la forma escalonada reducida de
esta matriz:
-->A=[0 -2 3 9;-4 6 0 -4;2 -5 5 17];

-->rref(A)
ans =

1. 0. 0. 1.
0. 1. 0. 0.
0. 0. 1. 3.
Por tanto la solución única del sistema es:

x = 1, y = 0, z = 3.

3. Resolución de sistemas lineales con el operador \


3.1. Descripción del operador \
Un procedimiento comúnmente utilizado para resolver un sistema de ecuaciones lineales
A~x = ~b con Scilab consiste en introducir la matriz de coeficientes A y el vector de términos
independientes ~b y escribir A\b. Este operador funciona de la siguiente manera:

3
1. Si el sistema es compatible determinado entonces A\b proporciona la solución única del
sistema.
2. Si el sistema es compatible indeterminado entonces A\b proporciona una de las soluciones
(elige una con, a lo sumo, r componentes no nulas, donde r es el rango de A).
3. Si el sistema es incompatible Scilab calcula un vector, llamado aproximación por mí-
nimos cuadrados de la solución, es decir, un vector ~x0 tal que el valor de la norma
kA~x0 − ~bk es el mínimo posible de entre todos los posibles valores de ~x0 (notamos que
este vector no es necesariamente único); Scilab elige uno con, a lo sumo, r componentes
no nulas, donde r es el rango de A.
Notamos que, si el sistema es compatible, Scilab proporciona una de las soluciones. Si el
sistema no es compatible, Scilab nos presenta un vector que no es una solución. Esto quiere
decir que debemos ser muy cuidadosos con el operador \.
Ejemplo 3. Consideramos el siguiente sistema de ecuaciones lineales:

−2y +3z = 9 
−4x +6y = −4
2x −5y +5z = 17

Utilizaremos el operador \:
-->A=[0 -2 3; -4 6 0; 2 -5 5]; b=[9; -4; 17];

-->x=A\b
x =

1.
0.
3.
Ésta es la única solución del sistema lineal porque A es una matriz cuadrada invertible (tiene
rango máximo):
-->rank(A)
ans =

3.
Ejemplo 4. Consideramos el siguiente sistema de ecuaciones lineales:

x +y +z = 1 
x +y +z = 2
2x +2y +2z = 3

que es, evidentemente, incompatible

4
-->A=[1 1 1; 1 1 1; 2 2 2]; b=[1; 2; 3];

-->x=A\b
warning :
matrix is close to singular or badly scaled. rcond = 0.0000D+00

x =

1.5
0.
0.

Scilab da un resultado que no es una solución del sistema.

Ejemplo 5. Consideramos el sistema



x +y +z = 1 
x +y +z = 1
2x +2y +2z = 2

que tiene, evidentemente, una cantidad infinita de soluciones.

-->A=[1 1 1; 1 1 1; 2 2 2]; b=[1; 1; 2];

-->x=A\b
warning :
matrix close to singular or badly scaled. rcond = 0.0000D+00

x =

1.
0.
0.

En este caso hemos obtenido una solución particular del sistema. De hecho,

-->A*x
ans =

1.
1.
2.

5
3.2. Solución general de un sistema utilizando \ y kernel
Si un sistema tiene una cantidad infinita de soluciones, hemos visto que el operador \
proporciona sólo una de las soluciones del sistema. No obstante, es posible obtener todas
las soluciones de una manera fácil calculando el núcleo de la matriz de coeficientes. Primero
debemos aclarar este concepto:
El núcleo de una matriz A es el conjunto de soluciones del sistema homogéneo cuya matriz
de coeficientes es A, es decir, A~x = ~0. Por ejemplo, el núcleo de la matriz
 
1 2 −3
A = 2 4 −6 
5 10 −15

es el conjunto de soluciones del sistema


    
1 2 −3 x 0
2 4 −6  y  = 0 .
5 10 −15 z 0

El núcleo de una matriz se puede calcular fácilmente con Scilab utilizando la función kernel:

-->A=[1 2 -3; 2 4 -6; 5 10 -15];

-->kernel(A)
ans =

- 0.1195229 0.9561829
0.8440132 - 0.0439019
0.5228345 0.2894597

El núcleo de la matriz es el conjunto de combinaciones lineales de los vectores columna de la


matriz obtenida, es decir:
     
 −0,1195229 0,9561829 
Ker A = α 0,8440132 + β −0,0439019 con α, β ∈ R .
   
0,5228345 0,2894597
 

(Esto también puede expresarse diciendo que los vectores columna de la matriz forman un
sistema de generadores del núcleo).
Ahora enunciaremos un teorema que muestra como obtener la solución general de un sistema
de ecuaciones lineales a partir de

una solución particular, y

el núcleo de la matriz de coeficientes.

6
Teorema. Sea A~x = ~b un sistema de ecuaciones lineales compatible y sea ~x0 una solución
particular. Entonces la solución general del sistema es:

~x = ~x0 + λ1~u1 + λ2~u2 + . . . + λn~un , λ1 , λ2 , . . . , λn ∈ R,

donde {~u1 , ~u2 , . . . , ~un } es un sistema de generadores del núcleo de A.1

Ejemplo 6. Consideramos el sistema de ecuaciones lineales


    
1 0 2 3 x 6
7 1 1 1 y  10
8 1 3 4 z  = 16 .
    

9 1 5 7 t 22

Aplicamos, con Scilab, el operador \ para estudiar la compatibilidad del sistema:

-->A=[1 0 2 3; 7 1 1 1 ; 8 1 3 4; 9 1 5 7]; b=[6; 10; 16; 22];

-->x=A\b
warning :
matrix is close to singular or badly scaled. rcond = 2.2204D-18

x =

1.2
0.
0.
1.6

-->clean(A*x-b)
ans =

0.
0.
0.
0.

De los resultados anteriores podemos ver que el sistema es compatible y que el vector ~x0 =
(1,2, 0, 0, 1,6) es una solución particular. Ahora calculamos el núcleo de la matriz de coeficientes:

-->kernel(A)
ans =

1
La demostración es muy fácil: ~x es una solución del sistema ⇔ A~x = ~b ⇔ A~x − A~x0 = ~b − A~x0 ⇔
A(~x − ~x0 ) = ~0 (porque A~x0 = ~b) ⇔ ~x − ~x0 pertenece al núcleo de A.

7
- 0.1490641 - 0.0418627
0.8434185 0.5144634
0.4510273 - 0.7061368
- 0.2509968 0.4847121

Esto quiere decir que el sistema tiene una cantidad infinita de soluciones y que su solución
general es:
     
1,2 −0,1490641 −0,0418627
0
  +λ1  0,8434185  + λ2  0,5144634  ,
   
0  0,4510273  −0,7061368 λ1 , λ2 ∈ R.
1,6 −0,2509968 0,4847121
| {z }
~
x0

Ejemplo 7. Consideramos el sistema de ecuaciones lineales (con la misma matriz de coeficientes


que antes)     
1 0 2 3 x 1
7 1 1 1 y  2
8 1 3 4 z  = 3 .
    

9 1 5 7 t 5
Como antes, utilizando \ para estudiar la compatibilidad del sistema:

-->b=[1; 2; 3; 5];

-->clean(A*x-b)
ans =

0.
0.
0.
- 1.

De estos resultados vemos que el operador \ nos da un vector que no es una solución. Esto
implica que el sistema es incompatible.

Ejemplo 8. Consideramos el sistema de ecuaciones lineales


    
1 2 3 x 1
−1 0 1 y  = 2 .
0 3 1 z 3

Como antes, aplicamos primero el operador \:

-->A=[1 2 3; -1 0 1; 0 3 1]; b=[1; 2; 3];

8
-->x=A\b
x =

- 1.7
0.9
0.3

-->clean(A*x-b)
ans =

0.
0.
0.

Los resultados muestran que el sistema es compatible y que el vector ~x0 = (−1,7, 0,9, 0,3) es
una solución. Ahora calculamos el núcleo de la matriz de coeficientes:

-->kernel(A)
ans =

[]

Esto quiere decir que el núcleo es trivial, es decir, Ker A = {~0}. Por consiguiente la única
solución del sistema es ~x0 , la obtenida utilizando \.

4. Redes de flujo
Cuando investigamos el flujo de una cantidad a través de una red nos aparecen sistemas
de ecuaciones lineales. Estas redes las podemos encontrar en diversos campos de la ciencia,
economía, estadística o ingeniería. Dos ejemplos de este tipo son los patrones de flujo de tráfico
a través de una ciudad y la distribución de productos de los fabricantes a los consumidores por
medio de una red de distribuidores y vendedores.
Una red consta de un conjunto de puntos, llamados nodos (o vértices), y arcos dirigidos que
conectan todos o parte de los nodos. El flujo está indicado por un número o una variable. Un
flujo de redes tiene que cumplir las siguientes condiciones:

El flujo total que entra a un nodo es igual al flujo total que sale del nodo.

El flujo total que entra dentro de la red es igual al flujo total que sale de la red.

Ejemplo 9. Consideremos una pequeña red cerrada de tubos a través de los cuales fluye un

9
líquido como se describe en el siguiente grafo:

Ao 20
BO
y z

x C t
10
 ~ 10 
D / E
u

Los arcos representan los tubos, y las intersecciones entre los tubos corresponden a los nodos
de la red. El peso de cada arco indica la cantidad de litros de líquido que fluye por hora y las
flechas indican las direcciones de los flujos.
A partir de las condiciones básicas de todo flujo de redes y de la descripción de la red con-
creta, podemos obtener el siguiente sistema de ecuaciones: cada nodo da lugar a una ecuación
lineal. 
Nodo A: x + y = 20  
Nodo B: z + 20 = t 


Nodo C: y + z = 20 ,
Nodo D: x + 10 = u 



Nodo E: u + 10 = t

Para resolver el sistema, escribimos su matriz ampliada


 
1 1 0 0 0 20
0 0 1
 −1 0 −20
M= 0 1 1 0 0 20 
.
1 0 0 0 −1 −10
0 0 0 −1 1 −10
y calculamos, con Scilab, la forma escalonada reducida de M:

-->M=[1 1 0 0 0 20;0 0 1 -1 0 -20;0 1 1 0 0 20;


--> 1 0 0 0 -1 -10;0 0 0 -1 1 -10]); rref(M)
ans =

1. 0. 0. 0. - 1. - 10.
0. 1. 0. 0. 1. 30.
0. 0. 1. 0. - 1. - 10.
0. 0. 0. 1. - 1. 10.
0. 0. 0. 0. 0. 0.

Como se puede ver, el sistema es compatible indeterminado y la solución paramétrica del


sistema es: x = −10 + λ, y = 30 − λ, z = −10 + λ, t = 10 + λ, u = λ, con λ ∈ R. Como los
valores de las incógnitas son litros de líquido, han de cumplir x, y, z, t, u ≥ 0 y, por lo tanto,
10 ≤ λ ≤ 30. Concluimos, entonces, que hay una cantidad infinita de posibilidades para la
distribución de flujos (una para cada valor de λ en el intervalo [10, 30]).

10
Práctica 2
Resolución de sistemas de ecuaciones lineales: métodos
iterativos

Índice
1. Introducción 1

2. El método de Jacobi 2

3. El método de Gauss-Seidel 6

4. Criterio de convergencia 9

1. Introducción
En matemáticas computacionales, un método iterativo intenta resolver un problema (por
ejemplo, encontrar la solución de una ecuación o sistema de ecuaciones) encontrando aproxi-
maciones sucesivas a la solución partiendo de una estimación inicial. Este método aproximativo
contrasta con los métodos directos, que tratan de resolver el problema mediante una sucesión
finita de operaciones y, en ausencia de errores de redondeo, darían una solución exacta (como la
resolución de un sistema de ecuaciones lineales A~x = ~b por eliminación gaussiana). Los métodos
iterativos substituyen a los directos cuando estos no son programables o se prevee tengan un
alto coste o acumulen excesivo error, pero también han demostrado su posible ventaja en la
resolución de problemas lineales que involucran un gran número de variables (cientos, miles,
millones...) porque la precisión de la solución puede ser determinada sin necesitar para ello un
alto número de iteraciones.
Estudiaremos dos métodos iterativos de resolución de sistemas de ecuaciones lineales: el mé-
todo de Jacobi y el de Gauss-Seidel. En ambos casos necesitamos que el sistema sea compatible
y determinado: el mismo número de ecuaciones que de incógnitas y que la matriz de coeficien-
tes tenga rango máximo. Además, todos los elementos de la diagonal de la matriz de
coeficientes deben ser no nulos.

1
2. El método de Jacobi
Consideremos un sistema de ecuaciones lineales que satisface las hipótesis antes menciona-
das. Supongamos que su expresión matricial es

A~x = ~b.

Consideremos la siguiente descomposición de la matriz de coeficientes A:

A = L + D + U,

donde la matriz L es la «parte triangular inferior» de A, U es la «parte triangular superior»


de A y D es la «parte diagonal» de A. Veamos un ejemplo con el objetivo de aclarar esta
descomposición:
Ejemplo 1. Tomamos la matriz
 
10 3 1
A =  2 −10 3 
1 3 10

Entonces A = L + D + U, donde
     
0 0 0 10 0 0 0 3 1
L = 2 0 0 , D =  0 −10 0  , U = 0 0 3 .
1 3 0 0 0 10 0 0 0

Observamos la siguiente sucesión de equivalencias:

El vector ~x es una solución del sistema A~x = ~b ⇔ (L + D + U)~x = ~b


⇔ D~x = ~b − (L + U)~x
⇔ ~x = D−1 [~b − (L + U)~x] (1)

Notamos que D es invertible porque los elementos de su diagonal son no nulos (por hipótesis).
Así D−1 puede calcularse fácilmente porque es una matriz diagonal: D−1 es una matriz diagonal
que tiene como entradas de la diagonal los inversos de los elementos respectivos de la diagonal
de D.
El método de Jacobi es una técnica iterativa basada en la igualdad (1). Consta de los
siguientes pasos: tomamos una aproximación inicial de la solución ~x0 , la sustituimos en el
primer miembro de (1) y calculamos otra aproximación ~x1 , la sustituimos en el primer miembro
de (1) y calculamos otra aproximación ~x2 , y así sucesivamente. Haciendo esto, obtenemos una
sucesión de vectores ~x0 , ~x1 , ~x2 , . . . tal que

~xk+1 = D−1 [~b − (L + U)~xk ], k = 0, 1, 2, 3, . . . (2)

El hecho importante aquí es la siguiente propiedad:

2
Proposición 1. Si esta sucesión de vectores es convergente, entonces el vector límite es una
solución del sistema de ecuaciones lineales.

La demostración de esta propiedad es muy sencilla: sea ~v el vector límite de la sucesión


(~xk ). Tomando límites a ambos lados de la igualdad (1), obtenemos ~v = D−1 [~b − (L + U)~v ],
que es equivalente a decir que ~v es una solución del sistema de ecuaciones lineales (teniendo
en cuenta la anterior sucesión de equivalencias).

Ejemplo 2. Consideremos el siguiente sistema de ecuaciones lineales:



10x + 3y + z = 14 
2x − 10y + 3z = −5 ,
x + 3y + 10z = 14

La matriz de coeficientes de este sistema es la matriz A de el ejemplo 1. La relació de recurren-


cia (2) es, en este caso:
 
      
1/10 0 0  14 0 3 1 
~xk+1 = 0 −1/10 0  −5 − 2 0 3 ~xk 
      
0 0 1/10  14 1 3 0
 

| {z } | {z } | {z }
D−1 ~b L+U

Aplicamos ahora el método de Jacobi eligiendo un vector inicial cualquiera. Tomamos, por
ejemplo, ~x0 = (0, 0, 0). Entonces
      
1/10 0 0 14 0 3 1
~x1 =  0 −1/10 0   −5 − 2 0
  3 ~x0 
0 0 1/10 14 1 3 0
         
1/10 0 0 14 0 3 1 0 7/5
=  0 −1/10 0   −5 − 2 0
  3 0
   = 1/2

0 0 1/10 14 1 3 0 0 7/5

Calculamos ahora ~x2 :


      
1/10 0 0 14 0 3 1
~x2 =  0 −1/10 0   −5 − 2
  0 3 ~x1 
0 0 1/10 14 1 3 0
         
1/10 0 0 14 0 3 1 7/5 111/100
=  0 −1/10 0   −5 − 2
  0 3 1/2 =  6/5 
0 0 1/10 14 1 3 0 7/5 111/100

Queremos continuar haciendo iteraciones para «ver» si el proceso es convergente o no. Con
Scilab es más fácil:

3
-->A=[10 3 1; 2 -10 3; 1 3 10];
-->D=diag([diag(A)])
D =
10. 0. 0.
0. - 10. 0.
0. 0. 10.
-->L=tril(A)-D
L =
0. 0. 0.
2. 0. 0.
1. 3. 0.
-->U=triu(A)-D
U =
0. 3. 1.
0. 0. 3.
0. 0. 0.
Con la ayuda de las funciones diag, tril y triu hemos calculado fácilmente las matrices L, D y
U.
-->F=inv(D)
F =
0.1 0. 0.
0. - 0.1 0.
0. 0. 0.1
-->R=L+U
R =
0. 3. 1.
2. 0. 3.
1. 3. 0.
-->x0=[0; 0; 0];x1=F*(b-R*x0)
x1 =
1.4
0.5
1.4
-->x2=F*(b-R*x1)
x2 =
1.11
1.2
1.11
-->x3=F*(b-R*x2)
x3 =
0.929
1.055

4
0.929
-->x4=F*(b-R*x3)
x4 =
0.9906
0.9645
0.9906
-->x5=F*(b-R*x4)
x5 =
1.01159
0.9953
1.01159
-->x6=F*(b-R*x5)
x6 =
1.000251
1.005795
1.000251

«Vemos» que el proceso parece ser convergente al vector (1, 1, 1). Podéis comprobar que este
es, de hecho, una solución del sistema.
Podemos hacer lo mismo pero usando un código de Scilab más eficiente (más corto) (con
la ayuda de la función for):

-->for i=1:6
-->x=F*(b-R*x);
-->end;

-->x
x =
1.000251
1.005795
1.000251

El vector que nos retorna después del bucle es, directamente, ~x6 . Si queremos estar «más
seguros» de la convergencia, podemos aplicar más iteraciones:

-->for i=1:50
-->x=F*(b-R*x);
-->end;

-->x
x =
1.
1.
1.

5
3. El método de Gauss-Seidel
Este método es una ligera modificación del método de Jacobi. En la mayoría de los casos,
el número de iteraciones necesario para obtener una solución aproximada es más pequeño que
para el método de Jacobi.
Dado un sistema de ecuaciones lineales A~x = ~b (que satisfaga la hipótesis establecida a
comienzos de la sección), se usa la misma descomposición de la matriz A :
A = L + D + U.
Pero ahora rescribimos la igualdad A~x = ~b como
(L + D)~x = ~b − U~x. (3)
Esta es la igualdad crucial del método de Gauss-Seidel. Comenzamos con un vector inicial
cualquiera ~x0 y calculamos ~x1 de manera que
(L + D)~x1 = ~b − U~x0 .
Entonces, calculamos ~x2 de manera que
(L + D)~x2 = ~b − U~x1 ,
y así sucesivamente: para cada k = 0, 1, 2, . . . calculamos ~xk+1 de manera que
(L + D)~xk+1 = ~b − U~xk (4)
Como la matriz L + D es triangular inferior, las componentes del vector ~xk+1 se calculan a partir
de las componentes de ~xk por sustitución progresiva. Como en el caso del método de Jacobi,
si la sucesión de vectores ~x0 , ~x1 , . . . es convergente, entonces el vector límite es la solución del
sistema. Aclaremos estos hechos con un ejemplo.
Ejemplo 3. Aplicaremos el método de Gauss-Seidel al sistema del ejemplo 2.
     
10 0 0 0 3 1 14
L + D = 2 −10 0 , U = 0
    ~
0 3 , b = −5 
1 3 10 0 0 0 14
Comenzamos también con el vector inicial ~x0 = (0, 0, 0). La primera iteración es:
      
10 0 0 14 0 3 1 0
2 −10 0  ~x1 = −5 − 0 0 3 0 (5)
1 3 10 14 0 0 0 0
| {z } | {z } | {z } |{z}
L+D ~b U ~
x0

Si llamamos  
x
~x1 = y  ,
z

6
la igualdad (5) se puede escribir como
    
10 0 0 x 14
 2 −10 0  y  = −5 .
1 3 10 z 14
| {z }
L+D

Y este es un sistema de ecuaciones lineales cuya matriz de coeficientes es triangular inferior:



10x = 14 
2x − 10y = −5 .
x + 3y + 10z = 14

Ahora, por sustitución progresiva obtenemos x = 7/5, y = 39/50 y z = 513/500, o sea:


 
7/5
~x1 =  39/50  .
513/500
La segunda iteración es:
      
10 0 0 14 0 3 1 7/5
 2 −10 0  ~x2 = −5 − 0 0 3  39/50  (6)
1 3 10 14 0 0 0 513/500
| {z } | {z } | {z } | {z }
L+D ~b U ~
x1

Si llamamos ahora  
x
~x2 = y 

z
la anterior igualdad puede escribirse como
    
10 0 0 x 5317/500
 2 −10 0  y  = −4039/500 .
1 3 10 z 14
| {z }
L+D

Y este es un sistema de ecuaciones lineales cuya matriz de coeficientes es triangular inferior:



10x = 5317/500 
2x − 10y = −4039/500 .
x + 3y + 10z = 14

5317 3189 246879


Ahora, por sustitución progresiva, obtenemos x = 5000 ,y= 3125
yz= 250000
, es decir:
 
5317/5000
~x2 =  3189/3125  .
246879/250000

7
Y así sucesivamente...
Hagamoslo con Scilab. Primero, hemos de ejecutar el fichero SustitucionProgresiva.sci,
donde hemos definido una función, SustitucionProgresiva, que calcula la solución por sus-
titución progresiva de un sistema T~x = ~b, donde T es una matriz triangular inferior invertible.
La sintaxis es SustitucionProgresiva(T ,b ), donde T es la matriz de coeficientes y b es
el vector de términos independientes.

-->M=L+D; x0=[0; 0; 0];


-->x1=SustitucionProgresiva(M,b-U*x0)
x1 =
1.4
0.78
1.026
-->x2=SustitucionProgresiva(M,b-U*x1)
x2 =
1.0634
1.02048
0.987516
-->x3=SustitucionProgresiva(M,b-U*x2)
x3 =
0.9951044
0.9952757
1.0019069
-->x4=SustitucionProgresiva(M,b-U*x3)
x4 =
1.0012266
1.0008174
0.9996321
-->x5=SustitucionProgresiva(M,b-U*x4)
x5 =
0.9997916
0.9998480
1.0000665
-->x6=SustitucionProgresiva(M,b-U*x5)
x6 =
1.000039
1.0000277
0.9999878

Con la función for podemos efectuar más iteraciones, si queremos:

-->x=x0;

-->for(i=1:50) x=SustitucionProgresiva(M,b-U*x); end;

8
-->x
x =
1.
1.
1.

4. Criterio de convergencia
Es posible que, cuando se aplique el método de Jacobi o Gauss-Seidel, la sucesión de vectores
obtenida sea divergente. No obstante, cuando la matriz de coeficientes es de un tipo especial,
podemos garantizar la convergencia de ambos métodos.

Definición 1. Una matriz cuadrada A es estrictamente diagonalmente dominante (por


filas) si en todas las filas el valor absoluto del elemento de la diagonal es más grande que la
suma de los valores absolutos del resto de los elementos de esta fila. Es decir, para todo i
X
|aii | > |aij |;
j6=i

o (por columnas) si X
|aii | > |aji |
j6=i

Cuando la matriz de coeficientes no es estrictamente diagonal dominante (ni por filas ni por
columnas) a veces es posible manipular el sistema (multiplicándolo por matrices elementales)
para obtener un sistema equivalente cuya matriz de coeficientes sí sea estrictamente diagonal-
mente dominante. No vamos a indicar aquí como conseguirlo, pero es interesante que ensayes
métodos (permutar filas o columnas, multiplicar o dividir una fila o una columna por alguna
cantidad...) pues es la condición que asegura la convergencia de los métodos de Jacobi y de
Gauss-Seidel:

Teorema 1. Si una matriz cuadrada A es estrictamente diagonalmente dominante, entonces


los métodos de Jacobi y de Gauss-Seidel son convergentes.

Nota 1: Comprobando que la matriz cuadrada A es estrictamente diagonalmente dominante


quedan además garantizadas todas las condiciones iniciales asumidas en la Sección 1: el sistema
es compatible y determinado porque A tiene rango máximo y las entradas diagonales no pueden
ser nulas!
Nota 2: Si la matriz original no es estrictamente diagonalmente dominante pero has encon-
trado alguna manipulación del sistema en la que la matriz de coeficientes sí es estrictamente
diagonalmente dominante, puedes resolver ese nuevo sistema con los métodos de Jacobi o
Gauss-Seidel pues está garantizada su convergencia.

9
Nota 3: En caso contrario, es decir, cuando la matriz “no puede ser estrictamente diago-
nalmente dominante", los métodos iterativos estudiados pueden ser caóticos. Como ejemplo de
este caso aplica el método de Jacobi con la matriz de coeficientes
 
3 1 2
0 1 1
1 1 1

e intenta deducir a qué “tiende” el vector de soluciones ~xk .

10
Práctica 3
Matrices estocásticas y cadenas de Markov

Índice
1. Ejemplo introductorio 1

2. Matrices estocásticas y cadenas de Markov 3

1. Ejemplo introductorio
Una aplicación clásica del cálculo matricial es el estudio del movimiento de poblaciones
dentro de un conjunto finito de posibles estados. Veamos un ejemplo ilustrativo.
Dos compañías ofrecen televisión por cable a una ciudad con 100000 viviendas. El cambio
anual en la suscripción viene dado en el siguiente diagrama.

20 %
-
70 % 8 AZ m 9Bg 80 %
15 %
10 % 15 %

15 % 5%
 y
NY

70 %

Inicialmente la compañía A tiene 15000 suscriptores, la compañía B 20000, y hay 65000


viviendas sin suscripción (N ). Calculemos cuantos suscriptores tendrá cada compañía después
de 10, 20 y 30 años.
A cada vivienda le corresponde uno de los siguientes estados: A, B o N . El vector de
estados iniciales ~x0 , que almacena la proporción inicial de suscriptores en cada estado, es el
siguiente:  
0, 15
~x0 = 0, 20 .
0, 65

1
(Observa que las componentes del vector ~x0 se han calculado dividiendo el número de suscrip-
tores en cada estado por el número total de suscriptores, que es 100.000).
Si ~x1 = (a, b, n) denota el vector de estados que proporciona las proporciones de suscrip-
tores (en A, B y N ) después de un año, a partir del diagrama anterior se deduce fácilmente lo
siguiente:
a = 0,70 · 0,15 + 0,15 · 0,20 + 0,15 · 0,65,
b = 0,20 · 0,15 + 0,80 · 0,20 + 0,15 · 0,65,
n = 0,10 · 0,15 + 0,05 · 0,20 + 0,70 · 0,65.
Es decir:     
a 0,70 0,15 0,15 0, 15
 b  = 0,20 0,80 0,15 0, 20 .
n 0,10 0,05 0,70 0, 65
|{z} | {z } | {z }
~
x1 P ~
x0

La matriz que hemos denotado por P se denomina matriz de transición. Razonando de


forma similar se tiene que si ~xk denota el vector de estados después de k años:

~x2 = P~x1 = PP~x0 = P2~x0

y, en general,
~xk = Pk ~x0 para todo k ≥ 1.
Calculemos, con Scilab, los porcentajes de suscriptores en cada estado después de 10, 20 y
30 años:

-->x0=[0.15000; 0.20; 0.65];


-->P=[0.70, 0.15, 0.15; 0.20, 0.80, 0.15;0.10, 0.05, 0.70];
-->x10=P^10*x0
x10 =
0.33286896
0.4714703
0.19566074
-->x20=P^20*x0
x20 =
0.33333216
0.47612439
0.19054345
-->x30=P^30*x0
x30 =
0.33333333
0.47618958
0.19047709

2
Observa que, aunque ~x10 es bastante distinto de ~x0 , las diferencias entre ~x10 y ~x20 son pequeñas,
y aun son menores las diferencias entre ~x20 y ~x30 . Así pues, podríamos decir que la distribución
de suscriptores «tiende a estabilizarse» y que, después de 10 años, la situación es «casi estable».
Calculando más vectores de estados ~x40 , ~x50 , . . . , ~x100 , . . . veríamos que, con el transcurrir de
los años, la proporción de suscriptores en cada uno de los tres estados se va estabilizando en
torno a un cierto valor. Aclaremos el significado de estos conceptos imprecisos:

«tiende a estabilizarse» significa que la sucesión de vectores ~xn es convergente a un


cierto vector ~v , el supuesto «estado final» o «estado límite». Es decir:

~v = lı́m Pn~x0 .
n→∞

la expresión «después de 10 años, la situación es casi estable» significa que la diferencia


entre ~x10 y los vectores sucesivos ~xk , k > 10, es razonablemente pequeña.

Acabamos de ver un proceso que tiende a ser estable. La pregunta que nos planteamos es
la siguiente: ¿bajo qué condiciones procesos similares a éste tienden a ser estables? En el resto
de este boletín daremos respuesta a esta pregunta.

2. Matrices estocásticas y cadenas de Markov


El mismo planteamiento del ejemplo anterior puede hacerse en general. Supongamos que
debemos estudiar un proceso similar sobre proporciones de individuos pertenecientes a n estados
y que disponemos de una matriz n × n, P = [pij ], llamada matriz de transición, de forma
que cada entrada pij indica la probabilidad de que un miembro de la población cambie del
estado j al estado i. Por la teoría de la probabilidad, 0 ≤ pij ≤ 1 para todo i y j, y la suma de
entradas de cada columna es 1. Observa que pij = 0 significa que el miembro j no cambiará al
estado i (sino a cualquiera de los otros, con determinadas probabilidades), mientras que pij = 1
significa que es seguro que el miembro se moverá del estado j al estado i (y, por tanto, el resto
de entradas de la columna j serán nulas). Observa también que pii representa la probabilidad
de permanecer en el mismo estado, de no cambiar.
El vector de estados iniciales, ~x0 es un vector de Rn cuya componente i-ésima es la
proporción inicial de individuos en el estado i, para i ∈ {1, . . . , n}. El k-ésimo vector de
estados, ~xk , es un vector de Rn cuya componente i-ésima es la proporción de individuos en el
estado i tras k «pasos» (usualmente unidades de tiempo), para i ∈ {1, . . . , n}. Nótese que la
suma de las componentes de cada vector de estados es siempre igual a 1.
Al igual que en el ejemplo anterior, se pueden obtener los sucesivos vectores de estados
~x1 , ~x2 , . . . , a partir de la matriz de transición P:

~x1 = P~x0 , ~x2 = P~x1 , ~xk = P~xk−1 , . . .

o también
~xk = Pk ~x0 para todo k ≥ 1.

3
Establezcamos ahora la terminología que se utiliza normalmente para describir y estudiar
este tipo de procesos.
Definición 1. Un vector con entradas no negativas, la suma de las cuales es 1, se dirá un
vector de probabilidad. Una matriz estocástica (o matriz de Markov) es una matriz
cuadrada cuyas columnas son vectores de probabilidad.
Nótese que las matrices de transición P antes consideradas son matrices estocásticas y que
los vectores de estados ~xk son vectores de probabilidad. Las secuencias de vectores de estados
~x0 , ~x1 , . . . obtenidas a partir de matries de transición P se denominan usualmente cadenas de
Markov, término que precisamos en la siguiente definición:
Definición 2. Una cadena de Markov es una sucesión de vectores de probabilidad ~x0 ,
~x1 , . . . tal que existe una matriz estocástica P (matriz de transición) que verifica

~x1 = P~x0 , ~x2 = P~x1 , ~xk = P~xk−1 , . . .

El problema que usualmente se intenta resolver cuando se tiene una cadena de Markov es
conocer si la evolución del proceso a lo largo del tiempo tiende a “estabilizarse” y, en caso
afirmativo, quiere conocerse ese “estado final”. Dicho de otro modo, quiere saberse si existe un
vector de estados límite
~v = lı́m ~xk .
k→∞

Si tal vector existe, diremos que la cadena de Markov es convergente.


Nótese que, en caso de existir ese vector límite ~v , como ~xk+1 = P~xk , tomando límites
cuando k → ∞ a ambos lados de la igualdad obtenemos que ~v = P~v . Es decir, ~v es un vector
que queda invariante al multiplicarlo (por la izquierda) por la matriz P. Dicho de otro
modo, ~v es un vector estacionario para P, según la terminología precisada en la siguiente
definición:
Definición 3. Dada una matriz cuadrada P, diremos que un vector no nulo1 ~v es estacionario
para P si P~v = ~v .
Así pues, se tiene la siguiente propiedad:
Proposición 1. Sea ~x0 , ~x1 , . . . una cadena de Markov convergente con matriz de transición
P. Si ~v = lı́mk→∞ xk entonces ~v es un vector de probabilidad estacionario para P.
Ejemplo 1. Comprobemos esta propiedad con el ejemplo dado en la primera sección:

-->x0=[0.15; 0.20; 0.65];


-->P=[0.70, 0.15, 0.15; 0.20, 0.80, 0.15;0.10, 0.05, 0.70];

Calculando ~xk , con k suficientemente grande, obtendremos una buena aproximación del
vector límite:
1
El vector nulo sería estacionario para cualquier matriz cuadrada P de dimensión apropiada, por eso se quita
de la definición pues carece de interés.

4
-->v=P^100*x0
v =
0.33333333
0.47619048
0.19047619

Comprobemos que es un vector estacionario:

-->clean(P*v-v)
ans =
0.
0.
0.

Nota. Observa que cada múltiplo no nulo de un vector estacionario es de nuevo un vector
estacionario. De hecho, si ~v es un vector estacionario de una matriz A y λ es un escalar no
nulo, utilizando propiedades de matrices obtenemos que

A(λ~v ) = λ |{z}
A~v = λ~v .
~v

Además, las matrices estocásticas satisfacen las siguientes propiedades (que no probamos):
1. El producto de matrices estocásticas es de nuevo una matriz estocástica.

2. Toda matriz estocástica tiene vectores estacionarios.


Veremos a continuación que la matriz P del ejemplo introductorio tiene un solo vector
de probabilidad estacionario:
Ejemplo 2. Calcularemos todos los vectores estacionarios de la matriz P del ejemplo intro-
ductorio. Observamos que un vector estacionario de P es un vector no nulo cualquiera ~x tal
que P~x = ~x. Pero esto es equivalente a la igualdad P~x = I~x (donde I es la matriz identidad).
Pasando I~x al primer miembro y aplicando la propiedad distributiva obtenemos esta condición
equivalente:
(P − I)~x = ~0.
Esta es la expresión matricial de un sistema homogéneo de ecuaciones lineales. Por tanto, los
vectores estacionarios de P son exactamente las soluciones no nulas de este sistema de
ecuaciones lineales, es decir, los vectors no nulos delnúcleo de la matriz P−I. Calculémoslo
usando Scilab:
-->A=[0.7 0.15 0.15; 0.2 0.8 0.15; 0.1 0.05 0.7];kernel(A-eye(3,3))
ans =
0.5449493
0.7784989
0.3113996

5
Así pues, el conjunto de vectores estacionarios para la matriz P es
   
 0,5449493 
λ 0,7784989 | λ ∈ R \ {0}
 
0,3113996
 

Dividiendo todos los vectores de este conjunto entre la suma de sus componentes obtendremos
todos los vectores de probabilidad estacionarios:
     
0,5449493 0,3333333
 1 
λ 0,7784989 | λ ∈ R \ {0} = {0,4761905}
 λ(0,5449493 + 0,7784989 + 0,3113996)
0,3113996 0,1904762

Evidentemente, al dividir, siempre nos sale el mismo vector. Por tanto solo hay un vector
de probabilidad estacionario que, en virtud de la Proposicion 1, debe de coincidir con el
vector límite de la cadena de Markov dada en la Sección 1 (compara con la aproximación del
vector límite obtenida). Es más, como sólo hay un vector de probabilidad estacionario, éste
debera ser el límite de cualquier cadena de Markov convergente con matriz de transicion P,
independientemente del vector de estados iniciales ~x0 !

No todas las matrices de transición P asociadas a una cadena de Markov poseen un único
vector estacionario como en el ejemplo anterior, y ello provoca que diferentes cadenas de Markov
con la misma matriz de transición P puedan converger a vectores diferentes. Una muestra de
ello es el ejemplo siguiente:

Ejemplo 3. Consideremos la matriz estocástica


 
1/2 0 0
P =  0 1 0
1/2 0 1

y la cadena de Markov con matriz de transición P y vector de estado inicial ~x0 = (1/3, 2/3, 0).
Para estudiar la convergencia del proceso escribiremos, en Scilab, las siguientes instrucciones:

-->P=[1/2 0 0; 0 1 0; 1/2 0 1];x0=[1/3; 2/3; 0];P^10*x0


ans =
0.0003255
0.6666667
0.3330078
-->P^30*x0
ans =
3.104D-10
0.6666667
0.3333333

6
-->P^50*x0
ans =
2.961D-16
0.6666667
0.3333333
-->clean(ans)
ans =
0.
0.6666667
0.3333333

Vemos claramente que el proceso es convergente al vector de probabilidad (0, 2/3, 1/3). Sin
embargo, ¿qué pasa si elegimos un vector de estado inicial diferente? Tomemos, por ejemplo,
el vector ~x0 = (1/3, 1/3, 1/2):

-->x0=[1/3; 1/3; 1/3];P^10*x0


ans =
0.0003255
0.3333333
0.6663411
-->P^30*x0
ans =
3.104D-10
0.3333333
0.6666667
-->P^50*x0
ans =
2.961D-16
0.3333333
0.6666667
-->clean(ans)
ans =
0.
0.3333333
0.6666667

Vemos que el proceso es de nuevo convergente, pero el límite es diferente: (0, 1/3, 2/3).
Ambos vectores son dos vectores de probabilidad estacionarios diferentes y tampoco es uno
múltiplo del otro.
Podemos calcular todos los vectores estacionarios de la matriz P calculando el núcleo de
P − I:

-->P=[1/2 0 0; 0 1 0; 1/2 0 1];kernel(P-eye(3,3))


ans =

7
0. 0.
0. 1.
1. 0.
A partir de aquí deducimos que el conjunto vectores estacionarios consta de los vectores
λ1 (0, 1, 0) + λ2 (0, 0, 1) = (0, λ1 , λ2 ), con λ1 , λ2 ∈ R y alguno λi 6= 0. Dividiendo por la
suma de sus componentes (es decir, λ1 + λ2 ) obtendremos todos los vectores de probabilidad
estacionarios:
1
(0, λ1 , λ2 ), λ1 , λ2 ∈ R.
λ1 + λ2
Observamos que hay una cantidad infinita.
A continuación daremos una condición suficiente para que una matriz estocástica satisfaga
las buenas condiciones del ejemplo introductorio, es decir, que garantice que una cadena de
Markov tenga un único vector de probabilidad estacionario y, además, sea ese vector su límite
para cualquier vector de estado inicial que consideremos.
Definición 4. Una matriz estocástica P es regular si existe un número natural k tal que todas
las entradas de la matriz Pk son estrictamente positivas (P k no tiene ninguna entrada nula).
Teorema 1. Si P es una matriz estocástica regular, existe un único vector de probabilidad
estacionario ~v para P . Además, si ~x0 es cualquier vector de probabilidad y ~xk+1 = P~xk para
todo k ≥ 0, entonces la cadena de Markov {~xk } converge a ~v .
Nota. Observa que una matriz estocástica sin entradas nulas es siempre regular (véase la matriz
P del ejemplo introductorio). Por el contrario, para que no sea regular debe tener muchas
componentes nulas (Ejemplo 3). ¿Serán regulares las siguiente matrices:
   
1/2 1 0 0 1 0
 0 0 1 , 0 0 1?
1/2 0 0 1 0 0

Nota. Existen numerosas aplicaciones prácticas (entre las que se encuentra el cálculo del Pa-
geRank de Google) en las que interesa calcular un vector de probabilidad estacionario para
una cierta matriz estocástica P. En casi todas estas aplicaciones la matriz P es grande y lo
que se hace en la práctica, esencialmente, es, en lugar de calcular directamente el núcleo de
la matriz P − I (como en nuestro ejemplo), se comienza con un vector inicial ~x = ~x0 y se
repite el proceso iterativo ~x ← P~x (almacenando sólo el vector ~x resultante en cada iteración)
con la idea de detener el proceso cuando la diferencia entre el x introducido y el obtenido sea,
componente a componente, menor que determinada pequeña cantidad . El vector así obtenido
será, por tanto, una aproximación al vector de estados límite de una cadena de Markov y, así,
será también un vector de probabilidad estacionario para la matriz de transición P (en virtud de
la Proposición 1)2 . Si la matriz P cumple las condiciones del Teorema 1, quedará garantizada
2
Este método iterativo descrito se conoce como el Método de la Potencia y es comúnmente utilizado en
multitud de problemas.

8
la existencia de un único vector de probabilidad estacionario; esto es esencial, por ejemplo, en
el algoritmo de cálculo del PageRank de Google, que se verá en una práctica posterior.

9
Práctica 4
Cálculo de inversas y descomposición LU

Índice
1. Cálculo de la matriz inversa 1
1.1. La función inv . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.2. Cálculo de matrices inversas con el algoritmo de Gauss-Jordan . . . . . . . . . 3

2. Descomposición LU de una matriz cuadrada 4


2.1. Cálculo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.2. Aplicaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.2.1. Resolución de sistemas de ecuaciones lineales . . . . . . . . . . . . . . 8
2.2.2. Aplicación al cálculo de determinantes . . . . . . . . . . . . . . . . . 10
2.2.3. Aplicación al cálculo de matrices inversas . . . . . . . . . . . . . . . . 11

1. Cálculo de la matriz inversa


1.1. La función inv
Para calcular la matriz inversa de una matriz cuadrada A, utilizamos la función inv aplicada
sobre A. Si A es invertible, entonces el comando
-->inv(A)
nos da la matriz inversa A−1 . En otro caso, o bien aparece un error indicando que la matriz
es singular (es decir, no invertible), o aparece un mensaje de aviso diciendo que la matriz es
próxima a ser singular o está mal condicionada. En el último caso no es claro si la matriz es
singular o no, podemos utilizar, en esta situación, la función rank para calcular el rango de A
y comprobar si A tiene rango máximo.
Ejemplo 1. Consideramos la matriz
 
2 5 −1
A = 0 0 9  .
0 5 4

1
-->A=[2 5 -1;0 0 9;0 -5 4];

-->inv(A)
ans =
0.5 - 0.1666667 0.5
0. 0.0888889 - 0.2
0. 0.1111111 0.

Podemos comprobar que la inversa proporcionada es correcta:

-->A*inv(A)
ans =
1. 5.551D-17 0.
0. 1. 0.
0. - 5.551D-17 1.

Las entradas (1, 2) y (3, 2) (es decir, 5,551 · 10−17 y −5,551 · 10−17 ) habrían, probablemente, de
ser cero (no son cero, probablemente, debido a errores de redondeo en los cálculos). Utilizando
la función clean, podemos sustituir a estos números por 0:

-->clean(ans)
ans =
1. 0. 0.
0. 1. 0.
0. 0. 1.

Esta es la matriz identidad y, por lo tanto, el resultado es correcto.

Ejemplo 2. Consideramos la matriz


 
1 1 1
B = 2 2 2 .
3 3 3

-->B=[1 1 1; 2 2 2; 3 3 3]
B =
1. 1. 1.
2. 2. 2.
3. 3. 3.

-->inv(B)
!--error 19
Problem is singular.

Calculando el rango de B podemos ver que esta matriz no tiene rango máximo:

2
->rank(B)
ans =
1.

Así, la matriz no es invertible en este caso.

Ejemplo 3. Consideramos ahora la matriz


 
1 2 3
C = 4 5 6 .
7 8 9

-->C=[1 2 3;4 5 6;7 8 9]


C =
1. 2. 3.
4. 5. 6.
7. 8. 9.

-->inv(C)
warning :
matrix is close to singular or badly scaled. rcond = 0.0000D+00

ans =
1.0D+15 *

- 4.5035996 9.0071993 - 4.5035996


9.0071993 - 18.014399 9.0071993
- 4.5035996 9.0071993 - 4.5035996

-->rank(C)
ans =
2.

Concluimos que C no es invertible.

1.2. Cálculo de matrices inversas con el algoritmo de Gauss-Jordan


Dada una matriz cuadrada A, podemos también encontrar la inversa de A aplicando el
algoritmo de Gauss Jordan a la matriz A1 = [A I], donde I es la matriz identidad:

Ejemplo 4. Sea A la matriz del ejemplo 1.

-->A1=[A,eye(3,3)]
A1 =
2. 5. - 1. 1. 0. 0.

3
0. 0. 9. 0. 1. 0.
0. - 5. 4. 0. 0. 1.

-->rref(A1)
ans =
1. 0. 0. 0.5 - 0.1666667 0.5
0. 1. 0. 0. 0.0888889 - 0.2
0. 0. 1. 0. 0.1111111 0.

Entonces A es invertible y su inversa es

-->ans(:,4:6)
ans =
0.5 - 0.1666667 0.5
0. 0.0888889 - 0.2
0. 0.1111111 0.

Ejemplo 5. Haciendo lo mismo con la matriz C del ejemplo 3:

-->C1=[C, eye(3,3)]
C1 =
1. 2. 3. 1. 0. 0.
4. 5. 6. 0. 1. 0.
7. 8. 9. 0. 0. 1.

-->rref(C1)
ans =
1. 0. - 1. 0. - 2.6666667 1.6666667
0. 1. 2. 0. 2.3333333 - 1.3333333
0. 0. 0. 1. - 2. 1.

Como la matriz de la izquierda no es la matriz identidad, C no es invertible.

2. Descomposición LU de una matriz cuadrada


2.1. Cálculo
Una descomposición LU (también llamada factorización LU) es una descomposición de
una matriz que escribe una matriz como el producto de una matriz triangular inferior y una
triangular superior. Esta descomposición tiene muchas aplicaciones. Presentaremos aquí tres
de ellas: resolución de sistemas de ecuaciones lineales, cálculo del determinante de una matriz
cuadrada y cálculo de matrices inversas.

4
Antes que nada, explicaremos el proceso de obtención (a mano) de una descomposición LU
mediante un par de ejemplos. Consideramos la matriz
 
2 5 −3
A= 4 7 −4
−6 −3 1

Efectuando operaciones elementales por filas (es decir, multiplicando A por matrices elementales
convenientes) podemos encontrar, en este caso, una matriz triangular superior que es equivalente
(por filas) a A:  
2 5 −3
E32 (4)E31 (3)E21 (−2)A = 0 −3 2  .
0 0 0
Tomando B = E32 (4)E31 (3)E21 (−2) y
 
2 5 −3
U = 0 −3 2 
0 0 0

tenemos que
BA = U,
donde B es una matriz triangular inferior y U es una matriz triangular superior. Como B es
producto de matrices elementales, es invertible. Multiplicando la igualdad anterior por B−1 (por
la izquierda), tenemos:
A = B−1 U.
No es difícil probar que la inversa de una matriz triangular inferior invertible es también una
matriz triangular inferior. Por tanto, tomando L = B−1 , obtenemos una descomposición LU de
A:
A = LU.
Es muy fácil calcular L a mano porque conocemos las inversas de las matrices elementales:

L = B−1 = (E32 (4)E31 (3)E21 (−2))−1 = E21 (−2)−1 E31 (3)−1 E32 (4)−1
 
1 0 0
= E21 (2)E31 (−3)E32 (−4) =  2 1 0 .
−3 −4 1

En resumen, hemos obtenido la siguiente descomposición LU de A:


  
1 0 0 2 5 −3
A= 2 1 0 0 −3 2  .
−3 −4 1 0 0 0
| {z }| {z }
L U

5
Veamos otro ejemplo. Consideramos la matriz
 
0 −2 1
C = 3 0 2 .
0 2 4

Si aplicamos el mismo proceso de antes a la matriz C obtenemos:


 
3 0 2
E32 (1)E12 C = 0
 −2 1 .
0 0 5
| {z }
U

Entonces,
 
0 1 0
L = (E32 (1)E12 )−1 = E12
−1
E32 (1)−1 = E12 E32 (−1) = 1 0 0 .
0 −1 1

Pero... esta matriz L no es triangular inferior! La razón es que, en el proceso de obten-


ción, hemos intercambiado filas (es decir, hemos efectuado operaciones elementales de tipo 1).
Ésta es la diferencia con el ejemplo previo. No obstante, en este caso, mantendremos el nombre
de «descomposició LU» para referirnos a la factorización obtenida. Es decir: una descom-
posición LU de una matriz A será una factorización A = LU donde U es triangular
superior y L es triangular inferior (excepto reordenación de filas).
Las descomposiciones LU pueden obtenerse fácilmente con Scilab utilizando la función lu.
Pero... atención! Esta función utiliza la eliminación gaussiana con pivotación parcial para ob-
tener la descomposición. Esto quiere decir que, probablemente, Scilab utilizará intercambios
de filas en el proceso y que la matriz obtenida L no será triangular inferior (aunque, natu-
ralmente, lo será si reordenamos las filas). Por ejemplo, si calculamos, utilizando Scilab, una
descomposición LU de la matriz anterior A:

-->A=[2 5 -3; 4 7 -4; -6 -3 1];

-->[L,U]=lu(A)
U =
- 6. - 3. 1.
0. 5. - 3.3333333
0. 0. 4.441D-16
L =
- 0.3333333 0.8 1.
- 0.6666667 1. 0.
1. 0. 0.

«Anulamos» los elementos «cercanos a cero» del factor U:

6
->clean(U)
ans =
- 6. - 3. 1.
0. 5. - 3.3333333
0. 0. 0.

Observamos que el factor L que Scilab ha calculado no es triangular inferior.


También se puede utilizar el comando de Scilab [L, U, P] = lu(A) (añadiendo otro parámetro
a la salida):

-->[L1,U1,P]=lu(A)
P =
0. 0. 1.
0. 1. 0.
1. 0. 0.
U1 =
- 6. - 3. 1.
0. 5. - 3.3333333
0. 0. 4.441D-16
L1 =
1. 0. 0.
- 0.6666667 1. 0.
- 0.3333333 0.8 1.

-->P*L1*U1
ans =
2. 5. - 3.
4. 7. - 4.
- 6. - 3. 1.

-->U-U1
ans =
0. 0. 0.
0. 0. 0.
0. 0. 0.

-->L-P*L1
ans =
0. 0. 0.
0. 0. 0.
0. 0. 0.

Es decir, cuando escribimos tres parámetros como salida, [L, U, P] = lu(A), nos devuelve
la matriz de permutación P tal que PA = LU, donde U es triangular superior y L es triangular

7
inferior con todos sus elementos diagonales iguales a 1; si escribimos sólo dos parámetros,
[L, U] = lu(A), la matriz U es la misma pero la matriz L nos la da ya permutada y, por tanto,
esta L verificará la igualdad A = LU.

2.2. Aplicaciones
2.2.1. Resolución de sistemas de ecuaciones lineales
La descomposición LU puede aplicarse a la resolución de sistemas de ecuaciones lineales.
Veamos un ejemplo.
Consideramos el sistema 
−2y + z = 1 
3x + 2y = 2 ,
2y + 4z = 3

cuya matriz de coeficientes es la matriz C del ejemplo anterior y cuya espresión matricial es:
    
0 −2 1 x 1
3 0 2 y  = 2 .
0 2 4 z 3

Sustituyendo la matriz de coeficientes por su descomposición LU tenemos


     
0 1 0 3 0 2 x 1
1 0 0 0 −2 1 y  = 2 . (1)
0 −1 1 0 0 5 z 3
| {z }| {z } |{z} |{z}
L U ~
x ~b

El producto U~x es un vector columna de tres componentes que denotaremos por ~y , es decir:
 
y1
U~x = ~y = y2  .

y3

Por consiguiente, la igualdad (1) se puede escribir:


    
0 1 0 y1 1
1 0 0   y2 = 2 .
 
0 −1 1 y3 3
| {z } | {z } |{z}
L ~
y ~b

Esta es la expresión matricial del siguiente sistema:



y2 = 1 
y1 = 2 (2)
−y2 + y3 = 3

8
Este sistema tiene una matriz de coeficientes «casi triangular» y puede ser resuelto directamente
por una sustitución progresiva, dando lugar a esta solución:
 
2
~y = 1 .

4

Ahora, como U~x = ~y y conocemos ~y , podemos calcular ~x resolviendo el sistema de ecuaciones


lineales cuya expresión matricial es U~x = ~y :
    
3 0 2 x 2
0 −2 1 y  = 1 .
0 0 5 z 4
| {z } |{z} |{z}
U ~
x ~
y

Este es el «sistema triangular» 


3x + 2z = 2 
−2y + z = 1 . (3)
−3z = 4

Resolviéndolo por sustitución regresiva obtenemos la solución:


 
2/15
~x = −1/10 .
4/5

En resumen, la descomposición LU de la matriz de coeficientes nos ha permitido transformar


el sistema de ecuaciones en dos sistemas que pueden resolverse directamente por sustitución
progresiva y regresiva, respectivamente: (2) y (3).
Notamos que este método de resolver sistemas de ecuaciones es especialmente útil cuando
se deben resolver muchos sistemas de ecuaciones lineales con la misma matriz de coeficientes.
La razón es que la descomposición LU se aplica sólo sobre la matriz de coeficientes; esto significa
que la misma descomposición LU es válida para todos los sistemas lineales.
Ejemplo 6. Si quisiéramos resolver el sistema de ecuaciones anterior utilizando la descompo-
sición LU y con Scilab podríamos introducir lo siguiente:
-->C=[0 -2 1;3 0 2;0 2 4];[L,U]=lu(C)
U =
3. 0. 2.
0. - 2. 1.
0. 0. 5.
L =
0. 1. 0.
1. 0. 0.
0. - 1. 1.

9
-->y=L\[1;2;3]
y =
2.
1.
4.

-->x=U\y
x =
0.1333333
- 0.1
0.8

2.2.2. Aplicación al cálculo de determinantes


El determinante de una matriz cuadrada se puede calcular con Scilab utilizando la función
det. Por ejemplo:

-->D=[1 2; 3 4];

-->det(D)
ans =
- 2.

El procedimiento utilizado internamente por Scilab cuando se aplica esta función a una matriz
A es el siguiente:

1. Se obtiene la descomposición LU de A.

2. Teniendo en cuenta que A = LU, el determinante de A se calcula como det L det U.


Notamos que ambos determinantes involucrados aquí son muy fáciles de calcular:

Como U es triangular superior, su determinante es el producto de las entradas


diagonales.
El determinante de L es ±1, donde el signo será + cuando el número de operaciones
elementales de intercambio sea par, y − cuando este número sea impar1 .

-->A=[0 2 3; -4 6 0; 2 -5 5];

-->[L,U]=lu(A)
U =
- 4. 6. 0.
1
Scilab calcula L de manera que, después de permutar convenientemente las filas para obtener una matriz
triangular inferior, en la diagonal sólo hay unos.

10
0. 2. 3.
0. 0. 8.
L =
0. 1. 0.
1. 0. 0.
- 0.5 - 1. 1.

-->det(L)
ans =
- 1.

-->det(U)
ans =
- 64.

-->det(L)*det(U)
ans =
64.

-->det(A)
ans =
64.

2.2.3. Aplicación al cálculo de matrices inversas


Cuando utilizamos la función inv para calcular la inversa de una matriz cuadrada A de orden
n, Scilab efectúa, automáticamente, las siguientes operaciones:
1. Obtén una descomposición LU de A.
2. Calcula det U.
3. Si det U = 0, entonces Scilab indica que la matriz es singular (no invertible).
4. Si det U 6= 0, entonces calcula U−1 de la siguiente manera: Si ~uj denota la columna j
de U−1 e I es la matriz identidad, es evidente que la igualdad UU−1 = I es equivalente al
conjunto de igualdades
U~uj = ~ej j = 1, 2, . . . n,
donde ~ej es el vector columna j de la matriz identidad; por consiguiente, resolviendo
todos los sistemas de ecuaciones lineales U~x = ~ej se obtienen todas las columnas de U−1 ,
es decir, se obtiene la matriz inversa de U. La inversa de la matriz L, L−1 , se calcula con
el mismo algoritmo. Finalmente, A−1 se obtiene como el producto U−1 L−1 .
Notamos que es posible obtener una matriz singular tal que todas las entradas diagonales de
U sean diferentes de cero (debido a errores de redondeo en la eliminación gaussiana). En este

11
caso, la matriz inversa es calculada por Scilab y, en algunos casos, aparece un mensaje de aviso.
Por esta razón, recomendamos comprobar si o bien la matriz obtenida cuando introducimos el
comando inv(A) es de verdad la matriz inversa de A o A tiene rango máximo (por medio de la
función rank).

Ejemplo 7. Consideramos la matriz:


 
1 2 −5
A = −4 1 0  .
1 2 7

Calculamos su inversa a partir de su descomposición LU y utilizando la función inv:

-->A=[1 2 -5; -4 1 0; 1 2 7]; [L,U]=lu(A)


U =
- 4. 1. 0.
0. 2.25 - 5.
0. 0. 12.
L =
- 0.25 1. 0.
1. 0. 0.
- 0.25 1. 1.

-->inv(U)*inv(L)
ans =
0.0648148 - 0.2222222 0.0462963
0.2592593 0.1111111 0.1851852
- 0.0833333 0. 0.0833333

-->inv(A)
ans =
0.0648148 - 0.2222222 0.0462963
0.2592593 0.1111111 0.1851852
- 0.0833333 0. 0.0833333

Comprobamos que la matriz obtenida es la inversa de A:

-->clean(A*ans)
ans =
1. 0. 0.
0. 1. 0.
0. 0. 1.

12
Práctica 6
Ortogonalidad y proyecciones ortogonales

Índice
1. Producto escalar, norma y distancia 1

2. Proyecciones ortogonales 5
2.1. Definición . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.2. Caso fácil: proyección ortogonal sobre una recta . . . . . . . . . . . . . . . . 5
2.3. Caso general . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

1. Producto escalar, norma y distancia


Recordaremos en este apartado diversos conceptos presentados en la teoría. Sean ~u y ~v dos
vectores de Rn .

El producto escalar (o producto interior) de ~u y ~v es el número real

~u · ~v = ~ut~v = u1 v1 + u2 v2 + · · · + un vn .

Si ~u · ~v = 0, se dice que los vectores ~u y ~v son ortogonales.

Si W es un subespacio vectorial de Rn , se denomina complemento ortogonal de W al


subespacio
W ⊥ = {~z ∈ Rn : ~z · w ~ ∈ W }.
~ = 0 para todo w

La norma (o longitud) de ~v es
√ q
k~v k = ~v · ~v = v12 + v22 + · · · + vn2

i k~v k2 = ~v · ~v .

Un vector se dice que es unitario si su norma es 1. El vector (1/k~v k)~v siempre es unitario.

La distancia entre ~u y ~v es k~u − ~v k.

1
Dada una matriz real A con m filas y n columnas, se denomina subespacio columna de A
(y se denota por Col A) al subespacio vectorial de Rm generado por los vectores columna
de A.

Dada una matriz real A con m files y n columnas, se denomina subespacio fila de A (y
se denota por Fil A) al subespacio vectorial de Rn generado por los traspuestos de los
vectores fila de A.
Teorema 1. Sea A una matriz real con m filas y n columnas. Se satisface lo siguiente:

(Fil A)⊥ = Nul A i (Col A)⊥ = Nul At .

Ejemplo 1. Sean      
5 −4 3
−4 1 3
~u = 
 0 ,
 ~v = 
−3 ,
 w
~ =
 5 ,

−3 8 −1
y consideremos W = h~u, ~v , wi
~ y
 
5 −4 3
−4 1 3
A=
 0 −3 5  .

3 8 −1

Los vectores ~u y ~v son ortogonales porque ~u ·~v = 5 · (−4) + (−4) · 1 + 0 · (−3) + 3 · 8 = 0.


p √
~ = 32 + 32 + 52 + (−1)2 = 2 11.
kwk
 √ 
3/2√11
 3/2 11 
1
El vector kwk √ 
~
w
~ =  5/2 11  es unitario.

−1/2 11
p √
k~u − ~v k = (5 − 4)2 + (−4 − 1)2 + (0 − (−3))2 + (3 − 8)2 = 2 15.

A es equivalente por filas a  


5 −4 3
0 7 9 
0 0 62 ,
 

0 0 0
por tanto
*     +⊥
5 0 0

(Fil A) =  −4 , 7 , 0   = Nul A i (Col A)⊥ = W ⊥ = Nul At
   
3 9 62

2
Con Scilab:

Introducimos los vectores ~u, ~v y w:


~

-->u=[5;-4;0;3], v=[-4;1;-3;8], w=[3;3;5;-1]


u =

5.
- 4.
0.
3.
v =

- 4.
1.
- 3.
8.
w =

3.
3.
5.
- 1.

Para comprobar que los vectores ~u y ~v son ortogonales, calculamos su producto escalar:

-->uv=u'*v
uv =

0.

~ usaremos el comando norm():


Para determinar la norma del vector w,

-->norm(w)
ans =

6.6332496

Para determinar un vector unitario asociado a w


~ calculamos

-->t=w/norm(w)
t =

0.4522670
0.4522670

3
0.7537784
- 0.1507557

Comprobamos que ~t es unitario:

-->norm(t)
ans =

1.

Para determinar la distancia entre los vectores ~u y ~v , hacemos lo siguiente:

-->norm(u-v)
ans =

11.83216

Construimos la matriz A que tiene como columnas a los vectores ~u, ~v y w:


~

-->A=[u v w]
A =

5. - 4. 3.
- 4. 1. 3.
0. - 3. 5.
3. 8. - 1.

Para calcular una base del subespacio (Fil A)⊥ , calcularemos el núcleo de la matriz A:

-->NF=kernel(A)
NF =

[]

Es decir: el vector nulo es el único vector ortogonal al subespacio fila Fil A.

De forma análoga, para determinar una base del subespacio (Col A)⊥ tendremos que
calcular una base del núcleo de At :

-->NC=kernel(A')
NC =

0.4958960
0.5689754
- 0.6524947
- 0.0678594

4
2. Proyecciones ortogonales
2.1. Definición
Sea W un subespacio vectorial de Rn . Para cada vector ~x ∈ Rn existen un único vector w ~∈

W y un único vector ~xort en el complemento ortogonal W tales que ~x = w ~ + ~xort . El vector w
~
se denomina proyección ortogonal de ~x sobre el subespacio W , y lo denotaremos por P royW (~x).
Esta definición formaliza y generaliza la idea greométrica de “proyección perpendicular”:
36



~x


 ~xort

 
 

 W 




  
 r
 P royW (~x) - 
 
 
 
 
 
 

El vector ~x se puede descomponer, de forma única, como una suma de dos componentes: una
de ellas (P royW (~x)) sobre W y la otra (~xort ) es ortogonal a todos los vectores de W (es decir,
pertenece a W ⊥ ). Cuando hablemos de proyección ortogonal de ~x sobre W estaremos hablando
de la componente P royW (~x) sobre W en esta descomposición.

2.2. Caso fácil: proyección ortogonal sobre una recta


Consideremos el caso en el cual W es una recta de Rn , es decir, está generado por un único
vector no nulo. Podemos dividir este generador entre su norma y transformalo en un vector
unitario (que continuará generando la recta). Tomamos S = {~q}, donde ~q es un vector unitario
que genera la recta.

5
36



~x


 ~xort







r


-
P royW (~x) - W
~q

Consideremos un vector no nulo cualquiera ~x ∈ Rn . Queremos calcular la proyección orto-


gonal P royW (~x) de ~x sobre W . Como P royW (~x) pertenece a la recta W , existe un escalar
λ tal que P royW (~x) = λ~q. Pero el vector ~x − λ~q = ~xort es ortogonal a W y, por tanto,
(~x − λ~q) · ~q = 0. Es decir, ~x · ~q − λ~q · ~q = 0; como ~q es unitario tenemos que λ = ~q · ~x o,
utilizando la notación de producto fila-columna en lugar de la notación del producto escalar,
λ = ~q t~x. Concluimos, por tanto, la siguiente propiedad:

La proyección ortogonal de un vector ~x sobre una recta W es el vector

P royW (~x) = (~q t~x)~q

donde ~q es un generador unitario de la recta.

Ejemplo 2. Consideremos la recta W = h(1, −2, 5)i ⊆ R3 . Calcularemos a continuación la


proyección ortogonal del vector ~x = (0, 1, 1) sobre W . Primero calcularemos un generador
unitario de la recta, dividiendo este vector entre su norma:
-->u=[1; -2; 5];

-->q=u/norm(u)
q =

0.1825742
- 0.3651484
0.9128709
Ahora calcularemos la proyección usando la fórmula de antes:
-->x=[0; 1; 1];

-->(q'*x)*q
ans =

6
0.1
- 0.2
0.5

Por tanto, la proyección ortogonal es (0,1, −0,2, 0,5).

2.3. Caso general


Queremos ahora calcular la proyección ortogonal de un vector sobre un subespacio vectorial
cualquiera W . Suponemos conocido un sistema generador S = {~u1 , . . . , ~ur } de W . Entonces
W puede verse como el subespacio columna de la matriz M(S) (la matriz que tiene, como
columnas, los vectores ~ui ). Por tanto

W ⊥ = Nul(M(S)t ).

Como ~x = P royW (~x) + ~xort se tiene que ~x − P royW (~x) = ~xort y, por tanto,

~x − P royW (~x) ha de ser ortogonal a W ,

es decir,
~x − P royW (~x) ∈ W ⊥ = Nul(M(S)t ).
Así, tenemos que
M(S)t (~x − P royW (~x)) = ~0,
es decir,
M(S)t P royW (~x) = M(S)t~x. (1)
Por otro lado

el vector P royW (~x) pertenece a W

y esto quiere decir que puede escribirse como combinación lineal de los vectores de S (que es
un sistema generador de W ). Denotamos por yi a los coeficientes de esta combinación lineal:

P royW (~x) = y1~u1 + · · · + yr ~ur (2)

y definimos el vector  
y1
 .. 
~y :=  .  .
yr
(Observa que calcular P royW (~x) equivale a calcular ~y ).
La igualdad (2) significa que

P royW (~x) = M(S)~y .

7
Sustituyendo esta nueva expresión de P royW (~x) en la igualdad (1) se tiene que

M (S)t M(S)~y = M(S)t~x.

Observa que M (S)t M(S) es una matriz cuadrada de orden r y que la igualdad anterior es la
expresión matricial de un sistema de r ecuaciones lineales con incógnitas y1 , . . . , yr y con vector
de términos independientes M (S)t~x (recuerda que ~x es el vector que estamos proyectando).
Puede razonarse fácilmente que todas las soluciones (y1 , . . . , yr ) de este sistema dan lugar a la
misma combinación lineal y1~u1 + · · · + yr ~ur , que es la proyección ortogonal deseada.
Hemos deducido, por tanto, el siguiente resultado:

La proyección ortogonal de un vector ~x sobre un subespacio vectorial W generado por


un conjunto de vectores S = {~u1 , . . . , ~ur } es el vector P royW (~x) = y1~u1 + · · · + yr ~ur ,
donde ~y = (y1 , . . . , yr ) es una solución del sistema

M (S)t M(S)~y = M(S)t~x. (3)

Supongamos ahora que S és linealmente independiente, es decir, que es una


base de W .

En este caso, rang(M(S)t M(S)) = r y esto implica que el sistema (3) tiene solución
única que nos da los coeficientes ~yi (respecto de la base S) de la proyección ortogonal de ~x.
Como la matriz M(S)t M(S) es invertible se tiene que la igualdad (3) equivale a

~y = (M(S)t M(S))−1 M(S)t~x.

Como las componentes de ~y son las coordenadas respecto de la base S de la proyección de ~x,
el producto M(S)~y será igual a P royW (~x):

P royW (~x) = M(S)(M(S)t M(S))−1 M(S)t~x.

Así, cuando el sistema de generadores S es una base de W , hemos obtenido una formula ele-
gante para proyectar sobre W cualquier vector:

La proyección ortogonal de un vector ~x sobre un subespacio vectorial W generado por


una base S de W es
P royW (~x) = PW ~x, (4)
donde
PW = M(S)(M(S)t M(S))−1 M(S)t
se denomina matriz de proyección sobre W .

(La matriz de proyección PW es independiente de la base S que consideremos).

8
Ejemplo 3. Sea W el subespacio vectorial de R3 con base S = {(1, 2, 3), (−3, 5, 1)} (observa
que S es, efectivamente, una base!) y consideremos el vector ~x = (2, 3, 4) ∈ R3 . Calcularemos,
con la ayuda de Scilab, la proyección ortogonal de ~x sobre W .
Primero definiremos la matriz M(S):

-->u1=[1; 2; 3;]; u2=[-3; -5; 1]; MS=[u1 u2]


MS =

1. - 3.
2. - 5.
3. 1.

Calculemos la matriz de proyección PW :

-->x=[2; 3; 4];
-->PW=MS*inv(MS'*MS)*MS'
PW =

0.2589744 0.4358974 - 0.0435897


0.4358974 0.7435897 0.0256410
- 0.0435897 0.0256410 0.9974359

Multiplicando esta matriz por el vector ~x obtendremos la proyección ortogonal:

-->PW*x
ans =

1.6512821
3.2051282
3.9794872

Por tanto P royW (~x) = (1,6512821, 3,2051282, 3,9794872).

9
Práctica 7
Método de los mínimos cuadrados

Índice
1. Ajuste por mínimos cuadrados 1

2. Aplicaciones del ajuste por mínimos cuadrados 3


2.1. Ajuste de rectas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.2. Ajuste de curvas por mínimos cuadrados . . . . . . . . . . . . . . . . . . . . 5

1. Ajuste por mínimos cuadrados


El término mínimos cuadrados describe el problema muy frecuente de resolver sistemas de
ecuaciones lineales “sobredeterminados” o "sobredimensionados", esto es, sistemas lineales con
más ecuaciones que incógnitas. En tal caso, como normalmente no existe tal solución, en lugar
de resolver las ecuaciones de manera exacta se busca sólo una “solución” que haga A~x tan
próximo a ~b como sea posible.

Una solución por mínimos cuadrados del sistema de ecuaciones lineales A~x = ~b es un
vector ~xM en Rn tal que k~b − A~xM k ≤ k~b − A~xk para todo ~x ∈ Rn .
Si aplicamos el teorema de la aproximación óptima al subespacio Col A y llamamos ~bp
a la proyección ortogonal de ~b sobre Col A, sabemos que bp es el vector de Col A más
próximo a b. Entonces habrá un vector ~xM que será la solución de A~x = bp . Tendremos,
pues, que A~xM = ~bp .
Como también sabemos que ~b − ~bp ∈ (Col A)⊥ , entonces ~b − A~xM ∈ (Col A)⊥ = Nul At ,
es decir,
At (~b − A~xM ) = 0,
de donde
At A~xM = At~b.

La ecuación matricial At A~xM = At~b se conoce como sistema de ecuaciones normales para
xM .

1
Si las columnas de A son linealmente independientes, la matriz At A es invertible y la
solución por mínimos cuadrados ~xM = (At A)−1 At~b será única.

Si las columnas de A son linealmente independientes y A = QR, la única solución por


mínimos cuadrados viene dada por ~xM = R−1 Qt~b.

Se llama error residual a k~b − A~xM k.

Ejemplo 1. Determinamos las soluciones por mínimos cuadrados de A~x = ~b, siendo
   
1 3 5
A = 1 −1 , ~b = 1 .
1 1 0

Debemos resolver At A~xM = At~b.


   
  1 3     5  
t 1 1 1  3 3 t~ 1 1 1   6
AA= 1 −1 =  , Ab= 1 = .
3 −1 1 3 11 3 −1 1 14
1 1 0

El sistema     
3 3 x1M 6
=
3 11 x2M 14
tiene como única solución    
x1M 1
= .
x2M 1
El error residual será
   
5 1 3   √
1
k~b − A~xM k = 1 − 1 −1 = 6
1
0 1 1

Con Scilab:
Encontramos la solución por mínimos cuadrados teniendo en cuenta que en Scilab el co-
mando x =A \b proporciona una solución por mínimos cuadrados en caso de que A no sea una
matriz cuadrada. Además, si A es de rango completo por columnas, entonces la solución será
única. Del mismo modo, cuando A no es de rango completo por columnas, la solución no es
única.

-->A=[1 3;1 -1;1 1];b=[5;1;0];


-->Am=A'*A
Am =
3. 3.
3. 11.
-->bm=A'*b

2
bm =
6.
14.
-->xm=Am\bm
xm =
1.
1.

y puedes comprobar que, directamente, x =A \b da la misma solución.

2. Aplicaciones del ajuste por mínimos cuadrados


En ciencias e ingeniería, los experimentos que se realizan producen un conjunto de datos
(x1 , y1 ), (x2 , y2 ), . . . , (xn , yn ) con las abscisas diferentes. El problema que se plantea es en-
contrar una función y = f (x) que relacione los datos lo mejor posible. Buscar esta solución
implicará resolver un problema de mínimos cuadrados.

2.1. Ajuste de rectas


La relación más sencilla entre dos variables x e y es la ecuación lineal y = β0 + β1 x. A
menudo, al representar gráficamente el conjunto de datos experimentales hace el efecto que
estos quedan cerca de una recta. Queremos determinar los parámetros β0 y β1 que hagan la
recta tan «pròxima» a los puntos como sea posible.
La recta de regresión por mínimos cuadrados es aquella recta y = β0 + β1 x que minimiza
el error residual.
Si los datos estuviesen sobre la recta, los parámetros β0 y β1 cumplirian las ecuaciones

β0 + β1 xi = yi para i ∈ {1, 2, . . . , n}.

que, en forma matricial, sería    


1 x1   y1
1 x2  β0  y2 
 . . . . .  β1 = . . . .
   

1 xn yn
Llamaremos matriz de diseño a  
1 x1
1 x2 
X=
. . . . . ,

1 xn
vector parámetro a  
β
β~ = 0
β1

3
y vector observación a  
y1
 y2 
~y =  
. . .
yn
Se llama vector residual a
~
~ε = ~y − Xβ.
Para determinar el vector parámetro basta con resolver por mínimos cuadrados el sistema
~
Xβ = y, es decir, encontrar la solución que minimiza la norma del vector residual.
Ejemplo 2. Encontraremos la solución de la ecuación y = β0 + β1 x de la recta de mínimos
cuadrados que se ajuste a los puntos (0, 1), (1, 1), (2, 2) y (3, 2). Construimos la matriz de
diseño X y calculamos Xt X.
   
1 0   1 0  
1 1  t 1 1 1 1 1 1 4 6
X= 1 2  ,
 XX=  = .
0 1 2 3 1 2 6 14
1 3 1 3
Obtenemos  
  1  
t 1 1 1 1 
 = 6
1
X ~y =
0 1 2 3 2 11
2
Resolvemos         
4 6 β0 6 β0 9/10
= , cuya solución es =
6 14 β1 11 β1 2/5
Por lo tanto, la recta de ajuste por mínimos cuadrados será
9 2
y= + x.
10 5
Con Scilab:
-->X=[1 0;1 1;1 2;1 3], y=[1;1;2;2];
-->X1=X'*X, y1=X'*y
X1 =
4. 6.
6. 14.
y1 =
6.
11.
-->b=X1\y1
b =
0.9
0.4

4
~
Calculamos ahora la norma del vector residual k~y − Xβk:

-->norm(y-X*b)
ans =
0.4472136

2.2. Ajuste de curvas por mínimos cuadrados


Si representamos gráficamente el conjunto de datos y observamos que no están cerca de
una recta, buscaremos la curva que mejor los ajuste

y = β0 f0 (x) + β1 f1 (x) + · · · + βk fk (x),

donde f0 , f1 , . . . , fn son funciones conocidas y β0 , β1 , . . . , βn los parámetros que debemos


determinar para construir la curva. Procediendo de manera análoga a como lo hemos hecho
en la regresión lineal, debemos encontrar un vector parámetro que haga mínima la norma del
vector residual. En este caso, el sistema escrito en forma matricial será
   
f0 (x1 ) f1 (x1 ) . . . fk (x1 )   y1
 f0 (x2 ) f1 (x2 ) . . . fk (x1 )  β0  y2 
. . . . . . . . . . . . . . . . . . . . . . . . . . .  β1  = . . . .
    
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
    
. . .
βk
f0 (xn ) f1 (xn ) . . . fk (xn ) yn

La matriz de este sistema es la matriz de diseño.


1 2 3 4 5
Ejemplo 3. Con los datos de la tabla determinaremos el vector
1,8 2,7 3,4 3,8 3,9
parámetro, el vector residual y la curva de mínimos cuadrados asociada a la función y =
β0 + β1 x + β2 x2 .

1. Deberemos resolver por el método de mínimos cuadrados el sistema de ecuaciones lineales


~
~y = Xβ:    
1,8 1 1 1  
2,7 1 2 4  β0
   
3,4 = 1 3 9  β1  .
   
3,8 1 4 16 β2
3,9 1 5 25

2. Calculamos    
5 15 55 15,6
Xt X = 15 55 225 , Xt ~y =  52,1  .
55 225 979 201,5

5
3. Resolviendo el sistema (compatible determinado) Xt Xβ~ = Xt ~y obtendremos el vector
parámetro que minimiza el error residual
   
β0 0,58
β1  =  1,34  .
β2 −0,136

Por lo tanto la función (parábola) que mejor se ajusta a los datos será y = 0,58+1,34x−0,136x2 .
Si calculamos ~ε = ~y − Xβ,~ obtenemos el vector residual
 
0,114
−0,026
 
 0,008  .
 
 0,014 
0,008

Con Scilab:
Introducimos las matrices X, ~y :
-->X=[1 1 1;1 2 4;1 3 9;1 4 16;1 5 25], y=[1.8;2.7;3.4;3.8;3.9];
y, con la función \ obtenemos la solución por mínimos cuadrados:
-->b=X1\y1
b =
0.58
1.3442857
- 0.1357143
Luego la parábola que mejor se aproxima a los datos tiene los parámetros de b y su error residual
será
-->ER=norm(y-X*b)
ER =
0.0338062
Ejemplo 4. Con los datos del ejemplo anterior, determinaremos los parámetros que ajustan la
función y = β1 cos(πx/3) + β2 sin(πx/3).

cos π3 sin π3
 
cos 2π sin 2π 
 3 3 
3π 3π 
X=  cos 3
sin 3 
cos 4π sin 4π 
3 3
cos 5π
3
sin 5π
3
   
t 2 0 t −3,8
XX= , X ~y =
0 3 −2,8

6
Resolvemos el sistema y obtenemos el vector parámetro.
        
2 0 β1 −3,8 β1 −1,9
= , cuya solución es = .
0 3 β2 −2,8 β2 −0,9

Por lo tanto, la función pedida será y = −1,9 cos(πx/3) − 0,9 sin(πx/3), y el vector residual
es  
3,5
2,5
~ε = ~y − Xβ~ = 
 
1,5 .

2
4
Observamos que el vector residual es menor cuando usamos la primera función para ajustar los
datos que cuando usamos la segunda.
Con Scilab:
Introducimos la matriz de diseño X (el vector y ya estaba introducido):

-->X=[cos(%pi/3), sin(%pi/3)
--> cos(%pi*2/3), sin(%pi*2/3)
--> cos(%pi*3/3), sin(%pi*3/3)
--> cos(%pi*4/3), sin(%pi*4/3)
--> cos(%pi*5/3), sin(%pi*5/3)]
X =
0.5 0.8660254
- 0.5 0.8660254
- 1. 1.225D-16
- 0.5 - 0.8660254
0.5 - 0.8660254

Y podemos obtener los parámetros directamente:

-->b=X\y
b =
- 1.9
- 0.9237604

que no ha salido exactamente igual (debido a errores de redondeo con las funciones trigonomé-
tricas).
Podemos también repetir con Scilab el proceso hecho a mano para ver si se obtiene el
resultado correcto. Primero calculamos Xt X y Xt ~y :

-->X1=X'*X,y1=X'*y
X1 =
2. 2.924D-16
2.924D-16 3.

7
y1 =
- 3.8
- 2.7712813

y luego resolvemos el sistema 2 × 2: X1~b = ~y1

-->b1=X1\y1
b1 =
- 1.9
- 0.9237604

Como se puede observar, este proceso largo ha obtenido el mismo resultado que el corto (porque
\ realiza exactamente este proceso siempre que el sistema no es compatible determinado) y
sigue conteniendo cierto error de redondeo.
Veamos el error residual que proporciona esta función:

-->ER=norm(y-X*b1)
ER =
6.4776539

Luego no parece ser una función apropiada a los datos del problema.
Nota: con una recta y = β0 + β1 x

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


-->b=X\y
b =
1.53
0.53
-->ER=norm(y-X*b)
ER =
0.5089204

Conclusión: por el momento, la curva que mejor se ajusta a los datos es la parábola

y = 0,58 + 1,34x − 0,136x2

También podría gustarte