Showing 13 of 25 files from the diff.

@@ -3,6 +3,8 @@
Loading
 3 3 from abc import ABC, abstractmethod 4 4 from typing import Generic, Tuple, TypeVar 5 5 6 + from ._stopping_criterion import StoppingCriterion 7 + 6 8 ProblemType = TypeVar("ProblemType") 7 9 BeliefType = TypeVar("BeliefType") 8 10 StateType = TypeVar("StateType")
@@ -17,8 +19,8 @@
Loading
 17 19 18 20  Parameters 19 21  ---------- 20 -  prior : 21 -  Prior knowledge about quantities of interest for the numerical problem. 22 +  stopping_criterion 23 +  Stopping criterion determining when a desired terminal condition is met. 22 24 23 25  References 24 26  ----------
@@ -28,6 +30,11 @@
Loading
 28 30  .. [2] Cockayne, J., Oates, C., Sullivan Tim J. and Girolami M., Bayesian 29 31  probabilistic numerical methods. *SIAM Review*, 61(4):756–789, 2019 30 32 33 +  See Also 34 +  -------- 35 +  ~probnum.linalg.solvers.ProbabilisticLinearSolver : Compose a custom 36 +  probabilistic linear solver. 37 + 31 38  Notes 32 39  ----- 33 40  All PN methods should subclass this base class. Typically convenience functions
