Categoría: Sol_1Eva 2011-2020

  • s1Eva_IIT2019_T1 Ecuación Recursiva

    Ejercicio: 1Eva_IIT2019_T1 Ecuación Recursiva

    la ecuación recursiva es:

    x_n = g(x_{n-1}) = \sqrt{3 + x_{n-1}}

    literal a y b

    g(x) es creciente en todo el intervalo, con valor minimo en g(1) = 2, y máximo en g(3) =2.449. Por observación de la gráfica, la pendiente g(x) es menor que la recta identidad en todo el intervalo

    Verifique la cota de g'(x)

    g(x) = \sqrt{3 + x} =(3+x)^{1/2} g'(x) =\frac{1}{2}(3+x)^{-1/2} g'(x) =\frac{1}{2\sqrt{3+x}}

    Tarea: verificar que g'(x) es menor que 1 en todo el intervalo.

    Literal c

    Usando el algoritmo del punto fijo, iniciando con el punto x0=2
    y tolerancia de 10-4, se tiene que:

    Iteración 1: x0=2

    g(x_0) = \sqrt{3 + 2} = 2.2361

    error = |2.2361 - 2| = 0.2361

    Iteración 2: x1 = 2.2361

    g(x_1) = \sqrt{3 + 2.2361} = 2.2882

    error = |2.2882 - 2.2361| = 0.0522

    Iteración 3: x2 = 2.2882

    g(x_2) = \sqrt{3 + 2.2882} = 2.2996

    error = |2.2996 - 2.28821| = 0.0114

    Iteración 4: x3 = 2.2996

    g(x_3) = \sqrt{3 + 2.2996} = 2.3021

    error = |2.3021- 2.2996| = 0.0025

    Iteración 5: x4 = 2.3021

    g(x_4) = \sqrt{3 + 2.3021} = 2.3026

    error = |2.3021- 2.2996| = 5.3672e-04

    con lo que determina que el error en la 5ta iteración es de 5.3672e-04 y el error se reduce en casi 1/4 entre iteraciones. El punto fijo converge a 2.3028

    Se muestra como referencia la tabla resumen.

    [[ x ,   g(x), 	 tramo  ] 
     [1.      2.      1.    ]
     [2.      2.2361  0.2361]
     [2.2361  2.2882  0.0522]
     [2.2882  2.2996  0.0114]
     [2.2996  2.3021  0.0025]
     [2.3021  2.3026  5.3672e-04]
     [2.3026  2.3027  1.1654e-04]
     [2.3027  2.3028  2.5305e-05]
    raiz:  2.3027686193257098
    

    con el siguiente comportamiento de la funcion:

    literal e

    Realizando el mismo ejercicio para el método de la bisección, se requiere cambiar a la forma f(x)=0

    x = \sqrt{3 + x} 0 = \sqrt{3 + x} -x f(x) = \sqrt{3 + x} -x

    tomando como intervalo el mismo que el inicio del problema [1,3], al realizar las operaciones se tiene que:

    a = 1 ; f(a) = 1
    b = 3 ; f(b) = -0.551
    c = (a+b)/2 = (1+3)/2 = 2
    f(c) = f(2) = (3 + 2)^(.5) +2 = 0.236
    Siendo f(c) positivo, y tamaño de paso 2, se reduce a 1
    
    a = 2 ; f(a) = 0.236
    b = 3 ; f(b) = -0.551
    c = (a+b)/2 = (2+3)/2 = 2.5
    f(c) = f(2.5) = (3 + 2.5)^(.5) +2.5 = -0.155
    Siendo fc(c) negativo y tamaño de paso 1, se reduce a .5
    
    a = 2
    b = 2.5
    ...

    Siguiendo las operaciones se obtiene la siguiente tabla:

    [ i, a,   c,   b,    f(a),  f(c),  f(b), paso]
     1 1.000 2.000 3.000 1.000  0.236 -0.551 2.000 
     2 2.000 2.500 3.000 0.236 -0.155 -0.551 1.000 
     3 2.000 2.250 2.500 0.236  0.041 -0.155 0.500 
     4 2.250 2.375 2.500 0.041 -0.057 -0.155 0.250 
     5 2.250 2.312 2.375 0.041 -0.008 -0.057 0.125 
     6 2.250 2.281 2.312 0.041  0.017 -0.008 0.062 
     7 2.281 2.297 2.312 0.017  0.005 -0.008 0.031 
     8 2.297 2.305 2.312 0.005 -0.001 -0.008 0.016 
     9 2.297 2.301 2.305 0.005  0.002 -0.001 0.008 
    10 2.301 2.303 2.305 0.002  0.000 -0.001 0.004 
    11 2.303 2.304 2.305 0.000 -0.001 -0.001 0.002 
    12 2.303 2.303 2.304 0.000 -0.000 -0.001 0.001 
    13 2.303 2.303 2.303 0.000 -0.000 -0.000 0.000 
    14 2.303 2.303 2.303 0.000 -0.000 -0.000 0.000 
    15 2.303 2.303 2.303 0.000 -0.000 -0.000 0.000 
    16 2.303 2.303 2.303 0.000  0.000 -0.000 0.000 
    raiz:  2.302764892578125
    

    Donde se observa que para la misma tolerancia de 10-4, se incrementan las iteraciones a 16. Mientra que con punto fijo eran solo 8.

    Nota: En la evaluación solo se requeria calcular hasta la 5ta iteración. Lo presentado es para fines didácticos

  • s1Eva_IIT2019_T3 Circuito eléctrico

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

    Planteo 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 3x3 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

    18.068796 I_4 = 36.11793612 I_4 =\frac{36.11793612}{18.068796}= 1.99891216 -37 I_3 -4 I_4 = -250 -37 I_3= -250 + 4 I_4 I_3=\frac{-250 + 4 I_4}{-37} I_3=\frac{-250 + 4 (1.99891216)}{-37} = 6.54065815

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

    con 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 =-10

    teniendo 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 4x4, 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:

    18.06879607 x_4 = 36.11793612 x_4 = 1.99891216

    para x3:

    -37 x_3 -4 x_3 = -250 37 x_3 = 250-4 x_4 = 250-4(1.99891216) x_3 = 6.54065815

    como ejercicio, continuar con x1, dado que x2=-10

    55 x_1 + 25 x_4 = -200

    El 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 3x3. 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)
    

    .

  • s1Eva_IIT2019_T2 Proceso Termodinámico

    Ejercicio: 1Eva_IIT2019_T2 Proceso Termodinámico

    la ecuación para el problema se describe como:

    f(x)=e^{-0.5x}

    ecuación que se usa para describir los siguientes puntos:

    x 0 1 2 3 4
    f(x) 1 0.60653065 0.36787944 0.22313016  0.13533528

    Como el polinomio es de grado 2, se utilizan tres puntos. Para cubrir el intervalo los puntos seleccionados incluyen los extremos y el punto medio.

    literal a

    Con los puntos seleccionados se escriben las ecuaciones del polinomio:

    p_2(x)= a_0 x^2 + a_1 x + a_2

    usando los valores de la tabla:

    p_2(0)=a_0 (0)^2 + a_1 (0) + a_2 = 1 p_2(2)=a_0 (2)^2 + a_1 (2) + a_2 = 0.36787944 p_2(4)=a_0 (4)^2 + a_1 (4) + a_2 = 0.13533528

    con la que se escribe la matriz Vandermonde con la forma A.x=B

    A= [[ 0.,  0.,  1.,]
        [ 4.,  2.,  1.,]
        [16.,  4.,  1.,]]
    
    B= [[1.        ],
        [0.36787944],
        [0.13533528]]) 
    

    matriz aumentada

    [[ 0.,  0.,  1.,  1.        ]
     [ 4.,  2.,  1.,  0.36787944]
     [16.,  4.,  1.,  0.13533528]]
    

    matriz pivoteada

    [[16.,  4.,  1.,  0.13533528]
     [ 4.,  2.,  1.,  0.36787944]
     [ 0.,  0.,  1.,  1.        ]]
    

    Resolviendo por algún método directo, la solución proporciona los coeficientes del polinomio

    Tarea: escribir la solución del método directo, semejante a la presentada en el tema 3

    [ 0.04994705 -0.41595438  1.        ]
    

    con lo que el polinomio de interpolación es:

    p_2(x) = 0.04994705 x^2 - 0.41595438 x + 1.0

    en el enunciado se requiere la evaluación en x=2.4

    p_2(2.4) = 0.04994705 (2.4)^2 - 0.41595438 (2.4) + 1.0 f(2.4)=e^{-0.5(2.4)} error = |f(2.4)-p_2(2.4)|
    Evaluando en X1:  2.4
    Evaluando p(x1):  0.2894044975129779
    Error en x1:      0.011789714399224216
     Error relativo:  0.039143230291095066
    

    La diferencia entre la función y el polinomio de interpolación se puede observar en la gráfica:
    s1eIIT2019T2_grafica


    literal b

    Tarea: Encontrar la cota de error con f(1.7)


    Algoritmo en Python

    Resultado con el algoritmo

    Matriz Vandermonde: 
    [[ 0.  0.  1.]
     [ 4.  2.  1.]
     [16.  4.  1.]]
    los coeficientes del polinomio: 
    [ 0.04994705 -0.41595438  1.        ]
    Polinomio de interpolación: 
    0.049947050111716*x**2 - 0.415954379637711*x + 1.0
    
     formato pprint
                       2                            
    0.049947050111716*x  - 0.415954379637711*x + 1.0
    
    Evaluando en X1:  2.4
    Evaluando p(x1):  0.2894044975129779
    Error en x1:      0.011789714399224216
     Error relativo:  0.039143230291095066
    
    Evaluando en X2:  1.7
    Evaluando p(x2):  0.2894044975129779
    Error en x2:      0.011789714399224216
     Error relativo:  0.039143230291095066
    

    Presentado por secciones, semejante a lo desarrollado en clases

    # 1Eva_IIT2019_T2 Proceso Termodinámico
    # El polinomio de interpolación
    import numpy as np
    import sympy as sym
    
    # INGRESO
    fx = lambda x: np.exp(-0.5*x)
    xi =np.array([0,2,4],dtype=float)
    
    # determina vector
    fi= fx(xi)
    
    # PROCEDIMIENTO
    # Convierte a arreglos numpy 
    xi = np.array(xi,dtype=float)
    fi = np.array(fi,dtype=float)
    
    B = fi
    n = len(xi)
    
    # Matriz Vandermonde D
    D = np.zeros(shape=(n,n),dtype=float)
    for i in range(0,n,1):
        for j in range(0,n,1):
            potencia = (n-1)-j # Derecha a izquierda
            D[i,j] = xi[i]**potencia
    
    # Aplicar métodos Unidad03. Tarea
    # Resuelve sistema de ecuaciones A.X=B
    coeficiente = np.linalg.solve(D,B)
    
    # Polinomio en forma simbólica
    x = sym.Symbol('x')
    polinomio = 0
    for i in range(0,n,1):
        potencia = (n-1)-i   # Derecha a izquierda
        termino = coeficiente[i]*(x**potencia)
        polinomio = polinomio + termino
    
    # Polinomio a forma Lambda x:
    # para evaluación con vectores de datos xin
    muestras = 21
    px = sym.lambdify(x,polinomio)
    
    # SALIDA
    print('Matriz Vandermonde: ')
    print(D)
    print('los coeficientes del polinomio: ')
    print(coeficiente)
    print('Polinomio de interpolación: ')
    print(polinomio)
    print('\n formato pprint')
    sym.pprint(polinomio)
    
    
    # literal b
    x1 = 2.4
    px1 = px(x1)
    fx1 = fx(x1)
    errorx1 = np.abs(px1-fx1)
    errorx1rel = errorx1/fx1
    x2 = 1.7
    px2 = px(x1)
    fx2 = fx(x1)
    errorx2 = np.abs(px1-fx1)
    errorx2rel = errorx1/fx1
    print()
    print('Evaluando en X1: ',x1)
    print('Evaluando p(x1): ',px1)
    print('Error en x1:     ',errorx1)
    print(' Error relativo: ', errorx1rel)
    print()
    print('Evaluando en X2: ',x2)
    print('Evaluando p(x2): ',px2)
    print('Error en x2:     ',errorx2)
    print(' Error relativo: ', errorx2rel)
    
    
    # GRAFICA
    import matplotlib.pyplot as plt
    a = np.min(xi)
    b = np.max(xi)
    xin = np.linspace(a,b,muestras)
    yin = px(xin)
    
    # Usando evaluación simbólica
    ##yin = np.zeros(muestras,dtype=float)
    ##for j in range(0,muestras,1):
    ##    yin[j] = polinomio.subs(x,xin[j])
    
    plt.plot(xi,fi,'o', label='[xi,fi]')
    plt.plot(xin,yin, label='p(x)')
    plt.plot(xin,fx(xin), label='f(x)')
    plt.xlabel('xi')
    plt.ylabel('fi')
    plt.legend()
    plt.title(polinomio)
    plt.show()
    

     

  • s1Eva_IIT2019_T4 Concentración de químico

    Ejercicio: 1Eva_IIT2019_T4 Concentración de químico

    formula a usar:

    C = C_{ent} ( 1 - e^{-0.04t})+C_{0} e^{-0.03t}

    Se sustituyen los valores dados con:
    C0 = 4, Cent = 10, C = 0.93 Cent.

    0.93(10) = 10 ( 1 - e^{-0.04t}) + 4 e^{-0.03t}

    igualando a cero para forma estandarizada del algoritmo,

    10( 1 - e^{-0.04t}) + 4 e^{-0.03t} - 9.3 = 0 0.7 - 10 e^{-0.04t} + 4 e^{-0.03t} = 0

    se usas las funciones f(t) y f'(t) para el método de Newton-Raphson,

    f(t) = 0.7 - 10 e^{-0.04t} + 4 e^{-0.03t} f'(t) = - 10(-0.04) e^{-0.04t} + 4(-0.03) e^{-0.03t} f'(t) = 0.4 e^{-0.04t} - 0.12 e^{-0.03t}

    con lo que se pueden realizar los cálculos de forma iterativa.

    t_{i+1} = t_i -\frac{f(t_i)}{f'(t_i)}

    De no disponer de la gráfica de f(t), y se desconoce el valor inicial para t0 se usa 0. Como no se indica la tolerancia, se estima en 10-4

    Iteración 1

    t0 = 0

    f(0) = 0.7 - 10 e^{-0.04(0)} + 4 e^{-0.03(0)} = 5.3 f'(0) = 0.4 e^{-0.04(0)} - 0.12 e^{-0.03(0)} = -0.28 t_{1} = 0 -\frac{5.3}{-0.28} = 18.92 error = |18.92-0| = 18.92

    Iteración 2

    f(18.92) = 0.7 - 10 e^{-0.04(18.92)} + 4 e^{-0.03(18.92)} = -1.72308 f'(18.92) = 0.4 e^{-0.04(18.92)} - 0.12 e^{-0.03(18.92)} = 0.119593 t_{2} = 18.92 -\frac{-1.723087}{0.119593} = 33.3365 error = |33.3365 - 18.92| = 14.4079

    Iteración 3

    f(33.3365) = 0.7 - 10 e^{-0.04(33.3365)} + 4 e^{-0.03(33.3365)} = -0.4642 f'(33.3365) = 0.4 e^{-0.04(33.3365)} - 0.12 e^{-0.03(33.3365)} = 0.06128 t_{3} = 33.3365 -\frac{-0.46427}{-5.8013} = 40.912 error = |40.912 - 33.3365| = 7.5755

    Observando que los errores disminuyen entre cada iteración, se encuentra que el método converge.

    y se forma la siguiente tabla:

    ['xi' ,  'xnuevo', 'error']
    [ 0.      18.9286  18.9286]
    [18.9286  33.3365  14.4079]
    [33.3365  40.912    7.5755]
    [40.912   42.654     1.742]
    [42.654   42.7316   0.0776]
    [4.2732e+01 4.2732e+01 1.4632e-04]
    raiz en:  42.731721341402796
    

    Observando la gráfica de la función puede observar el resultado:


    Algoritmo en Python

    # 1Eva_IIT2019_T4
    # Método de Newton-Raphson
    
    import numpy as np
    import matplotlib.pyplot as plt
    
    # INGRESO
    fx = lambda t: 0.7-10*np.exp(-0.04*t)+4*np.exp(-0.03*t)
    dfx = lambda t:0.40*np.exp(-0.04*t)-0.12*np.exp(-0.03*t)
    
    x0 = 0
    tolera = 0.001
    
    a = 0
    b = 60
    muestras = 21
    
    # PROCEDIMIENTO
    tabla = []
    tramo = abs(2*tolera)
    xi = x0
    while (tramo>=tolera):
        xnuevo = xi - fx(xi)/dfx(xi)
        tramo = abs(xnuevo-xi)
        tabla.append([xi,xnuevo,tramo])
        xi = xnuevo
    
    tabla = np.array(tabla)
    n=len(tabla)
    
    # para la gráfica
    xk = np.linspace(a,b,muestras)
    fk = fx(xk)
    
    # SALIDA
    print(['xi', 'xnuevo', 'error'])
    np.set_printoptions(precision = 4)
    for i in range(0,n,1):
        print(tabla[i])
    print('raiz en: ', xi)
    
    # grafica
    plt.plot(xk,fk)
    plt.axhline(0, color='black')
    plt.xlabel('t')
    plt.ylabel('f(t)')
    plt.show()
    
  • s1Eva_IT2019_T3 Vector perpendicular a plano

    Ejercicio: 1Eva_IT2019_T3 Vector perpendicular a plano

    Literal a

    Para que un vector sea perpendicular a otro, se debe cumplir que
    V1.V2 =0.

    \begin{bmatrix} 2 \\ -3 \\ a \end{bmatrix} . \begin{bmatrix} b \\ 1 \\ -4 \end{bmatrix} = 0

    se obtiene entonces la ecuación:

    (2)(b)+(-3)(1)+(a)(-4)=0
    2b -3 -4a =0
    

    procediendo de la misma forma con los siguientes pares de vectores:

    \begin{bmatrix} 2 \\ -3 \\ a \end{bmatrix} . \begin{bmatrix} 3 \\ c \\ 2 \end{bmatrix} = 0

    se obtiene entonces la ecuación:

    (2)(3)+(-3)(c)+(a)(2)=0
    6 -3c +2a = 0
    
    \begin{bmatrix} b \\ 1 \\ -4 \end{bmatrix} . \begin{bmatrix} 3 \\ c \\ 2 \end{bmatrix} = 2

    se obtiene entonces la ecuación:

    (b)(3)+(1)(c)+(-4)(2)=2
    3b +c -8 =2
    

    se obtiene el sistema de ecuaciones:

    \begin{cases}-4a+2b=3 \\ 2a-3c=-6 \\3b+c=10 \end{cases}

    Literal b

    Se convierte a la forma matricial Ax=B

    \begin{bmatrix} -4 && 2 && 0 \\ 2 && 0 && -3 \\ 0 && 3 && 1\end{bmatrix}.\begin{bmatrix} a \\b\\c \end{bmatrix} = \begin{bmatrix} 3 \\ -6 \\ 10 \end{bmatrix}

    se crea la matriz aumentada:

    \begin{bmatrix} -4 && 2 && 0 && 3 \\ 2 && 0 && -3 &&-6 \\ 0 && 3 && 1 && 10 \end{bmatrix}

    se pivotea por filas buscando hacerla diagonal dominante:

    \begin{bmatrix} -4 && 2 && 0 && 3 \\ 0 && 3 && 1 && 10 \\ 2 && 0 && -3 &&-6 \end{bmatrix}

    se aplica el algoritmo de eliminación hacia adelante:
    1ra Iteración

    la eliminación del primer término columna es necesario solo para la tercera fila:

    \begin{bmatrix} -4 && 2 && 0 && 3 \\ 0 && 3 && 1 && 10 \\ 2 -(-4)\Big( \frac{2}{-4}\Big) && 0-2\Big(\frac{2}{-4}\Big) && -3 -0\Big(\frac{2}{-4}\Big) &&-6 -3\Big(\frac{2}{-4}\Big) \end{bmatrix} \begin{bmatrix} -4 && 2 && 0 && 3 \\ 0 && 3 && 1 && 10 \\ 0 && 1 && -3 && -4.5 \end{bmatrix}

    2da Iteración

    \begin{bmatrix} -4 && 2 && 0 && 3 \\ 0 && 3 && 1 && 10 \\ 0 && 1 -3\Big(\frac{1}{3}\Big) && -3-(1)\Big(\frac{1}{3}\Big) && -4.5-10\Big(\frac{1}{3}\Big) \end{bmatrix} \begin{bmatrix} -4 && 2 && 0 && 3 \\ 0 && 3 && 1 && 10 \\ 0 && 0 && -\frac{10}{3} && -7.8333 \end{bmatrix}

    Aplicando eliminación hacia atras

    (-10/3)c = -7.8333
    c = -7.8333(-3/10) = 2.35
    
    3b +c = 10
    b= (10-c)/3 = (10-2.35)/3 = 2.55
    
    -4a +2b =3
    a= (3-2b)/(-4) = (3-2(2.55))/(-4) = 0.525
    

    como resultado, los vectores buscados:

    v1 = (2,-3,0.525)
    v2 = (2.55,1,-4)
    v3 = (3,2.35,2)

    comprobando resultados:

    >>> np.dot((2,-3,0.525),(2.55,1,-4))
    -4.440892098500626e-16
    >>> np.dot((2,-3,0.525),(3,2.35,2))
    -6.661338147750939e-16
    >>> np.dot((2.55,1,-4),(3,2.35,2))
    2.0
    

    Los dos primeros resultados son muy cercanos a cero, por lo que se los considera válidos

    literal c

    Para usar el método de Jacobi, se despeja una de las variables de cada ecuación:

    \begin{cases} a = \frac{2b -3}{4} \\b = \frac{10-c}{3} \\c = \frac{2a+6}{3} \end{cases}

    usando el vector x(0) = [0,0,0]

    1ra iteración

    a = \frac{2b -3}{4} = \frac{2(0) -3}{4} = -\frac{3}{4} b = \frac{10-c}{3} = \frac{10-0}{3} = \frac{10}{3} c = \frac{2a+6}{3 }= \frac{2(0)+6}{3} = 2

    x(1) = [-3/4,10/3,2]
    diferencias = [-3/4-0,10/3-0,2-0] = [-3/4,10/3,2]
    error = max|diferencias| = 10/3 = 3.3333

    2da iteración

    a = \frac{2b -3}{4} = \frac{2(10/3) -3}{4} = \frac{11}{12} b = \frac{10-c}{3} = \frac{10-2}{3} = \frac{8}{3} c = \frac{2a+6}{3} = \frac{2(-3/4)+6}{3} = \frac{3}{2}

    x(2) = [11/12,8/3,3/2]
    diferencias = [11/12-(-3/4),8/3-10/3,3/2-2] = [20/12, -2/3, -1/2]
    error = max|diferencias| = 5/3= 1.666

    3ra iteración

    a = \frac{2b -3}{4} = \frac{2(8/3)-3}{4} = \frac{7}{12} b = \frac{10-c}{3} = \frac{10-3/2}{3} = \frac{17}{6} c = \frac{2a+6}{3} = \frac{2(11/12)+6}{3} = 2.6111

    x(3) = [7/12, 17/6, 2.6111]
    diferencias = [7/12-11/12, 17/6-8/3, 2.6111-3/2] = [-1/3, 1/6, 1.1111]
    error = max|diferencias| = 1.1111

    Los errores disminuyen en cada iteración, por lo que el método converge,
    si se analiza en número de condición de la matriz A es 2, lo que es muy cercano a 1, por lo tanto el método converge.


    Revisión de resultados

    Resultados usando algoritmos desarrollados en clase:

    matriz aumentada: 
    [[-4.   2.   0.   3. ]
     [ 0.   3.   1.  10. ]
     [ 2.   0.  -3.  -6. ]]
    Elimina hacia adelante
    [[-4.   2.   0.   3. ]
     [ 0.   3.   1.  10. ]
     [ 0.   1.  -3.  -4.5]]
    Elimina hacia adelante
    [[-4.   2.   0.        3.      ]
     [ 0.   3.   1.       10.      ]
     [ 0.   0.  -3.333333 -7.833333]]
    Elimina hacia adelante
    [[-4.   2.   0.        3.      ]
     [ 0.   3.   1.       10.      ]
     [ 0.   0.  -3.333333 -7.833333]]
    Elimina hacia atras
    [[ 1.  -0.  -0.   0.525]
     [ 0.   1.   0.   2.55 ]
     [-0.  -0.   1.   2.35 ]]
    el vector solución X es:
    [[0.525]
     [2.55 ]
     [2.35 ]]
    verificar que A.X = B
    [[ 3.]
     [10.]
     [-6.]]
    
    Número de condición de A: 2.005894
    
    los resultados para [a,b,c]:
    [0.525 2.55  2.35 ]
    
    producto punto entre vectores:
    v12:  0.0
    v13:  1.3322676295501878e-15
    v23:  2.0
    

    Algoritmos en Python:

    # 1Eva_IT2019_T3 Vector perpendicular a plano
    import numpy as np
    
    # INGRESO
    A = np.array([[-4.,2,0],
                  [ 0., 3,1],
                  [ 2.,0,-3]])
    B = np.array([3.,10,-6])
    
    # PROCEDIMIENTO
    B = np.transpose([B])
    
    casicero = 1e-15 # 0
    AB = np.concatenate((A,B),axis=1)
    tamano = np.shape(AB)
    n = tamano[0]
    m = tamano[1]
    
    print('matriz aumentada: ')
    print(AB)
    # Gauss elimina hacia adelante
    # tarea: verificar términos cero
    for i in range(0,n,1):
        pivote = AB[i,i]
        adelante = i+1 
        for k in range(adelante,n,1):
            if (np.abs(pivote)>=casicero):
                factor = AB[k,i]/pivote
                AB[k,:] = AB[k,:] - factor*AB[i,:]
        print('Elimina hacia adelante')
        print(AB)
    
    # Gauss-Jordan elimina hacia atras
    ultfila = n-1
    ultcolumna = m-1
    for i in range(ultfila,0-1,-1):
        # Normaliza a 1 elemento diagonal
        AB[i,:] = AB[i,:]/AB[i,i]
        pivote = AB[i,i] # uno
        # arriba de la fila i
        atras = i-1 
        for k in range(atras,0-1,-1):
            if (np.abs(AB[k,i])>=casicero):
                factor = pivote/AB[k,i]
                AB[k,:] = AB[k,:]*factor - AB[i,:]
            else:
                factor= 'division para cero'
    print('Elimina hacia atras')
    print(AB)
    
    X = AB[:,ultcolumna]
    
    # Verifica resultado
    verifica = np.dot(A,X)
    
    # SALIDA
    print('el vector solución X es:')
    print(np.transpose([X]))
    
    print('verificar que A.X = B')
    print(np.transpose([verifica]))
    
    numcond = np.linalg.cond(A)
    
    # para comprobar respuestas
    
    v1 = [2,-3,X[0]]
    v2 = [X[1],1,-4]
    v3 = [3,X[2],2]
    
    v12 = np.dot(v1,v2)
    v13 = np.dot(v1,v3)
    v23 = np.dot(v2,v3)
          
    # SALIDA
    print('\n Número de condición de A: ', numcond)
    
    print('\n los resultados para [a,b,c]:')
    print(X)
    
    print('\n productos punto entre vectores:')
    print('v12: ',v12)
    print('v13: ',v13)
    print('v23: ',v23)
    

    Tarea, usar el algoritmo de Jacobi usado en el taller correspondiente.

  • s1Eva_IT2019_T2 Catenaria cable

    Ejercicio: 1Eva_IT2019_T2 Catenaria cable

    Las fórmulas con las que se requiere trabajar son:

    y = \frac{T_A}{w} cosh \Big( \frac{w}{T_A}x \Big) + y_0 - \frac{T_A}{w}

    Donde la altura y del cable está en función de la distancia x.

    Además se tiene que:

    cosh(z) = \frac{e^z+ e^{-z}}{2}

    que sustituyendo la segunda en la primera se convierte en:

    y = \frac{T_A}{w} \frac{e^{\frac{w}{T_A}x}+ e^{-\frac{w}{T_A}x}}{2} + y_0 - \frac{T_A}{w}

    y usando los valores del enunciado w=12, y0=6 , y=15, x=50 se convierte en:

    15 = \frac{T_A}{12} \frac{e^{\frac{12}{T_A}50}+ e^{-\frac{12}{T_A}50}}{2} + 6 - \frac{T_A}{12}

    simplificando, para usar el método de búsqueda de raíces:

    \frac{1}{2}\frac{T_A}{12} e^{\frac{12}{T_A}50} + \frac{1}{2}\frac{T_A}{12} e^{-\frac{12}{T_A}50} - \frac{T_A}{12} - 9 = 0

    cambiando la variable \frac{12}{T_A}=x

    \frac{1}{2x} e^{50x} + \frac{1}{2x} e^{-50x} - \frac{1}{x}-9=0

    la función a usar para la búsqueda de raíces es:

    f(x)=\frac{1}{2x} e^{50x} + \frac{1}{2x} e^{-50x} - \frac{1}{x}-9

    Para el método de Newton-Raphson se tiene que:

    x_{i+1} = x_i -\frac{f(x_i)}{f'(x_i)}

    por lo que se determina:

    f'(x)= - \frac{1}{2x^2}e^{50x} + \frac{1}{2x}(50) e^{50x} + - \frac{1}{2x^2} e^{-50x} + \frac{1}{2x}(-50)e^{-50x} + \frac{1}{x^2} f'(x)= -\frac{1}{2x^2}[e^{50x}+e^{-50x}] + + \frac{25}{x}[e^{50x}-e^{-50x}] +\frac{1}{x^2} f'(x)= \Big[\frac{25}{x} -\frac{1}{2x^2}\Big]\Big[e^{50x}+e^{-50x}\Big] +\frac{1}{x^2}

    Con lo que se puede inicar las iteraciones.

    Por no disponer de valor inicial para TA, considere que el cable colgado no debería tener tensión TA=0 N, pues en la forma x=12/TA se crea una indeterminación. Si no dispone de algún criterio para seleccionar el valor de TA puede iniciar un valor positivo, por ejemplo 120 con lo que el valor de x0=12/120=0.1

    Iteración 1

    f(0.1)=\frac{1}{2(0.1)} e^{50(0.1)} + \frac{1}{2(0.1)} e^{-50(0.1)} - \frac{1}{0.1}-9 =723.0994 f'(0.1)=\Big[\frac{25}{0.1} - \frac{1}{2(0.1)^2}\Big]\Big[e^{50(0.1)}+e^{-50(0.1)}\Big] + +\frac{1}{(0.1)^2} = 29780.61043 x_{1} = 0.1 -\frac{723.0994}{29780.61043} = 0.07571

    error = | x1 - x0| = | 0.07571 - 0.1| = 0.02428

    Iteración 2

    f(0.07571)=\frac{1}{2(0.07571)} e^{50(0.07571)}+ + \frac{1}{2(0.07571)} e^{-50(0.07571)} - \frac{1}{0.07571}-9 = 269.0042 f'(0.07571)= \Big[\frac{25}{0.07571} -\frac{1}{2(0.07571)^2}\Big]. .\Big[e^{50(0.07571)}+e^{-50(0.07571)}\Big] + +\frac{1}{(0.07571)^2} = 10874.0462 x_{2} = 0.07571 -\frac{269.0042}{10874.0462} = 0.05098

    error = | x2 - x1| = |0.05098- 0.02428| = 0.02473

    Iteración 3

    f(0.05098) = 97.6345 f'(0.05098) = 4144.1544 x_{3} = 0.0274

    error = | x3 - x2| = |0.05098- 0.0274| = 0.0236

    finalmente después de varias iteraciones, la raiz se encuentra en: 0.007124346154337298

    que convitiendo

    T_A = \frac{12}{x} = \frac{12}{0.0071243461} = 1684.36 N

    Revisión de resultados

    Usando como base los algoritmos desarrollados en clase:

    ['xi', 'xnuevo', 'tramo']
    [0.1    0.0757 0.0243]
    [0.0757 0.051  0.0247]
    [0.051  0.0274 0.0236]
    [0.0274 0.0111 0.0163]
    [0.0111 0.0072 0.0039]
    [7.2176e-03 7.1244e-03 9.3199e-05]
    [7.1244e-03 7.1243e-03 3.8351e-08]
    raiz en:  0.007124346154337298
    TA = 12/x =  1684.365096815854
    

    catenaria cable

    Algoritmos Python usando el procedimiento de:

    https://blog.espol.edu.ec/analisisnumerico/2-3-1-newton-raphson-ejemplo01/

    # 1Eva_IT2019_T2 Catenaria cable
    import numpy as np
    import matplotlib.pyplot as plt
    
    # INGRESO
    a = 0.001
    b = 0.1
    muestras = 51
    
    x0 = 0.1
    tolera = 0.00001
    
    fx = lambda x: 0.5*(1/x)*np.exp(50*x) + 0.5*(1/x)*np.exp(-50*x)-1/x -9
    dfx = lambda x: -0.5*(1/(x**2))*(np.exp(50*x)+np.exp(-50*x)) + (25/x)*(np.exp(50*x)-np.exp(-50*x)) + 1/(x**2)
    
    # PROCEDIMIENTO
    tabla = []
    tramo = abs(2*tolera)
    xi = x0
    while (tramo>=tolera):
        xnuevo = xi - fx(xi)/dfx(xi)
        tramo = abs(xnuevo-xi)
        tabla.append([xi,xnuevo,tramo])
        xi = xnuevo
    
    tabla = np.array(tabla)
    n=len(tabla)
    
    TA = 12/xnuevo
    
    # para la gráfica
    xp = np.linspace(a,b,muestras)
    fp = fx(xp)
    
    # SALIDA
    print(['xi', 'xnuevo', 'tramo'])
    np.set_printoptions(precision = 4)
    for i in range(0,n,1):
        print(tabla[i])
    print('raiz en: ', xi)
    print('TA = 12/x = ', TA)
    
    # Grafica
    plt.plot(xp,fp)
    plt.xlabel('x=12/TA')
    plt.ylabel('f(x)')
    plt.axhline(0, color = 'green')
    plt.grid()
    plt.show()
    
  • s1Eva_IT2019_T1 Oxígeno y temperatura en agua

    Ejercicio: 1Eva_IT2019_T1 Oxígeno y temperatura en agua

    Literal a

    Se requiere un polinomio de grado 3 siendo el eje x correspondiente a temperatura. Son necesarios 4 puntos de referencia alrededor de 15 grados, dos a la izquierda y dos a la derecha.

    Se observa que los datos en el eje x son equidistantes, h=8, y ordenados en forma ascendente, se cumple con los requisitos para usar diferencias finitas avanzadas. que tiene la forma de:

    p_n (x) = f_0 + \frac{\Delta f_0}{h} (x - x_0) + + \frac{\Delta^2 f_0}{2!h^2} (x - x_0)(x - x_1) + + \frac{\Delta^3 f_0}{3!h^3} (x - x_0)(x - x_1)(x - x_2) + \text{...}

    Tabla

    xi f[xi] f[x1,x0] f[x2,x1,x0] f[x2,x1,x0] f[x3,x2,x1,x0]
    8 11.5 9.9-11.5=
    -1.6
    -1.5-(-1.6) =
    0.1
    0.4-0.1=
    0.3
    ---
    16 9.9 8.4-9.9=
    -1.5
    -1.1-(1.5)=
    0.4
    --- ---
    24 8.4 7.3-8.4=
    -1.1
    --- --- ---
    32 7.3 --- --- --- ---

    Con lo que el polinomio buscado es:

    p_3 (x) = 11.5 + \frac{-1.6}{8} (x - 8) + + \frac{0.1}{2!8^2} (x - 8)(x - 16) + \frac{0.3}{3!8^3} (x - 8)(x - 16)(x - 24)

    Resolviendo y simplificando el polinomio, se puede observar que al aumentar el grado, la constante del término disminuye.

    p_3(x)=12.9- 0.15 x - 0.00390625 x^2 + 0.00009765625 x^3

    para el cálculo del error se puede usar un término adicional del polinomio, añadiendo un punto más a la tabla de diferencia finitas. Se evalúa éste término y se estima el error que dado que el término de grado 3 es del orden de 10-5, el error será menor. (Tarea)

    p_3(15)=12.9- 0.15 (15) - 0.00390625 (15)^2 + 0.00009765625 (15)^3

    Evaluando el polinomio en temperatura = 15:

    p3(15) = 10.1006835937500

    literal b

    se deriva el polinomio del literal anterior y se evalúa en 16:

    p'_3(x)=0- 0.15 - 0.00390625 (2) x + 0.00009765625 (3)x^2 p'_3(16)=0- 0.15 - 0.00390625 (2)(16) + 0.00009765625 (3)(16)^2

    p'3(16) = -0.20

    literal c

    El valor de oxígeno usado como referencia es 9, cuyos valores de temperatura se encuentran entre 16 y 24 que se toman como rango inicial de búsqueda [a,b]. Por lo que el polinomio se iguala a 9 y se crea la forma estandarizada del problema:

    p_3(x)=9 9 = 12.9- 0.15 x - 0.00390625 x^2 + 0.00009765625 x^3 12.9- 0.15 x - 0.00390625 x^2 + 0.00009765625 x^3 -9 = 0 f(x) = 3.9- 0.15 x - 0.00390625 x^2 + 0.00009765625 x^3

    Para mostrar el procedimiento se realizan solo tres iteraciones,

    1ra Iteración
    a=16 , b = 24, c = (16+24)/2 = 20
    f(a) = 0.9, f(b) = -0.6, f(c) = 0.011
    error = |24-16| = 8
    como f(c) es positivo, se mueve el extremo f(x) del mismo signo, es decir a

    2da Iteración
    a=20 , b = 24, c = (20+24)/2 = 22
    f(a) = 0.119, f(b) = -0.6, f(c) = -0.251
    error = |24-20|= 4
    como f(c) es negativo, se mueve el extremo f(x) del mismo signo, b

    3ra Iteración
    a=20 , b = 22, c = (20+22)/2 = 21
    f(a) = 0.119, f(b) = -0.251, f(c) = -0.068
    error = |22-20| = 2
    como f(c) es negativo, se mueve el extremo f(x) del mismo signo, b
    y así sucesivamente hasta que error< que 10-3

    Usando el algoritmo en python se obtendrá la raiz en 20.632 con la tolerancia requerida.


    Revisión de resultados

    Usando como base los algoritmos desarrollados en clase:

    oxigeno Temperatura p3

    tabla de diferencias finitas
    ['i', 'xi', 'fi', 'df1', 'df2', 'df3', 'df4']
    [[ 0.   8.  11.5 -1.6  0.1  0.3  0. ]
     [ 1.  16.   9.9 -1.5  0.4  0.   0. ]
     [ 2.  24.   8.4 -1.1  0.   0.   0. ]
     [ 3.  32.   7.3  0.   0.   0.   0. ]]
    dfinita:  [-1.6  0.1  0.3  0. ]
    11.5 +
    +( -1.6 / 8.0 )* ( x - 8.0 )
    +( 0.1 / 128.0 )*  (x - 16.0)*(x - 8.0) 
    +( 0.3 / 3072.0 )*  (x - 24.0)*(x - 16.0)*(x - 8.0) 
    polinomio simplificado
    9.8e-5*x**3 - 0.003923*x**2 - 0.149752*x + 12.898912
    Literal a
    9.8e-5*x**3 - 0.003923*x**2 - 0.149752*x + 12.898912
    p(15) =  10.1007070000000
    
    Literal b
    0.000294*x**2 - 0.007846*x - 0.149752
    dp(16) = -0.200024000000000
    método de Bisección
    i ['a', 'c', 'b'] ['f(a)', 'f(c)', 'f(b)']
       tramo
    0 [16, 20.0, 24] [ 0.9     0.1187 -0.6   ]
       4.0
    1 [20.0, 22.0, 24] [ 0.1187 -0.2509 -0.6   ]
       2.0
    2 [20.0, 21.0, 22.0] [ 0.1187 -0.0683 -0.2509]
       1.0
    3 [20.0, 20.5, 21.0] [ 0.1187  0.0246 -0.0683]
       0.5
    4 [20.5, 20.75, 21.0] [ 0.0246 -0.022  -0.0683]
       0.25
    5 [20.5, 20.625, 20.75] [ 0.0246  0.0013 -0.022 ]
       0.125
    6 [20.625, 20.6875, 20.75] [ 0.0013 -0.0104 -0.022 ]
       0.0625
    7 [20.625, 20.65625, 20.6875] [ 0.0013 -0.0045 -0.0104]
       0.03125
    8 [20.625, 20.640625, 20.65625] [ 0.0013 -0.0016 -0.0045]
       0.015625
    9 [20.625, 20.6328125, 20.640625] [ 0.0013 -0.0002 -0.0016]
       0.0078125
    10 [20.625, 20.62890625, 20.6328125] [ 0.0013  0.0006 -0.0002]
       0.00390625
    11 [20.62890625, 20.630859375, 20.6328125] [ 0.0006  0.0002 -0.0002]
       0.001953125
    12 [20.630859375, 20.6318359375, 20.6328125] [ 1.9762e-04  1.5502e-05 -1.6661e-04]
       0.0009765625
    raíz en:  20.6318359375
    

    Algoritmos Python usando la función de interpolación y un procedimiento encontrado en:

    Interpolación por Diferencias finitas avanzadas

    Método de la Bisección – Ejemplo con Python

    # 1Eva_IT2019_T1 Oxígeno y temperatura en mar
    import numpy as np
    import math
    import matplotlib.pyplot as plt
    import sympy as sym
    
    def interpola_dfinitasAvz(xi,fi, vertabla=False,
                           precision=6, casicero = 1e-15):
        '''Interpolación de diferencias finitas
        resultado: polinomio en forma simbólica,
        redondear a cero si es menor que casicero 
        '''
        xi = np.array(xi,dtype=float)
        fi = np.array(fi,dtype=float)
        n = len(xi)
        # revisa tamaños de paso equidistantes
        h_iguales = pasosEquidistantes(xi, casicero)
        if vertabla==True:
            np.set_printoptions(precision)
        # POLINOMIO con diferencias Finitas avanzadas
        x = sym.Symbol('x')
        polisimple = sym.S.Zero # expresión del polinomio con Sympy
        if h_iguales==True:
            tabla,titulo = dif_finitas(xi,fi,vertabla)
            h = xi[1] - xi[0]
            dfinita = tabla[0,3:]
            if vertabla==True:
                print('dfinita: ',dfinita)
                print(fi[0],'+')
            n = len(dfinita)
            polinomio = fi[0]
            for j in range(1,n,1):
                denominador = math.factorial(j)*(h**j)
                factor = np.around(dfinita[j-1]/denominador,precision)
                termino = 1
                for k in range(0,j,1):
                    termino = termino*(x-xi[k])
                if vertabla==True:
                    txt1='';txt2=''
                    if n<=2 or j<=1:
                        txt1 = '('; txt2 = ')'
                    print('+(',np.around(dfinita[j-1],precision),
                          '/',np.around(denominador,precision),
                          ')*',txt1,termino,txt2)
                polinomio = polinomio + termino*factor
            # simplifica multiplicando entre (x-xi)
            polisimple = polinomio.expand() 
        if vertabla==True:
            print('polinomio simplificado')
            print(polisimple)
        return(polisimple)
    
    def dif_finitas(xi,fi, vertabla=False):
        '''Genera la tabla de diferencias finitas
        resultado en: [título,tabla]
        Tarea: verificar tamaño de vectores
        '''
        xi = np.array(xi,dtype=float)
        fi = np.array(fi,dtype=float)
        # Tabla de Diferencias Finitas
        titulo = ['i','xi','fi']
        n = len(xi)
        ki = np.arange(0,n,1)
        tabla = np.concatenate(([ki],[xi],[fi]),axis=0)
        tabla = np.transpose(tabla)
        # diferencias finitas vacia
        dfinita = np.zeros(shape=(n,n),dtype=float)
        tabla = np.concatenate((tabla,dfinita), axis=1)
        # Calcula tabla, inicia en columna 3
        [n,m] = np.shape(tabla)
        diagonal = n-1
        j = 3
        while (j < m):
            # Añade título para cada columna
            titulo.append('df'+str(j-2))
            # cada fila de columna
            i = 0
            while (i < diagonal):
                tabla[i,j] = tabla[i+1,j-1]-tabla[i,j-1]
                i = i+1
            diagonal = diagonal - 1
            j = j+1
        if vertabla==True:
            print('tabla de diferencias finitas')
            print(titulo)
            print(tabla)
        return(tabla, titulo)
    
    def pasosEquidistantes(xi, casicero = 1e-15):
        ''' Revisa tamaños de paso h en vector xi.
        True:  h son equidistantes,
        False: h tiene tamaño de paso diferentes y dónde.
        '''
        xi = np.array(xi,dtype=float)
        n = len(xi)
        # revisa tamaños de paso equidistantes
        h_iguales = True
        if n>3: 
            dx = np.zeros(n,dtype=float)
            for i in range(0,n-1,1): # calcula hi como dx
                dx[i] = xi[i+1]-xi[i]
            for i in range(0,n-2,1): # revisa diferencias
                dx[i] = dx[i+1]-dx[i]
                if dx[i]<=casicero: # redondea cero
                    dx[i]=0
                if abs(dx[i])>0:
                    h_iguales=False
                    print('tamaños de paso diferentes en i:',i+1,',',i+2)
            dx[n-2]=0
        return(h_iguales)
    
    # PROGRAMA ----------------
    
    # INGRESO
    tm = [0.,8,16,24,32,40]
    ox = [14.6,11.5,9.9,8.4,7.3,6.4]
    
    xi = [8,16,24,32]
    fi = [11.5,9.9,8.4,7.3]
    
    # PROCEDIMIENTO
    x = sym.Symbol('x')
    # literal a
    polinomio = interpola_dfinitasAvz(xi,fi, vertabla=True)
    p15 = polinomio.subs(x,15)
    # literal b
    derivap = polinomio.diff(x,1)
    dp16 = derivap.subs(x,16)
    
    px =  sym.lambdify(x,polinomio)
    xk = np.linspace(np.min(xi),np.max(xi))
    pk = px(xk)
    
    # SALIDA
    print('Literal a')
    print(polinomio)
    print('p(15) = ',p15)
    print('Literal b')
    print(derivap)
    print('dp(16) =', dp16)
    
    # gráfica
    plt.plot(tm,ox,'ro')
    plt.plot(xk,pk)
    plt.axhline(9,color="green")
    plt.xlabel('temperatura')
    plt.ylabel('concentracion de oxigeno')
    plt.grid()
    plt.show()
    
    # --------literal c ------------
    
    def biseccion(fx,a,b,tolera,iteramax = 20, vertabla=False, precision=4):
        '''
        Algoritmo de Bisección
        Los valores de [a,b] son seleccionados
        desde la gráfica de la función
        error = tolera
        '''
        fa = fx(a)
        fb = fx(b)
        tramo = np.abs(b-a)
        itera = 0
        cambia = np.sign(fa)*np.sign(fb)
        if cambia<0: # existe cambio de signo f(a) vs f(b)
            if vertabla==True:
                print('método de Bisección')
                print('i', ['a','c','b'],[ 'f(a)', 'f(c)','f(b)'])
                print('  ','tramo')
                np.set_printoptions(precision)
                
            while (tramo>=tolera and itera<=iteramax):
                c = (a+b)/2
                fc = fx(c)
                cambia = np.sign(fa)*np.sign(fc)
                if vertabla==True:
                    print(itera,[a,c,b],np.array([fa,fc,fb]))
                if (cambia<0):
                    b = c
                    fb = fc
                else:
                    a = c
                    fa = fc
                tramo = np.abs(b-a)
                if vertabla==True:
                    print('  ',tramo)
                itera = itera + 1
            respuesta = c
            # Valida respuesta
            if (itera>=iteramax):
                respuesta = np.nan
    
        else: 
            print(' No existe cambio de signo entre f(a) y f(b)')
            print(' f(a) =',fa,',  f(b) =',fb) 
            respuesta=np.nan
        return(respuesta)
    # se convierte forma de símbolos a numéricos
    buscar = polinomio-9
    fx = sym.lambdify(x,buscar)
    
    # INGRESO
    a = 16
    b = 24
    tolera = 0.001
    
    # PROCEDIMIENTO
    respuesta = biseccion(fx,a,b,tolera,vertabla=True)
    
    # SALIDA
    print('raíz en: ', respuesta)
    
  • s1Eva_IIT2018_T4 Tasa de interés en hipoteca

    Ejercicio: 1Eva_IIT2018_T4 Tasa de interés en hipoteca

    literal a

    Siguiendo el desarrollo analítico tradicional, para adecuar la ecuación para los algoritmo de búsquda de raíces de ecuaciones,  se reemplazan los valores en la fórmula.

    P = A\Big(\frac{1-(1+i)^{-n}}{i} \Big) 70000 = 1200\Big(\frac{1-(1+i)^{-300}}{i} \Big)

    Como ambos lados de la ecuación deben ser iguales, si se restan ambos se obtiene una ecuación que tiene como resultado cero, que es la forma ideal para usar en el algoritmo que representa f(x) o en este caso f(i)

    70000 - 1200\Big(\frac{1-(1+i)^{-300}}{i} \Big) = 0

    Para evitar inconvenientes con la división para cero en caso que i tome el valor de cero, dado se multiplica toda la ecuación por i:

    i \Big[70000 - 1200\Big(\frac{1-(1+i)^{-300}}{i} \Big) \Big]= i (0) 70000 i - 1200 (1-(1+i)^{-300}) = 0

    La ecuación es la utilizada en el algoritmo de búsqueda de raíces pueden ser:

    fx(i) = 70000 - 1200\Big(\frac{1-(1+i)^{-300}}{i} \Big) fx(i) = 70000i - 1200(1-(1+i)^{-300})

    literal b

    El intervalo de existencia correspondería a la tasa de interés mínimo y el interés máximo.

    [izquierda, derecha] = [a,b]

    Para el intervalo se deben tomar en cuenta algunas consideraciones descritas a continuación:

    izquierda:

    En el extremo izquierdo, las tasas no son negativas, lo que se interpreta en que un banco paga por que le presten dinero.

    Tampoco tiene mucho sentido el valor cero, que son prestamos sin intereses. A menos que sean sus padres quienes le dan el dinero.

    Un valor inicial para el interés puede ser por ejemplo 1% ó 0.01, siempre que se cumpla que existe cambio de signo en la función a usar.

    derecha:

    En el extremo derecho, si se propone por ejemplo i con 100%, o 1.00, no tendría mucho sentido un préstamo con intereses al 100% anual, que resulta en el doble del valor inicial en tan solo un periodo o año.

    La tasa de interés de consumo que son de las más alto valor, se encuentran reguladas. En Ecuador es un valor alrededor del 16% anuales o 0.16.

    Considerando las observaciones iniciales del problema, se propone empezar el análisis para la búsqueda de la raíz en el intervalo en un rango más amplio:

    [ 0.01, 0.50]

    Ser realiza la comprobación que existe cambio de signo en los extremos del intervalo.

    fx(0.001) =- 43935.86

    fx(0.50) = 67600.0

    Para el ejercicio se hace notar que la es tasa nominal anual, pero los pagos son mensuales. Por lo que se debe unificar las tasas de interes a mensuales. Una aproximación es usar las tasas anuales divididas para los 12 meses del año.

    Tolerancia al error

    La tolerancia se considera en éste ejercicio como el valor de diferencias  (tramo) entre iteraciones con precisión satisfactoria.

    Por ejemplo si no negociaremos más con el banco por variaciones de tasas del 0.1% , entonces la tolerancia será de 0.001.

    Las publicaciones de tasas en el mercado incluyen dos decimales, por lo que para el ejercicio aumentamos la precisión a : 0.0001

    tolera = 1x10-4


    Literal c


    Se presentan dos formas se solución para el litera c:

    - c.1 la requerida en el enunciado con Newton-Raphson

    - c.2 una alterna con el método de la Bisección.


    c.1. Desarrollo del ejercicio con el método del enunciado Newton-Raphson


    Para el método de Newton-Raphson se tiene que:

    x_{i+1} = x_{i} - \frac{f(x_0i)}{f'(x_i)}

    Se requiere la derivada de la función planteada en el literal a:

    fx(i) = 70000i - 1200(1-(1+i)^{-300}) f'x(i) = 70000 + 1200(300)(1+i)^{-301})

    tomando como valor inicial xi = 0.16/12 ≈ 0.013

    Se realizan las iteraciones suponiendo que tolera = 1x10-4

    iteración 1

    fx(0.013) = 70000(0.013) - 1200(1-(1+0.013)^{-300})

     = -265.09

    f'x(0.013) = 70000 + 1200(300)(1+0.013)^{-301})

    = 62623.3

    x_{2} = 0.013 - \frac{-265.09}{62623.34} = 0.017233

    error = |0.013 - 0.01723| = 0.004331

    iteración 2

    fx(0.01723) = 70000i - 1200(1-(1+0.0.01723)^{-300})

    = 13.446

    f'x(0.01723) = 70000 + 1200(300)(1+0.01723)^{-301}

    = 67897.5

    x_{3} = 0.017233 - \frac{13.446}{67897.5} = 0.017031

    error = |0.017233 - 0.017031| = 0.000198

    cuyo valor de error está casi dentro del valor de tolerancia,

    que permite tomar el último valor como respuesta de tasa mensual

    raiz = tasa mensual = 0.01703

    Convirtiendo a la tasa tasa anual que es la publicada por las instituciones financieras se tiene que:

    tasa anual nominal =  0.01703*12 = 0.2043

    Teniendo como resultado una tasa anual de 20.43%

    E2_IIT2018_T4 Tasa Interes Hipoteca 01


    Algoritmo en Python

    El resultado con el algoritmo es:

    método de Newton-Raphson
    i ['xi', 'fi', 'dfi', 'xnuevo', 'tramo']
    0 [ 1.30000e-02 -2.65091e+02  6.26233e+04  1.72331e-02  4.23311e-03]
    1 [1.72331e-02 1.34468e+01 6.78975e+04 1.70351e-02 1.98045e-04]
    2 [1.70351e-02 1.24433e-02 6.77706e+04 1.70349e-02 1.83609e-07]
    raiz encontrada en:  0.017034880749732726
    tasa anual:  0.20441856899679273

    Instrucciones en Python

    # 1ra Evaluación II Término 2018
    # Tema 4. Tasa de interes para hipoteca
    import numpy as np
    
    def newton_raphson(fx,dfx,xi, tolera, iteramax=100,
                       vertabla=False, precision=4):
        '''fx y dfx en forma numérica lambda
        xi es el punto inicial de búsqueda
        '''
        itera=0
        tramo = abs(2*tolera)
        if vertabla==True:
            print('método de Newton-Raphson')
            print('i', ['xi','fi','dfi', 'xnuevo', 'tramo'])
            np.set_printoptions(precision)
        while (tramo>=tolera):
            fi = fx(xi)
            dfi = dfx(xi)
            xnuevo = xi - fi/dfi
            tramo = abs(xnuevo-xi)
            if vertabla==True:
                print(itera,np.array([xi,fi,dfi,xnuevo,tramo]))
            xi = xnuevo
            itera = itera + 1
    
        if itera>=iteramax:
            xi = np.nan
            print('itera: ',itera,
                  'No converge,se alcanzó el máximo de iteraciones')
    
        return(xi)
    
    # INGRESO
    P = 70000.00
    A = 1200.00
    n = 25*12
    fx  = lambda i: P*i - A*(1-(1+i)**(-n))
    dfx = lambda i: P + A*(-n)*(i+1)**(-n-1)
    
    x0 = 0.013 # 0.16/12
    tolera = 0.0001
    
    # PROCEDIMIENTO
    raiz   = newton_raphson(fx, dfx, x0, tolera, vertabla=True, precision=5)
    tanual = 12*raiz
    
    # SALIDA
    print('raiz encontrada en: ', raiz)
    print('tasa anual: ',tanual)
    
    # GRAFICA
    import matplotlib.pyplot as plt
    a = 0.01/12
    b = 0.25/12
    muestras = 21
    
    tasa = np.linspace(a,b,muestras)
    fi   = fx(tasa)
    
    plt.plot(tasa*12,fi, label="tasa anual")
    plt.axhline(0, color='green')
    plt.title('tasa anual de interes para Hipoteca')
    plt.xlabel('tasa')
    plt.ylabel('fx(tasa)')
    plt.grid()
    plt.legend()
    plt.show()
    

    c.2. Desarrollo con el método de la Bisección


    Desarrollo Analítico con Bisección

    Como parte del desarrollo del ejercicio se presenta las iteraciones para el algoritmo, tradicionalmente realizadas con una calculadora.

    fx(i) = 70000 - 1200\Big(\frac{1-(1+i)^{-300}}{i} \Big)

    iteración 1

    a = 0.01, b = 0.5 c = \frac{a+b}{2} = \frac{0.01+0.5}{2} = 0.255 fx(0.01) = 70000 - 1200\Big(\frac{1-(1+(0.01))^{-300}}{0.01} \Big) = -43935.86 fx(0.255) = 70000 - 1200\Big(\frac{1-(1+(0.255))^{-300}}{0.255} \Big) = 65294.11 fx(0.5) = 70000 - 1200\Big(\frac{1-(1+(0.5))^{-300}}{0.5} \Big) = 67600.0 tramo = 0.5-0.01 =0.49

    cambio de signo a la izquierda

    a = 0.01, b=0.255

    iteración 2

    c = \frac{a+b}{2} = \frac{0.01+0.225}{2} = 0.1325 fx(0.1325) = 70000 - 1200\Big(\frac{1-(1+(0.1325))^{-300}}{0.1325} \Big) = 60943.39 tramo = 0.225-0.01 =0.215

    cambio de signo a la izquierda

    a = 0.01, b=0.1325

    iteración 3

    c = \frac{a+b}{2} = \frac{0.01+0.1325}{2} = 0.07125 fx(0.07125) = 70000 - 1200\Big(\frac{1-(1+(0.07125))^{-300}}{0.07125} \Big) = 53157.89 tramo = 0.1325-0.01 =0.1225

    cambio de signo a la izquierda

    a = 0.01, b=0.07125

    y se continuaría con las iteraciones, hasta cumplir que tramo<=tolera

    Tabla de datos obtenidos

    tabla para Bisección
    i a c b f(a) f(c) f(b) tramo
    1 0.01 0.255 0.5 -43935.86 65294.11 67600.0 0.49
    2 0.01 0.1325 0.255 -43935.86 60943.39 65294.11 0.215
    3 0.01 0.07125 0.1325 -43935.86 53157.89 60943.39 0.1225

    hasta lo calculado la raiz se encontraría en el intervalo [0.01,0.07125] con error estImado de 0.06125, aún por mejorar con más iteraciones.

    Algoritmo en Python para Bisección

    • El algoritmo bisección usa las variables a y b, por lo que los limites en el intervalo usados son [La,Lb]
    • para el problema la variable 'i' se usa en el eje x.
    • La selección de cambio de rango [a,b] se hace usando solo el signo del valor.
    • El algoritmo presentado es tal como se explica en la parte conceptual

    Se deja como tarea convertir el algoritmo a funcion def-return de Python.

    # 1Eva_IIT2018_T4 Tasa de interés en hipoteca
    import numpy as np
    import matplotlib.pyplot as plt
    
    # INGRESO
    P = 70000.00
    A = 1200.00
    n = 25*12
    fi = lambda i: P - A*(1-((1+i)**-n))/i
    
    # Intervalo de observación
    # e inicio de Bisección
    La = 0.01
    Lb = 0.50
    
    tolera = 0.0001 #grafica
    
    muestras = 21
    
    # PROCEDIMIENTO
    
    # Método de Bisección
    a = La
    b = Lb
    c = (a+b)/2
    tramo = np.abs(b-a)
    while (tramo>tolera):
        fa = fi(a)
        fb = fi(b)
        fc = fi(c)
        cambio = np.sign(fc)*np.sign(fa)
        if (cambio>0):
            a = c
            b = b
        else:   
            b = c
            a = a
        c = (a+b)/2
        tramo = np.abs(b-a)
    
    # Para la gráfica
    tasa = np.linspace(La,Lb,muestras)
    fr = fi(tasa)
    
    # SALIDA
    print('a, f(a):', a,fa)
    print('c, f(c):', c,fc)
    print('b, f(b):', b,fb)
    print('la raiz esta entre: \n',a,b)
    print('con un error de: ', tramo)
    print('raiz es tasa buscada: ', c)
    print('tasas anual buscada: ',c*12)
    
    # Gráfica
    plt.plot(tasa,fr)
    plt.axhline(0, color='green')
    plt.title('tasa de interes mensual')
    plt.show()
    

    la ejecución del algoritmo da como resultado

    >>> 
     RESTART: D:/MATG1052Ejemplos/HipotecaInteres.py 
    a, f(a): 0.016998291015625 -385.52828922150366
    c, f(c): 0.0170281982421875 -145.85350695741363
    b, f(b): 0.01705810546875 92.28034212642524
    la raiz esta entre: 
     0.016998291015625 0.01705810546875
    con un error de:  5.981445312500111e-05
    raiz es tasa buscada:  0.0170281982421875
    tasas anual buscada:  0.20433837890625
    

    y la gráfica obtenida es:

    tasa interes mensual

  • s1Eva_IIT2018_T1 Interpolar velocidad del paracaidista

    Ejercicio: 1Eva_IIT2018_T1 Interpolar velocidad del paracaidista

    El ejercicio tiene dos partes: la interpolación y el integral.

    Literal a

    t [s] 0 2 4 6 8
    v(t) [m/s] 0.0 16.40 27.77 35.64 41.10

    https://www.dreamstime.com/stock-photo-skydiving-formation-group-people-image62015024No se especifica el método a seguir, por lo que se puede seleccionar el de mayor preferencia.

    Por ejemplo. usando el método de Lagrange, con los puntos primero, medio y último, para cubrir todo el intervalo:

    p_2(t) = 0\frac{(t-4)(t-8)}{(0-4)(0-8)} + + 27.77\frac{(t-0)(t-8)}{(4-0)(4-8)} + + 41.10\frac{(t-0)(t-4)}{(8-0)(8-4)} p_2(t) = 0 + 27.77\frac{t(t-8)}{-16}) + + 41.10\frac{t(t-4)}{32} p_2(t) = -1.73(t^2-8t) + 1.28(t^2-4t) p_2(t) = -0.45 t^2 + 8.74t

    2_IIT2018_T1 Interpola Paracaidista 01


    Literal b

    El tema de integración para primera evaluación se realiza de forma analítica.

    Una de las formas, que es independiente si se resolvió el literal a, es usar los datos proporcionados en la tabla el ejercicio:

    t [s] 0 2 4 6 8
    v(t) [m/s] 0.0 16.40 27.77 35.64 41.10

    Se podría usar el método de Simpson de 1/3, puesto que los tamaños de paso en t son equidistantes se puede aplicar: h=2-0=2

    \int_0^8 v(t)dt = \frac{2}{3}\Big( 0+ 4(16.40)+27.77\Big) + \frac{2}{3}\Big( 27.77+ 4(35.64)+41.10\Big) =203.2

    con error del orden de O(h5) que al considerar h=2 no permite hacer una buena estimación del error. Sin embargo la respuesta es bastante cercana si se usa el método el trapecio con el algoritmo:

        valores de fi:  [ 0.   27.77 41.1 ]
    divisores en L(i):  [ 32. -16.  32.]
    
    Polinomio de Lagrange, expresiones
    -1.735625*x*(x - 8.0) + 1.284375*x*(x - 4.0)
    
    Polinomio de Lagrange: 
    -0.45125*x**2 + 8.7475*x
    Método del trapecio
    distancia recorrida:  193.28
    >>> 
    

    El error entre los métodos es |203.2-193.28|= 9.92

    Revisar el resultado usando un método con mayor precisión que el trapecio.


    Algoritmo con Python

    Las instrucciones en Python para el ejercicio son:

    # 1ra Evaluación II Término 2018
    # Tema 1. Interpolar velocidad del paracaidista
    import numpy as np
    import sympy as sym
    import matplotlib.pyplot as plt
    
    # Literal a)
    # Interpolacion de Lagrange
    # divisoresL solo para mostrar valores
    
    # INGRESO
    t = [0.0, 2, 4, 6, 8]
    v = [0.0, 16.40, 27.77, 35.64, 41.10]
    
    cuales = [0,2,4]
    
    # PROCEDIMIENTO
    xi = np.array(t,dtype=float)
    fi = np.array(v,dtype=float)
    
    xi = xi[cuales]
    fi = fi[cuales]
    
    # Polinomio de Lagrange
    n = len(xi)
    x = sym.Symbol('x')
    polinomio = 0
    divisorL = np.zeros(n, dtype = float)
    for i in range(0,n,1):
        
        # Termino de Lagrange
        numerador = 1
        denominador = 1
        for j  in range(0,n,1):
            if (j!=i):
                numerador = numerador*(x-xi[j])
                denominador = denominador*(xi[i]-xi[j])
        terminoLi = numerador/denominador
    
        polinomio = polinomio + terminoLi*fi[i]
        divisorL[i] = denominador
    
    # simplifica el polinomio
    polisimple = polinomio.expand()
    
    # para evaluación numérica
    px = sym.lambdify(x,polisimple)
    
    # Puntos para la gráfica
    muestras = 51
    a = np.min(xi)
    b = np.max(xi)
    pxi = np.linspace(a,b,muestras)
    pfi = px(pxi)
    
    # SALIDA
    print('    valores de fi: ',fi)
    print('divisores en L(i): ',divisorL)
    print()
    print('Polinomio de Lagrange, expresiones')
    print(polinomio)
    print()
    print('Polinomio de Lagrange: ')
    print(polisimple)
    
    # Gráfica
    plt.plot(t,v,'o', label = 'Puntos')
    plt.plot(xi,fi,'o', label = 'Puntos en polinomio')
    plt.plot(pxi,pfi, label = 'Polinomio')
    plt.legend()
    plt.xlabel('xi')
    plt.ylabel('fi')
    plt.title('Interpolación Lagrange')
    plt.grid()
    plt.show()
    
    # Literal b
    # INGRESO
    # El ingreso es el polinomio en forma lambda
    # se mantienen las muestras
    
    # intervalo de integración
    # a, b seleccionados para la gráfica anterior
    tramos = muestras -1
    
    # PROCEDIMIENTO
    def integratrapecio_fi(xi,fi):
        ''' sobre muestras de fi para cada xi
            integral con método de trapecio
        '''
        n = len(xi)
        suma = 0
        for i in range(0,n-1,1):
            dx = xi[i+1]-xi[i]
            untrapecio = dx*(fi[i+1]+fi[i])/2
            suma = suma + untrapecio
        return(suma)
    
    
    tramos = muestras-1
    # PROCEDIMIENTO
    distancia = integratrapecio_fi(xi,fi)
    
    # SALIDA
    print('Método del trapecio')
    print('distancia recorrida: ', distancia)
    
  • s1Eva_IIT2018_T3 Interpolar con sistema de ecuaciones

    Ejercicio: 1Eva_IIT2018_T3 Interpolar con sistema de ecuaciones

    Los datos del ejercicio proporcionados son:

    i 0 1 2 3 4 5
    x 1.0 1.1 1.3 1.5 1.9 2.1
    y(x) 1.84 1.90 2.10 2.28 2.91 3.28

    Literal a

    El tema es semejante al tema 1, cambiando el método de interpolación.
    Se usan los puntos de las posiciones 0, 3 y 5.

    p_2(x) = b_0 + b_1x + b_2 x^2

    en la fórmula:

    punto x[0] = 1, y[0]= 1.84

    1.84 = b_0 + b_1(1) + b_2 (1)^2 1.84 = b_0 + b_1 + b_2

    punto x[3] = 1.5, y[3]= 2.28

    2.28 = b_0 + b_1(1.5) + b_2 (1.5)^2 2.28 = b_0 + 1.5 b_1 + 2.25 b_2

    punto x[5] = 2.1, y[5]= 3.28

    3.28= b_0 + b_1(2.1) + b_2 (2.1)^2 3.28= b_0 + 2.1 b_1 + 4.41 b_2

    se obtiene el sistema de ecuaciones:

    b_0 + b_1 + b_2 = 1.84 b_0 + 1.5 b_1 + 2.25 b_2 = 2.28 b_0 + 2.1 b_1 + 4.41 b_2 = 3.28

    Con lo que se plantea la forma Ax=B:

    A = \begin{bmatrix} 1 & 1 & 1\\ 1 & 1.5 & 2.25 \\1 & 2.1 & 4.41 \end{bmatrix} B = \begin{bmatrix} 1.84\\ 2.28 \\ 3.28 \end{bmatrix}

    Matriz Aumentada

    AB = \begin{bmatrix} 1 & 1 & 1 & 1.84 \\ 1 & 1.5 & 2.25 & 2.28 \\1 & 2.1 & 4.41 &3.28 \end{bmatrix}

    Pivoteo parcial por filas

    Para el primer pivote no se requieren cambio de filas.
    para el segundo pivote de la diagonal se deben intercambiar la fila segunda con la tercera

    \begin{bmatrix} 1 & 1 & 1 & 1.84 \\ 1 & 2.1 & 4.41 &3.28 \\ 1 & 1.5 & 2.25 & 2.28 \end{bmatrix}

    Se aplica eliminación hacia adelante:

    fila = 0, columna=0  pivote = AB[0,0]=1

    factor entre las filas es 1/1=1.

    \begin{bmatrix}1 & 1 & 1 & 1.84 \\ 1-1 & 2.1-1 & 4.41 -1 &3.28 -1.84 \\ 1-1 & 1.5 -1 & 2.25 -1 & 2.28 - 1.84 \end{bmatrix} \begin{bmatrix} 1 & 1 & 1 & 1.84 \\ 0 & 1.1 & 3.41 &1.44 \\ 0 & 0.5 & 1.25 & 0.44 \end{bmatrix}

    fila =1,  columna=1, pivote=AB[1,1] =1.1

    factor entre filas es 0.5/1.1 = 1/2.2

    \begin{bmatrix} 1 & 1 & 1 & 1.84 \\ 0 & 1.1 & 3.41 &1.44 \\ 0 & 0.5 -\frac{0.5}{1.1}(1.1)& 1.25 -\frac{0.5}{1.1}(3.41)& 0.44-\frac{0.5}{1.1}(1.44) \end{bmatrix} \begin{bmatrix} 1 & 1 & 1 & 1.84 \\ 0 & 1.1 & 3.41 &1.44 \\ 0 & 0 & -0.3 & -0.214545 \end{bmatrix}

    aplicando sustitución hacia atrás

    b2 = -0.21/(-0.3) = 0.71515 b1= \frac{1.44-3.41 b_2}{1.1} = \frac{1.44-3.41( 0.71515)}{1.1}=-0.9078 b3= \frac{1.84-b_1-b_2}{1} = \frac{1.84-(-0.9078)-(0.71515)}{1} =2.0327

    con lo que el polinomio buscado es:

    p_2(x) = 2.0327 -0.9078 x + 0.71515 x^2

    y se obtiene el resultado de la interpolación.

    E2_IIT2018_T3 Interpola Sistema Ecuaciones 01Observación: En la gráfica se muestra que el polinomio pasa por los puntos seleccionados de la tabla. En los otros puntos hay un error que se puede calcular como la resta del punto y su valor con p(x). Queda como tarea.

    Usando el algoritmo del polinomio de interpolación con la matriz de Vandermonde se obtiene:

    Matriz Vandermonde: 
    [[1.   1.   1.  ]
     [2.25 1.5  1.  ]
     [4.41 2.1  1.  ]]
    los coeficientes del polinomio: 
    [ 0.71515152 -0.90787879  2.03272727]
    Polinomio de interpolación: 
    0.715151515151516*x**2 - 0.907878787878792*x + 2.03272727272728
    
     formato pprint
                       2                                         
    0.715151515151516*x  - 0.907878787878792*x + 2.03272727272728
    suma de columnas:  [3.   4.75 7.51]
    norma D:  7.51
    numero de condicion:  97.03737354737122
    solucion: 
    [ 0.71515152 -0.90787879  2.03272727]
    >>> 
    
    

    Literal b

    Se requiere calcular una norma de suma de filas. es suficiente para demostrar el conocimiento del concepto el usar A.

    Se adjunta el cálculo del número de condición y la solución al sistema de ecuaciones:

    suma de columnas:  [3.   4.75 7.51]
    norma A:  7.51
    numero de condición:  97.03737354737129
    solución: 
    [ 2.03272727 -0.90787879  0.71515152]
    

    El comentario importante corresponde al número de condición, que es un número muy alto para usar un método iterativo, por lo que la solución debe ser un método directo.
    Se puede estimar será un número mucho mayor que 1, pues la matriz no es diagonal dominante.


    Instrucciones en Python

    # 1Eva_IIT2018_T3 Interpolar con sistema de ecuaciones
    # El polinomio de interpolación
    import numpy as np
    import sympy as sym
    import matplotlib.pyplot as plt
    
    # INGRESO
    xj = [1.0,  1.1,  1.3,  1.5,  1.9,  2.1 ]
    yj = [1.84, 1.90, 2.10, 2.28, 2.91, 3.28]
    cuales = [0, 3, 5]
    
    # muestras = tramos+1
    muestras = 51
    
    # PROCEDIMIENTO
    # Convierte a arreglos numpy 
    xi = np.array(xj,dtype=float)
    fi = np.array(yj,dtype=float)
    
    xi = xi[cuales]
    fi  = fi[cuales]
    B = fi
    
    n = len(xi)
    
    # Matriz Vandermonde D
    D = np.zeros(shape=(n,n),dtype =float)
    for i in range(0,n,1):
        for j in range(0,n,1):
            potencia = (n-1)-j # Derecha a izquierda
            D[i,j] = xi[i]**potencia
    
    # Aplicar métodos Unidad03. Tarea
    # Resuelve sistema de ecuaciones A.X=B
    coeficiente = np.linalg.solve(D,B)
    
    # Polinomio en forma simbólica
    x = sym.Symbol('x')
    polinomio = 0
    for i in range(0,n,1):
        potencia = (n-1)-i   # Derecha a izquierda
        termino = coeficiente[i]*(x**potencia)
        polinomio = polinomio + termino
    
    # Polinomio a forma Lambda
    # para evaluación con vectores de datos xin
    px = sym.lambdify(x,polinomio)
    
    # Para graficar el polinomio en [a,b]
    a = np.min(xi)
    b = np.max(xi)
    xin = np.linspace(a,b,muestras)
    yin = px(xin)
    
    # Usando evaluación simbólica
    ##yin = np.zeros(muestras,dtype=float)
    ##for j in range(0,muestras,1):
    ##    yin[j] = polinomio.subs(x,xin[j])
        
    # SALIDA
    print('Matriz Vandermonde: ')
    print(D)
    print('los coeficientes del polinomio: ')
    print(coeficiente)
    print('Polinomio de interpolación: ')
    print(polinomio)
    print('\n formato pprint')
    sym.pprint(polinomio)
    
    # Grafica
    plt.plot(xj,yj,'o', label='Puntos')
    plt.plot(xi,B,'o', label='[xi,fi]')
    plt.plot(xin,yin, label='p(x)')
    plt.xlabel('xi')
    plt.ylabel('fi')
    plt.legend()
    plt.title(polinomio)
    plt.show()
    
    
    # literal b
    sumacolumnas = np.sum(D, axis =1)
    norma = np.max(sumacolumnas)
    print('suma de columnas: ', sumacolumnas)
    print('norma D: ', norma)
    
    numerocondicion = np.linalg.cond(D)
    print('numero de condicion: ', numerocondicion)
    
    solucion = np.linalg.solve(D,B)
    print('solucion: ')
    print(solucion)
    

    .