Skip to content

Commit

Permalink
Fixed the line-too-long message for all modules under `probnum.lina…
Browse files Browse the repository at this point in the history
…lg` subpackage. (#696)

* Fixed the `line-too-long` message for all modules under `probnum.linalg` subpackage.

* stopped ignoring the `line-too-long` issue for pylint checks by changing config in `tox.ini`.

* reduced lengths of all lines in `probnum.linalg` to under 88 in response to the failed pylint checks.

* Fixed minor formatting problems to fix `black` and `readthedocs` error messages.

* Fixed minor formatting problems in response to `black` error message.

* reformatted code using `black`

* disabled `line-too-long` check for `_probabilistic_linear_solver.py`

* Fixed formatting error in `_probabilistic_linear_solver.py`

* Added indentation in multi-line docstrings.

Co-authored-by: Qingxuan Wu <qingxuan.wu1@gmail.com>
Co-authored-by: Jonathan Wenger <jonathan.wenger@uni-tuebingen.de>
  • Loading branch information
3 people committed Apr 9, 2022
1 parent 93895f1 commit 275c492
Show file tree
Hide file tree
Showing 15 changed files with 133 additions and 59 deletions.
3 changes: 2 additions & 1 deletion src/probnum/linalg/_bayescg.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ def bayescg(
Parameters
----------
A
*shape=(n, n)* -- A symmetric positive definite matrix (or linear operator). Only matrix-vector products :math:`Av` are used internally.
*shape=(n, n)* -- A symmetric positive definite matrix (or linear operator).
Only matrix-vector products :math:`Av` are used internally.
b
*shape=(n, )* -- Right-hand side vector.
x0
Expand Down
38 changes: 27 additions & 11 deletions src/probnum/linalg/solvers/_probabilistic_linear_solver.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
Iterative probabilistic numerical methods solving linear systems :math:`Ax = b`.
"""

# pylint: disable=line-too-long

from __future__ import annotations

from typing import Generator, Optional, Tuple
Expand Down Expand Up @@ -63,7 +65,8 @@ class ProbabilisticLinearSolver(
See Also
--------
~probnum.linalg.problinsolve : Solve linear systems in a Bayesian framework.
~probnum.linalg.bayescg : Solve linear systems with prior information on the solution.
~probnum.linalg.bayescg : Solve linear systems with prior information on the
solution.
Examples
--------
Expand Down Expand Up @@ -143,7 +146,8 @@ def solve_iterator(
Parameters
----------
prior
Prior belief about the quantities of interest :math:`(x, A, A^{-1}, b)` of the linear system.
Prior belief about the quantities of interest :math:`(x, A, A^{-1}, b)` of
the linear system.
problem
Linear system to be solved.
rng
Expand Down Expand Up @@ -187,7 +191,8 @@ def solve(
Parameters
----------
prior
Prior belief about the quantities of interest :math:`(x, A, A^{-1}, b)` of the linear system.
Prior belief about the quantities of interest :math:`(x, A, A^{-1}, b)` of
the linear system.
problem
Linear system to be solved.
rng
Expand All @@ -197,7 +202,9 @@ def solve(
-------
belief
Posterior belief :math:`(\mathsf{x}, \mathsf{A}, \mathsf{H}, \mathsf{b})`
over the solution :math:`x`, the system matrix :math:`A`, its (pseudo-)inverse :math:`H=A^\dagger` and the right hand side :math:`b`.
over the solution :math:`x`, the system matrix :math:`A`, its
(pseudo-)inverse :math:`H=A^\dagger` and the right hand side
:math:`b`.
solver_state
Final state of the solver.
"""
Expand Down Expand Up @@ -247,7 +254,8 @@ class ProbabilisticKaczmarz(ProbabilisticLinearSolver):
Probabilistic analogue of the (randomized) Kaczmarz method [1]_ [2]_, taking prior
information about the solution and randomly choosing rows of the matrix :math:`A_i`
and entries :math:`b_i` of the right-hand-side to obtain information about the solution.
and entries :math:`b_i` of the right-hand-side to obtain information about
the solution.
Parameters
----------
Expand All @@ -257,9 +265,12 @@ class ProbabilisticKaczmarz(ProbabilisticLinearSolver):
References
----------
.. [1] Kaczmarz, Stefan, Angenäherte Auflösung von Systemen linearer Gleichungen,
*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
*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
.. [2] Strohmer, Thomas; Vershynin, Roman, A randomized Kaczmarz algorithm for
linear systems with exponential convergence, *Journal of Fourier Analysis and Applications*, 2009
linear systems with exponential convergence, *Journal of Fourier Analysis and
Applications*, 2009
"""

def __init__(
Expand All @@ -278,8 +289,9 @@ def __init__(
class MatrixBasedPLS(ProbabilisticLinearSolver):
r"""Matrix-based probabilistic linear solver.
Probabilistic linear solver updating beliefs over the system matrix and its
inverse. The solver makes use of prior information and iteratively infers the matrix and its inverse by matrix-vector multiplication.
Probabilistic linear solver updating beliefs over the system matrix and its inverse.
The solver makes use of prior information and iteratively infers the matrix and
its inverse by matrix-vector multiplication.
This code implements the method described in Wenger et al. [1]_.
Expand Down Expand Up @@ -313,7 +325,9 @@ def __init__(
class SymMatrixBasedPLS(ProbabilisticLinearSolver):
r"""Symmetric matrix-based probabilistic linear solver.
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.
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.
This code implements the method described in Wenger et al. [1]_.
Expand All @@ -339,6 +353,8 @@ def __init__(
super().__init__(
policy=policy,
information_op=information_ops.MatVecInformationOp(),
belief_update=belief_updates.matrix_based.SymmetricMatrixBasedLinearBeliefUpdate(),
belief_update=(
belief_updates.matrix_based.SymmetricMatrixBasedLinearBeliefUpdate()
),
stopping_criterion=stopping_criterion,
)
11 changes: 7 additions & 4 deletions src/probnum/linalg/solvers/_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,13 @@
class LinearSolverState:
"""State of a probabilistic linear solver.
The solver state separates the state of a probabilistic linear solver from the algorithm itself, making the solver stateless.
The state contains the problem to be solved, the current belief over the quantities of interest and any miscellaneous quantities
computed during an iteration of a probabilistic linear solver. The solver state is passed between the different components of the
solver and may be used internally to cache quantities which are used more than once.
The solver state separates the state of a probabilistic linear solver from the
algorithm itself, making the solver stateless.
The state contains the problem to be solved, the current belief over the quantities
of interest and any miscellaneous quantities computed during an iteration of
a probabilistic linear solver.
The solver state is passed between the different components of the solver and
may be used internally to cache quantities which are used more than once.
Parameters
----------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
class LinearSolverBeliefUpdate(abc.ABC):
r"""Belief update for the quantities of interest of a linear system.
Given a solver state containing information about the linear system collected in the current step, update the belief about the quantities of interest.
Given a solver state containing information about the linear system collected
in the current step, update the belief about the quantities of interest.
"""

@abc.abstractmethod
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,14 @@


class MatrixBasedLinearBeliefUpdate(LinearSolverBeliefUpdate):
r"""Gaussian belief update in a matrix-based inference framework assuming linear information.
r"""Gaussian belief update in a matrix-based inference framework assuming
linear information.
Updates the belief over the quantities of interest of a linear system :math:`Ax=b` given matrix-variate Gaussian beliefs with Kronecker covariance structure and linear observations :math:`y=As`. The belief update computes :math:`p(M \mid y) = \mathcal{N}(M; M_{i+1}, V \otimes W_{i+1})`, [1]_ [2]_ such that
Updates the belief over the quantities of interest of a linear system :math:`Ax=b`
given matrix-variate Gaussian beliefs with Kronecker covariance structure and
linear observations :math:`y=As`.
The belief update computes :math:`p(M \mid y) = \mathcal{N}(M; M_{i+1},
V \otimes W_{i+1})`, [1]_ [2]_ such that
.. math ::
\begin{align}
Expand Down Expand Up @@ -60,7 +65,9 @@ def _matrix_based_update(
"""Matrix-based inference update for linear information."""
if not isinstance(matrix.cov, linops.Kronecker):
raise ValueError(
f"Covariance must have Kronecker structure, but is '{type(matrix.cov).__name__}'."
f"""Covariance must have Kronecker structure, but is
'{type(matrix.cov).__name__}'.
"""
)

pred = matrix.mean @ action
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,19 @@


class SymmetricMatrixBasedLinearBeliefUpdate(LinearSolverBeliefUpdate):
r"""Symmetric Gaussian belief update in a matrix-based inference framework assuming linear information.
r"""Symmetric Gaussian belief update in a matrix-based inference framework assuming
linear information.
Updates the belief over the quantities of interest of a linear system :math:`Ax=b` given symmetric matrix-variate Gaussian beliefs with symmetric Kronecker covariance structure and linear observations. The belief update computes :math:`p(M \mid y) = \mathcal{N}(M; M_{i+1}, W_{i+1} \otimes_s W_{i+1})`, [1]_ [2]_ such that
Updates the belief over the quantities of interest of a linear system :math:`Ax=b`
given symmetric matrix-variate Gaussian beliefs with symmetric Kronecker covariance
structure and linear observations.
The belief update computes :math:`p(M \mid y) = \mathcal{N}(M; M_{i+1}, W_{i+1}
\otimes_s W_{i+1})`, [1]_ [2]_ such that
.. math ::
\begin{align}
M_{i+1} &= M_i + (y - M_i s) u^\top + u (y - M_i s)^\top - u s^\top(y - M_i s)u^\top,\\
M_{i+1} &= M_i + (y - M_i s) u^\top + u (y - M_i s)^\top
- u s^\top(y - M_i s)u^\top,\\
W_{i+1} &= W_i - W_i s (s^\top W_i s)^\dagger s^\top W_i.
\end{align}
Expand Down Expand Up @@ -61,7 +67,9 @@ def _symmetric_matrix_based_update(
"""Symmetric matrix-based inference update for linear information."""
if not isinstance(matrix.cov, linops.SymmetricKronecker):
raise ValueError(
f"Covariance must have symmetric Kronecker structure, but is '{type(matrix.cov).__name__}'."
f"""Covariance must have symmetric Kronecker structure, but
is'{type(matrix.cov).__name__}'.
"""
)

pred = matrix.mean @ action
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,18 @@
class ProjectedResidualBeliefUpdate(LinearSolverBeliefUpdate):
r"""Gaussian belief update given projected residual information.
Updates the belief over the quantities of interest of a linear system :math:`Ax=b` given a Gaussian belief over the solution :math:`x` and information of the form :math:`s\^top r_i = s^\top (b - Ax_i) = s^\top A (x - x_i)`. The belief update computes the posterior belief about the solution, given by :math:`p(x \mid y) = \mathcal{N}(x; x_{i+1}, \Sigma_{i+1})`, such that
Updates the belief over the quantities of interest of a linear system :math:`Ax=b`
given a Gaussian belief over the solution :math:`x` and information of the form
:math:`s\^top r_i = s^\top (b - Ax_i) = s^\top A (x - x_i)`.
The belief update computes the posterior belief about the solution, given by
:math:`p(x \mid y) = \mathcal{N}(x; x_{i+1}, \Sigma_{i+1})`, such that
.. math ::
\begin{align}
x_{i+1} &= x_i + \Sigma_i A^\top s (s^\top A \Sigma_i A^\top s + \lambda)^\dagger s^\top r_i,\\
\Sigma_{i+1} &= \Sigma_i - \Sigma_i A^\top s (s^\top A \Sigma_i A s + \lambda)^\dagger s^\top A \Sigma_i,
x_{i+1} &= x_i + \Sigma_i A^\top s (s^\top A \Sigma_i A^\top s +
\lambda)^\dagger s^\top r_i,\\
\Sigma_{i+1} &= \Sigma_i - \Sigma_i A^\top s (s^\top A \Sigma_i A s +
\lambda)^\dagger s^\top A \Sigma_i,
\end{align}
where :math:`\lambda` is the noise variance.
Expand Down
51 changes: 34 additions & 17 deletions src/probnum/linalg/solvers/beliefs/_linear_system_belief.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""Linear system belief.
Class defining a belief about the quantities of interest of a linear system such as its
solution or the matrix inverse and any associated hyperparameters.
Class defining a belief about the quantities of interest of a linear system such
as its solution or the matrix inverse and any associated hyperparameters.
"""

from functools import cached_property
Expand All @@ -16,13 +16,13 @@ class LinearSystemBelief:
r"""Belief about quantities of interest of a linear system.
Random variables :math:`(\mathsf{x}, \mathsf{A}, \mathsf{H}, \mathsf{b})`
modelling the solution :math:`x`, the system matrix :math:`A`, its (pseudo-)inverse
:math:`H=A^{\dagger}` and the right hand side :math:`b` of a linear system :math:`Ax=b`,
as well as any associated hyperparameters.
modelling the solution :math:`x`, the system matrix :math:`A`, its
(pseudo-)inverse :math:`H=A^{\dagger}` and the right hand side :math:`b` of
a linear system :math:`Ax=b`, as well as any associated hyperparameters.
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.
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.
Parameters
----------
Expand Down Expand Up @@ -56,14 +56,17 @@ def __init__(
def dim_mismatch_error(**kwargs):
argnames = list(kwargs.keys())
return ValueError(
f"Dimension mismatch. The shapes of {argnames[0]} : {kwargs[argnames[0]].shape} "
f"Dimension mismatch. The shapes of {argnames[0]} :\
{kwargs[argnames[0]].shape} "
f"and {argnames[1]} : {kwargs[argnames[1]].shape} must match."
)

if x is not None:
if x.ndim > 2 or x.ndim < 1:
raise ValueError(
f"Belief over solution must have either one or two dimensions, but has {x.ndim}."
f"""Belief over solution must have either one or two dimensions,
but has {x.ndim}.
"""
)
if A is not None:
if A.shape[1] != x.shape[0]:
Expand All @@ -79,7 +82,9 @@ def dim_mismatch_error(**kwargs):
if Ainv is not None:
if Ainv.ndim != 2:
raise ValueError(
f"Belief over the inverse system matrix may have at most two dimensions, but has {Ainv.ndim}."
f"""Belief over the inverse system matrix may have at most two
dimensions, but has {Ainv.ndim}.
"""
)
if A is not None:
if A.shape != Ainv.shape:
Expand All @@ -88,7 +93,9 @@ def dim_mismatch_error(**kwargs):
if A is not None:
if A.ndim != 2:
raise ValueError(
f"Belief over the system matrix may have at most two dimensions, but has {A.ndim}."
f"""Belief over the system matrix may have at most two dimensions
, but has {A.ndim}.
"""
)
if b is not None:
if A.shape[0] != b.shape[0]:
Expand All @@ -97,24 +104,34 @@ def dim_mismatch_error(**kwargs):
if b is not None:
if b.ndim > 2 or b.ndim < 1:
raise ValueError(
f"Belief over right-hand-side may have either one or two dimensions but has {b.ndim}."
f"""Belief over right-hand-side may have either one or two
dimensions but has {b.ndim}.
"""
)

if x is not None and not isinstance(x, randvars.RandomVariable):
raise TypeError(
f"The belief about the solution 'x' must be a RandomVariable, but is {type(x)}."
f"""The belief about the solution 'x' must be a RandomVariable, but
is {type(x)}.
"""
)
if A is not None and not isinstance(A, randvars.RandomVariable):
raise TypeError(
f"The belief about the matrix 'A' must be a RandomVariable, but is {type(A)}."
f"""The belief about the matrix 'A' must be a RandomVariable, but
is {type(A)}.
"""
)
if Ainv is not None and not isinstance(Ainv, randvars.RandomVariable):
raise TypeError(
f"The belief about the inverse matrix 'Ainv' must be a RandomVariable, but is {type(Ainv)}."
f"""The belief about the inverse matrix 'Ainv' must be a RandomVariable,
but is {type(Ainv)}.
"""
)
if b is not None and not isinstance(b, randvars.RandomVariable):
raise TypeError(
f"The belief about the right-hand-side 'b' must be a RandomVariable, but is {type(b)}."
f"""The belief about the right-hand-side 'b' must be a RandomVariable,
but is {type(b)}.
"""
)

self._x = x
Expand Down
3 changes: 2 additions & 1 deletion src/probnum/linalg/solvers/information_ops/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
by observing the numerical problem to be solved given an action. When solving
linear systems, the information operator takes an action vector and observes
the tuple :math:`(A, b)`, returning an observation vector. For example, one might
observe the right hand side :math:`y = b^\top s = (Ax)^\top s` with the action :math:`s`.
observe the right hand side :math:`y = b^\top s = (Ax)^\top s` with the action
:math:`s`.
"""

from ._linear_solver_information_op import LinearSolverInformationOp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@
class LinearSolverInformationOp(abc.ABC):
r"""Information operator of a (probabilistic) linear solver.
For a given action, the information operator collects information about the linear system to be solved.
For a given action, the information operator collects information about the
linear system to be solved.
See Also
--------
MatVecInformationOp: Collect information via matrix-vector multiplication.
ProjectedResidualInformationOp: Collect information via a projection of the current residual.
ProjectedResidualInformationOp: Collect information via a projection of the
current residual.
"""

@abc.abstractmethod
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,17 @@
class ProjectedResidualInformationOp(LinearSolverInformationOp):
r"""Projected residual information operator.
Obtain information about a linear system by projecting the residual :math:`b-Ax_{i-1}` onto a given action :math:`s_i` resulting in :math:`s_i \mapsto s_i^\top r_{i-1} = s_i^\top (b - A x_{i-1}) = s_i^\top A (x - x_{i-1})`.
Obtain information about a linear system by projecting the residual
:math:`b-Ax_{i-1}` onto a given action :math:`s_i` resulting in :math:`s_i
\mapsto s_i^\top r_{i-1} = s_i^\top (b - A x_{i-1}) = s_i^\top
A (x - x_{i-1})`.
"""

def __call__(
self, solver_state: "probnum.linalg.solvers.LinearSolverState"
) -> np.ndarray:
r"""Projected residual :math:`s_i^\top r_{i-1} = s_i^\top (b - A x_{i-1})` of the linear system.
r"""Projected residual :math:`s_i^\top r_{i-1} = s_i^\top (b - A x_{i-1})`
of the linear system.
Parameters
----------
Expand Down

0 comments on commit 275c492

Please sign in to comment.