| | | |

Minicurso de Python para Matemáticas

Ajude a manter o site livre, gratuito e sem propagandas. Colabore!

4 Elementos de la computación matricial

En esta sección, vamos a explorar la NumPy (Numerical Python), biblioteca para el tratamiento numérico de datos. Es ampliamente utilizada en los más diversos campos de la ciencia y la ingeniería. Aquí, nos restringiremos a introducir algunas de sus herramientas para la computación matricial.

Usualmente, la biblioteca se importa como sigue

1import numpy as np

4.1 NumPy array

Un numpy.array es una tabla de valores (vector, matriz o multidimensional) y contiene información sobre los datos brutos, indexación y cómo interpretarlos. Los elementos son todos del mismo tipo (diferente de una lista Python), referenciados por la propiedad dtype. La indexación de los elementos puede hacerse por un tuple de enteros no negativos, por booleanos, por otro numpy.array o por números enteros. El ndim de un numpy.array es su número de dimensiones (llamadas axes111111axes, del inglés, plural de axis, eje.). El numpy.ndarray.shape es un tuple de enteros que proporciona su tamaño (número de elementos) en cada dimensión. Su inicialización puede hacerse usando listas simples o anidadas. Por ejemplo,

1a = np.array([1, 3, -1, 2])
2print(a)
[ 1 3 -1 2]
1a.dtype
dtype('int64')
1a.shape
(4,)
1a[2]
-1
1a[1:3]
array([ 3, -1])

tenemos un numpy.array de números enteros con cuatro elementos dispuestos en un único axis (eje). Podemos interpretarlo como una representación de un vector fila o columna, es decir

a=(1,3,1,2) (28)

vector columna o aT vector fila.

Outro exemplo,

1a = np.array([[1.0,2,3],
2 [-3,-2,-1]])
3a.dtype
dtype('float64')
1a.shape
(2, 3)
1a[1,1]
-2.0

tenemos un numpy.array de números decimales (float) dispuestos en un arreglo con dos axes (ejes). El primer axis tiene tamaño 2 y el segundo tiene tamaño 3. Es decir, podemos interpretarlo como una matriz de dos filas y tres columnas. Podemos hacer su representación algebraica como

a=[123321] (29)
Ejercicio 4.1.1.

Use numpy.array para asignar:

  1. a)

    el vector

    v=(5,π,sen(π/3)) (30)
  2. b)

    la matriz

    A=[11322e13] (31)
Respuesta 0.
1import numpy as np
2# a)
3v = np.array([-5., np.pi, np.sin(np.pi/3)])
4print('v = ', v)
5# b)
6A = np.array([[-1., 1./3],
7 [2., np.sqrt(2)],
8 [np.exp(-1.), -3.]])
9print('A = \n', A)

4.1.1 Inicialización de un array

El NumPy cuenta con útiles funciones de inicialización de numpy.array. Vea algunas de las más frecuentes:

  • numpy.zeros: inicializa un numpy.array con todos sus elementos iguales a cero.

    1np.zeros(2)
    array([0., 0.])
  • numpy.ones: inicializa un numpy.array con todos sus elementos iguales a 1.

    1np.ones((3,2), dtype='int')
    array([[1, 1],
    [1, 1],
    [1, 1]])
  • numpy.empty: inicializa un numpy.array sin asignar valores a sus elementos121212¡Atención! En el momento de la asignación, los valores de los elementos serán dinámicos según “basura” de la memoria..

    1np.empty(3)
    array([4.9e-324, 1.5e-323, 2.5e-323])
  • numpy.arange: inicializa un numpy.array con una secuencia de elementos131313Similar a la función Python range..

    1np.arange(1,6,2)
    array([1, 3, 5])
  • numpy.linspace(a, b[, num=n]): inicializa un numpy.array como una secuencia de elementos que comienza en a, termina en b (incluidos) y contiene n elementos igualmente espaciados.

    1np.linspace(0, 1, num=5)
    array([0. , 0.25, 0.5 , 0.75, 1. ])
Ejercicio 4.1.2.

Asigne la matriz escalar

A=[200020002] (32)

como un numpy.array.

Respuesta 0.
1import numpy as np
2A = -2*np.ones((3,3))
3print('A = \n', A)
Ejercicio 4.1.3.

