s1Eva2016TI_T3_MN Tasa interés anual

Ejercicio: 1Eva2016TI_T3_MN Tasa interés anual

Propuesta de Solución  empieza con el planteamiento del problema, luego se desarrolla con el método de Bisección y método del Punto Fijo solo con el objetivo de comparar resultados.


Planteamiento del problema

La fórmula del enunciado para el problema es:

A = P \frac{i(1+i)^{n}}{(1+i)^{n} -1}

que con los datos dados se convierte a:

5800 = 35000 \frac{i(1+i)^8}{(1+i)^8 -1} 35000 \frac{i(1+i)^8}{(1+i)^8 -1}-5800 =0

que es la forma de f(x) = 0

f(i)=35000 \frac{i(1+i)^8}{(1+i)^8 -1}-5800

Intervalo de búsqueda

Como el problema plantea la búsqueda de una tasa de interés, consideramos que:

  • Las tasas de interés no son negativas. ⌉(i<0)
  • Las tasas de interés no son cero en las instituciones bancarias (i≠0)
  • Las tasas muy grandes 1 = 100/100 = 100% tampoco tienen mucho sentido

permite acotar la búsqueda a un intervalo (0,1].
Sin embargo tasas demasiado altas tampoco se consideran en el problema pues el asunto es regulado (superintendencia de bancos), por lo que se podría intentar entre un 1% = 0.01l y la mitad del intervalo 50%= 0.5 quedando

[0.01,0.5]

Tolerancia

si la tolerancia es de tan solo menor a un orden de magnitud que el valor buscado, se tiene que las tasas de interés se representan por dos dígitos después del punto decimal, por lo que la tolerancia debe ser menor a eso.

Por ejemplo: tolerancia < 0.001 o aumentando la precisión

tolera = 0.0001


Método de la Bisección

itera = 1

a = 0.01, b = 0.5

c = \frac{a+b}{2} = \frac{0.01+0.5}{2} = 0.255 f(0.01) = 35000 \frac{0.01(1+0.01)^8}{(1+0.01)^8-1}-5800 = -1225.83 f(0.5) = 35000 \frac{0.5(1+0.5i)^8}{(1+0.5)^8-1}-5800 = 12410.54

con lo que se verifica que existe cambio de signo al evaluar f(x) en el intervalo y puede existir una raíz.

f(0.255) = 35000 \frac{0.255(1+0.255)^8}{(1+0.255)^8-1}-5800 = 4856.70

lo que muestra que f(x) tiene signos en a,c,b de (-) (+) (+), seleccionamos el intervalo izquierdo para continuar la búsqueda [0.01, 0.255]

El tramo permite estimar el error, reduce el intervalo a:

tramo = b-a = 0.255-0.01 = 0.245

valor que todavía es más grande que la tolerancia de 10-4, por lo que hay que continuar las iteraciones.

itera = 2

a = 0.01, b = 0.255

c = \frac{0.01+0.255}{2} = 0.1325 f(0.01) = -1225.83 f(0.255) = 4856.70 f(0.1325 ) = 35000 \frac{0.1325(1+0.1325)^8}{(1+0.1325)^8-1}-5800 = 1556.06

lo que muestra que f(x) tiene signos en a,c,b de (-) (+) (+), seleccionamos el intervalo izquierdo para continuar la búsqueda [0.01, 0.1325]

El tramo permite estimar el error, reduce el intervalo a:

tramo = b-a = 0.1325-0.01 = 0.1225

valor que todavía es más grande que la tolerancia de 10-4, por lo que hay que continuar las iteraciones.

itera = 3

a = 0.01, b = 0.1325

c = \frac{0.01+0.1225}{2} = 0.071 f(0.01) = -1225.83 f(0.1325) = 1556.06 f(0.071 ) = 35000 \frac{0.071(1+0.071)^8}{(1+0.071)^8-1}-5800 = 89.79

lo que muestra que f(x) tiene signos en a,c,b de (-) (+) (+), seleccionamos el intervalo izquierdo para continuar la búsqueda [0.01, 0.071]

El tramo permite estimar el error, reduce el intervalo a:

tramo = b-a = 0.071-0.01 = 0.061

valor que todavía es más grande que la tolerancia de 10-4, por lo que hay que continuar las iteraciones.

Para una evaluación del tema en forma escrita es suficiente para mostrar el objetivo de aprendizaje, el valor final se lo encuentra usando el algoritmo.

método de Bisección
i ['a', 'c', 'b'] ['f(a)', 'f(c)', 'f(b)']
   tramo
