Ejercicio: 1Eva_IT2011_T3_MN Precios unitarios en factura, k
Las ecuaciones basadas en las sumas de cantidad.preciounitario representan el valor pagado en cada factura.
Siendo Xi el precio unitario de cada material:
2x_1 + 5x_2 + 4x_3 = 35 3x_1 + 9x_2 + 8x_3 = k 5x_1 + 3x_2 + x_3 = 17se escriben en la forma matricial Ax=B
\begin{bmatrix} 2 && 5 && 4 \\ 3 && 9 && 8 \\ 5 && 3 && 1 \end{bmatrix}.\begin{bmatrix} x_1 \\ x_2 \\ x_3 \end{bmatrix}=\begin{bmatrix} 35 \\ k \\ 17 \end{bmatrix}luego se escribe la matriz aumentada:
\begin{bmatrix} 2 && 5 && 4 && 35\\ 3 && 9 && 8 && k\\ 5 && 3 && 1 && 17\end{bmatrix}se pivotea por filas buscando tener una matriz diagonal dominante,
\begin{bmatrix} 5 && 3 && 1 && 17 \\ 3 && 9 && 8 && k\\ 2 && 5 && 4 && 35\\\end{bmatrix}Luego se usa el procedimiento de eliminación hacia adelante,
\begin{bmatrix} 5 && 3 && 1 && 17 \\ 3-5\frac{3}{5} && 9-3\frac{3}{5} && 8-1\frac{3}{5} && k-17\frac{3}{5} \\ 2-5\frac{2}{5} && 5-3\frac{2}{5} && 4-1\frac{2}{5} && 35-17\frac{2}{5} \end{bmatrix} \begin{bmatrix} 5 && 3 && 1 && 17 \\ 0 && \frac{36}{5} && \frac{37}{5} && k-\frac{51}{5} \\ 0 && \frac{19}{5} && \frac{18}{5} && \frac{141}{5} \end{bmatrix} \begin{bmatrix} 5 && 3 && 1 && 17 \\ 0 && 36 && 37 && 5k-51 \\ 0 && 19 && 18 && 141 \end{bmatrix} \begin{bmatrix} 5 && 3 && 1 && 17 \\ 0 && 36 && 37 && 5k-51 \\ 0 && 19-36\frac{19}{36} && 18-37\frac{19}{36} && 141-(5k-51)\frac{19}{36} \end{bmatrix} \begin{bmatrix} 5 && 3 && 1 && 17 \\ 0 && 36 && 37 && 5k-51 \\ 0 && 0 && \frac{-55}{36} && \frac{6045-5k}{36} \end{bmatrix}multiplicando la última fila por 36,
\begin{bmatrix} 5 && 3 && 1 && 17 \\ 0 && 36 && 37 && 5k-51 \\ 0 && 0 && -55 && 6045-5k \end{bmatrix}con lo que se pueden obtener cada precio unitario en función de k.
Como variante, se continua siguiendo el procedimieno de Gauss, dejando como tarea el uso de Gauss-Jordan
para luego simplificar las expresiones (tarea).
En el literal c se indica que el valor de k es 65, con lo que se requiere sustituir en la solución el valor de K para encontrar los precios unitarios.
\begin{bmatrix} 5 && 3 && 1 && 17 \\ 3 && 9 && 8 && 65\\ 2 && 5 && 4 && 35\\\end{bmatrix}Se encuentra que:
el vector solución X es:
[[-0.18181818] [ 5.18181818] [ 2.36363636]]
Lo que muestra que debe existir un error en el planteamiento del enunciado, considerando que los precios NO deberían ser negativos como sucede con el primer precio unitario de la respuesta.
que es lo que suponemos ser trata de corregir en el literal d, al indicar que se cambie en la matriz el valor de 5 por 5.1. Los resultados en éste caso son más coherentes con el enunciado. Todas las soluciones son positivas.
A = np.array([[ 5.1, 3 , 1], [ 3. , 9 , 8], [ 2. , 5.1, 4]]) B1 = np.array([ 17, 65, 35]) el vector solución X es: [[0.33596838] [3.88669302] [3.62648221]]
El error relativo de los precios encontrados entre las ecuaciones planteadas es:
diferencia = [0.335968-0.181818, 3.886693-5.181818, 3.626482-2.363636] = [0.154150, -1.295125, 1.262845] error(dolares) = max|diferencia| = 1.295125 Por las magnitudes de los precios, el error se aprecia usando el error relativo referenciado al mayor valor de la nueva solución error relativo = 1.295125/3.886693 = 0.333220 es decir de aproximadamente 33%
Para revisar otra causa del error se analiza el número de condición de la matriz:
>>> A array([[5.1, 3. , 1. ], [3. , 9. , 8. ], [2. , 5.1, 4. ]]) >>> np.linalg.cond(A) 60.28297696795716
El número de condición resulta lejano a 1, por lo que para éste problema:
pequeños cambios en la matriz de entrada producen grandes cambios en los resultados.
por ejemplo: un 0.1/5= 0.02 que es un 2% de variación en la entrada produce un cambio del 33% en el resultado.
Algoritmo en Python
Resultados del algoritmo
Matriz aumentada [[ 2. 5. 4. 35.] [ 3. 9. 8. 65.] [ 5. 3. 1. 17.]] Pivoteo parcial: 1 intercambiar filas: 0 y 2 [[ 5. 3. 1. 17.] [ 3. 9. 8. 65.] [ 2. 5. 4. 35.]] Elimina hacia adelante: fila 0 pivote: 5.0 factor: 0.6 para fila: 1 factor: 0.4 para fila: 2 fila 1 pivote: 7.2 factor: 0.5277777777777778 para fila: 2 fila 2 pivote: -0.3055555555555558 [[ 5.00000000e+00 3.00000000e+00 1.00000000e+00 1.70000000e+01] [ 0.00000000e+00 7.20000000e+00 7.40000000e+00 5.48000000e+01] [ 0.00000000e+00 -4.44089210e-16 -3.05555556e-01 -7.22222222e-01]] Elimina hacia Atras: fila 2 pivote: -0.3055555555555558 factor: -24.2181818181818 para fila: 1 factor: -3.2727272727272703 para fila: 0 fila 1 pivote: 7.1999999999999895 factor: 0.4166666666666671 para fila: 0 fila 0 pivote: 5.0 [[ 1.00000000e+00 0.00000000e+00 0.00000000e+00 -1.81818182e-01] [ 0.00000000e+00 1.00000000e+00 0.00000000e+00 5.18181818e+00] [-0.00000000e+00 1.45338287e-15 1.00000000e+00 2.36363636e+00]] solución X: [-0.18181818 5.18181818 2.36363636] >>>
Instrucciones en Python
# 1Eva_IT2011_T3_MN Precios unitarios en factura, k # Método de Gauss-Jordan # Solución a Sistemas de Ecuaciones # de la forma A.X=B import numpy as np def pivoteafila(A,B,vertabla=False): ''' Pivotea parcial por filas 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) def gauss_eliminaAdelante(AB, vertabla=False,lu=False,casicero = 1e-15): ''' Gauss elimina hacia adelante, a partir de, matriz aumentada y pivoteada. Para respuesta en forma A=L.U usar lu=True entrega[AB,L,U] ''' tamano = np.shape(AB) n = tamano[0] m = tamano[1] L = np.identity(n,dtype=float) # Inicializa L if vertabla==True: print('Elimina hacia adelante:') for i in range(0,n,1): pivote = AB[i,i] adelante = i+1 if vertabla==True: print(' fila',i,'pivote: ', pivote) for k in range(adelante,n,1): if (np.abs(pivote)>=casicero): factor = AB[k,i]/pivote AB[k,:] = AB[k,:] - factor*AB[i,:] L[k,i] = factor # llena L if vertabla==True: print(' factor: ',factor,' para fila: ',k) else: print(' pivote:', pivote,'en fila:',i, 'genera division para cero') respuesta = AB if vertabla==True: print(AB) if lu==True: U = AB[:,:n-1] respuesta = [AB,L,U] return(respuesta) def gauss_eliminaAtras(AB, vertabla=False, precision=5, casicero = 1e-15): ''' Gauss-Jordan elimina hacia atras Requiere la matriz triangular inferior Tarea: Verificar que sea triangular inferior ''' tamano = np.shape(AB) n = tamano[0] m = tamano[1] ultfila = n-1 ultcolumna = m-1 if vertabla==True: print('Elimina hacia Atras:') for i in range(ultfila,0-1,-1): pivote = AB[i,i] atras = i-1 # arriba de la fila i if vertabla==True: print(' fila',i,'pivote: ', pivote) for k in range(atras,0-1,-1): if (np.abs(AB[k,i])>=casicero): factor = AB[k,i]/pivote AB[k,:] = AB[k,:] - factor*AB[i,:] if vertabla==True: print(' factor: ',factor,' para fila: ',k) else: print(' pivote:', pivote,'en fila:',i, 'genera division para cero') AB[i,:] = AB[i,:]/AB[i,i] # diagonal a unos X = np.copy(AB[:,ultcolumna]) if vertabla==True: print(AB) return(X) # PROGRAMA ------------------------ # INGRESO A = np.array([[2,5,4], [3,9,8], [5,3,1]]) B = np.array([[35], [65], [17]]) # PROCEDIMIENTO AB = pivoteafila(A,B,vertabla=True) AB = gauss_eliminaAdelante(AB,vertabla=True) X = gauss_eliminaAtras(AB,vertabla=True) # SALIDA print('solución X: ') print(X)