Construya un numpy.array para asignar una partición uniforme con 11 puntos del intervalo [0,1]. Es decir, un arreglo 𝒙=(x1,x2,,xn), de elementos xi=(i1)h, con paso h=1/(n1).

Respuesta 0.
1import numpy as np
2x = np.linspace(0., 1., 11)
3print('x = ', x)

4.1.2 Manipulación de arrays

Otras dos funciones importantes en el tratamiento de arrays son:

  • numpy.reshape: permite la alteración de la forma de un numpy.array.

    1a = np.array([-2,-1])
    2print(a)
    [-2 -1]
    1b = a.reshape(2,1)
    2print(b)
    [[-2]
    [-1]]

    El numpy.reshape también permite el uso de un carácter comodín -1 que será determinado dinámicamente para obtener una estructura adecuada. Por ejemplo,

    1a = np.array([[1,2],[3,4]])
    2print(a)
    [[1 2]
    [3 4]]
    1b = a.reshape((-1,1))
    2print(b)
    [[1]
    [2]
    [3]
    [4]]
  • numpy.transpose: computa la transpuesta de una matriz.

    1a = np.array([[1,2],[3,4]])
    2print(a)
    [[1 2]
    [3 4]]
    1b = a.transpose()
    2print(b)
    [[1 3]
    [2 4]]
  • numpy.concatenate: concatena arrays.

    1a = np.array([1,2])
    2b = np.array([2,3])
    3c = np.concatenate((a,b))
    4print(c)
    [1 2 2 3]
    1a = a.reshape((1,-1))
    2b = b.reshape((1,-1))
    3d = np.concatenate((a,b), axis=0)
    4print(d)
    [[1 2]
    [2 3]]
Ejercicio 4.1.4.

Asigne el siguiente vector como un numpy.array

𝒂=(2,3,1,1,4,5). (33)

Luego, use el método numpy.reshape para, a partir de b, asignar la matriz

A=[1145] (34)

como un numpy.array.

Respuesta 0.
1import numpy as np
2a = np.array([2, 3, -1, 1, 4, 5])
3A = a.reshape((3,-1))
Ejercicio 4.1.5.

Teniendo en cuenta que

A=[32121232] (35)

es una matriz ortogonal141414A se dice matriz ortogonal, cuando A1=AT., calcule A1.

Respuesta 0.
1import numpy as np
2A = np.array([[np.sqrt(3)/2, -1./2],
3 [1./2, np.sqrt(3)/2]])
4Ainv = A.transpose()
Ejercicio 4.1.6.

Considere el siguiente sistema de ecuaciones

2x1x2 =3 (36)
x1+3x2 =2

Use numpy.array para asignar:

  1. 1.

    la matriz de coeficientes de este sistema.

  2. 2.

    el vector de los términos constantes de este sistema.

  3. 3.

    la matriz ampliada de este sistema.

Respuesta 0.
1import numpy as np
2# a)
3A = np.array([[2, -1],
4 [1, 3]])
5# b)
6b = np.array([3, -2])
7# c)
8E = np.concatenate((A, b.reshape(-1,1)), axis=1)

4.1.3 Operadores elemento-a-elemento

Los operadores aritméticos disponibles en Python actúan elemento-a-elemento en los numpy.arrays. Por ejemplo,

1a = np.array([1,2])
2b = np.array([2,3])
3a+b
array([3, 5])
1a-b
array([-1, -1])
1b*a
array([2, 6])
1a**b
array([1, 8])
12*b
array([4, 6])

El NumPy también cuenta con varias funciones matemáticas elementales que operan elemento-a-elemento en arrays. Por ejemplo,

1a = np.array([np.pi, np.sqrt(2)])
2a
array([3.14159265, 1.41421356])
1np.sin(a)
array([1.22464680e-16, 9.87765946e-01])
1np.exp(a)
array([23.14069263, 4.11325038])
Ejercicio 4.1.7.

Calcule los valores de la función coseno para los elementos del vector

𝜽=(0.,30,45,60,90). (37)
Respuesta 0.
1import numpy as np
2thta = np.array([0., np.pi/6, np.pi/4,
3 np.pi/3, np.pi/2])
4y = np.cos(thta)

