[ Ejercicio ] [ Matriz Aumentada ] [ Pivotea filas ] [ Algoritmo ] [ función ]
Referencia: Chapra 9.4.2 p268. Burden 6.2 p279. Rodríguez 4.0 p105
Los métodos de solución a sistemas de ecuaciones en los primeros pasos usan la matriz aumentada y pivoteada por filas. Como es un procedimiento usado en todos los métodos de la unidad, para simplificar se presenta como uno de los primeros algoritmos.
Para mostrar el desarrollo del proceso se usa como referencia un ejercicio.
1. Ejercicio
Referencia: Rodríguez 4.0 p105, 1Eva_IT2010_T3_MN Precio artículos
Ejemplo 1. Un comerciante compra tres productos A, B, C, pero en las facturas únicamente consta la cantidad comprada en Kg y el valor total de la compra.
Se necesita determinar el precio unitario de cada producto. Dispone de solo tres facturas con los siguientes datos:
Cantidad | Valor ($) | |||
Factura | X1 | X2 | X3 | Pagado |
---|---|---|---|---|
1 | 4 | 2 | 5 | 60.70 |
2 | 2 | 5 | 8 | 92.90 |
3 | 5 | 4 | 3 | 56.30 |
Los precios unitarios se pueden representar por las variables x1, x2, x3 para escribir el sistema de ecuaciones que muestran las relaciones de cantidad, precio y valor pagado:
\begin{cases} 4x_1+2x_2+5x_3 = 60.70 \\ 2x_1+5x_2+8x_3 = 92.90 \\ 5x_1+4x_2+3x_3 = 56.30 \end{cases}[ Ejercicio ] [ Matriz Aumentada ] [ Pivotea filas ] [ Algoritmo ] [ función ]
..
2. Matriz, Vector y la Matriz Aumentada
El sistema de ecuaciones se escribe en la forma algebraica como matrices y vectores de la forma Ax=B
\begin{pmatrix} 4 & 2 & 5 \\ 2 & 5 & 8 \\5 & 4 & 3 \end{pmatrix} \begin{pmatrix} x_1 \\ x_2 \\ x_3 \end{pmatrix} = \begin{pmatrix} 60.70 \\ 92.90 \\ 56.30 \end{pmatrix}Para el algoritmo la matriz A y el vector B se escriben como arreglos.
A = np.array([[4,2,5], [2,5,8], [5,4,3]]) B = np.array([[60.70], [92.90], [56.30]])
Observe que:
- Las matrices y vectores se ingresan como arreglos de la librería Numpy
- el vector B se escribe en forma de columna
- No se usan listas, de ser el caso se convierten hacia arreglos con
np.array()
Si el vector B está como fila, se aumenta una dimensión [B]
y se aplica la transpuesta
Bfila = np.array([60.70,92.90,56.30]) Bcolumna = np.transpose([Bfila]) print(Bcolumna)
>>> Bcolumna array([[60.7], [92.9], [56.3]])
En el desarrollo de la solución, se usa la matriz aumentada, para mantener sincronía entre las operaciones entre filas de la matriz A y el vector B.
La matriz aumentada AB se forma al concatenar por columnas la matriz A con el vector B, usando el parámetro axis=1
.
AB = np.concatenate((A,B),axis=1)
el resultado AB se muestra como:
>>> AB array([[ 4. , 2. , 5. , 60.7], [ 2. , 5. , 8. , 92.9], [ 5. , 4. , 3. , 56.3]])
[ Ejercicio ] [ Matriz Aumentada ] [ Pivotea filas ] [ Algoritmo ] [ función ]
..
3. Pivoteo parcial por filas
Para el pivoteo por fila de la matriz aumentada AB, tiene como primer paso revisar la primera columna desde la diagonal en adelante.
columna = [|4|, |2|, |5|] dondemax = 2
El procedimiento de «pivoteo» se realiza si la posición dónde se encuentra el valor de mayor magnitud no corresponde a la diagonal de la matriz (posición 0 de la columna).
En el ejercicio se encuentra que la magnitud de mayor valor está en la última fila, por lo que en AB se realiza el intercambio entre la fila 3 y la fila 1
AB = [[ 5. , 4. , 3. , 56.3], [ 2. , 5. , 8. , 92.9], [ 4. , 2. , 5. , 60.7]]
Se repite al paso anterior, pero para la segunda columna formada desde la diagonal.
columna = [|5|, |2|] dondemax = 0
como la posición dondemax
es la primera, índice 0, se determina que ya está en la diagonal de AB y no es necesario realizar el intercambio de filas.
Se repite el proceso para la tercera columna desde la diagonal, que resulta tener solo una casilla (columna =[5]) y no ser requiere continuar.
El resultado del pivoteo por fila se muestra como:
matriz pivoteada por fila: AB = [[ 5. , 4. , 3. , 56.3], [ 2. , 5. , 8. , 92.9], [ 4. , 2. , 5. , 60.7]]
[ Ejercicio ] [ Matriz Aumentada ] [ Pivotea filas ] [ Algoritmo ] [ función ]
..
4. Algoritmo en Python
Para realizar el algoritmo, es de recordar que para realizar operaciones en una matriz sin alterar la original, se usa una copia de la matriz (np.copy
). Se puede comparar y observar los cambios entre la matriz original y la copia a la que se aplicaron cambios
Si no es necesaria la comparación entre el antes y después, no se realiza la copia y se ahorra el espacio de memoria, detalle importante para matrices de «gran tamaño» y una computadora con «limitada» memoria.
# Pivoteo parcial por filas # Solución a Sistemas de Ecuaciones import numpy as np # INGRESO A = np.array([[4,2,5], [2,5,8], [5,4,3]]) B = np.array([[60.70], [92.90], [56.30]]) # PROCEDIMIENTO # Matriz aumentada AB = np.concatenate((A,B),axis=1) AB0 = np.copy(AB) # Pivoteo parcial por filas tamano = np.shape(AB) n = tamano[0] m = tamano[1] # Para cada fila en AB for i in range(0,n-1,1): # columna desde diagonal i en adelante columna = abs(AB[i:,i]) dondemax = np.argmax(columna) # dondemax no está en diagonal if (dondemax !=0): # intercambia filas temporal = np.copy(AB[i,:]) AB[i,:] = AB[dondemax+i,:] AB[dondemax+i,:] = temporal # SALIDA print('Matriz aumentada:') print(AB0) print('Pivoteo parcial por filas') print(AB)
[ Ejercicio ] [ Matriz Aumentada ] [ Pivotea filas ] [ Algoritmo ] [ función ]
..
5. Función pivoteafila(M)
Los bloques de cada procedimiento que se repiten en otros métodos se convierten a funciones def-return
, empaquetando las soluciones algorítmicas a problemas resueltos.
Se usa la matriz M para generalizar y diferenciar de ‘A’ que es usada en los ejercicios en realizados en adelante.
# Pivoteo parcial por filas # Solución a Sistemas de Ecuaciones import numpy as np def pivoteafila(A,B,vertabla=False): ''' Pivotea parcial por filas, entrega matriz aumentada AB Si hay ceros en diagonal es matriz singular, Tarea: Revisar si diagonal tiene ceros ''' A = np.array(A,dtype=float) B = np.array(B,dtype=float) # Matriz aumentada nB = len(np.shape(B)) if nB == 1: B = np.transpose([B]) AB = np.concatenate((A,B),axis=1) if vertabla==True: print('Matriz aumentada') print(AB) print('Pivoteo parcial:') # Pivoteo por filas AB tamano = np.shape(AB) n = tamano[0] m = tamano[1] # Para cada fila en AB pivoteado = 0 for i in range(0,n-1,1): # columna desde diagonal i en adelante columna = np.abs(AB[i:,i]) dondemax = np.argmax(columna) # dondemax no es en diagonal if (dondemax != 0): # intercambia filas temporal = np.copy(AB[i,:]) AB[i,:] = AB[dondemax+i,:] AB[dondemax+i,:] = temporal pivoteado = pivoteado + 1 if vertabla==True: print(' ',pivoteado, 'intercambiar filas: ',i,'y', dondemax+i) if vertabla==True: if pivoteado==0: print(' Pivoteo por filas NO requerido') else: print(AB) return(AB) # INGRESO A = [[4,2,5], [2,5,8], [5,4,3]] B = [60.70, 92.90, 56.30] # PROCEDIMIENTO AB = pivoteafila(A,B,vertabla=True) # SALIDA print('Resultado de Pivoteo parcial por filas') print(AB)
El resultado del ejercicio es:
Matriz aumentada [[ 4. 2. 5. 60.7] [ 2. 5. 8. 92.9] [ 5. 4. 3. 56.3]] Pivoteo parcial: 1 intercambiar filas: 0 y 2 Pivoteo parcial por filas [[ 5. 4. 3. 56.3] [ 2. 5. 8. 92.9] [ 4. 2. 5. 60.7]] >>>
[ Ejercicio ] [ Matriz Aumentada ] [ Pivotea filas ] [ Algoritmo ] [ función ]