Ejercicio: 1Eva2015TI_T4 Lingotes metales
Se plantea que cada lingote debe aportar una proporción xi al lingote nuevo a ser fundido.
Se dispone de los compuestos de cada lingote por filas:
[oro,plata,cobre,estaño]
compuesto = [[ 20, 50, 20, 10],
[ 30, 40, 10, 20],
[ 20, 40, 10, 30],
[ 50, 20, 20, 10]]
proporcion = [ 27, 39.5, 14, 19.5]
El contenido final de cada componente basado en los aportes xi de cada lingote para cada componente.
Ejemplo para los 27 gramos de oro
20x_1 + 30x_2+ 20x_3 + 50x_4 = 27Se debe observar que se está sumando la columna, por lo que para el algoritmo se está usando A transpuesta:
A = np.array(compuesto,dtype=float)
A = np.transpose(A)
B = proporcion
se realiza el mismo procedimiento para los otros tipos de metal.
50x_1 + 40x_2+ 40x_3 + 20x_4 = 39.5 20x_1 + 10x_2+ 10x_3 + 20x_4 = 14 10x_1 + 20x_2+ 30x_3 + 10x_4 = 19.5Las ecuaciones se escriben en la forma matricial Ax=B
\begin{bmatrix} 20 && 30&& 20 &&50 \\ 50 && 40 && 40 && 20 \\ 20 && 10 && 10 && 20 \\ 10 && 20 && 30 && 10 \end{bmatrix} = \begin{bmatrix} x_1 \\ x_2 \\x_3 \\ x_4 \end{bmatrix} = \begin{bmatrix} 27 \\ 39.5 \\ 14 \\ 19.5 \end{bmatrix}Para resolver se plantea la matriz aumentada
\begin{bmatrix} 20 && 30&& 20 &&50 && 27\\ 50 && 40 && 40 && 20 && 39.5\\ 20 && 10 && 10 && 20 && 14 \\ 10 && 20 && 30 && 10 && 19.5 \end{bmatrix}se pivotea por filas la matriz:
\begin{bmatrix} 50 && 40 && 40 && 20 && 39.5\\ 20 && 30&& 20 &&50 && 27\\ 10 && 20 && 30 && 10 && 19.5 \\ 20 && 10 && 10 && 20 && 14 \end{bmatrix}Para eliminar hacia adelante:
\begin{bmatrix} 50 && 40 && 40 && 20 && 39.5 \\ 20 - 50\frac{20}{50} && 30-40\frac{20}{50} && 20-40\frac{20}{50} && 50-20\frac{20}{50} && 27-39.5\frac{20}{50}\\ 10 - 50\frac{10}{50} && 20-40\frac{10}{50} && 30-40\frac{10}{50} && 10-20\frac{10}{50} && 19.5-39.5\frac{10}{50} \\ 20 - 50\frac{20}{50} && 10-40\frac{20}{50} && 10-40\frac{20}{50} && 20-20\frac{20}{50} && 14-39.5\frac{20}{50} \end{bmatrix}continuando con el desarrollo:
Matriz aumentada
[[20. 30. 20. 50. 27. ]
[50. 40. 40. 20. 39.5]
[20. 10. 10. 20. 14. ]
[10. 20. 30. 10. 19.5]]
Pivoteo parcial:
1 intercambiar filas: 0 y 1
2 intercambiar filas: 2 y 3
AB
[[50. 40. 40. 20. 39.5]
[20. 30. 20. 50. 27. ]
[10. 20. 30. 10. 19.5]
[20. 10. 10. 20. 14. ]]
Elimina hacia adelante:
fila i: 0 pivote: 50.0
fila k: 1 factor: 0.4
fila k: 2 factor: 0.2
fila k: 3 factor: 0.4
[[50. 40. 40. 20. 39.5]
[ 0. 14. 4. 42. 11.2]
[ 0. 12. 22. 6. 11.6]
[ 0. -6. -6. 12. -1.8]]
fila i: 1 pivote: 14.0
fila k: 2 factor: 0.8571428571428571
fila k: 3 factor: -0.42857142857142855
[[ 50. 40. 40. 20. 39.5 ]
[ 0. 14. 4. 42. 11.2 ]
[ 0. 0. 18.5714 -30. 2. ]
[ 0. 0. -4.2857 30. 3. ]]
fila i: 2 pivote: 18.571428571428573
fila k: 3 factor: -0.23076923076923075
[[ 50. 40. 40. 20. 39.5 ]
[ 0. 14. 4. 42. 11.2 ]
[ 0. 0. 18.5714 -30. 2. ]
[ 0. 0. 0. 23.0769 3.4615]]
fila i: 3 pivote: 23.076923076923077
[[ 50. 40. 40. 20. 39.5 ]
[ 0. 14. 4. 42. 11.2 ]
[ 0. 0. 18.5714 -30. 2. ]
[ 0. 0. 0. 23.0769 3.4615]]
Elimina hacia Atrás:
fila i: 3 pivote: 23.076923076923077
fila k: 2 factor: -1.3
fila k: 1 factor: 1.82
fila k: 0 factor: 0.8666666666666667
[[50. 40. 40. 0. 36.5 ]
[ 0. 14. 4. 0. 4.9 ]
[ 0. 0. 18.5714 0. 6.5 ]
[ 0. 0. 0. 1. 0.15 ]]
fila i: 2 pivote: 18.571428571428573
fila k: 1 factor: 0.21538461538461537
fila k: 0 factor: 2.1538461538461537
[[50. 40. 0. 0. 22.5 ]
[ 0. 14. 0. 0. 3.5 ]
[ 0. 0. 1. 0. 0.35]
[ 0. 0. 0. 1. 0.15]]
fila i: 1 pivote: 14.0
fila k: 0 factor: 2.857142857142857
[[50. 0. 0. 0. 12.5 ]
[ 0. 1. 0. 0. 0.25]
[ 0. 0. 1. 0. 0.35]
[ 0. 0. 0. 1. 0.15]]
fila i: 0 pivote: 50.0
[[1. 0. 0. 0. 0.25]
[0. 1. 0. 0. 0.25]
[0. 0. 1. 0. 0.35]
[0. 0. 0. 1. 0.15]]
solución X:
[0.25 0.25 0.35 0.15]
Las proporciones de cada lingote a usar para el nuevo lingote que cumple con lo solicitado son:
[0.25, 0.25, 0.35, 0.15]
Algoritmo en python
usado para la solución es:
# 1Eva2015TI_T4 Lingotes metales
# Método de Gauss-Jordan
# Sistemas de Ecuaciones A.X=B
import numpy as np
def gauss_eliminaAtras(AB, vertabla=False,
inversa=False,
casicero = 1e-15):
''' Gauss-Jordan elimina hacia atrás
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 Atrás:')
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:',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,:]
# redondeo a cero
for j in range(0,m,1):
if np.abs(AB[k,j])<=casicero:
AB[k,j]=0
if vertabla==True:
print(' fila k:',k,
' factor:',factor)
else:
print(' pivote:', pivote,'en fila:',i,
'genera division para cero')
AB[i,:] = AB[i,:]/AB[i,i] # diagonal a unos
if vertabla==True:
print(AB)
respuesta = np.copy(AB[:,ultcolumna])
if inversa==True: # matriz inversa
respuesta = np.copy(AB[:,n:])
return(respuesta)
def gauss_eliminaAdelante(AB,vertabla=False,
lu=False,casicero = 1e-15):
''' Gauss elimina hacia adelante
tarea: verificar términos cero
'''
tamano = np.shape(AB)
n = tamano[0]
m = tamano[1]
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:',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,:]
for j in range(0,m,1): # casicero revisa
if abs(AB[k,j])<casicero:
AB[k,j]=0
if vertabla==True:
print(' fila k:',k,
' factor:',factor)
else:
print(' pivote:', pivote,'en fila:',i,
'genera division para cero')
if vertabla==True:
print(AB)
respuesta = np.copy(AB)
if lu==True: # matriz triangular A=L.U
U = AB[:,:n-1]
respuesta = [AB,L,U]
return(respuesta)
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')
print(AB)
return(AB)
# PROGRAMA ------------------------
# INGRESO
compuesto = [[ 20, 50, 20, 10],
[ 30, 40, 10, 20],
[ 20, 40, 10, 30],
[ 50, 20, 20, 10]]
proporcion = [ 27, 39.5, 14, 19.5]
A = np.array(compuesto,dtype=float)
A = np.transpose(A)
B = proporcion
# PROCEDIMIENTO
np.set_printoptions(precision=4) # 4 decimales en print
casicero = 1e-15 # redondear a cero
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)
Tarea: Revisar sobre la última pregunta.