Source code for lbfgsb.utils
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) 2025 Antoine COLLET
"""Provide optimization utilities."""
import numpy as np
from scipy.optimize import LbfgsInvHessProduct
from lbfgsb.types import NDArrayFloat
[docs]
def extract_hess_inv_diag(hess_inv: LbfgsInvHessProduct) -> NDArrayFloat:
"""
Extract efficiently the diagonal of the L-BFGS approximate inverse Hessian.
It relies on the linear operator `matvec` operation and consequenlty does not
require to build the dense matrix which is much longer and generally untractable
for large-scale problems.
Parameters
----------
hess_inv : LbfgsInvHessProduct
Linear operator for the L-BFGS approximate inverse Hessian.
Returns
-------
NDArrayFloat
The diagonal of the L-BFGS approximated inverse Hessian.
"""
n_params = hess_inv.shape[0]
hess_inv_diag = np.zeros(n_params)
for i in range(n_params):
v = np.zeros(n_params)
v[i] = 1.0
hess_inv_diag[i] = hess_inv.matvec(v)[i]
return hess_inv_diag
[docs]
def get_grad_projection_inf_norm(
x: NDArrayFloat,
grad: NDArrayFloat,
lbounds: NDArrayFloat,
ubounds: NDArrayFloat,
) -> float:
"""
Get the infinite norm of the projected gradient.
Parameters
----------
x : NDArrayFloat
Parameter vector.
grad : NDArrayFloat
Gradient of the parameter vector.
lbounds : NDArrayFloat
Lower bounds.
ubounds : NDArrayFloat
Upper bounds.
Returns
-------
float
The scaling factor.
"""
return np.max(np.abs(x - np.clip(x - grad, a_min=lbounds, a_max=ubounds))).item()