@@ -35,18 +42,19 @@
Loading
 35 42  derived subclass. 36 43  """ 37 44 38 -  def __init__(self, prior: BeliefType): 39 -  self.prior = prior 45 +  def __init__(self, stopping_criterion: StoppingCriterion): 46 +  self.stopping_criterion = stopping_criterion 40 47 41 48  @abstractmethod 42 49  def solve( 43 -  self, 44 -  problem: ProblemType, 50 +  self, prior: BeliefType, problem: ProblemType, **kwargs 45 51  ) -> Tuple[BeliefType, StateType]: 46 52  """Solve the given numerical problem. 47 53 48 54  Parameters 49 55  ---------- 56 +  prior : 57 +  Prior knowledge about quantities of interest of the numerical problem. 50 58  problem : 51 59  Numerical problem to be solved. 52 60  """

@@ -1,10 +1,10 @@
Loading
 1 1 """Linear Algebra. 2 2 3 - This package implements probabilistic numerical methods for the solution 4 - of problems arising in linear algebra, such as the solution of linear 5 - systems :math:Ax=b. 3 + This package implements probabilistic numerical methods for the solution of problems 4 + arising in linear algebra, such as the solution of linear systems :math:Ax=b. 6 5 """ 7 - from probnum.linalg._problinsolve import bayescg, problinsolve 6 + from probnum.linalg._bayescg import bayescg 7 + from probnum.linalg._problinsolve import problinsolve 8 8 9 9 from . import solvers 10 10

@@ -3,8 +3,25 @@
Loading
 3 3 Iterative probabilistic numerical methods solving linear systems :math:Ax = b. 4 4 """ 5 5 6 + from typing import Generator, Optional, Tuple 6 7 7 - class ProbabilisticLinearSolver: 8 + import numpy as np 9 + 10 + from probnum import ProbabilisticNumericalMethod, problems 11 + from probnum.linalg.solvers import ( 12 +  belief_updates, 13 +  beliefs, 14 +  information_ops, 15 +  policies, 16 +  stopping_criteria, 17 + ) 18 + 19 + from ._state import LinearSolverState 20 + 21 + 22 + class ProbabilisticLinearSolver( 23 +  ProbabilisticNumericalMethod[problems.LinearSystem, beliefs.LinearSystemBelief] 24 + ): 8 25  r"""Compose a custom probabilistic linear solver. 9 26 10 27  Class implementing probabilistic linear solvers. Such (iterative) solvers infer
@@ -20,7 +37,15 @@
Loading
 20 37 21 38  Parameters 22 39  ---------- 23 - 40 +  policy 41 +  Policy returning actions taken by the solver. 42 +  information_op 43 +  Information operator defining how information about the linear system is 44 +  obtained given an action. 45 +  belief_update 46 +  Belief update defining how to update the QoI beliefs given new observations. 47 +  stopping_criterion 48 +  Stopping criterion determining when a desired terminal condition is met. 24 49 25 50  References 26 51  ----------
@@ -35,9 +60,283 @@
Loading
 35 60 36 61  See Also 37 62  -------- 38 -  problinsolve : Solve linear systems in a Bayesian framework. 39 -  bayescg : Solve linear systems with prior information on the solution. 63 +  ~probnum.linalg.problinsolve : Solve linear systems in a Bayesian framework. 64 +  ~probnum.linalg.bayescg : Solve linear systems with prior information on the solution. 40 65 41 66  Examples 42 67  -------- 68 +  Define a linear system. 69 + 70 +  >>> import numpy as np 71 +  >>> from probnum.problems import LinearSystem 72 +  >>> from probnum.problems.zoo.linalg import random_spd_matrix 73 + 74 +  >>> rng = np.random.default_rng(42) 75 +  >>> n = 100 76 +  >>> A = random_spd_matrix(rng=rng, dim=n) 77 +  >>> b = rng.standard_normal(size=(n,)) 78 +  >>> linsys = LinearSystem(A=A, b=b) 79 + 80 +  Create a custom probabilistic linear solver from pre-defined components. 81 + 82 +  >>> from probnum.linalg.solvers import ( 83 +  ... ProbabilisticLinearSolver, 84 +  ... belief_updates, 85 +  ... beliefs, 86 +  ... information_ops, 87 +  ... policies, 88 +  ... stopping_criteria, 89 +  ... ) 90 + 91 +  >>> pls = ProbabilisticLinearSolver( 92 +  ... policy=policies.ConjugateGradientPolicy(), 93 +  ... information_op=information_ops.ProjectedRHSInformationOp(), 94 +  ... belief_update=belief_updates.solution_based.SolutionBasedProjectedRHSBeliefUpdate(), 95 +  ... stopping_criterion=( 96 +  ... stopping_criteria.MaxIterationsStoppingCriterion(100) 97 +  ... | stopping_criteria.ResidualNormStoppingCriterion(atol=1e-5, rtol=1e-5) 98 +  ... ), 99 +  ... ) 100 + 101 +  Define a prior over the solution. 102 + 103 +  >>> from probnum import linops, randvars 104 +  >>> prior = beliefs.LinearSystemBelief( 105 +  ... x=randvars.Normal( 106 +  ... mean=np.zeros((n,)), 107 +  ... cov=np.eye(n), 108 +  ... ), 109 +  ... ) 110 + 111 +  Solve the linear system using the custom solver. 112 + 113 +  >>> belief, solver_state = pls.solve(prior=prior, problem=linsys) 114 +  >>> np.linalg.norm(linsys.A @ belief.x.mean - linsys.b) / np.linalg.norm(linsys.b) 115 +  7.1886e-06 116 +  """ 117 + 118 +  def __init__( 119 +  self, 120 +  policy: policies.LinearSolverPolicy, 121 +  information_op: information_ops.LinearSolverInformationOp, 122 +  belief_update: belief_updates.LinearSolverBeliefUpdate, 123 +  stopping_criterion: stopping_criteria.LinearSolverStoppingCriterion, 124 +  ): 125 +  self.policy = policy 126 +  self.information_op = information_op 127 +  self.belief_update = belief_update 128 +  super().__init__(stopping_criterion=stopping_criterion) 129 + 130 +  def solve_iterator( 131 +  self, 132 +  prior: beliefs.LinearSystemBelief, 133 +  problem: problems.LinearSystem, 134 +  rng: Optional[np.random.Generator] = None, 135 +  ) -> Generator[LinearSolverState, None, None]: 136 +  """Generator implementing the solver iteration. 137 + 138 +  This function allows stepping through the solver iteration one step at a time 139 +  and exposes the internal solver state. 140 + 141 +  Parameters 142 +  ---------- 143 +  prior 144 +  Prior belief about the quantities of interest :math:(x, A, A^{-1}, b) of the linear system. 145 +  problem 146 +  Linear system to be solved. 147 +  rng 148 +  Random number generator. 149 + 150 +  Yields 151 +  ------ 152 +  solver_state 153 +  State of the probabilistic linear solver. 154 +  """ 155 +  solver_state = LinearSolverState(problem=problem, prior=prior, rng=rng) 156 + 157 +  while True: 158 + 159 +  yield solver_state 160 + 161 +  # Check stopping criterion 162 +  if self.stopping_criterion(solver_state=solver_state): 163 +  break 164 + 165 +  # Compute action via policy 166 +  solver_state.action = self.policy(solver_state=solver_state) 167 + 168 +  # Make observation via information operator 169 +  solver_state.observation = self.information_op(solver_state=solver_state) 170 + 171 +  # Update belief about the quantities of interest 172 +  solver_state.belief = self.belief_update(solver_state=solver_state) 173 + 174 +  # Advance state to next step and invalidate caches 175 +  solver_state.next_step() 176 + 177 +  def solve( 178 +  self, 179 +  prior: beliefs.LinearSystemBelief, 180 +  problem: problems.LinearSystem, 181 +  rng: Optional[np.random.Generator] = None, 182 +  ) -> Tuple[beliefs.LinearSystemBelief, LinearSolverState]: 183 +  r"""Solve the linear system. 184 + 185 +  Parameters 186 +  ---------- 187 +  prior 188 +  Prior belief about the quantities of interest :math:(x, A, A^{-1}, b) of the linear system. 189 +  problem 190 +  Linear system to be solved. 191 +  rng 192 +  Random number generator. 193 + 194 +  Returns 195 +  ------- 196 +  belief 197 +  Posterior belief :math:(\mathsf{x}, \mathsf{A}, \mathsf{H}, \mathsf{b}) 198 +  over the solution :math:x, the system matrix :math:A, its (pseudo-)inverse :math:H=A^\dagger and the right hand side :math:b. 199 +  solver_state 200 +  Final state of the solver. 201 +  """ 202 +  solver_state = None 203 + 204 +  for solver_state in self.solve_iterator(prior=prior, problem=problem, rng=rng): 205 +  pass 206 + 207 +  return solver_state.belief, solver_state 208 + 209 + 210 + class BayesCG(ProbabilisticLinearSolver): 211 +  r"""Bayesian conjugate gradient method. 212 + 213 +  Probabilistic linear solver taking prior information about the solution and 214 +  choosing :math:A-conjugate actions to gain information about the solution 215 +  by projecting the current residual. 216 + 217 +  This code implements the method described in Cockayne et al. [1]_. 218 + 219 +  Parameters 220 +  ---------- 221 +  stopping_criterion 222 +  Stopping criterion determining when a desired terminal condition is met. 223 + 224 +  References 225 +  ---------- 226 +  .. [1] Cockayne, J. et al., A Bayesian Conjugate Gradient Method, *Bayesian 227 +  Analysis*, 2019 228 +  """ 229 + 230 +  def __init__( 231 +  self, 232 +  stopping_criterion: stopping_criteria.LinearSolverStoppingCriterion = stopping_criteria.MaxIterationsStoppingCriterion() 233 +  | stopping_criteria.ResidualNormStoppingCriterion(atol=1e-5, rtol=1e-5), 234 +  ): 235 +  super().__init__( 236 +  policy=policies.ConjugateGradientPolicy(), 237 +  information_op=information_ops.ProjectedRHSInformationOp(), 238 +  belief_update=belief_updates.solution_based.SolutionBasedProjectedRHSBeliefUpdate(), 239 +  stopping_criterion=stopping_criterion, 240 +  ) 241 + 242 + 243 + class ProbabilisticKaczmarz(ProbabilisticLinearSolver): 244 +  r"""Probabilistic Kaczmarz method. 245 + 246 +  Probabilistic analogue of the (randomized) Kaczmarz method [1]_ [2]_, taking prior 247 +  information about the solution and randomly choosing rows of the matrix :math:A_i 248 +  and entries :math:b_i of the right-hand-side to obtain information about the solution. 249 + 250 +  Parameters 251 +  ---------- 252 +  stopping_criterion 253 +  Stopping criterion determining when a desired terminal condition is met. 254 + 255 +  References 256 +  ---------- 257 +  .. [1] Kaczmarz, Stefan, Angenäherte Auflösung von Systemen linearer Gleichungen, 258 +  *Bulletin International de l'Académie Polonaise des Sciences et des Lettres. Classe des Sciences Mathématiques et Naturelles. Série A, Sciences Mathématiques*, 1937 259 +  .. [2] Strohmer, Thomas; Vershynin, Roman, A randomized Kaczmarz algorithm for 260 +  linear systems with exponential convergence, *Journal of Fourier Analysis and Applications*, 2009 261 +  """ 262 + 263 +  def __init__( 264 +  self, 265 +  stopping_criterion: stopping_criteria.LinearSolverStoppingCriterion = stopping_criteria.MaxIterationsStoppingCriterion() 266 +  | stopping_criteria.ResidualNormStoppingCriterion(atol=1e-5, rtol=1e-5), 267 +  ): 268 +  super().__init__( 269 +  policy=policies.RandomUnitVectorPolicy(), 270 +  information_op=information_ops.ProjectedRHSInformationOp(), 271 +  belief_update=belief_updates.solution_based.SolutionBasedProjectedRHSBeliefUpdate(), 272 +  stopping_criterion=stopping_criterion, 273 +  ) 274 + 275 + 276 + class MatrixBasedPLS(ProbabilisticLinearSolver): 277 +  r"""Matrix-based probabilistic linear solver. 278 + 279 +  Probabilistic linear solver updating beliefs over the system matrix and its 280 +  inverse. The solver makes use of prior information and iteratively infers the matrix and its inverse by matrix-vector multiplication. 281 + 282 +  This code implements the method described in Wenger et al. [1]_. 283 + 284 +  Parameters 285 +  ---------- 286 +  policy 287 +  Policy returning actions taken by the solver. 288 +  stopping_criterion 289 +  Stopping criterion determining when a desired terminal condition is met. 290 + 291 +  References 292 +  ---------- 293 +  .. [1] Wenger, J. and Hennig, P., Probabilistic Linear Solvers for Machine Learning, 294 +  *Advances in Neural Information Processing Systems (NeurIPS)*, 2020 295 +  """ 296 + 297 +  def __init__( 298 +  self, 299 +  policy: policies.LinearSolverPolicy = policies.ConjugateGradientPolicy(), 300 +  stopping_criterion: stopping_criteria.LinearSolverStoppingCriterion = stopping_criteria.MaxIterationsStoppingCriterion() 301 +  | stopping_criteria.ResidualNormStoppingCriterion(atol=1e-5, rtol=1e-5), 302 +  ): 303 +  super().__init__( 304 +  policy=policy, 305 +  information_op=information_ops.MatVecInformationOp(), 306 +  belief_update=belief_updates.matrix_based.MatrixBasedLinearBeliefUpdate(), 307 +  stopping_criterion=stopping_criterion, 308 +  ) 309 + 310 + 311 + class SymMatrixBasedPLS(ProbabilisticLinearSolver): 312 +  r"""Symmetric matrix-based probabilistic linear solver. 313 + 314 +  Probabilistic linear solver updating beliefs over the symmetric system matrix and its inverse. The solver makes use of prior information and iteratively infers the matrix and its inverse by matrix-vector multiplication. 315 + 316 +  This code implements the method described in Wenger et al. [1]_. 317 + 318 +  Parameters 319 +  ---------- 320 +  policy 321 +  Policy returning actions taken by the solver. 322 +  stopping_criterion 323 +  Stopping criterion determining when a desired terminal condition is met. 324 + 325 +  References 326 +  ---------- 327 +  .. [1] Wenger, J. and Hennig, P., Probabilistic Linear Solvers for Machine Learning, 328 +  *Advances in Neural Information Processing Systems (NeurIPS)*, 2020 43 329  """ 330 + 331 +  def __init__( 332 +  self, 333 +  policy: policies.LinearSolverPolicy = policies.ConjugateGradientPolicy(), 334 +  stopping_criterion: stopping_criteria.LinearSolverStoppingCriterion = stopping_criteria.MaxIterationsStoppingCriterion() 335 +  | stopping_criteria.ResidualNormStoppingCriterion(atol=1e-5, rtol=1e-5), 336 +  ): 337 +  super().__init__( 338 +  policy=policy, 339 +  information_op=information_ops.MatVecInformationOp(), 340 +  belief_update=belief_updates.matrix_based.SymmetricMatrixBasedLinearBeliefUpdate(), 341 +  stopping_criterion=stopping_criterion, 342 +  )

