Ejercicio: 1Eva2012TI_T2_MN Modelo Leontief
Planteamiento
X - TX = D
A(I-T) = D
(I-T)X = D
para el algoritmo:
A = I - T
B = D
Desarrollo analítico
Se asigna como tarea
Algoritmo en Python
Resultados del algoritmo
Matriz aumentada
[[ 6.0e-01 -3.0e-02 -2.0e-02 8.0e+01]
[-6.0e-02 6.3e-01 -1.0e-01 1.4e+02]
[-1.2e-01 -1.5e-01 8.1e-01 2.0e+02]]
Pivoteo parcial:
Pivoteo por filas NO requerido
Iteraciones Gauss-Seidel
itera,[X]
errado,[diferencia]
0 [200. 200. 200.]
nan
1 [150. 268.254 318.8125]
118.81246325690768 [ 50. 68.254 118.8125]
2 [157.3731 287.8153 323.5272]
19.561322471375377 [ 7.3731 19.5613 4.7148]
3 [158.5083 288.6718 323.854 ]
1.1352254665011685 [1.1352 0.8565 0.3268]
4 [158.5621 288.7288 323.8725]
0.05698766962200352 [0.0537 0.057 0.0185]
5 [158.5655 288.732 323.8737]
0.0034664322156459093 [0.0035 0.0033 0.0011]
6 [158.5657 288.7322 323.8737]
0.00020071707112379045 [2.0072e-04 1.9671e-04 6.6163e-05]
7 [158.5657 288.7322 323.8737]
1.2040721173889324e-05 [1.2041e-05 1.1649e-05 3.9410e-06]
8 [158.5657 288.7323 323.8737]
7.138053206290351e-07 [7.1381e-07 6.9354e-07 2.3418e-07]
Metodo de Gauss-Seidel
numero de condición: 1.7314308659809885
X: [158.5657 288.7323 323.8737]
errado: 7.138053206290351e-07
iteraciones: 8
Algoritmo en Python
# 1Eva2012TI_T2_MN Modelo Leontief
# Algoritmo Gauss-Seidel
# solución de matrices
# métodos iterativos
import numpy as np
def gauss_seidel(A,B,X0,tolera, iteramax=100, vertabla=False, precision=4):
''' Método de Gauss Seidel, tolerancia, vector inicial X0
para mostrar iteraciones: vertabla=True
'''
# Matrices como arreglo, numeros reales
A = np.array(A, dtype=float)
B = np.array(B, dtype=float)
X0 = np.array(X0, dtype=float)
tamano = np.shape(A)
n = tamano[0]
m = tamano[1]
# valores iniciales
diferencia = 2*tolera*np.ones(n, dtype=float)
errado = 2*tolera # np.max(diferencia)
tabla = [np.copy(X0)] # tabla de iteraciones
tabla = np.concatenate((tabla,[[np.nan]]),
axis=1) # añade errado
if vertabla==True:
print('Iteraciones Gauss-Seidel')
print('itera,[X]')
print(' errado,[diferencia]')
print(0,X0)
print(' ',np.nan)
np.set_printoptions(precision)
itera = 0 # Gauss-Sediel
X = np.copy(X0)
while (errado>tolera and itera<iteramax):
for i in range(0,n,1): # una ecuacion
suma = B[i]
for j in range(0,m,1):
if (i!=j):
suma = suma-A[i,j]*X[j]
nuevo = suma/A[i,i]
diferencia[i] = np.abs(nuevo-X[i])
X[i] = nuevo
errado = np.max(diferencia)
Xfila= np.concatenate((X,[errado]),axis=0)
tabla = np.concatenate((tabla,[Xfila]),axis = 0)
itera = itera + 1
if vertabla==True:
print(itera, X)
print(' ', errado,diferencia)
# No converge
if (itera>iteramax):
X = np.nan
print('No converge,iteramax superado')
return(X,tabla)
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')
print(AB)
return(AB)
# PROGRAMA Búsqueda de solucion --------
# INGRESO
T = [[0.40, 0.03, 0.02],
[0.06, 0.37, 0.10],
[0.12, 0.15, 0.19]]
A = np.identity(3) - T
B = [80.0, 140.0, 200.0]
X0 = [200.0,200.0,200.0]
tolera = 0.00001
iteramax = 100
verdecimal = 4
# PROCEDIMIENTO
AB = pivoteafila(A,B,vertabla=True)
n,m = np.shape(AB)
A = AB[:,:n] # separa en A y B
B = AB[:,n]
[X, tabla] = gauss_seidel(A,B,X0, tolera,
vertabla=True,
precision=verdecimal)
n_itera = len(tabla)-1
errado = tabla[-1,-1]
# numero de condicion
ncond = np.linalg.cond(A)
# SALIDA
print('Metodo de Gauss-Seidel')
print('numero de condición:', ncond)
print('X: ',X)
print('errado:',errado)
print('iteraciones:', n_itera)