4.2 Elementos del álgebra lineal

El numpy cuenta con un módulo de álgebra lineal, usualmente importado con

1import numpy.linalg as npla

4.2.1 Vectores

Un vector puede asignarse usando un numpy.array de un eje (dimensión). Por ejemplo,

x=(2,1), (38)
y=(3,1,π) (39)

podem ser alocados com

1x = np.array([2,-1])
2print(x)
[ 2 -1]

e

1y = np.array([3, 1, np.pi])
2print(y)
[3. 1. 3.14159265]
Ejercicio 4.2.1.

Asigne cada uno de los siguientes vectores como un numpy.array:

  1. a)

    x=(1,2,3,1,4)

  2. c)

    z=(π,2,e2)

Respuesta 0.
1import numpy as np
2# a)
3x = np.array([1.2, -3.1, 4])
4print('x = ', x)
5# b)
6z = np.array([np.pi, np.sqrt(2.), np.exp(-2)])
7print('z = ', z)

4.2.2 Producto escalar y norma

Dados dos vectores

x=(x0,x1,,xn1), (40)
y=(y0,y1,,yn1), (41)

define-se el producto escalar por

xy=x0y0+x1y1++xn1yn1. (42)

Con el NumPy, podemos calcularlo con la función numpy.dot. Por ejemplo,

1x = np.array([-1, 0, 2])
2y = np.array([0, 1, 1])
3d = np.dot(x,y)
4print(d)
2

La norma l2 de un vector se define por

x2=i=0n1xi2. (43)

El NumPy cuenta con el método numpy.linalg.norm para calcularla. Por ejemplo,

1nrm = npla.norm(y)
2print(nrm)
4.457533443631058
Ejercicio 4.2.2.

Haga un código para calcular el producto escalar xy siendo

x=(1,2,ln(2),4), (44)
y=(π2,3,e) (45)
Respuesta 0.
1import numpy as np
2x = np.array([1.2, np.log(2), 4])
3y = np.array([np.pi**2, np.sqrt(3), np.e])
4d = np.dot(x,y)

4.2.3 Matrices

Una matriz puede asignarse como un numpy.array de dos ejes (dimensiones). Por ejemplo, las matrices

A=[217310], (46)
B=[402186] (47)

podem ser alocadas como segue

1A = np.array([[2,-1,7],
2 [3,1,0]])
3print(A)
[[ 2 -1 7]
[ 3 1 0]]

e

1B = np.array([[4,0],
2 [2,1],
3 [-8,6]])
4print(B)
[[ 4 0]
[ 2 1]
[-8 6]]

Como ya hemos visto, el NumPy cuenta con operadores elemento-a-elemento que pueden utilizarse en el álgebra involucrando arrays, luego también aplicables a matrices (consulte la Subseção 4.1.3). A continuación, vamos a introducir otras operaciones propias de este tipo de objeto.

Ejercicio 4.2.3.

Asigne cada una de las siguientes matrices como un numpy.array:

  1. a)
    A=[122460] (48)
  2. b)

    B=AT

Respuesta 0.
1import numpy as np
2A = np.array([[-1, 2],
3 [2, -4],
4 [6, 0]])
5# b)
6B = A.transpose()
Ejercicio 4.2.4.

Sea

1A = np.array([[2,1],[1,1],[-3,-2]])

Determine el formato (shape) de los siguientes arrays:

  1. a)

    A[:,0]

  2. b)

    A[:,0:1]

  3. c)

    A[1:3,0]

  4. d)

    A[1:3,0:1]

  5. e)

    A[1:3,0:2]

Respuesta 0.
1import numpy as np
2# a)
3A = np.array([[2, 1],
4 [1, 1],
5 [-3, -2]])
6print('a)', A[:,0].shape)
7print('b)', A[:,0:1].shape)
8print('c)', A[1:3,0].shape)
9print('d)', A[1:3,0:1].shape)
10print('e)', A[1:3,0:2].shape)

4.2.4 Inicialización de matrices

