Source code for mrinufft.extras.gradient
"""Conjugate gradient optimization algorithm for image reconstruction."""
import numpy as np
from mrinufft.operators.base import with_numpy
[docs]
@with_numpy
def cg(operator, kspace_data, x_init=None, num_iter=10, tol=1e-4):
"""
Perform conjugate gradient (CG) optimization for image reconstruction.
The image is updated using the gradient of a data consistency term,
and a velocity vector is used to accelerate convergence.
Parameters
----------
kspace_data : numpy.ndarray
The k-space data to be used for image reconstruction.
x_init : numpy.ndarray, optional
An initial guess for the image. If None, an image of zeros with the same
shape as the expected output is used. Default is None.
num_iter : int, optional
The maximum number of iterations to perform. Default is 10.
tol : float, optional
The tolerance for convergence. If the norm of the gradient falls below
this value or the dot product between the image and k-space data is
non-positive, the iterations stop. Default is 1e-4.
Returns
-------
image : numpy.ndarray
The reconstructed image after the optimization process.
"""
Lipschitz_cst = operator.get_lipschitz_cst()
image = (
np.zeros(operator.shape, dtype=type(kspace_data[0]))
if x_init is None
else x_init
)
velocity = np.zeros_like(image)
grad = operator.data_consistency(image, kspace_data)
velocity = tol * velocity + grad / Lipschitz_cst
image = image - velocity
for _ in range(num_iter):
grad_new = operator.data_consistency(image, kspace_data)
if np.linalg.norm(grad_new) <= tol:
break
beta = np.dot(grad_new.flatten(), grad_new.flatten()) / np.dot(
grad.flatten(), grad.flatten()
)
velocity = grad_new + beta * velocity
image = image - velocity / Lipschitz_cst
return image