Ejercicio: 1Eva2007TII_T2 Aplicar Gauss-Seidel 6x6
1. Desarrollo Analítico
- Verificar que la matriz es diagonal dominante
No es necesario realizar el pivoteo por filas, ya la matriz tiene la diagonal dominante.
A = [[7.63, 0.30, 0.15, 0.50, 0.34, 0.84],
[0.38, 6.40, 0.70, 0.90, 0.29, 0.57],
[0.83, 0.19, 8.33, 0.82, 0.34, 0.37],
[0.50, 0.68, 0.86, 10.21, 0.53, 0.70],
[0.71, 0.30, 0.85, 0.82, 5.95, 0.55],
[0.43, 0.54, 0.59, 0.66, 0.31, 9.25]]
B = [ -9.44, 25.27, -48.01, 19.76, -23.63, 62.59]
- revisar el número de condición
cond(A) = || A||.||A-1||
El número de condición no es "muy alto", los valores de la diagonal son los mayores en toda la fila, por lo que el sistema converge.
>>> np.linalg.cond(A)
2.04518539662910119
- realizar iteraciones con las expresiones:
x_0 = \Big(-9.44 -0.3 x_1 -0.15x_2 -0.50 x_3 -0.34 x_4 -0.84 x_5\Big)\frac{1}{7.63} x_1 = \Big( 25.27 -0.38 x_0 -0.70 x_2 -0.90 x_3 -0.29 x_4 -0.57 x_5 \Big) \frac{1}{6.40} x_2 = \Big(-48.01 -0.83x_0 -0.19 x_1 -0.82x_3 -0.34x_4 -0.37x_5 \Big)\frac{1}{8.33} x_3 = \Big(19.76 -0.50 x_0 -0.68 x_1 -0.86 x_2 -0.53 x_4 -0.70x_5 \Big)\frac{1}{10.21} x_4 = \Big( -23.63 - 0.71 x_0 -0.30 x_1 -0.85 x_2 -0.82 x_3 -0.55x_5 \Big)\frac{1}{5.95} x_5 = \Big( 62.59 - 0.43x_0 -0.54x_1 - 0.59 x_2 -0.66 x_3 -0.31 x_4 \Big)\frac{1}{9.25}Dado que no se establece en el enunciado el vector inicial, se usará el vector cero. La tolerancia requerida es 10-5
X0 = [ 0. 0. 0. 0. 0. 0.] = [x0,x1,x2,x3,x4,x5]
iteración 0
x_0 = \Big(-9.44 -0.3 (0) -0.15(0) -0.50 (0) -0.34(0) -0.84 (0)\Big)\frac{1}{7.63} = -1.23722 x_1 = \Big( 25.27 -0.38 (-1.23722) -0.70 (0) -0.90 (0) -0.29 (0) -0.57 (0) \Big) \frac{1}{6.40} = 4.0219 x_2 = \Big(-48.01 -0.83 (-1.23722) -0.19 (4.0219) -0.82(0) -0.34(0) -0.37(0) \Big)\frac{1}{8.33} = -5.73196 x_3 = \Big( 19.76 -0.50 (-1.23722) -0.68 (4.0219) -0.86 (-5.73196) -0.53 (0) -0.70(0) \Big)\frac{1}{10.21} = 2.21089 x_4 = \Big( -23.63 - 0.71 (-1.23722) -0.30 (4.0219) -0.85 (-5.73196) -0.82 (2.21089) -0.55(0) \Big)\frac{1}{5.95} = -3.51242 x_5 = \Big( 62.59 - 0.43(-1.23722) -0.54(4.0219) - 0.59 (-5.73196) -0.66 (2.21089) -0.31 (-3.51242) \Big)\frac{1}{9.25} = 6.91478 X_1 = [-1.23722, 4.0219, -5.73196, 2.21089, -3.51242, 6.91478 ] diferencia = X1 - [0,0,0,0,0,0] errado = max(|diferencia|) = 6.91478iteración 1
x_0 = \Big(-9.44 -0.3 (4.0219) -0.15(4.0219) -0.50 (2.21089) -0.34 (-3.51242) -0.84(6.91478) \Big)\frac{1}{7.63} = -2.0323 x_1 = \Big( 25.27 -0.38 (-2.0323) -0.70 ( -5.73196) -0.90 (2.21089) -0.29 (-3.51242) -0.57 (6.91478) \Big) \frac{1}{6.40} = 3.92844 x_2 = \Big(-48.01 -0.83(-2.0323) -0.19 (3.92844) -0.82(2.21089) -0.34(-3.51242) -0.37(6.91478) \Big)\frac{1}{8.33} = -6.03203 x_3 = \Big(19.76 -0.50 (-2.0323) -0.68 (3.92844) -0.86 (-6.03203) -0.53 (-3.51242) -0.70(6.91478) \Big)\frac{1}{10.21} = 1.98958 x_4 = \Big( -23.63 - 0.71 (-2.0323) -0.30 (3.92844) -0.85 (-6.03203) -0.82 (1.98958) -0.55(6.91478) \Big)\frac{1}{5.95} = -3.97865 x_5 = \Big( 62.59 - 0.43(-2.0323) -0.54(3.92844) - 0.59 (-6.03203) -0.66 (1.98958) -0.31 (-3.97865) \Big)\frac{1}{9.25} = 7.00775 X_2 = [-2.0323, 3.92844, -6.03203, 1.98958, -3.97865, 7.00775] diferencia = X2 - [-1.23722, 4.0219, -5.73196, 2.21089, -3.51242, 6.91478 ] errado = max(|diferencia|) = 0.79507iteración 2
Desarrollar como tarea.
2. Algoritmo en Python
La tabla de aproximaciones sucesivas para el vector X es:
Matriz aumentada
[[ 7.63 0.3 0.15 0.5 0.34 0.84 -9.44]
[ 0.38 6.4 0.7 0.9 0.29 0.57 25.27]
[ 0.83 0.19 8.33 0.82 0.34 0.37 -48.01]
[ 0.5 0.68 0.86 10.21 0.53 0.7 19.76]
[ 0.71 0.3 0.85 0.82 5.95 0.55 -23.63]
[ 0.43 0.54 0.59 0.66 0.31 9.25 62.59]]
Pivoteo parcial:
Pivoteo por filas NO requerido
Iteraciones Gauss-Seidel
itera,[X]
errado,[diferencia]
0 [0. 0. 0. 0. 0. 0.]
nan
1 [-1.2372 4.0219 -5.732 2.2109 -3.5124 6.9148]
6.91477852326521 [1.2372 4.0219 5.732 2.2109 3.5124 6.9148]
2 [-2.0323 3.9284 -6.032 1.9896 -3.9786 7.0077]
0.7950736009265342 [0.7951 0.0935 0.3001 0.2213 0.4662 0.093 ]
3 [-1.9977 4.0032 -6.0005 1.9981 -4.0008 6.9999]
0.0747319197184444 [0.0346 0.0747 0.0315 0.0085 0.0222 0.0078]
4 [-1.9999 4.0004 -5.9998 2. -4. 7. ]
0.002806312415341239 [2.2635e-03 2.8063e-03 7.0626e-04 1.9270e-03 7.7045e-04 6.0687e-05]
5 [-2. 4. -6. 2. -4. 7.]
0.00038434237385231995 [7.0836e-05 3.8434e-04 2.0801e-04 2.4329e-06 5.1602e-05 3.7095e-05]
6 [-2. 4. -6. 2. -4. 7.]
1.601551550134417e-05 [1.2658e-05 1.6016e-05 5.6200e-06 6.4351e-06 4.0572e-06 5.6982e-07]
Metodo de Gauss-Seidel
numero de condición: 2.045185396629101
X: [-2. 4. -6. 2. -4. 7.]
errado: 1.601551550134417e-05
iteraciones: 6
el gráfico de los iteraciones vs errores es:

La tabla obtiene aplicando la función de Gauss-Seidel, tomando como vector inicial el vector de ceros.
Tarea: X=TX+C
Algoritmo en Python
# 1Eva2007TII_T2 Aplicar Gauss-Seidel 6x6
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
A = [[7.63, 0.30, 0.15, 0.50, 0.34, 0.84],
[0.38, 6.40, 0.70, 0.90, 0.29, 0.57],
[0.83, 0.19, 8.33, 0.82, 0.34, 0.37],
[0.50, 0.68, 0.86, 10.21, 0.53, 0.70],
[0.71, 0.30, 0.85, 0.82, 5.95, 0.55],
[0.43, 0.54, 0.59, 0.66, 0.31, 9.25]]
B = [-9.44,25.27,-48.01,19.76,-23.63,62.59]
X0 = np.zeros(len(A), dtype=float)
tolera = 0.0001
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)
La gráfica se completa con:
# GRAFICA de iteraciones
errados = tabla[:,n]
import matplotlib.pyplot as plt
# grafica de error por iteracion
fig2D = plt.figure()
graf = fig2D.add_subplot(111)
graf.plot(errados,color='purple')
graf.set_xlabel('itera')
graf.set_ylabel('|error|')
graf.set_title('Método de Gauss-Seidel: error[itera]')
graf.grid()
plt.show()
En el caso de la norma infinito, para la matriz A, se puede usar el algoritmo desarrollado en clase.
Como valor para verificar su algoritmo, se obtuvo:
>>> np.linalg.norm(A, np.inf)
13.479999999999999
Tarea: incluir la norma infinito para T