Además de las inicializaciones de arrays ya estudiadas en la Subseção 4.1.1, tenemos algunas más que son particularmente útiles en el caso de matrices.

  • numpy.eye(n): retorna la matriz identidad n×n.

    1I = np.eye(3)
    2print(I)
    [[1. 0. 0.],
    [0. 1. 0.],
    [0. 0. 1.]]
  • numpy.diag: extrae la diagonal o construye un numpy.array diagonal.

    1D = np.diag([1,2,3])
    2print(D)
    [[1, 0, 0],
    [0, 2, 0],
    [0, 0, 3]]
Ejercicio 4.2.5.

Asigne la matriz de los coeficientes y el vector de los términos constantes del siguiente sistema de ecuaciones

x1=0 (49)
xi1+2xixi+1=h2fi
xn=0

donde fi=π2sin(πxi), xi=(i1)h, h=1/(n1), n=5.

Respuesta 0.
1import numpy as np
2n = 5
3h = 1./(n-1)
4x = np.linspace(0., 1., n)
5b = np.pi**2*np.sin(np.pi*x)
6A = np.diag(2*np.ones(n)) + \
7 np.diag(-np.ones(n-1), k=-1) + \
8 np.diag(-np.ones(n-1), k=1)
9A[0,0] = 1.
10A[0,1] = 0.
11A[n-1,n-2] = 0.
12A[n-1,n-1] = 1.
13print('A = \n', A)
14print('b = \n', b)

4.2.5 Multiplicación de matrices

La multiplicación de la matriz A=[aij]i,j=0n1,l1 por la matriz B=[bij]i,j=0l1,m1 es la matriz C=AB=[cij]i,j=0n1,m1 tal que

cij=k=0l1aikbk,j (50)

El numpy tiene la función numpy.matmul para calcular la multiplicación de matrices. Por ejemplo, la multiplicación de las matrices dadas en (46) y (47), calculamos

1C = np.matmul(A,B)
2print(C)
[[-50 41],
[ 14 1]]
Observación 4.2.1.(matmul, *, @)

Es importante notar que numpy.matmul(A,B) es la multiplicación de matrices, mientras que * consiste en la multiplicación elemento a elemento. Alternativamente a numpy.matmul(A,B) puede-se usar A @ B.

Ejercicio 4.2.6.

Asigne las matrices

C=[121321023] (51)
D=[231164] (52)
E=[121013] (53)

Entonces, si existen, calcule y proporcione las dimensiones de las siguientes matrices

  1. a)

    CD

  2. b)

    DTE

  3. c)

    DTC

  4. d)

    DE

Respuesta 0.
1import numpy as np
2C = np.array([[1, 2, -1],
3 [3, 2, 1],
4 [0, -2, -3]])
5D = np.array([[2, 3],
6 [1, -1],
7 [6, 4]])
8E = np.array([[1, 2, 1],
9 [0, -1, 3]])
10print('a) CD = \n', C@D)
11print("no existe D'E")
12print("c) D'C = \n", C.T@C)
13print("d) DE = \n", D@E)

4.2.6 Traza y determinante de una matriz

El numpy tiene la función numpy.ndarray.trace para calcular la traza de una matriz (suma de los elementos de su diagonal). Por ejemplo,

1A = np.array([[-1,2,0],[2,3,1],[1,2,-3]])
2print('tr(A) = ', A.trace())
tr(A) = -1

Ya, el determinante es proporcionado en el módulo numpy.linalg. Por ejemplo,

1A = np.array([[-1,2,0],[2,3,1],[1,2,-3]])
2print('det(A) = ', npla.det(A))
det(A) = 25.000000000000007
Ejercicio 4.2.7.

Calcule la solución del siguiente sistema de ecuaciones

x1x2+x3 =2 (54)
2x1+2x2+x3 =5
x1x2+2x3 =5

por el método de Cramer151515Gabriel Cramer, 1704 - 1752, matemático suíço. Fonte: Wikipédia: Gabriel Cramer..

Respuesta 0.
1import numpy as np
2import numpy.linalg as npla
3# matriz de coefs
4A = np.array([[1, -1, 1],
5 [2, 2, 1],
6 [-1, -1, 2]])
7# vector de términos constantes
8b = np.array([-2, 5, -5])
9# mat aux A1
10A1 = A.copy()
11A1[:,0] = b
12# sol x1
13x1 = npla.det(A1)/npla.det(A)
14print('x1 = ', x1)
15# mat aux A2
16A2 = A.copy()
17A2[:,1] = b
18# sol x2
19x2 = npla.det(A2)/npla.det(A)
20print('x2 = ', x2)
21# mat aux A3
22A3 = A.copy()
23A3[:,2] = b
24# sol x3
25x3 = npla.det(A3)/npla.det(A)
26print('x3 = ', x3)

