Ejercicio: 1Eva_IIT2019_T3 Circuito eléctrico
Las ecuaciones del problema son:
55 I_1 - 25 I_4 =-200 -37 I_3 - 4 I_4 =-250 -25 I_1 - 4 I_3 +29 I_4 =100 I_2 =-10Planteo del problema en la forma A.X=B
A = [[ 55.0, 0, 0, -25], [ 0 , 0,-37, -4], [-25 , 0, -4, 29], [ 0 , 1, 0, 0]] B = [-200,-250,100,-10]
El ejercicio se puede simplificar con una matriz de 3×3 dado que una de las corrientes I2 es conocida con valor -10, queda resolver el problema para
[I1 ,I3 ,I4 ]
A = [[ 55.0, 0, -25], [ 0 , -37, -4], [-25 , -4, 29]] B = [-200,-250,100]
conformando la matriz aumentada
[[ 55. 0. -25. -200.] [ 0. -37. -4. -250.] [ -25. -4. 29. 100.]]
que se pivotea por filas para acercar a matriz diagonal dominante:
[[ 55. 0. -25. -200.] [ 0. -37. -4. -250.] [ -25. -4. 29. 100.]]
Literal a
Para métodos directos se aplica el método de eliminación hacia adelante.
Usando el primer elemento en la diagonal se convierten en ceros los números debajo de la posición primera de la diagonal
[[ 55. 0. -25. -200. ] [ 0. -37. -4. -250. ] [ 0. -4. 17.636363 9.090909]]
luego se continúa con la segunda columna:
[[ 55. 0. -25. -200. ] [ 0. -37. -4. -250. ] [ 0. 0. 18.068796 36.117936]]
y para el método de Gauss se emplea sustitución hacia atrás
se determina el valor de I4
y planteando se obtiene el último valor
55 I_1 +25 I_4 = -200 55 I_1 = -200 -25 I_4 I_1 = \frac{-200 -25 I_4}{55} I_1 = \frac{-200 -25(1.99891216)}{55} = -2.7277672con lo que el vector solución es:
[-2.7277672 6.54065815 1.99891216]
sin embargo, para verificar la respuesta se aplica A.X=B
verificar que A.X = B, obteniendo nuevamente el vector B. [-200. -250. 100.]]
literal b
La norma de la matriz infinito se determina como:
||x|| = max\Big[ |x_i| \Big]considere que en el problema el término en A de magnitud mayor es 55.
El vector suma de filas es:
[[| 55|+| 0|+|-25|], [[80], [| 0|+|-37|+| -4|], = [41], [[-25|+| -4|+| 29|]] [58]] por lo que la norma ∞ ejemplo ||A||∞ es el maximo de suma de filas: 80
para revisar la estabilidad de la solución, se observa el número de condición
>>> np.linalg.cond(A) 4.997509004325602
En éste caso no está muy alejado de 1. De resultar alejado del valor ideal de uno, la solución se considera poco estable. Pequeños cambios en la entrada del sistema generan grandes cambios en la salida.
Tarea: Matriz de transición de Jacobi
Literal c
En el método de Gauss-Seidel acorde a lo indicado, se inicia con el vector cero. Como no se indica el valor de tolerancia para el error, se considera tolera = 0.0001
las ecuaciones para el método son:
I_1 =\frac{-200 + 25 I_4}{55} I_3 = \frac{-250+ 4 I_4}{-37} I_4 =\frac{100 +25 I_1 + 4 I_3}{29}Como I2 es constante, no se usa en las iteraciones
I_2 =-10teniendo como resultados de las iteraciones:
Matriz aumentada [[ 55. 0. -25. -200.] [ 0. -37. -4. -250.] [ -25. -4. 29. 100.]] Pivoteo parcial: Pivoteo por filas NO requerido Iteraciones Gauss-Seidel itera,[X] diferencia,errado 0 [0. 0. 0.] 2e-05 1 [-3.6363636 6.7567568 1.2454461] [3.6363636 6.7567568 1.2454461] 6.756756756756757 2 [-3.0702518 6.6221139 1.7149021] [0.5661119 0.1346428 0.469456 ] 0.5661118513783094 3 [-2.8568627 6.5713619 1.891858 ] [0.2133891 0.050752 0.1769559] 0.2133891067340583 4 [-2.7764282 6.5522316 1.9585594] [0.0804345 0.0191304 0.0667014] 0.08043447732439457 5 [-2.7461094 6.5450206 1.9837016] [0.0303188 0.007211 0.0251423] 0.030318816370094925 6 [-2.7346811 6.5423025 1.9931787] [0.0114283 0.0027181 0.0094771] 0.011428316023939011 7 [-2.7303733 6.541278 1.996751 ] [0.0043078 0.0010246 0.0035723] 0.004307767346479974 8 [-2.7287495 6.5408918 1.9980975] [0.0016238 0.0003862 0.0013465] 0.001623761494915943 9 [-2.7281375 6.5407462 1.9986051] [0.0006121 0.0001456 0.0005076] 0.0006120575185017962 10 [-2.7279068 6.5406913 1.9987964] [2.3070778e-04 5.4871039e-05 1.9131760e-04] 0.00023070777766820427 11 [-2.7278198 6.5406707 1.9988685] [8.6962544e-05 2.0682983e-05 7.2114885e-05] 8.696254366213907e-05 12 [-2.727787 6.5406629 1.9988957] [3.2779493e-05 7.7962038e-06 2.7182845e-05] 3.277949307367578e-05 13 [-2.7277747 6.5406599 1.998906 ] [1.2355839e-05 2.9386860e-06 1.0246249e-05] 1.235583874370505e-05 14 [-2.72777 6.5406588 1.9989098] [4.6573860e-06 1.1077026e-06 3.8622013e-06] 4.6573859666665385e-06 numero de condición: 4.997509004325604 respuesta con Gauss-Seidel [-2.72777 6.5406588 1.9989098] >>>
con lo que el vector resultante es:
respuesta con Gauss-Seidel [-2.72777 6.5406588 1.9989098]
que para verificar, se realiza la operación A.X
observando que el resultado es igual a B
[[-200.00002751] [-249.9999956 ] [ 100.0000125 ]]
Solución alterna
Usando la matriz de 4×4, los resultados son iguales para las corrientes
[I1 ,I2 , I3 ,I4 ]. Realizando la matriz aumentada,
[[ 55. 0. 0. -25. -200.] [ 0. 0. -37. -4. -250.] [ -25. 0. -4. 29. 100.] [ 0. 1. 0. 0. -10.]]
que se pivotea por filas para acercar a matriz diagonal dominante:
[[ 55. 0. 0. -25. -200.] [ 0. 1. 0. 0. -10.] [ 0. 0. -37. -4. -250.] [ -25. 0. -4. 29. 100.]]
Literal a
Para métodos directos se aplica el método de eliminación hacia adelante.
Usando el primer elemento en la diagonal.
[[ 55. 0. 0. -25. -200. ] [ 0. 1. 0. 0. -10. ] [ 0. 0. -37. -4. -250. ] [ 0. 0. -4. 17.63636364 9.09090909]]
para el segundo no es necesario, por debajo se encuentran valores cero.
Por lo que se pasa al tercer elemento de la diagonal
[[ 55. 0. 0. -25. -200. ] [ 0. 1. 0. 0. -10. ] [ 0. 0. -37. -4. -250. ] [ 0. 0. 0. 18.06879607 36.11793612]]
y para el método de Gauss se emplea sustitución hacia atras.
para x4:
para x3:
-37 x_3 -4 x_3 = -250 37 x_3 = 250-4 x_4 = 250-4(1.99891216) x_3 = 6.54065815como ejercicio, continuar con x1, dado que x2=-10
55 x_1 + 25 x_4 = -200El vector solución obtenido es:
el vector solución X es: [[ -2.7277672 ] [-10. ] [ 6.54065815] [ 1.99891216]]
sin embargo, para verificar la respuesta se aplica A.X=B.
[[-200.] [-250.] [ 100.] [ -10.]]
Se revisa el número de condición de la matriz:
>>> np.linalg.cond(A) 70.21827416891405
Y para éste caso, el número de condición se encuentra alejado del valor 1, contrario a la respuesta del la primera forma de solución con la matriz 3×3. De resultar alejado del valor ideal de uno, la solución se considera poco estable. Pequeños cambios en la entrada del sistema generan grandes cambios en la salida.
Algoritmo en Python
Presentado por partes para revisión:
Para el método de Gauss, los resultados del algoritmo se muestran como:
Matriz aumentada [[ 55. 0. -25. -200.] [ 0. -37. -4. -250.] [ -25. -4. 29. 100.]] Pivoteo parcial: Pivoteo por filas NO requerido Elimina hacia adelante: fila 0 pivote: 55.0 factor: 0.0 para fila: 1 factor: -0.45454545454545453 para fila: 2 fila 1 pivote: -37.0 factor: 0.10810810810810811 para fila: 2 fila 2 pivote: 18.06879606879607 [[ 55. 0. -25. -200. ] [ 0. -37. -4. -250. ] [ 0. 0. 18.06879607 36.11793612]] solución: [-2.7277672 6.54065815 1.99891216]
Instrucciones en Python usando las funciones creadas en la unidad:
# 1Eva_IIT2019_T3 Circuito eléctrico # Método de Gauss # 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, 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,'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,:] if vertabla==True: print(' factor: ',factor,' para fila: ',k) else: print(' pivote:', pivote,'en fila:',i, 'genera division para cero') if vertabla==True: print(AB) return(AB) def gauss_sustituyeAtras(AB,vertabla=False, casicero = 1e-15): ''' Gauss sustituye hacia atras ''' tamano = np.shape(AB) n = tamano[0] m = tamano[1] # Sustitución hacia atras X = np.zeros(n,dtype=float) ultfila = n-1 ultcolumna = m-1 for i in range(ultfila,0-1,-1): suma = 0 for j in range(i+1,ultcolumna,1): suma = suma + AB[i,j]*X[j] X[i] = (AB[i,ultcolumna]-suma)/AB[i,i] return(X) # INGRESO A = [[ 55.0, 0, -25], [ 0 , -37, -4], [-25 , -4, 29]] B = [-200,-250,100] # PROCEDIMIENTO AB = pivoteafila(A,B,vertabla=True) AB = gauss_eliminaAdelante(AB,vertabla=True) X = gauss_sustituyeAtras(AB,vertabla=True) # SALIDA print('solución: ') print(X)
literal c
Resultados con el algoritmo de Gauss Seidel
Matriz aumentada [[ 55. 0. -25. -200.] [ 0. -37. -4. -250.] [ -25. -4. 29. 100.]] Pivoteo parcial: Pivoteo por filas NO requerido Iteraciones Gauss-Seidel itera,[X] diferencia,errado 0 [0. 0. 0.] 2e-05 1 [-3.6363636 6.7567568 1.2454461] [3.6363636 6.7567568 1.2454461] 6.756756756756757 2 [-3.0702518 6.6221139 1.7149021] [0.5661119 0.1346428 0.469456 ] 0.5661118513783094 3 [-2.8568627 6.5713619 1.891858 ] [0.2133891 0.050752 0.1769559] 0.2133891067340583 4 [-2.7764282 6.5522316 1.9585594] [0.0804345 0.0191304 0.0667014] 0.08043447732439457 5 [-2.7461094 6.5450206 1.9837016] [0.0303188 0.007211 0.0251423] 0.030318816370094925 6 [-2.7346811 6.5423025 1.9931787] [0.0114283 0.0027181 0.0094771] 0.011428316023939011 7 [-2.7303733 6.541278 1.996751 ] [0.0043078 0.0010246 0.0035723] 0.004307767346479974 8 [-2.7287495 6.5408918 1.9980975] [0.0016238 0.0003862 0.0013465] 0.001623761494915943 9 [-2.7281375 6.5407462 1.9986051] [0.0006121 0.0001456 0.0005076] 0.0006120575185017962 10 [-2.7279068 6.5406913 1.9987964] [2.3070778e-04 5.4871039e-05 1.9131760e-04] 0.00023070777766820427 11 [-2.7278198 6.5406707 1.9988685] [8.6962544e-05 2.0682983e-05 7.2114885e-05] 8.696254366213907e-05 12 [-2.727787 6.5406629 1.9988957] [3.2779493e-05 7.7962038e-06 2.7182845e-05] 3.277949307367578e-05 13 [-2.7277747 6.5406599 1.998906 ] [1.2355839e-05 2.9386860e-06 1.0246249e-05] 1.235583874370505e-05 14 [-2.72777 6.5406588 1.9989098] [4.6573860e-06 1.1077026e-06 3.8622013e-06] 4.6573859666665385e-06 numero de condición: 4.997509004325604 respuesta con Gauss-Seidel [-2.72777 6.5406588 1.9989098] >>>
Instrucciones en Python
# 1Eva_IIT2019_T3 Circuito eléctrico # Algoritmo Gauss-Seidel # solución de matrices # métodos iterativos # Referencia: Chapra 11.2, p.310, # Rodriguez 5.2 p.162 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 ''' 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] diferencia = 2*tolera*np.ones(n, dtype=float) errado = np.max(diferencia) X = np.copy(X0) itera = 0 if vertabla==True: print('Iteraciones Gauss-Seidel') print('itera,[X]') print(' diferencia,errado') print(itera, X, errado) np.set_printoptions(precision) while (errado>tolera and itera<iteramax): for i in range(0,n,1): xi = B[i] for j in range(0,m,1): if (i!=j): xi = xi-A[i,j]*X[j] xi = xi/A[i,i] diferencia[i] = np.abs(xi-X[i]) X[i] = xi errado = np.max(diferencia) itera = itera + 1 if vertabla==True: print(itera, X) print(' ', diferencia, errado) # No converge if (itera>iteramax): X=itera print('iteramax superado, No converge') return(X) 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') return(AB) # INGRESO A = [[ 55.0, 0, -25], [ 0 , -37, -4], [-25 , -4, 29]] B = [-200,-250,100] X0 = [0.,0.,0.] tolera = 0.00001 iteramax = 100 verdecimal = 7 # PROCEDIMIENTO # numero de condicion ncond = np.linalg.cond(A) AB = pivoteafila(A,B,vertabla=True) # separa matriz aumentada en A y B [n,m] = np.shape(AB) A = AB[:,:m-1] B = AB[:,m-1] respuesta = gauss_seidel(A,B,X0, tolera, vertabla=True, precision=verdecimal) # SALIDA print('numero de condición:', ncond) print('respuesta con Gauss-Seidel') print(respuesta)
.