mrpro.algorithms.optimizers.cg
- mrpro.algorithms.optimizers.cg(operator: Callable[[Tensor], tuple[Tensor]], right_hand_side: tuple[Tensor] | Tensor, *, initial_value: tuple[Tensor] | Tensor | None = None, preconditioner_inverse: Callable[[Tensor], tuple[Tensor]] | None = None, max_iterations: int = 128, tolerance: float = 0.0001, callback: Callable[[CGStatus], bool | None] | None = None) tuple[Tensor] [source]
- mrpro.algorithms.optimizers.cg(operator: Callable[[Unpack[tuple[Tensor, ...]]], tuple[Tensor, ...]], right_hand_side: Sequence[Tensor], *, initial_value: Sequence[Tensor] | None = None, preconditioner_inverse: Callable[[Unpack[tuple[Tensor, ...]]], tuple[Tensor, ...]] | None = None, max_iterations: int = 128, tolerance: float = 0.0001, callback: Callable[[CGStatus], bool | None] | None = None) tuple[Tensor, ...]
(Preconditioned) Conjugate Gradient for solving \(Hx=b\).
This algorithm solves systems of the form \(H x = b\), where \(H\) is a self-adjoint positive semidefinite linear operator and \(b\) is the right-hand side.
The method performs the following steps:
Initialize the residual \(r_0 = b - Hx_0\) (with \(x_0\) as the initial guess).
Set the search direction \(p_0 = r_0\).
For each iteration \(k = 0, 1, 2, ...\):
Compute \(\alpha_k = \frac{r_k^T r_k}{p_k^T H p_k}\).
Update the solution: \(x_{k+1} = x_k + \alpha_k p_k\).
Compute the new residual: \(r_{k+1} = r_k - \alpha_k H p_k\).
- Update the search direction: \(\beta_k = \frac{r_{k+1}^T r_{k+1}}{r_k^T r_k}\),
then \(p_{k+1} = r_{k+1} + \beta_k p_k\).
The operator can be either a
LinearOperator
or aLinearOperatorMatrix
. In both cases, this implementation does not verify if the operator is self-adjoint and positive semidefinite. It will silently return the wrong result if the assumptions are not met. It can solve a batch of \(N\) systems jointly ifright_hand_side
has a batch dimension and the operator interprets the batch dimension as \(H\) being block-diagonal with blocks \(H_i\) resulting in \(b = [b_1, ..., b_N] ^T\).If
preconditioner_inverse
is provided, it solves \(M^{-1}Hx = M^{-1}b\) implicitly, wherepreconditioner_inverse(r)
computes \(M^{-1}r\).See [Hestenes1952], [Nocedal2006], and [WikipediaCG] for more information.
- Parameters:
operator (
LinearOperator
|LinearOperatorMatrix
|Callable
[[Unpack
[tuple
[Tensor
,...
]]],tuple
[Tensor
,...
]] |Callable
[[Tensor
],tuple
[Tensor
]]) – Self-adjoint operator \(H\)right_hand_side (
Sequence
[Tensor
] |Tensor
) – Right-hand-side \(b\).initial_value (
Sequence
[Tensor
] |Tensor
|None
, default:None
) – Initial guess \(x_0\). IfNone
, the initial guess is set to the zero vector.preconditioner_inverse (
LinearOperator
|LinearOperatorMatrix
|Callable
[[Unpack
[tuple
[Tensor
,...
]]],tuple
[Tensor
,...
]] |Callable
[[Tensor
],tuple
[Tensor
]] |None
, default:None
) – Preconditioner \(M^{-1}\). If None, no preconditioning is applied.max_iterations (
int
, default:128
) – Maximum number of iterations.tolerance (
float
, default:1e-4
) – Tolerance for the L2 norm of the residual \(\|r_k\|_2\).callback (
Callable
[[CGStatus
],bool
|None
] |None
, default:None
) – Function called at each iteration. SeeCGStatus
.
- Returns:
An approximate solution of the linear system \(Hx=b\).
References
[Hestenes1952]Hestenes, M. R., & Stiefel, E. (1952). Methods of conjugate gradients for solving linear systems. Journal of Research of the National Bureau of Standards , 49(6), 409-436
[Nocedal2006]Nocedal, J. (2006). Numerical Optimization (2nd ed.). Springer.
[WikipediaCG]Wikipedia: Conjugate Gradient https://en.wikipedia.org/wiki/Conjugate_gradient