The blkop Module

Linear operators are sometimes defined by blocks. This is often the case in numerical optimization and the solution of partial-differential equations. An example of operator defined by blocks is

\[\begin{split}K = \begin{bmatrix} A & B \\ C & D \end{bmatrix}\end{split}\]

where \(A\), \(B\), \(C\) and \(D\) are linear operators (perhaps themselves defined by blocks) of appropriate shape.

The general class BlockLinearOperator may be used to represent the operator above. If more structure is present, for example if the off-diagonal blocks are zero, \(K\) is a block-diagonal operator and the class BlockDiagonalLinearOperator may be used to define it.

General Block Operators

General block operators are defined using a list of lists, each of which defines a block row. If the block operator is specified as symmetric, each block on the diagonal must be symmetric. For example:

A = LinearOperator(nargin=3, nargout=3,
                matvec=lambda v: 2*v, symmetric=True)
B = LinearOperator(nargin=4, nargout=3, matvec=lambda v: v[:3],
                rmatvec=lambda v: np.concatenate((v, np.zeros(1))))
C = LinearOperator(nargin=3, nargout=2, matvec=lambda v: v[:2],
                rmatvec=lambda v: np.concatenate((v, np.zeros(1))))
D = LinearOperator(nargin=4, nargout=2, matvec=lambda v: v[:2],
                rmatvec=lambda v: np.concatenate((v, np.zeros(2))))
E = LinearOperator(nargin=4, nargout=4,
                matvec=lambda v: -v, symmetric=True)

# Build [A  B].
K1 = BlockLinearOperator([[A, B]])

# Build [A  B]
#       [C  D].
K2 = BlockLinearOperator([[A, B], [C, D]])

# Build [A]
#       [C].
K3 = BlockLinearOperator([[A], [C]])

# Build [A  B]
#       [B' E].
K4 = BlockLinearOperator([[A, B], [E]], symmetric=True)
class linop.blkop.BlockLinearOperator(blocks, symmetric=False, **kwargs)

Bases: linop.linop.LinearOperator

A linear operator defined by blocks. Each block must be a linear operator.

blocks should be a list of lists describing the blocks row-wise. If there is only one block row, it should be specified as [[b1, b2, ..., bn]], not as [b1, b2, ..., bn].

If the overall linear operator is symmetric, only its upper triangle need be specified, e.g., [[A,B,C], [D,E], [F]], and the blocks on the diagonal must be square and symmetric.

H

The adjoint operator.

T

The transpose operator.

Note

this is an alias to the adjoint operator

blocks

The list of blocks defining the block operator.

dot(x)

Numpy-like dot() method.

dtype

The data type of the operator.

matvec(x)

Matrix-vector multiplication.

The matvec property encapsulates the matvec routine specified at construct time, to ensure the consistency of the input and output arrays with the operator’s shape.

nMatvec

The number of products with vectors computed so far.

nargin

The size of an input vector.

nargout

The size of an output vector.

reset_counters()

Reset operator/vector product counter to zero.

shape

The shape of the operator.

symmetric

Indicate whether the operator is symmetric or not.

to_array()

Block Diagonal Operators

Block diagonal operators are a special case of block operators and are defined with a list containing the blocks on the diagonal. If the block operator is specified as symmetric, each block must be symmetric. For example:

K5 = BlockDiagonalLinearOperator([A, E], symmetric=True)
class linop.blkop.BlockDiagonalLinearOperator(blocks, **kwargs)

Bases: linop.linop.LinearOperator

A block diagonal linear operator.

Each block must be a linear operator. The blocks may be specified as one list, e.g., [A, B, C].

H

The adjoint operator.

T

The transpose operator.

Note

this is an alias to the adjoint operator

blocks

The list of blocks defining the block diagonal operator.

dot(x)

Numpy-like dot() method.

dtype

The data type of the operator.

matvec(x)

Matrix-vector multiplication.

The matvec property encapsulates the matvec routine specified at construct time, to ensure the consistency of the input and output arrays with the operator’s shape.

nMatvec

The number of products with vectors computed so far.

nargin

The size of an input vector.

nargout

The size of an output vector.

reset_counters()

Reset operator/vector product counter to zero.

shape

The shape of the operator.

symmetric

Indicate whether the operator is symmetric or not.

to_array()

Block Vertical and Horizontal Operators

Block vertical and horizontal operators are special cases of the generic block operator, where the list of blocks are either stacked vertically or horizontally. They must be defined in a flattened list.

# same result as K1
K6 = BlockHorizontalLinearOperator([A, B])
# same result as K3
K7 = BlockVerticalLinearOperator([A, C])
class linop.blkop.BlockHorizontalLinearOperator(blocks, **kwargs)

Bases: linop.blkop.BlockLinearOperator

A block horizontal linear operator.

Each block must be a linear operator. The blocks must be specified as one list, e.g., [A, B, C].

H

The adjoint operator.

T

The transpose operator.

Note

this is an alias to the adjoint operator

blocks

The list of blocks defining the block operator.

dot(x)

Numpy-like dot() method.

dtype

The data type of the operator.

matvec(x)

Matrix-vector multiplication.

The matvec property encapsulates the matvec routine specified at construct time, to ensure the consistency of the input and output arrays with the operator’s shape.

nMatvec

The number of products with vectors computed so far.

nargin

The size of an input vector.

nargout

The size of an output vector.

reset_counters()

Reset operator/vector product counter to zero.

shape

The shape of the operator.

symmetric

Indicate whether the operator is symmetric or not.

to_array()
class linop.blkop.BlockVerticalLinearOperator(blocks, **kwargs)

Bases: linop.blkop.BlockLinearOperator

A block vertical linear operator.

Each block must be a linear operator. The blocks must be specified as one list, e.g., [A, B, C].

H

The adjoint operator.

T

The transpose operator.

Note

this is an alias to the adjoint operator

blocks

The list of blocks defining the block operator.

dot(x)

Numpy-like dot() method.

dtype

The data type of the operator.

matvec(x)

Matrix-vector multiplication.

The matvec property encapsulates the matvec routine specified at construct time, to ensure the consistency of the input and output arrays with the operator’s shape.

nMatvec

The number of products with vectors computed so far.

nargin

The size of an input vector.

nargout

The size of an output vector.

reset_counters()

Reset operator/vector product counter to zero.

shape

The shape of the operator.

symmetric

Indicate whether the operator is symmetric or not.

to_array()

Aliases

New in version 0.5.

Shorter aliases to some linear operators are now available and listed below:

Iterating and indexing

Block operators also support iteration and indexing. Iterating over a block operator amounts to iterating row-wise over its blocks. Iterating over a block diagonal operator amounts to iterating over its diagonal blocks. Indexing works as expected. Indexing general block operators requires two indices, much as when indexing a matrix, while indexing a block diagonal operator requires a single indices. For example:

K2 = BlockLinearOperator([[A, B], [C, D]])
K2[0,:]   # Returns the block operator defined by [[A, B]].
K2[:,1]   # Returns the block operator defined by [[C], [D]].
K2[1,1]   # Returns the linear operator D.

K4 = BlockLinearOperator([[A, B], [E]], symmetric=True)
K4[0,1]   # Returns the linear operator B.T.

K5 = BlockDiagonalLinearOperator([A, E], symmetric=True)
K5[0]     # Returns the linear operator A.
K5[1]     # Returns the linear operator B.
K5[:]     # Returns the diagonal operator defines by [A, E].