from numpy import sqrt

1/(2*sqrt(12))

"""
Explanation: Métodos de punto fijo I
En esta ocasión empezaremos a implementar un método para obtener una raiz real de una ecuación no lineal. Este método se le conoce como punto fijo, pero la variante especificamente que implementaremos ahora es la de aproximaciones sucesivas.
Aproximaciones sucesivas
Tenemos un polinomio $f(x) = 2 x^2 - x - 5$ y un valor inicial $x_0 = 1$ y queremos saber cuales son sus raices reales. Lo primero que tenemos que hacer es pasarlo a la siguiente forma:
$$x = g(x)$$
Podemos notar que hay muchas maneras de hacer esto, como por ejemplo:

$x = 2 x^2 - 5$
$x = \sqrt{\frac{x + 5}{2}}$
$x = \frac{5}{2x - 1}$

Pero no todas estas formas nos proveerán de un calculo que converja hacia la solución, por lo que tenemos que analizar la convergencia de cada una, hasta que encontremos una que nos acomode.
Sabemos que si el valor absoluto de la primera derivada de $g(x)$ es menor a 1, $\left| g'(x) < 1 \right|$, converjerá adecuadamente, por lo que esto es lo que analizaremos ahora:

$g_1(x) = 2 x^2 - 5$, entonces $g_1'(x) = 4 x$
$g_2(x) = \sqrt{\frac{x + 5}{2}}$, entonces $g_2' = \frac{1}{2} \frac{1}{\sqrt{2(x + 5)}}$
$g_3(x) = \frac{5}{2x - 1}$, entonces $g_3'(x) = - \frac{10}{(2x - 1)^2}$

De aqui podemos ver que $g_1'(x_0) = 4$, por lo que no converjerá a la solución. $g_2'(x_0) = \frac{1}{2\sqrt{12}}$ en cambio, si nos da un numero menor a 1, por lo que es indicada para hacer iteraciones.
End of explanation
"""


x_0 = 1
g = lambda x: sqrt((x+5)/2)
x_1 = g(x_0)
x_1

"""
Explanation: Entonces ya tenemos una formula para iterar a través:
$$x_1 = g(x_0)$$
es decir:
$$x_1 = \sqrt{\frac{x_0 + 5}{2}}$$
End of explanation
"""


abs(x_1 - x_0)

"""
Explanation: Y ya tenemos la primera iteración. Cuando dejaremos de iterar? Cuando el error $\varepsilon = x_1 - x_0$ sea menor a $0.001$ (para este ejemplo).
End of explanation
"""


def aprox_sucesivas(g, x0, error):
    xs = [x0]
    while True:
        xs.append(g(xs[-1]))
        if abs(xs[-1] - xs[-2]) <= error:
            return xs[-1]

"""
Explanation: Como podemos ver, aun falta mucho... pero podemos decirle a la computadora que lo siga haciendo sin notsotros. Primero creamos una funcion que itere la funcion g hasta que la diferencia de las ultimas iteraciones sea menor al error.
End of explanation
"""


r = aprox_sucesivas(g, 0, 0.001)
r

from numpy import sin

"""
Explanation: Y ahora le damos a esta funcion nuestra $g(x)$, el punto donde queremos que inicie $x_0$ y el error maximo permitido.
End of explanation
"""


f = lambda x: 2*x**2 - x - 5

f(r)

"""
Explanation: Creamos una funcion en codigo, que contiene la función original, para evaluar que tan bien se aproximo la raiz.
End of explanation
"""


