Salut.
Si on reste à une seule dimension (x n'est pas un vecteur) alors on peut reformuler le problem comme ceci:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| import numpy as np
import matplotlib.pyplot as plt
def func(x):
return x + np.exp(-x**2) * np.cos(x)
def func_deriv(x):
return 1 + np.exp(-x**2) * (-2*x*np.cos(x) - np.sin(x))
def newton_bis(x0, target, func, func_deriv, eps=1e-6):
x = x0
while abs(func(x) - target) > eps:
err = func(x) - target
# Compute jacobian
df = func_deriv(x)
# Newton method
delta = (1/df**2) * err
x -= delta
return x, func(x), err
if __name__ == '__main__':
x0 = 20.
target = 0
print newton_bis(x0, target, func, func_deriv) |
Le principe de la method de newton est d'utiliser la derive pour estimer de combine doit-on modifier la valeur de x pour se rapprocher de la cible. La formulation générale fait appel à une matrice jacobienne qui contient les derivées. Dans ton cas on peut s'en passer, mais il faut quand meme regarder cette forme pour voir que (supposons J la jacobienne, E l'erreur avec la cible et Delta la proportion à modifier):
((J^T.J)^-1).J^T.E = Delta
Dans le cas à une dimension on déduit que:
Avec df la derivée..
Bien l'algorithme de Newton est assez simple:
1- On part d'une valeur x=x0
2- Tant que l'erreur entre f(x) et la target est supérieure à epsilon
a- On calcule la dérivée
b- On calcul delta
c- On modife x en function de delta
Et voilà !
Un fois le principe maitrisé on peut utiliser des modules qui le font très bien, comme scipy. Mais le faire une fois, c'est mieux
J
Partager