import numpy as np
import matplotlib.pyplot as plt
from numpy.linalg import norm
On considère la fonction $$f(x)=\dfrac{1}{2}\left((x_1-1)^2+(x_2-3)^2+(x_1x_2-3x_1)^2\right)$$ Le minimum de cette fonction est $(1,3)^T$
f=lambda x:((x[0]-1)**2+(x[1]-3)**2+(x[0]*x[1]-3*x[0])**2)/2
x=np.linspace(-6,6)
y=np.linspace(-2,8)
x,y=np.meshgrid(x,y)
z=f([x,y])
fig=plt.figure(1)
plt.contour(x,y,z,50)
plt.plot(1,3,'r+')
[<matplotlib.lines.Line2D at 0x172f3804e50>]
Ecrire la fonction descente_gradient(df,x0,alpha=0.5,niter=1000,tolerance=1e-12) qui retourne:
Le nombre d'itérations.
Le test d'arrêt étant: $$\Vert \nabla f(x^{(k)})\Vert <= tolerance $$
def descente_gradient(df,x0,alpha=0.5,niter=1000,tolerance=1e-12):
grad=df(x0)
i=0
while norm(grad)>tolerance and i<niter:
x0=x0-alpha*grad
grad=df(x0)
i+=1
return x0,i
df=lambda x: np.array([x[0]-1+(x[1]-3)*(x[0]*x[1]-3*x[0]),x[1]-3+x[0]*(x[0]*x[1]-3*x[0])])
x0=np.array([0,1])
descente_gradient(df,x0)
(array([1., 3.]), 42)
Comparer les résultats (valeurs, nombre d’itérations) de la méthode du gradient à pas fixe pour différentes valeurs de $\alpha$. On donne $$\alpha = 0.01, 0.03, 0.1, 0.3, 1, 1.3$$ Tracer le nombre d'itération en fonction de $\alpha$.
alpha = [0.01, 0.03, 0.1, 0.3, 1, 1.3]
n=[]
sol=[]
for a in alpha:
s,i=descente_gradient(df,x0,a,niter=1000,tolerance=1e-12)
n.append(i)
sol.append(s)
plt.plot(alpha,n)
[<matplotlib.lines.Line2D at 0x172f4173790>]
print(n)
[1000, 930, 269, 80, 1, 1000]
print(sol)
print(norm(sol[-1]-np.array([1,3])))
[array([0.99991534, 2.99999997]), array([1., 3.]), array([1., 3.]), array([1., 3.]), array([1, 3]), array([0.73379939, 2.39769585])] 0.6585082040410328
Conclusion