@@ -1,5 +1,7 @@
Loading
 1 1 """Belief update in a solution-based inference view where the information is given by 2 2 projecting the current residual to a subspace.""" 3 + import numpy as np 4 + 3 5 import probnum # pylint: disable="unused-import" 4 6 from probnum import randvars 5 7 from probnum.linalg.solvers.beliefs import LinearSystemBelief
@@ -49,13 +51,16 @@
Loading
 49 51  gram = action_A @ cov_xy + self._noise_var 50 52  gram_pinv = 1.0 / gram if gram > 0.0 else 0.0 51 53  gain = cov_xy * gram_pinv 52 -  cov_update = gain @ cov_xy.T 54 +  cov_update = np.outer(gain, cov_xy) 53 55 54 56  x = randvars.Normal( 55 57  mean=solver_state.belief.x.mean + gain * proj_resid, 56 58  cov=solver_state.belief.x.cov - cov_update, 57 59  ) 58 -  Ainv = solver_state.belief.Ainv + cov_update 60 +  if solver_state.belief.Ainv is None: 61 +  Ainv = randvars.Constant(cov_update) 62 +  else: 63 +  Ainv = solver_state.belief.Ainv + cov_update 59 64 60 65  return LinearSystemBelief( 61 66  x=x, A=solver_state.belief.A, Ainv=Ainv, b=solver_state.belief.b

@@ -1,8 +1,7 @@
Loading
 1 1 """Linear system belief. 2 2 3 - Class defining a belief about the quantities of interest of a linear 4 - system such as its solution or the matrix inverse and any associated 5 - hyperparameters. 3 + Class defining a belief about the quantities of interest of a linear system such as its 4 + solution or the matrix inverse and any associated hyperparameters. 6 5 """ 7 6 8 7 from typing import Mapping, Optional
@@ -23,9 +22,12 @@
Loading
 23 22 24 23  Random variables :math:(\mathsf{x}, \mathsf{A}, \mathsf{H}, \mathsf{b}) 25 24  modelling the solution :math:x, the system matrix :math:A, its (pseudo-)inverse 26 -  :math:H=A^{-1} and the right hand side :math:b of a linear system :math:Ax=b, as well as any associated hyperparameters. 25 +  :math:H=A^{\dagger} and the right hand side :math:b of a linear system :math:Ax=b, 26 +  as well as any associated hyperparameters. 27 27 28 -  For instantiation either a belief about the solution or the inverse and right hand side must be provided. Note that if both are specified, their consistency is not checked and depending on the algorithm either may be used. 28 +  For instantiation either a belief about the solution or the inverse and right hand side 29 +  must be provided. Note that if both are specified, their consistency is not checked and 30 +  depending on the algorithm either may be used. 29 31 30 32  Parameters 31 33  ----------

@@ -5,22 +5,30 @@
Loading
 5 5 linear systems. 6 6 """ 7 7 8 - from probnum.linalg.solvers.matrixbased import ( 9 -  MatrixBasedSolver, 10 -  SymmetricMatrixBasedSolver, 11 - ) 12 - 13 8 from . import belief_updates, beliefs, information_ops, policies, stopping_criteria 14 - from ._probabilistic_linear_solver import ProbabilisticLinearSolver 9 + from ._probabilistic_linear_solver import ( 10 +  BayesCG, 11 +  MatrixBasedPLS, 12 +  ProbabilisticKaczmarz, 13 +  ProbabilisticLinearSolver, 14 +  SymMatrixBasedPLS, 15 + ) 15 16 from ._state import LinearSolverState 16 17 17 18 # Public classes and functions. Order is reflected in documentation. 18 19 __all__ = [ 19 20  "ProbabilisticLinearSolver", 20 -  "MatrixBasedSolver", 21 -  "SymmetricMatrixBasedSolver", 22 21  "LinearSolverState", 22 +  "BayesCG", 23 +  "ProbabilisticKaczmarz", 24 +  "MatrixBasedPLS", 25 +  "SymMatrixBasedPLS", 23 26 ] 24 27 25 28 # Set correct module paths. Corrects links and module paths in documentation. 26 29 ProbabilisticLinearSolver.__module__ = "probnum.linalg.solvers" 30 + LinearSolverState.__module__ = "probnum.linalg.solvers" 31 + BayesCG.__module__ = "probnum.linalg.solvers" 32 + ProbabilisticKaczmarz.__module__ = "probnum.linalg.solvers" 33 + MatrixBasedPLS.__module__ = "probnum.linalg.solvers" 34 + SymMatrixBasedPLS.__module__ = "probnum.linalg.solvers"

@@ -28,7 +28,12 @@
Loading
 28 28 29 29  Parameters 30 30  ---------- 31 -  solver_state : 31 +  solver_state 32 32  Current state of the linear solver. 33 + 34 +  Returns 35 +  ------- 36 +  action 37 +  Next action to take. 33 38  """ 34 39  raise NotImplementedError

@@ -0,0 +1,61 @@
Loading
 1 + """A Bayesian conjugate gradient method.""" 2 + 3 + from typing import Callable, Optional 4 + 5 + 6 + def bayescg( 7 +  A, 8 +  b, 9 +  x0=None, 10 +  maxiter: Optional[int] = None, 11 +  atol: float = 1e-5, 12 +  rtol: float = 1e-5, 13 +  callback: Optional[Callable] = None, 14 + ): 15 +  r"""Bayesian Conjugate Gradient Method. 16 + 17 +  In the setting where :math:A is a symmetric positive-definite matrix, this solver 18 +  takes prior information on the solution and outputs a posterior belief over 19 +  :math:x. This code implements the method described in Cockayne et al. [1]_. 20 + 21 +  Note that the solution-based view of BayesCG and the matrix-based view of 22 +  :meth:problinsolve correspond [2]_. 23 + 24 +  Parameters 25 +  ---------- 26 +  A 27 +  *shape=(n, n)* -- A symmetric positive definite matrix (or linear operator). Only matrix-vector products :math:Av are used internally. 28 +  b 29 +  *shape=(n, )* -- Right-hand side vector. 30 +  x0 31 +  *shape=(n, )* -- Prior belief for the solution of the linear system. 32 +  maxiter 33 +  Maximum number of iterations. Defaults to :math:10n, where :math:n is the 34 +  dimension of :math:A. 35 +  atol 36 +  Absolute residual tolerance. If :math:\lVert r_i \rVert = \lVert Ax_i - b 37 +  \rVert < \text{atol}, the iteration terminates. 38 +  rtol 39 +  Relative residual tolerance. If :math:\lVert r_i \rVert < \text{rtol} 40 +  \lVert b \rVert, the iteration terminates. 41 +  callback 42 +  User-supplied function called after each iteration of the linear solver. It is 43 +  called as callback(xk, sk, yk, alphak, resid, **kwargs) and can be used to 44 +  return quantities from the iteration. Note that depending on the function 45 +  supplied, this can slow down the solver. 46 + 47 +  Returns 48 +  ------- 49 + 50 +  References 51 +  ---------- 52 +  .. [1] Cockayne, J. et al., A Bayesian Conjugate Gradient Method, *Bayesian 53 +  Analysis*, 2019, 14, 937-1012 54 +  .. [2] Bartels, S. et al., Probabilistic Linear Solvers: A Unifying View, 55 +  *Statistics and Computing*, 2019 56 + 57 +  See Also 58 +  -------- 59 +  problinsolve : Solve linear systems in a Bayesian framework. 60 +  """ 61 +  raise NotImplementedError

@@ -46,7 +46,13 @@
Loading
 46 46  action=solver_state.observation, 47 47  observ=solver_state.action, 48 48  ) 49 -  return LinearSystemBelief(A=A, Ainv=Ainv, x=None, b=solver_state.belief.b) 49 + 50 +  if solver_state.belief.b is None: 51 +  b = randvars.Constant(solver_state.problem.b) 52 +  else: 53 +  b = solver_state.belief.b 54 + 55 +  return LinearSystemBelief(A=A, Ainv=Ainv, x=None, b=b) 50 56 51 57  def _matrix_based_update( 52 58  self, matrix: randvars.Normal, action: np.ndarray, observ: np.ndarray

@@ -1,9 +1,9 @@
Loading
 1 1 """Probabilistic numerical methods for solving linear systems. 2 2 3 - This module provides routines to solve linear systems of equations in a 4 - Bayesian framework. This means that a prior distribution over elements 5 - of the linear system can be provided and is updated with information 6 - collected by the solvers to return a posterior distribution. 3 + This module provides routines to solve linear systems of equations in a Bayesian 4 + framework. This means that a prior distribution over elements of the linear system can 5 + be provided and is updated with information collected by the solvers to return a 6 + posterior distribution. 7 7 """ 8 8 9 9 import warnings
@@ -230,54 +230,6 @@
Loading
 230 230  return x, A0, Ainv0, info 231 231 232 232 233 - def bayescg(A, b, x0=None, maxiter=None, atol=None, rtol=None, callback=None): 234 -  """Conjugate Gradients using prior information on the solution of the linear system. 235 - 236 -  In the setting where :math:A is a symmetric positive-definite matrix, this solver 237 -  takes prior information on the solution and outputs a posterior belief over 238 -  :math:x. This code implements the method described in Cockayne et al. [1]_. 239 - 240 -  Note that the solution-based view of BayesCG and the matrix-based view of 241 -  :meth:problinsolve correspond [2]_. 242 - 243 -  Parameters 244 -  ---------- 245 -  A : array-like or LinearOperator, shape=(n,n) 246 -  A square linear operator (or matrix). Only matrix-vector products :math:Av are 247 -  used internally. 248 -  b : array_like, shape=(n,) or (n, nrhs) 249 -  Right-hand side vector or matrix in :math:A x = b. 250 -  x0 : array-like or RandomVariable, shape=(n,) or or (n, nrhs) 251 -  Prior belief over the solution of the linear system. 252 -  maxiter : int 253 -  Maximum number of iterations. Defaults to :math:10n, where :math:n is the 254 -  dimension of :math:A. 255 -  atol : float, optional 256 -  Absolute residual tolerance. If :math:\\lVert r_i \\rVert = \\lVert Ax_i - b 257 -  \\rVert < \\text{atol}, the iteration terminates. 258 -  rtol : float, optional 259 -  Relative residual tolerance. If :math:\\lVert r_i \\rVert < \\text{rtol} 260 -  \\lVert b \\rVert, the iteration terminates. 261 -  callback : function, optional 262 -  User-supplied function called after each iteration of the linear solver. It is 263 -  called as callback(xk, sk, yk, alphak, resid, **kwargs) and can be used to 264 -  return quantities from the iteration. Note that depending on the function 265 -  supplied, this can slow down the solver. 266 - 267 -  References 268 -  ---------- 269 -  .. [1] Cockayne, J. et al., A Bayesian Conjugate Gradient Method, *Bayesian 270 -  Analysis*, 2019, 14, 937-1012 271 -  .. [2] Bartels, S. et al., Probabilistic Linear Solvers: A Unifying View, 272 -  *Statistics and Computing*, 2019 273 - 274 -  See Also 275 -  -------- 276 -  problinsolve : Solve linear systems in a Bayesian framework. 277 -  """ 278 -  raise NotImplementedError 279 - 280 - 281 233 def _check_linear_system(A, b, A0=None, Ainv0=None, x0=None): 282 234  """Check linear system compatibility. 283 235

@@ -66,8 +66,8 @@
Loading
 66 66  See Also 67 67  -------- 68 68  LambdaStoppingCriterion : Stopping criterion defined via an anonymous function. 69 -  LinearSolverStoppingCriterion : Stopping criterion of a probabilistic linear solver. 70 -  FiltSmoothStoppingCriterion : Stopping criterion of filters and smoothers. 69 +  ~probnum.linalg.solvers.stopping_criteria.LinearSolverStoppingCriterion : Stopping criterion of a probabilistic linear solver. 70 +  ~probnum.filtsmooth.optim.FiltSmoothStoppingCriterion : Stopping criterion of filters and smoothers. 71 71  """ 72 72 73 73  @abc.abstractmethod

@@ -47,7 +47,13 @@
Loading
 47 47  action=solver_state.observation, 48 48  observ=solver_state.action, 49 49  ) 50 -  return LinearSystemBelief(A=A, Ainv=Ainv, x=None, b=solver_state.belief.b) 50 + 51 +  if solver_state.belief.b is None: 52 +  b = randvars.Constant(solver_state.problem.b) 53 +  else: 54 +  b = solver_state.belief.b 55 + 56 +  return LinearSystemBelief(A=A, Ainv=Ainv, x=None, b=b) 51 57 52 58  def _symmetric_matrix_based_update( 53 59  self, matrix: randvars.Normal, action: np.ndarray, observ: np.ndarray
@@ -64,7 +70,9 @@
Loading
 64 70  gram = action.T @ covfactor_Ms 65 71  gram_pinv = 1.0 / gram if gram > 0.0 else 0.0 66 72  gain = covfactor_Ms * gram_pinv 67 -  covfactor_update = gain @ covfactor_Ms.T 73 +  covfactor_update = linops.aslinop(gain[:, None]) @ linops.aslinop( 74 +  covfactor_Ms[None, :] 75 +  ) 68 76  resid_gain = linops.aslinop(resid[:, None]) @ linops.aslinop(gain[None, :]) 69 77 70 78  return randvars.Normal(

@@ -31,10 +31,12 @@
Loading
 31 31  prior: "probnum.linalg.solvers.beliefs.LinearSystemBelief", 32 32  rng: Optional[np.random.Generator] = None, 33 33  ): 34 -  self.problem = problem 35 -  self.belief = prior 34 +  self.problem: problems.LinearSystem = problem 36 35 37 -  self.step = 0 36 +  self.prior: "probnum.linalg.solvers.beliefs.LinearSystemBelief" = prior 37 +  self._belief: "probnum.linalg.solvers.beliefs.LinearSystemBelief" = prior 38 + 39 +  self._step: int = 0 38 40 39 41  self._actions: List[np.ndarray] = [None] 40 42  self._observations: List[Any] = [None]
@@ -42,11 +44,27 @@
Loading
 42 44  self.problem.A @ self.belief.x.mean - self.problem.b, 43 45  None, 44 46  ] 45 -  self.rng = rng 47 +  self.rng: Optional[np.random.Generator] = rng 46 48 47 49  def __repr__(self) -> str: 48 50  return f"{self.__class__.__name__}(step={self.step})" 49 51 52 +  @property 53 +  def step(self) -> int: 54 +  """Current step of the solver.""" 55 +  return self._step 56 + 57 +  @property 58 +  def belief(self) -> "probnum.linalg.solvers.beliefs.LinearSystemBelief": 59 +  """Belief over the quantities of interest of the linear system.""" 60 +  return self._belief 61 + 62 +  @belief.setter 63 +  def belief( 64 +  self, belief: "probnum.linalg.solvers.beliefs.LinearSystemBelief" 65 +  ) -> None: 66 +  self._belief = belief 67 + 50 68  @property 51 69  def action(self) -> Optional[np.ndarray]: 52 70  """Action of the solver for the current step.
@@ -101,10 +119,10 @@
Loading
 101 119  def next_step(self) -> None: 102 120  """Advance the solver state to the next solver step. 103 121 104 -  Called after a completed step / iteration of the probabilistic linear solver. 122 +  Called after a completed step / iteration of the linear solver. 105 123  """ 106 124  self._actions.append(None) 107 125  self._observations.append(None) 108 126  self._residuals.append(None) 109 127 110 -  self.step += 1 128 +  self._step += 1
Files Coverage
src/probnum 89.38%
Project Totals (180 files) 89.38%
 1 coverage:  2  precision: 2  3  status:  4  project:  5  default:  6  target: auto  7  threshold: 1%  8  patch:  9  default:  10  target: 90%  11  threshold: 1%  12 13 comment:  14  layout: "reach, diff, files"  15  behavior: default  16  require_changes: true 
Sunburst
The inner-most circle is the entire project, moving away from the center are folders then, finally, a single file. The size and color of each slice is representing the number of statements and the coverage, respectively.
Icicle
The top section represents the entire project. Proceeding with folders and finally individual files. The size and color of each slice is representing the number of statements and the coverage, respectively.
Grid
Each block represents a single file in the project. The size and color of each block is represented by the number of statements and the coverage, respectively.
Loading