linop — Base classes and algebraic operators

Base classes

class LinOp(ishape: tuple[int, ...], oshape: tuple[int, ...], name: str = "·"))[source]

Bases: ABC

An abstract base class for linear operators.

User must implement at least forward and adjoint methods in their concrete class.

Parameters:
  • ishape (tuple of int) – The shape of the input.

  • oshape (tuple of int) – The shape of the output.

  • name (str, optional) – The name of the operator.

metadata

Timing information populated automatically after each method call. See the guide for details.

Type:

dict

property isize: int

The input size N = math.prod(ishape).

property osize: int

The output size M = math.prod(oshape).

property shape: tuple[int, ...]

The shape (self.osize, self.isize) of the matrix.

property ndim: int

The number of dimensions (always 2).

property H: LinOp

Return Adjoint(self).

property G: LinOp

Return the Gram operator Aᴴ·A as a Symmetric.

abstractmethod forward(point: Array) Array[source]

Returns the forward application A·x.

abstractmethod adjoint(point: Array) Array[source]

Returns the adjoint application Aᴴ·y.

matvec(point: Array) Array[source]

Vectorized forward application A·x.

Parameters:

point (Array) – Column vector of shape (N, 1).

Returns:

Column vector of shape (M, 1).

Return type:

Array

rmatvec(point: Array) Array[source]

Vectorized adjoint application Aᴴ·y.

Parameters:

point (Array) – Column vector of shape (M, 1).

Returns:

Column vector of shape (N, 1).

Return type:

Array

fwadj(point: Array) Array[source]

Apply Aᴴ·A to point.

Parameters:

point (Array) – Input array of shape ishape.

Returns:

Output array of shape ishape.

Return type:

Array

asmatrix(like: Array | None = None) Array[source]

Return the matrix corresponding to the linear operator.

Applies forward to N unit vectors where N = linop.isize.

Parameters:

like (Array, optional) – If provided, use its array namespace; otherwise use float64 numpy array. See guide.

Returns:

2D array of shape (osize, isize).

Return type:

Array

Notes

Can be very heavy depending on the size of the operator.

class BaseOp(forward: Callable[[Array], Array], adjoint: Callable[[Array], Array], ishape: tuple[int, ...], oshape: tuple[int, ...], fwadj: Callable[[Array], Array] | None = None, name: str = '·')[source]

Bases: LinOp

A LinOp defined by callables rather than subclassing.

Parameters:
  • forward (callable) – The forward function x A·x.

  • adjoint (callable) – The adjoint function y Aᴴ·y.

  • ishape (tuple of int) – Shape of the input.

  • oshape (tuple of int) – Shape of the output.

  • fwadj (callable, optional) – The Aᴴ·A function. Defaults to adjoint(forward(x)).

  • name (str, optional) – Name of the operator.

forward(point: Array) Array[source]

Returns the forward application A·x.

adjoint(point: Array) Array[source]

Returns the adjoint application Aᴴ·y.

fwadj(point: Array) Array[source]

Apply Aᴴ·A to point.

Parameters:

point (Array) – Input array of shape ishape.

Returns:

Output array of shape ishape.

Return type:

Array

Algebraic operators

class Adjoint(linop: LinOp)[source]

Bases: LinOp

The adjoint Aᴴ of a linear operator A.

Adjoint is an involution: Adjoint(Adjoint(A)) is A.

Delegates to A methods.

Parameters:

linop (LinOp) – The operator to adjoint.

baseop

The base linear operator.

Type:

LinOp

property H: LinOp

Return the original operator (adjoint of adjoint is identity).

forward(point: Array) Array[source]

Returns the forward application A·x.

adjoint(point: Array) Array[source]

Returns the adjoint application Aᴴ·y.

asmatrix(like: Array | None = None) Array[source]

Return the matrix corresponding to the linear operator.

Applies forward to N unit vectors where N = linop.isize.

Parameters:

like (Array, optional) – If provided, use its array namespace; otherwise use float64 numpy array. See guide.

Returns:

2D array of shape (osize, isize).

Return type:

Array

Notes

Can be very heavy depending on the size of the operator.

class Scaled(baseop: LinOp, scale: complex | float)[source]

Bases: LinOp

An operator B scaled by a scalar γ (i.e. A = γ·B).

Parameters:
  • baseop (LinOp) – The base linear operator B.

  • scale (float or complex) – The scale factor γ.

baseop

The base linear operator B.

Type:

LinOp

scale

The scale factor γ.

Type:

complex or float

forward(point: Array) Array[source]

Returns the forward application A·x.

adjoint(point: Array) Array[source]

Returns the adjoint application Aᴴ·y.

fwadj(point: Array) Array[source]

Apply Aᴴ·A to point.

