# -*- coding: utf-8 -*-
"""
Created on Mon Jul  4 10:19:30 2022

@author: starons
"""

"""
Recherche du zéro d'une fonction f au voisinage d'un x0 en utlisant la méthode de Newton
"""

# On importe les bibliothèques utiles
# -----------------------------------
import numpy as np

# On définit la fonction dont on cherche un zéro : il est recommandé de la tracer au préalable
# --------------------------------------------------------------------------------------------
def mafonction(x):
    return x-np.tan(x)

# Abscisse du point au voisinage duquel on cherche le zéro de la fonction
# -----------------------------------------------------------------------
x0 = 4.5

# On crée une fonction qui estime la valeur de la dérivée d'une fonction en un point et ce d'autant mieux que h est petit
# ----------------------------------------------------------------------------------------------------------------------- 
def dérivée(g,x):
    h = 0.001
    return (g(x+h)-g(x-h))/2/h  # schéma numérique centré

# ou une autre si on préfère
# -------------------------- 
def dérivée2(g,x):
    h = 0.001
    return (g(x+h)-g(x))/h      # schéma numérique décentré 

# Implémentation de la méthode de Newton
# --------------------------------------
def mon_Newton(f,x0,epsilon):
    écart = 1                        # initialisation
    while (écart>epsilon):           # on cherche le zéro de f tant que la précision souhaitée n'est pas atteinte 
        x1 = x0-f(x0)/dérivée(f,x0)  # abscisse x1 du point d'intersection de la tangente en x0 avec l'axe des abscisses    
        écart = abs(x1-x0)           # distance entre deux termes consécutifs de la suite
        x0 = x1                      # on fera la même chose en remplaçant x0 par x1 à l'itération suivante  
    return x1

# On indique la précision souhaitée lors de l'appel de la fonction mon_Newton
# ---------------------------------------------------------------------------
print("La fonction f s'annule en x =",mon_Newton(mafonction,x0,1e-4))

# Une fonction préprogrammée dans Python fait exactement la même chose !
# ----------------------------------------------------------------------
from scipy.optimize import newton
print("Et en utilisant la fonction newton, on trouve que :")
print("La fonction f s'annule en x =",newton(mafonction,x0,tol=1e-4))