Coverage for suppy\feasibility\_hyperplanes\_kaczmarz_extrapolations.py: 86%
49 statements
« prev ^ index » next coverage.py v7.6.4, created at 2026-05-08 13:56 +0200
« prev ^ index » next coverage.py v7.6.4, created at 2026-05-08 13:56 +0200
1from typing import List
2import numpy as np
3import numpy.typing as npt
4from scipy import sparse
6try:
7 import cupy as cp
9 NO_GPU = False
11except ImportError:
12 NO_GPU = True
13 cp = np
16from suppy.feasibility._hyperplanes._kaczmarz_algorithms import SimultaneousKaczmarzMethod
19class ExtrapolatedLandweberHyperplane(SimultaneousKaczmarzMethod):
20 """
21 Extrapolated Landweber algorithm for solving linear equalities of the
22 form Ax = b.
24 Parameters
25 ----------
26 A : npt.NDArray or sparse.sparray
27 Matrix for linear systems
28 b : npt.NDArray
29 Bound for linear systems
30 relaxation : float, optional
31 The outer relaxation parameter, by default 1.0.
32 weights : None or List[float], optional
33 The weights for the constraints, by default None.
34 proximity_flag : bool, optional
35 Flag to indicate if proximity calculations should be performed, by default True.
37 References
38 ----------
39 - [1] https://doi.org/10.1007/s11075-025-02163-0
40 - [2] https://doi.org/10.1007/978-3-642-30901-4
41 """
43 def __init__(
44 self,
45 A: npt.NDArray | sparse.sparray,
46 b: npt.NDArray,
47 relaxation: float = 1.0,
48 weights: None | List[float] | npt.NDArray = None,
49 proximity_flag: bool = True,
50 ):
51 super().__init__(A, b, 1.0, relaxation, weights, proximity_flag)
52 self.a_i = self.A.row_norm(2, 2)
53 self.weight_norm = self.weights / self.a_i
54 self.sigmas = []
56 def _project(self, x: npt.NDArray) -> np.ndarray:
57 xp = cp if self._use_gpu else np
58 p = self.map(x)
59 res = self.b - p
60 res_idx = res != 0
61 if not xp.any(res_idx):
62 self.sigmas.append(0)
63 return x
64 t = self.weight_norm * res
65 t_2 = t @ self.A
66 sig = (res @ t) / (t_2 @ t_2)
67 self.sigmas.append(sig)
68 x += sig * t_2
70 return x
73class AdaptiveStepLandweberHyperplane(SimultaneousKaczmarzMethod):
74 """
75 Landweber algorithm with adaptive step size for solving linear
76 equalities
77 of the form Ax = b.
79 Parameters
80 ----------
81 A : npt.NDArray or sparse.sparray
82 Matrix for linear systems
83 b : npt.NDArray
84 Bound for linear systems
85 relaxation : float, optional
86 The outer relaxation parameter, by default 1.0.
87 weights : None or List[float], optional
88 The weights for the constraints, by default None.
89 proximity_flag : bool, optional
90 Flag to indicate if proximity calculations should be performed, by default True.
92 References
93 ----------
94 - [1] https://doi.org/10.1515/jiip-2015-0082
95 """
97 def __init__(
98 self,
99 A: npt.NDArray | sparse.sparray,
100 b: npt.NDArray,
101 relaxation: float = 1.0,
102 weights: None | List[float] | npt.NDArray = None,
103 proximity_flag: bool = True,
104 ):
105 super().__init__(A, b, 1.0, relaxation, weights, proximity_flag)
106 self.sigmas = []
108 def _project(self, x: npt.NDArray) -> np.ndarray:
109 xp = cp if self._use_gpu else np
110 p = self.map(x)
111 res = self.b - p
112 res_idx = res != 0
113 if not xp.any(res_idx):
114 self.sigmas.append(0)
115 return x
116 u_t = (self.weights * res) @ self.A
117 Au_t = self.A @ u_t
118 sig = (u_t @ u_t) / (Au_t @ (self.weights * Au_t))
119 self.sigmas.append(sig)
120 x += sig * u_t
122 return x