s1Eva2015TI_T4 Lingotes metales

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 = 27

Se 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.5

Las 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.

Ejemplos - Ejercicios resueltos de Métodos Numéricos