Parameters:

point (Array) – Input array of shape ishape.

Returns:

Output array of shape ishape.

Return type:

Array

asmatrix(like: Array | None = None) Array[source]

Return the matrix corresponding to the linear operator.

Applies forward to N unit vectors where N = linop.isize.

Parameters:

like (Array, optional) – If provided, use its array namespace; otherwise use float64 numpy array. See guide.

Returns:

2D array of shape (osize, isize).

Return type:

Array

Notes

Can be very heavy depending on the size of the operator.

class Symmetric(forward: Callable[[Array], Array], shape: tuple[int, ...], name: str = 'S')[source]

Bases: LinOp

A operator where Aᴴ = A.

For any Symmetric instance A, Adjoint(A) is A is True: it is fully defined by forward since adjoint delegates to it.

Parameters:
  • forward (callable) – The function implementing both forward and adjoint.

  • shape (tuple of int) – The (square) shape of the input and output.

  • name (str, optional) – Name of the operator.

classmethod gram(linop: LinOp) Symmetric[source]

Given B, return the Gram operator Bᴴ·B (self-adjoint).

property H: LinOp

the adjoint of a symmetric operator is itself.

Type:

Return self

forward(point: Array) Array[source]

Returns the application A·x.

adjoint(point: Array) Array[source]

Returns the adjoint application Aᴴ·y = A·y.

class Dense(matrix: Array, ishape: tuple[int, ...] | None = None, oshape: tuple[int, ...] | None = None, name: str = '_')[source]

Bases: LinOp

Dense linear operator from matrix instance.

Parameters:
  • matrix (Array) – A 2D array representing the operator. The namespace is inferred from this array.

  • ishape (tuple of int, optional) – Input shape. Defaults to (matrix.shape[1], 1).

  • oshape (tuple of int, optional) – Output shape. Defaults to (matrix.shape[0], 1).

  • name (str, optional) – Name of the operator.

forward(point: Array) Array[source]

Returns the forward application A·x.

adjoint(point: Array) Array[source]

Returns the adjoint application Aᴴ·y.

asmatrix(like: Array | None = None) Array[source]

Return the matrix corresponding to the linear operator.

Applies forward to N unit vectors where N = linop.isize.

Parameters:

like (Array, optional) – If provided, use its array namespace; otherwise use float64 numpy array. See guide.

Returns:

2D array of shape (osize, isize).

Return type:

Array

Notes

Can be very heavy depending on the size of the operator.

Compound operators

class ProdOp(left: LinOp, right: LinOp)[source]

Bases: LinOp

The product of two operators A·B.

Parameters:
  • left (LinOp) – The left operator A.

  • right (LinOp) – The right operator B.

forward(point: Array) Array[source]

Returns the forward application A·x.

adjoint(point: Array) Array[source]

Returns the adjoint application Aᴴ·y.

fwadj(point: Array) Array[source]

Apply Aᴴ·A to point.

Parameters:

point (Array) – Input array of shape ishape.

Returns:

Output array of shape ishape.

Return type:

Array

asmatrix(like: Array | None = None) Array[source]

Return the matrix corresponding to the linear operator.

Applies forward to N unit vectors where N = linop.isize.

Parameters:

like (Array, optional) – If provided, use its array namespace; otherwise use float64 numpy array. See guide.

Returns:

2D array of shape (osize, isize).

Return type:

Array

Notes

Can be very heavy depending on the size of the operator.

class AddOp(left: LinOp, right: LinOp)[source]

Bases: LinOp

The sum of two operators A + B.

Parameters:
  • left (LinOp) – The left operator.

  • right (LinOp) – The right operator.

forward(point: Array) Array[source]

Returns the forward application A·x.

adjoint(point: Array) Array[source]

Returns the adjoint application Aᴴ·y.

asmatrix(like: Array | None = None) Array[source]

Return the matrix corresponding to the linear operator.

Applies forward to N unit vectors where N = linop.isize.

Parameters:

like (Array, optional) – If provided, use its array namespace; otherwise use float64 numpy array. See guide.

Returns:

2D array of shape (osize, isize).

Return type:

Array

Notes

Can be very heavy depending on the size of the operator.

class SubOp(left: LinOp, right: LinOp)[source]

Bases: LinOp

The subtraction of two operators A - B.

Parameters:
  • left (LinOp) – The left operator.

  • right (LinOp) – The right operator.

forward(point: Array) Array[source]

Returns the forward application A·x.

adjoint(point: Array) Array[source]

Returns the adjoint application Aᴴ·y.

asmatrix(like: Array | None = None) Array[source]

Return the matrix corresponding to the linear operator.

Applies forward to N unit vectors where N = linop.isize.

Parameters:

like (Array, optional) – If provided, use its array namespace; otherwise use float64 numpy array. See guide.

Returns:

2D array of shape (osize, isize).

Return type:

Array

Notes

Can be very heavy depending on the size of the operator.

class VStack(oplist: ~typing.Sequence[~aljabr.linop.LinOp], name: str = "[·]"))[source]

Bases: LinOp

Vertical stack: maps x → vect([A₀x, A₁x, …]).

All operators must share the same ishape. forward returns a column vector of shape (sum(op.osize), 1). Use apply to get per-operator outputs as a list, or split to slice a column vector back into per-operator shapes.

VStack([A, B, C]).H returns HStack([Aᴴ, Bᴴ, Cᴴ]), and HStack([A, B, C]).H returns VStack([Aᴴ, Bᴴ, Cᴴ]).

So if y = vect([y₀, y₁, …]) of shape (N, 1), and A = VStack([A₀, A₁, …]), then y = Ax can be obtained with

>>> y_list = A.apply(x)          # list of per-operator outputs
>>> y = A.forward(x)             # stacked column vector, shape A.oshape
>>> A.split(y)                   # per-operator shapes, same as y_list
Parameters:
  • oplist (sequence of LinOp) – Operators to stack. All must share the same ishape.

  • name (str, optional) – Name of the operator.

Notes

This operator is for convenience. The recommendation is to write a custom operator that directly inherits from LinOp and implements forward and adjoint.

property H: HStack

Return HStack([Aᴴ, Bᴴ, …]), cached.

apply(point: Array) list[Array][source]

Apply each operator and return results as a list preserving shapes.

forward(point: Array) Array[source]

Returns the forward application A·x.

adjoint(point: Array) Array[source]

Returns the adjoint application Aᴴ·y.

split(point: Array) list[Array][source]

Split the output column vector back into per-operator shaped arrays.

class HStack(oplist: ~typing.Sequence[~aljabr.linop.LinOp], name: str = "[·|·]"):)[source]

Bases: LinOp

Horizontal stack: maps vect([x₀, x₁, …]) → Σ opᵢ(xᵢ).

Dual of VStack: all operators must share the same oshape. forward splits the input column vector by each operator’s ishape, applies op.forward, and sums. adjoint applies each op.adjoint to the same input and vectorizes the results.

VStack([A, B, C]).H returns HStack([Aᴴ, Bᴴ, Cᴴ]), and HStack([A, B, C]).H returns VStack([Aᴴ, Bᴴ, Cᴴ]).

So if x = vect([x₀, x₁, …]) of shape (M, 1), and A = HStack([A₀, A₁, …]), then y = Ax can be obtained with

>>> x_list = A.split(x)          # list of per-operator inputs
>>> y = A.forward(x)             # sum of op.forward(xᵢ), shape A.oshape
>>> A.apply(x)                   # per-operator outputs, same as x_list
Parameters:
  • oplist (sequence of LinOp) – Operators to stack. All must share the same oshape.

  • name (str, optional) – Name of the operator.

Notes

This operator is for convenience. The recommendation is to write a custom operator that directly inherits from LinOp and implements forward and adjoint.

property H: VStack

Return VStack([Aᴴ, Bᴴ, …]), cached.

forward(point: Array) Array[source]

Returns the forward application A·x.

adjoint(point: Array) Array[source]

Returns the adjoint application Aᴴ·y.

apply(point: Array) list[Array][source]

Split the input and apply each operator, returning results as a list.

split(point: Array) list[Array][source]

Split the input column vector into per-operator shaped arrays.

Types and utilities

vectorize(point: Array | Sequence[Array]) Array[source]

Vectorize an array or list of arrays as a column vector.

Parameters:

point (Array or list of Array) – A single array or a list of arrays to concatenate.

Returns:

Column vector of shape (N, 1).

Return type:

Array

unvectorize(point: Array, shapes: Sequence[tuple[int, ...]]) list[Array][source]

Unvectorize a column vector into a list of arrays.

Parameters:
  • point (Array) – Column vector of shape (N, 1).

  • shapes (list of Shape) – List of target shapes to split into.

Returns:

List of arrays with the given shapes.

Return type:

list of Array

asmatrix(linop: Array | LinOp, like: Array | None = None) Array[source]

Return the matrix corresponding to a linear operator or array.

Calls linop.asmatrix() if linop is a LinOp. Otherwise converts to array using xp.asarray (inferred from like) or numpy.asarray.

Parameters:
  • linop (Array or LinOp) – The linear operator or array to convert.

  • like (Array, optional) – If provided and linop is not a LinOp, use its array namespace.

Returns:

2D array representation.

Return type:

Array

Notes

The LinOp.asmatrix() method can be very heavy depending on operator size.