Méthode de quasi-Newton et BFGS

Bonjour,
on nous demande d'écrire un code python qui utilise la méthode de quasi-Newton et BFGS (Broyden-Fletcher-Goldfarb-Shanno).

Rappelons que l'avantage d'utiliser BFGS dans la méthode de quasi-Newton est qu'elle permet d'avoir une convergence plus rapide. Cependant, quand j'ai testé mon code sur une fonction ça fait l'effet inverse, càd qu'en utilisant BFGS la convergence est plus lente, donc il y a forcément quelque chose de faux dans mon code, pouvez-vous m'aider ?
#implementation of BFGS:
def update_bfgs(H, x_old, x, g_x_old, g_x):       #g_x:gradient en x_(k+1)  g_x_old : gradient de f en x_k
    ndim = x.shape[0]
    s = np.reshape(x - x_old, (ndim, 1))
    y = np.reshape(g_x - g_x_old, (ndim, 1))

    #calcul de B=B1+B2
    s_transpose=np.ndarray.transpose(s)
    y_transpose=np.ndarray.transpose(y)

    B1=-(s.dot(y_transpose.dot(H))+H.dot(y.dot(s_transpose)))/(s_transpose.dot(y))
    B2=(1+(y_transpose.dot(H.dot(y)/s_transpose.dot(y))))*(s.dot(s_transpose))/(s_transpose.dot(y))
    B=B1+B2
    return B
         
def quasi_newton(f, grad, x0, iterations, error_point, error_grad, hstep, use_bfgs):
    error_point_list, error_grad_list = [], []

    x_old=x0
    H = np.eye(dim)
    g_x_old=grad(x_old)
    k=0

    for i in range(iterations):
        k=k+1
        d=-H.dot(g_x_old)
        x = x_old + hstep*d
        g_x=grad(x)
        
        if use_bfgs:
            H = H + update_bfgs(H,x_old,x,g_x_old,g_x)

        err, err_grad = np.linalg.norm(x - x_old), np.linalg.norm(grad(x))
        error_point_list.append(err)
        error_grad_list.append(err_grad)

        if err_grad<error_grad or err<error_point : # termination condition
            break

        x_old = np.copy(x)
        g_x_old=grad(x_old)

    return { 'error_point_list': error_point_list,'iterations':k}
Merci d'avance.

[Isaac Newton (1642-1727) prend toujours une majuscule. AD]

Réponses

Connectez-vous ou Inscrivez-vous pour répondre.