Referencia: Chapra 9.4.2 p268, pdf 292. Burden 9Ed 6.2 p372. Rodriguez 4.0 p105
Los métodos de solución a sistema de ecuaciones, tienen en los primeros pasos en común usar la matriz aumentada y pivoteada por filas. Para compartir estos pasos y simplificar la presentación de los métodos, se presentan como una de las primeros algoritmos a implementar.
Para mostrar todo el desarrollo del proceso se usa como referencia un ejercicio.
Ejercicio
Referencia: Rodriguez cap4.0 Ejemplo 1 pdf.105
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 relaciónes 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}Sistema de ecuaciones como Matriz y Vector
El sistema de ecuaciones se escribe en la forma algebraica como matrices y vectoresl 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 con arreglos de la libreria 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 las soluciones, para mantener sincronía entre las operaciones entre filas de la matriz A y el vector B se usa la matriz aumentada.
Matriz Aumentada
Se realiza al concatenar la matriz A con el vector B en forma de columnas (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]])
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]]
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 despues, 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)
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 algoritmicas a problemas resueltos.
Se usa la matriz M para generalizar y diferenciar de A que es usada en los ejercicios en realizados en adelante.
def pivoteafila(M): ''' Pivotea parcial por filas Si hay ceros en diagonal es matriz singular, Tarea: Revisar si diagonal tiene ceros ''' # Pivoteo por filas AB tamano = np.shape(M) 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 = np.abs(M[i:,i]) dondemax = np.argmax(columna) # dondemax no es en diagonal if (dondemax != 0): # intercambia filas temporal = np.copy(M[i,:]) M[i,:] = M[dondemax+i,:] M[dondemax+i,:] = temporal return(M)