Source code for suppy.feasibility._hyperplanes._kaczmarz_extrapolations

from typing import List
import numpy as np
import numpy.typing as npt
from scipy import sparse

try:
    import cupy as cp

    NO_GPU = False

except ImportError:
    NO_GPU = True
    cp = np


from suppy.feasibility._hyperplanes._kaczmarz_algorithms import SimultaneousKaczmarzMethod


[docs] class ExtrapolatedLandweberHyperplane(SimultaneousKaczmarzMethod): """ Extrapolated Landweber algorithm for solving linear equalities of the form Ax = b. Parameters ---------- A : npt.NDArray or sparse.sparray Matrix for linear systems b : npt.NDArray Bound for linear systems relaxation : float, optional The outer relaxation parameter, by default 1.0. weights : None or List[float], optional The weights for the constraints, by default None. proximity_flag : bool, optional Flag to indicate if proximity calculations should be performed, by default True. References ---------- - [1] https://doi.org/10.1007/s11075-025-02163-0 - [2] https://doi.org/10.1007/978-3-642-30901-4 """ def __init__( self, A: npt.NDArray | sparse.sparray, b: npt.NDArray, relaxation: float = 1.0, weights: None | List[float] | npt.NDArray = None, proximity_flag: bool = True, ): super().__init__(A, b, 1.0, relaxation, weights, proximity_flag) self.a_i = self.A.row_norm(2, 2) self.weight_norm = self.weights / self.a_i self.sigmas = [] def _project(self, x: npt.NDArray) -> np.ndarray: xp = cp if self._use_gpu else np p = self.map(x) res = self.b - p res_idx = res != 0 if not xp.any(res_idx): self.sigmas.append(0) return x t = self.weight_norm * res t_2 = t @ self.A sig = (res @ t) / (t_2 @ t_2) self.sigmas.append(sig) x += sig * t_2 return x
[docs] class AdaptiveStepLandweberHyperplane(SimultaneousKaczmarzMethod): """ Landweber algorithm with adaptive step size for solving linear equalities of the form Ax = b. Parameters ---------- A : npt.NDArray or sparse.sparray Matrix for linear systems b : npt.NDArray Bound for linear systems relaxation : float, optional The outer relaxation parameter, by default 1.0. weights : None or List[float], optional The weights for the constraints, by default None. proximity_flag : bool, optional Flag to indicate if proximity calculations should be performed, by default True. References ---------- - [1] https://doi.org/10.1515/jiip-2015-0082 """ def __init__( self, A: npt.NDArray | sparse.sparray, b: npt.NDArray, relaxation: float = 1.0, weights: None | List[float] | npt.NDArray = None, proximity_flag: bool = True, ): super().__init__(A, b, 1.0, relaxation, weights, proximity_flag) self.sigmas = [] def _project(self, x: npt.NDArray) -> np.ndarray: xp = cp if self._use_gpu else np p = self.map(x) res = self.b - p res_idx = res != 0 if not xp.any(res_idx): self.sigmas.append(0) return x u_t = (self.weights * res) @ self.A Au_t = self.A @ u_t sig = (u_t @ u_t) / (Au_t @ (self.weights * Au_t)) self.sigmas.append(sig) x += sig * u_t return x