0 [0.01  0.255 0.5  ] [-1225.8398  4856.7013 12410.5472]
   0.245
1 [0.01   0.1325 0.255 ] [-1225.8398  1556.0665  4856.7013]
   0.12250000000000001
2 [0.01   0.0713 0.1325] [-1225.8398    89.7962  1556.0665]
   0.061250000000000006
3 [0.01   0.0406 0.0713] [-1225.8398  -588.1013    89.7962]
   0.030625000000000006
4 [0.0406 0.0559 0.0713] [-588.1013 -254.0227   89.7962]
   0.015312500000000007
5 [0.0559 0.0636 0.0713] [-254.0227  -83.3114   89.7962]
   0.007656250000000003
6 [0.0636 0.0674 0.0713] [-83.3114   2.9453  89.7962]
   0.0038281250000000017
7 [0.0636 0.0655 0.0674] [-83.3114 -40.2576   2.9453]
   0.001914062499999994
8 [0.0655 0.0665 0.0674] [-40.2576 -18.6747   2.9453]
   0.0009570312500000039
9 [0.0665 0.0669 0.0674] [-18.6747  -7.8694   2.9453]
   0.000478515624999995
10 [0.0669 0.0672 0.0674] [-7.8694 -2.4632  2.9453]
   0.00023925781249999056
11 [0.0672 0.0673 0.0674] [-2.4632  0.2408  2.9453]
   0.00011962890625000222
12 [0.0672 0.0672 0.0673] [-2.4632 -1.1113  0.2408]
   5.981445312500111e-05
raíz en:  0.06724243164062502
>>>
1Eva2016TI_T3_MN tasa interés anual con bisección

Algoritmo en Python

# Algoritmo de Bisección
# [a,b] se escogen de la gráfica de la función
# error = tolera
import numpy as np
 
def biseccion(fx,a,b,tolera,iteramax = 50, 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,np.array([a,c,b]),
                      np.array([fa,fc,fb]))
            if (cambia<0): # cambio de signo izquierda
                b = c
                fb = fc
            else: # cambio de signo derecha
                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)
 
# PROGRAMA ----------------------
# INGRESO
fx = lambda x: 35000*(x*(1+x)**8)/((1+x)**8 -1) -5800
a = 0.01
b = 0.5
tolera = 0.0001

 
# PROCEDIMIENTO
c = biseccion(fx,a,b,tolera,vertabla=True)
# SALIDA
print('raíz en: ',c)

Para la gráfica se añaden las instrucciones correspondientes:

# GRAFICA
import matplotlib.pyplot as plt
 
muestras = 21 # en intervalo [a,b]
 
xj = np.linspace(a,b,muestras)
fj = fx(xj)
 
plt.plot(xj,fj, label='f(x)')
plt.plot(c,0,'o')
plt.axhline(0)
plt.xlabel('x')
plt.ylabel('f(x)')
plt.title('Biseccion')
plt.grid()
plt.legend()
plt.show()


Método del Punto Fijo

El planteamiento del punto fijo se realiza con x= g(x), por lo que se reordena la ecuación a:

35000 \frac{i(1+i)^8}{(1+i)^8 -1}-5800 =0 35000 \frac{i(1+i)^8}{(1+i)^8 -1}=5800 \frac{i(1+i)^8}{(1+i)^8 -1}=\frac{5800}{35000} i=\frac{58}{350} \frac{(1+i)^8 -1} {i(1+i)^8}

con lo que g(x) es:

g(i)=\frac{58}{350} \frac{(1+i)^8 -1} {(1+i)^8}

valor inicial de búsqueda

Para el punto inicial i0 se puede usar uno de los extremos del intervalo propuesto en la sección de planteamiento. Para reducir aun más la búsqueda se pude seleccionar el punto intermedio

 i0 = 0.255

Itera = 1

 i0 = 0.255

g(0.255i)=\frac{58}{350} \frac{(1+0.255)^8 -1} {(1+0.255)^8} = 0.1387

el error se estrima como el tramo recorrido entre el valor nuevo y el valor inicial

tramo = | nuevo-antes| = |0.1387 - 0.255| = 0.1163

como el tramo o error es aún mayor que el valor de tolera, se continúa con la siguiente iteración.

Itera = 2

i1 = g(i0 ) = 0.1387

g(0.1387)=\frac{58}{350} \frac{(1+0.1387)^8 -1} {(1+0.1387)^8} = 0.1071

el error se estima como el tramo recorrido entre el valor nuevo y el valor inicial

tramo = | nuevo-antes| = |0.1071 - 0.1387| = 0,0316

