Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Curso 2022/23
En esta práctica se debe completar el fichero prac1.py, que inicialmente contiene solo
algunas funciones auxiliares que utilizaremos. Tras hacer la práctica, se espera que el fichero
contenga las funciones que se pide hacer en los distintos ejercicios. Como con el resto de
prácticas, el fichero se usará en algunas de las pruebas de evaluación de la asignatura, por lo
que solo debes escribir en él las funciones que se pide implementar en este boletín, sin otras
anotaciones o aclaraciones.
1. Objetivos
El objetivo de esta práctica es implementar y aplicar métodos para resolver sistemas de
ecuaciones lineales y calcular inversas de matrices, así como conocer las herramientas que
para ello nos proporciona el paquete scipy.linalg.
En primer lugar, utilizaremos las herramientas que nos proporciona el paquete scipy.linalg
para trabajar con sistemas de ecuaciones lineales. A continuación, replicaremos parte de la
funcionalidad de dicho paquete, desarrollando y utilizando nuestras propias funciones para:
Resolver sistemas triangulares, tanto inferiores como superiores.
Resolver sistemas lineales cuya matriz es simétrica y definida positiva, usando la des-
composición de Cholesky y la resolución de sistemas triangulares.
Por último, se podrá comprobar que no todos los sistemas lineales se pueden resolver.
1
2. Entorno de trabajo de las prácticas
Utilizaremos el entorno Spyder para las prácticas de la asignatura, así como las librerías
numpy y scipy. Aunque seguramente ya conoces numpy, revisaremos aquí los aspectos básicos
de la librería, que necesitaremos utilizar en las diferentes prácticas.
numpy permite trabajar con arrays multidimensionales, que nos servirán para representar
matrices y vectores. Se pueden crear arrays a partir de la lista de sus elementos, utilizando
listas anidadas si el array tiene dos o más dimensiones. Por ejemplo, las siguientes órdenes
definen un vector b y una matriz A (la marca >>> al principio de una línea indica que se trata
de una orden que escribimos en una terminal de Python; el resto de líneas son la respuesta
que obtenemos de Python):
>>> b = np.array([3,2,1]) nº enteros
>>> b
array([3, 2, 1])
>>> x = np.array([3.,2,1]) nº reales
>>> x
array([3., 2., 1.])
>>> A = np.array([[1,2],[3,4]],dtype='float')
>>> A nº reales
array([[1., 2.],
[3., 4.]])
Observa que hay una sutil diferencia entre los vectores b y x: el vector x contiene números
reales (se muestran con un punto decimal), mientras que el vector b contiene números enteros.
Esto es así porque, al construir x, hemos puesto punto decimal en uno de los elementos. Otra
forma de forzar que el array sea de números reales es añadir el argumento dtype='float'
de np.array, como se ha hecho al definir la matriz A.
La función np.zeros permite crear matrices o vectores de determinado tamaño cuyos
elementos valgan cero. La función np.ones es similar, pero con elementos igual a uno. En
ambos casos, serán números reales por defecto:
>>> np.zeros((2,3))
array([[0., 0., 0.],
[0., 0., 0.]])
>>> np.zeros(4) nº reales
por defecto
array([0., 0., 0., 0.])
>>> np.ones(3)*5
array([5., 5., 5.])
2
También podemos crear una matriz identidad con la función np.eye:
>>> np.eye(3)
array([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]])
Hay que tener en cuenta que el operador * no corresponde a la multiplicación matricial, sino a
la multiplicación elemento a elemento. Para la multiplicación matricial se utiliza el operador
@:
>>> A=np.array([[1,2,3],[4,5,6]])
>>> B=np.array([[1,2],[1,2],[1,2]])
>>> A@B multiplicación matricial
array([[ 6, 12],
[15, 30]])
Podemos obtener el número de filas y columnas de una matriz mediante la propiedad shape
del array. En general, shape devuelve una tupla de enteros que indican el número de elementos
correspondientes a cada dimensión del array:
>>> A=np.array([[1,2,3],[4,5,6]])
>>> b=np.array([1,2,3,4])
3
>>> A.shape (nº filas, nº columnas)
(2, 3)
>>> b.shape
(4,)
La propiedad size de un array devuelve el número de elementos del mismo (producto de los
elementos de shape). Por ejemplo, para los arrays A, b, anteriores:
>>> A.size
nº elementos
6
>>> b.size
4
Podemos acceder a elementos individuales o a secciones/bloques de vectores y matrices uti-
lizando índices, como haríamos con listas Python:
>>> b=np.array([1,2,3,4])
>>> b[0:2] pos 0 a pos 1
array([1, 2])
>>> b[-1] última posición
4
>>> A=np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> A[0,2] elemento de la fila 0, columna 2
3
>>> A[0:2,:] filas --> de la 0 a la 1
array([[1, 2, 3], columnas --> todas
[4, 5, 6]])
Finalmente, disponemos de distintas funciones para calcular sumas, máximos, mínimos, etc.
Por ejemplo, con la variable A anterior:
>>> A.sum()
suma de todos los elementos de A
45
>>> A[:,0].sum() suma de 'algunos' elementos de A
12
>>> b=np.array([1,2,3])
>>> np.sum(A[0,:]*b) suma del resultado de esa operación
14
>>> A.min()
1
>>> A.max()
9
4
from scipy import linalg
Podemos resolver un sistema lineal fácilmente usando la función linalg.solve. Por ejemplo,
dado el sistema de ecuaciones:
2x1 + 8x2 + 6x3 = 36
x1 − 3x2 + 5x3 = 10
−6x1 + 2x2 + 7x3 = 19
También podemos calcular la inversa de una matriz, con la función linalg.inv, o su deter-
minante, mediante la función linalg.det. Por ejemplo, para la matriz del sistema anterior:
>>> linalg.inv(A)
array([[ 0.06828194, 0.0969163 , -0.1277533 ],
[ 0.0814978 , -0.11013216, 0.00881057],
[ 0.03524229, 0.11453744, 0.030837 ]])
>>> linalg.det(A)
-454.0
Ejercicio 1.
Resuelve el sistema A1 x = b1, donde
4 3 1 1.5
A1 = −2 7 3, b1 = −1.5 .
5 −6 −9 −3.5
Ejercicio 2.
Calcula el determinante y la inversa de la matriz A1 usando las funciones correspon-
dientes de linalg.
5
4. Resolución de sistemas triangulares
Una de las tareas que debe hacer la función linalg.solve es resolver sistemas triangu-
lares. En este apartado se pide que hagas tus propias funciones para ello.
Empezaremos por los sistemas triangulares superiores. Como se ha visto en las clases de
teoría, este tipo de sistemas se puede resolver mediante el método de sustitución inversa o
regresiva (ver Algoritmo 1), que aplica la fórmula:
n
X
bi − aij xj
j=i+1
xi = , i = n, n − 1, · · · , 1
aii
Algoritmo 1: sustitucion_inversa
Entrada: A: matriz del sistema lineal, triangular superior
b: vector de términos independientes
Resultado: x: solución del sistema
1 para i ∈ invertido(rango(n)) hacer
2 s=0
3 para j ∈ rango(i + 1, n) hacer
4 s = s + aij xj
5 fin para
6 si aii = 0 entonces
7 error: el sistema no se puede resolver
8 fin si
bi − s
9 xi =
aii
10 fin para
Ejercicio 3.
Implementa una función, llamada sustitucion_inversa, para resolver un sistema
triangular superior. Si alguno de los elementos de la diagonal de la matriz es igual a cero,
se debe generar una excepción.
A continuación, utiliza la función para resolver el sistema A2 x = b2, siendo:
9 3 −2 −64
A2 = 0 −6 4 , b2 = 38 .
0 0 7 56
6
En el caso de sistemas triangulares inferiores, se utiliza el método de sustitución directa
o progresiva, que como sabemos aplica la fórmula:
i−1
X
bi − aij xj
j=1
xi = , i = 1, 2, · · · , n
aii
Ejercicio 4.
Implementa una función, llamada sustitucion_directa, para resolver sistemas trian-
gulares inferiores, con los siguientes datos de entrada y resultados:
Entrada: A: matriz del sistema lineal, triangular inferior
b: vector de términos independientes
Resultado: x: solución del sistema
9 4 −8 26
A = P LU.
Ejercicio 5.
Utiliza la función linalg.lu para calcular la descomposición LU con pivotación de
la matriz A1 (del ejercicio 1). Comprueba que se cumple la igualdad correspondiente a
la descomposición.
7
El siguiente ejercicio consiste en hacer nuestra propia implementación de la función lu,
de acuerdo con el algoritmo visto en las clases de teoría (Algoritmo 2).
Algoritmo 2: lu
Entrada: A: matriz a descomponer, de n filas y n columnas
Resultado: P, L, U , tales que P A = LU
1 hacer una copia de A para no modificar la matriz de entrada
2 P =I
3 para k ∈ rango(n − 1) hacer
4 s = busca_posmax(A, k)
5 si s ̸= k entonces
6 cambiofila(A, P, k, s)
7 fin si
8 si akk ̸= 0 entonces
9 para i ∈ rango(k + 1, n) hacer
aik
10 α=
akk
11 aik = α
12 para j ∈ rango(k + 1, n) hacer
13 aij = aij − αakj
14 fin para
15 fin para
16 fin si
17 fin para
18 L =parte triangular inferior estricta de A, con unos en la diagonal
19 U =parte triangular superior de A
Comentaremos a continuación cómo hacer algunas de las operaciones del algoritmo ante-
rior:
La función empezará haciendo una copia de la matriz A, sobre la cual trabajará, para
no modificar la matriz de entrada. Podemos hacerlo de la siguiente manera:
A=np.array(A,dtype='float')
Podemos construir una matriz identidad para la matriz P con la función np.eye. Por
ejemplo:
8
>>> np.eye(4)
array([[1., 0., 0., 0.],
[0., 1., 0., 0.],
[0., 0., 1., 0.],
[0., 0., 0., 1.]])
Podemos obtener la parte triangular inferior de una matriz mediante la función np.tril,
y la triangular superior mediante np.triu:
>>> M=np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> np.tril(M)
array([[1, 0, 0],
[4, 5, 0],
[7, 8, 9]])
>>> np.triu(M)
array([[1, 2, 3],
[0, 5, 6],
[0, 0, 9]])
donde el argumento −1 indica que se quiere tomar desde la primera subdiagonal infe-
rior. Si queremos que la diagonal esté formada por unos, podemos sumarle una matriz
identidad:
>>> np.tril(M,-1)+np.eye(3) triangular inferior con diagonal de 1s
array([[1., 0., 0.],
[4., 1., 0.],
[7., 8., 1.]])
Ejercicio 6.
Implementa una función, llamada lu, que calcule la descomposición LU con pivotación
parcial de una matriz, de acuerdo con el Algoritmo 2.
A continuación, utiliza dicha función para calcular la descomposición LU con pivota-
ción de la matriz A1 (ejercicio 1). Comprueba que se cumple la igualdad correspondiente
a la descomposición. Observa que la matriz P obtenida con nuestra función lu es la
9
transpuesta de la que se obtiene con la función linalg.lu, mientras que la L y la U
coinciden.
Ejercicio 7.
Obtén ahora la descomposición de estas dos matrices:
1 1 1 1 0.7 5
A4 = −2 −2 −2 , A5 = −2 −1.4 −8 .
1 2 3 10 7 7
Ejercicio 8.
Escribe una función, con el nombre resuelve, con los siguientes datos de entrada y
resultados, que resuelva un sistema de ecuaciones lineales mediante la descomposición
LU con pivotación de la matriz del sistema:
Entrada: A: matriz del sistema lineal
b: vector de términos independientes
Resultado: x: solución del sistema
Ejercicio 9.
Trata ahora de resolver los sistemas siguientes mediante la función resuelve:
3
a) A4 x = b4, siendo b4 = 2 .
6
¿Qué crees que puede estar ocurriendo?
−5
b) A5 x = b5, siendo b5 = 4 .
−9
¿Es correcta la solución proporcionada? (calcula el resultado de la operación A5 x−b5).
¿A qué crees que es debido? ¿Evitamos el problema si resolvemos el sistema con la
10
función linalg.solve?
A = U T U.
A = GGT .
Ejercicio 10.
Utiliza la función linalg.cholesky para obtener la matriz G de la descomposición
de la siguiente matriz. Comprueba que se cumple la igualdad anterior.
9 15 27
A6 = 15 26 49
27 49 161
Ejercicio 11.
Escribe una función, con el nombre resuelve_simpos y los siguientes datos de entrada
y resultados, que resuelva un sistema de ecuaciones cuya matriz es simétrica y definida
positiva, mediante la descomposición de Cholesky.
Entrada: A: matriz del sistema lineal, simétrica y definida positiva
b: vector de términos independientes
Resultado: x: solución del sistema
17
11
12