MatrixOperator
- class odl.MatrixOperator(*args, **kwargs)
Bases:
OperatorA matrix acting as a linear operator.
This operator uses a matrix to represent an operator, and get its adjoint and inverse by doing computations on the matrix. This is in general a rather slow and memory-inefficient approach, and users are recommended to use other alternatives if possible.
- __init__(matrix, domain=None, range=None, impl: str | None = None, device: str | None = None, axis=0)[source]
Initialize a new instance.
Parameters
- matrix
array-likeorscipy.sparse.base.spmatrix 2-dimensional array representing the linear operator. For Scipy sparse matrices only tensor spaces with
ndim == 1are allowed asdomain. The matrix is copied toimpl/device, if these are specified (only once, when the operator is initialized). If a plain Python list is supplied, it will first be converted to a NumPy array.- domain
TensorSpace, optional Space of elements on which the operator can act. Its
dtypemust be castable torange.dtype. For the defaultNone, a space with 1 axis and sizematrix.shape[1]is used, together with the matrix’ data type.- range
TensorSpace, optional Space of elements on to which the operator maps. Its
shapeanddtypeattributes must match those of the result of the multiplication. For the defaultNone, the range is inferred frommatrix,domainandaxis.- impl
ArrayBackend-identifyingstr, optional Which backend to use for the low-level matrix multiplication. If not explicitly provided, it will be inferred in the following order of preference, depending on what is available: 1. from
domain2. fromrange3. frommatrix- device
str, optional On which device to store the matrix. Same defaulting logic as for
impl.- axisint, optional
Sum over this axis of an input tensor in the multiplication.
Examples
By default,
domainandrangeare spaces of with one axis:>>> m = np.ones((3, 4)) >>> op = MatrixOperator(m) >>> op.domain rn(4) >>> op.range rn(3) >>> op([1, 2, 3, 4]) rn(3).element([ 10., 10., 10.])
For multi-dimensional arrays (tensors), the summation (contraction) can be performed along a specific axis. In this example, the number of matrix rows (4) must match the domain shape entry in the given axis:
>>> dom = odl.rn((5, 4, 4)) # can use axis=1 or axis=2 >>> op = MatrixOperator(m, domain=dom, axis=1) >>> op(dom.one()).shape (5, 3, 4) >>> op = MatrixOperator(m, domain=dom, axis=2) >>> op(dom.one()).shape (5, 4, 3)
The operator also works on
uniform_discrtype spaces. Note, however, that theweightingof the domain is propagated to the range by default, in order to keep the correspondence between adjoint and transposed matrix:>>> space = odl.uniform_discr(0, 1, 4) >>> op = MatrixOperator(m, domain=space) >>> op(space.one()) rn(3, weighting=0.25).element([ 4., 4., 4.]) >>> np.array_equal(op.adjoint.matrix, m.T) True
Notes
For a matrix
, the
operation on a tensor
is defined as the summation
It produces a new tensor
.- matrix