como el tramo o error es aún mayor que el valor de tolera, se continúa con la siguiente iteración.

Itera = 3

i2 = g(i1 ) = 0.1071

g(0.1071)=\frac{58}{350} \frac{(1+0.1071)^8 -1} {(1+0.1071)^8} = 0.0922

el error se estima como el tramo recorrido entre el valor nuevo y el valor inicial

tramo = | nuevo-antes| = |0.0922 - 0.1071| = 0,0149

como el tramo o error es aún mayor que el valor de tolera, se continúa con la siguiente iteración.

Observación: Como el error disminuye entre cada iteración, se considera que el método converge, si se realizan suficientes iteraciones se cumplirá con el valor de tolerancia y se habrá llegado a la precisión requerida.

Usando el algoritmo se tiene:

método del Punto Fijo
i ['xi', 'gi', 'tramo']
0 [0.255    0.138786 0.116214]
1 [0.138786 0.107124 0.031662]
2 [0.107124 0.092299 0.014826]
3 [0.092299 0.083938 0.008361]
4 [0.083938 0.078753 0.005185]
5 [0.078753 0.075353 0.0034  ]
6 [0.075353 0.073041 0.002311]
7 [0.073041 0.071432 0.001609]
8 [0.071432 0.070294 0.001139]
9 [0.070294 0.069479 0.000815]
10 [0.069479 0.06889  0.000588]
11 [0.06889  0.068463 0.000427]
12 [0.068463 0.068152 0.000312]
13 [0.068152 0.067924 0.000228]
14 [0.067924 0.067757 0.000167]
15 [0.067757 0.067634 0.000123]
16 [6.763408e-02 6.754389e-02 9.018452e-05]
raíz en:  0.06754389199556779
>>>
1Eva2016TI_T3_MN Tasa Interés Anual 01

Algoritmo en Python

# 1Eva2016TI_T3_MN Tasa interés anual
# Algoritmo de punto fijo
import numpy as np
 
def puntofijo(gx,c,tolera,iteramax=40,vertabla=True, precision=6):
    """
    g(x) se obtiene al despejar una x de f(x)
    máximo de iteraciones predeterminado: iteramax
    si no converge hasta iteramax iteraciones
    la respuesta es NaN (Not a Number)
    """
    itera = 0 # iteración inicial
    tramo = 2*tolera # al menos una iteracion
    if vertabla==True:
        print('método del Punto Fijo')
        print('i', ['xi','gi','tramo'])
        np.set_printoptions(precision)
    while (tramo>=tolera and itera<=iteramax):
        gc = gx(c)
        tramo = abs(gc-c)
        if vertabla==True:
            print(itera,np.array([c,gc,tramo]))
        c = gc
        itera = itera + 1
    respuesta = c
    # Valida respuesta
    if itera>=iteramax:
        respuesta = np.nan
        print('itera: ',itera,
              'No converge,se alcanzó el máximo de iteraciones')
    return(respuesta)
 
# PROGRAMA ----------------------
# INGRESO
fx = lambda x: 35000*(x*(1+x)**8)/((1+x)**8 -1)
gx = lambda i: (58/350)*((1+i)**8-1)/((1+i)**8)
 
c = 0.255
tolera = 0.0001
iteramax  = 50      # itera máximo
 
# PROCEDIMIENTO
respuesta = puntofijo(gx,c,tolera,iteramax,vertabla=True)
 
# SALIDA
print('raíz en: ', respuesta)

Para la gráfica se añaden las instrucciones correspondientes, sin embargo, la función f(x) tiene un rango diferente de respuestas para ser incluida en la gráfica, por lo que se omite. haciendo la línea:

fx = lambda x: 0*x #35000*(x*(1+x)**8)/((1+x)**8 -1)

con lo que se continúa con:

# GRAFICA
import matplotlib.pyplot as plt

a = 0.01  # intervalo de gráfica en [a,b]
b = 0.25
muestras = 21

# calcula los puntos para fx y gx
xj = np.linspace(a,b,muestras)
fj = fx(xj)
gj = gx(xj)

plt.plot(xj,fj, label='f(x)',
         linestyle='dashed')
plt.plot(xj,gj, label='g(x)')
plt.plot(xj,xj, label='y=x')
plt.plot(c,c, 'o')
plt.axvline(c, color='magenta',
            linestyle='dotted')
plt.axhline(0)
plt.xlabel('x')
plt.ylabel('f(x)')
plt.title('Punto Fijo')
plt.grid()
plt.legend()
plt.show()

Ejemplos - Ejercicios resueltos de Métodos Numéricos