4.2.7 Rango e inversa de una matriz

El rango (rank) de una matriz es el número de filas o columnas linealmente independientes. El numpy cuenta con la función numpy.linalg.matrix_rank para calcularla. Por ejemplo,

1npla.matrix_rank(np.eye(3))
3
1A = np.array([[1,2,3],[-1,1,-1],[0,3,2]])
2npla.matrix_rank(A)
2

El método numpy.linalg.inv puede usarse para calcular la inversa de una matriz full rank. Por ejemplo,

1A = np.array([[1, 2, 3],
2 [-1, 1, -1],
3 [1, 3, 2]])
4Ainv = np.linalg.inv(A)
5print('Ainv @ A = \n', Ainv @ A)
Ainv @ A =
[[ 1.00000000e+00 -2.22044605e-16 -8.88178420e-16]
[ 0.00000000e+00 1.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 -2.22044605e-16 1.00000000e+00]]
Ejercicio 4.2.8.

Calcule, si es posible, la matriz inversa de cada una de las siguientes matrices

B=[2121] (55)
C=[201311210] (56)

Verifique sus respuestas.

Respuesta 0.
1import numpy as np
2import numpy.linalg as npla
3
4def inv(A):
5 if (npla.matrix_rank(A) == A.shape[1]):
6 return npla.inv(A)
7 else:
8 print('Matriz no invertible.')
9 return None
10
11B = np.array([[2, -1],
12 [-2, 1]])
13print('inv(B) = \n', inv(B))
14
15A = np.array([[-2, 0, 1],
16 [3, 1, -1],
17 [2, 1, 0]])
18print('inv(A) = \n', inv(A))

4.2.8 Autovalores y autovectores de una Matriz

Un auto-par (λ,v) de una matriz A, λ un escalar llamado autovalor y v0 es un vector llamado autovector, es tal que

Aλ=λv. (57)

El numpy tiene la función numpy.linalg.eig para calcular los auto-pares de una matriz. Por ejemplo,

1lmbda, v = npla.eig(np.eye(3))
2print('autovalores = \n', lmbda)
3print('autovetores = \n', v)
autovalores =
[1. 1. 1.]
autovetores =
[[1. 0. 0.]
[0. 1. 0.]
[0. 0. 1.]]

Observamos que la función retorna un tuple de numpy.arrays, siendo que el primero contiene los autovalores (repetidos conforme sus multiplicidades) y el segundo ítem es la matriz de los autovectores (dispuestos en las columnas).

Ejercicio 4.2.9.

Calcule los auto-pares de la matriz

A=[132321211]. (58)

Entonces, verifique si, de hecho, Av=λv para cada auto-par (λ,v) calculado.

Respuesta 0.
1import numpy as np
2import numpy.linalg as npla
3A = np.array([[1, 3, 2],
4 [3, 2, -1],
5 [2, -1, 1]])
6lmbda, v = np.linalg.eig(A)
7# probando los auto-pares
8print(npla.norm(A @ v[:, 0] - lmbda[0] * v[:, 0]) < 1e-10)
9print(npla.norm(A @ v[:, 1] - lmbda[1] * v[:, 1]) < 1e-10)
10print(npla.norm(A @ v[:, 2] - lmbda[2] * v[:, 2]) < 1e-10)

Envie seu comentário

Aproveito para agradecer a todas/os que de forma assídua ou esporádica contribuem enviando correções, sugestões e críticas!

Opcional. Preencha seu nome para que eu possa lhe contatar.
Opcional. Preencha seu e-mail para que eu possa lhe contatar.
As informações preenchidas são enviadas por e-mail para o desenvolvedor do site e tratadas de forma privada. Consulte a política de uso de dados para mais informações.

Licença Creative Commons
Este texto é disponibilizado nos termos da Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional. Ícones e elementos gráficos podem estar sujeitos a condições adicionais.

Pedro H A Konzen
| | | |