%matplotlib inline
import numpy as np
from matplotlib import pyplot as plt

# Segundo passo: Definir função
def f(x): 
    return -x * np.e ** -x + 0.2

def p(A, B):
    plt.xlabel('x')
    plt.ylabel('y = f(x)')
    plt.title('Zero de funcoes')
    plt.grid()
    plt.plot(x, y)

    [xmin, xmax, ymin, ymax] = plt.axis()
    plt.plot([A, A], [ymin, ymax], 'k-')
    plt.plot([B, B], [ymin, ymax], 'k-')

# Terceiro passo: Visualizar função
x = np.linspace(0, 10, 100)
y = f(x)

p(1, 10)
plt.show()
    
A = 1.0
B = 10.0

x_tol = 0.0001
x_prev = B
y_tol = 0.0001

#for i in range(5):
while True:
    # Termo de recursao
    xi = (A + B) / 2.0

    p(A, B)
    [xmin, xmax, ymin, ymax] = plt.axis()
    plt.plot([xi, xi], [ymin, ymax], '--')
    plt.show()
    
    print('Aproximacao: %.6lf' %f(xi))

    if (f(A) * f(xi)) < 0:
        B = xi
    elif (f(A) * f(xi)) == 0:
        print('Raiz encontrada em %6.f' % xi)
    else:
        A = xi
    
    if abs(f(xi)) < y_tol:
        break
    
    if abs(x_prev - xi) < x_tol:
        break
    
    x_prev = xi
    
plt.show(block=True)

"""
Explanation: Revisão

Zero de função
Minimos de função

Metodo da bissecao
End of explanation
"""


%matplotlib inline
import numpy as np
from matplotlib import pyplot as plt

# Segundo passo: Definir função
def f(x): 
    return -x * np.e ** -x + 0.2

def p(A, B):
    plt.xlabel('x')
    plt.ylabel('y = f(x)')
    plt.title('Zero de funcoes')
    plt.grid()
    plt.plot(x, y)

    [xmin, xmax, ymin, ymax] = plt.axis()
    plt.plot([A, A], [ymin, ymax], 'k-')
    plt.plot([B, B], [ymin, ymax], 'k-')

# Terceiro passo: Visualizar função
x = np.linspace(0.0, 10.0, 100)
y = f(x)

p(1.0, 10.0)
plt.show()
    
A = 1.0
B = 10.0

x_tol = 0.001
x_prev = B
y_tol = 0.0001

while True:
    # Termo de recursao
    xi = (A * f(B) - B * f(A)) / (f(B) - f(A))

    p(A, B)
    [xmin, xmax, ymin, ymax] = plt.axis()
    plt.plot([xi, xi], [ymin, ymax], '--')
    plt.show()
    
    print('Aproximacao: %.6lf' %f(xi))

    if (f(A) * f(xi)) < 0:
        B = xi
    elif (f(A) * f(xi)) == 0:
        print('Raiz encontrada em %6.f' % xi)
    else:
        A = xi
    
    if abs(f(xi)) < y_tol:
        break
    
    if abs(x_prev - xi) < x_tol:
        break
    
    x_prev = xi
    
plt.show(block=True)

"""
Explanation: Posição Falsa

Só troca a funcao $(A + B) / 2$ por $(A * f(B) - B * f(A)) / (f(B) - f(A))$
End of explanation
"""


%matplotlib inline
import numpy as np
from matplotlib import pyplot as plt

# Segundo passo: Definir função
def f(x): 
    return -x * np.e ** -x + 0.2

def f_linha(x):
    return np.e ** -x * (x - 1)

def p(A, B):
    plt.xlabel('x')
    plt.ylabel('y = f(x)')
    plt.title('Zero de funcoes')
    plt.grid()
    plt.plot(x, y)
    
    if A != 0 and B != 0:
        [xmin, xmax, ymin, ymax] = plt.axis()
        plt.plot([A, A], [ymin, ymax], 'k-')
        plt.plot([B, B], [ymin, ymax], 'k-')


# Terceiro passo: Visualizar função
x = np.linspace(0.0, 10.0, 100)
y = f(x)

p(1.0, 10.0)
plt.show()
    
A = 1.0
B = 10.0

xi = 2.0
x_tol = 0.0001
y_tol = 0.0001
x_prev = xi

while True:
    p(0, 0)
    [xmin, xmax, ymin, ymax] = plt.axis()
    plt.plot([xi, xi], [ymin, ymax], '--')
    plt.show()
    
    print('Aproximacao: %.6lf' %f(xi))
    
    # Termo de recursao
    xi = xi - f(xi) / f_linha(xi)
    
    if abs(f(xi)) < y_tol:
        break
    
    if abs(x_prev - xi) < x_tol:
        break
    
    x_prev = xi
    
plt.show(block=True)

"""
Explanation: Metodos de newton e secante
End of explanation
"""


