Skip to content

Here we provide a list of structured matrices. This list is meant for internal purposes only. It exists because it is more convenient to read the rendered LaTeX code rather than the docstring source.

singd.structures.dense.DenseMatrix

DenseMatrix(mat: Tensor)

Bases: StructuredMatrix

Unstructured dense matrix implemented in the StructuredMatrix interface.

\[ \begin{pmatrix} \mathbf{A} \end{pmatrix} \quad \text{with} \quad \mathbf{A} = \mathbf{A}^\top\,. \]

Store the dense matrix internally.

Note

For performance reasons, symmetry is not checked internally and must be ensured by the caller.

Parameters:

  • mat (Tensor) –

    A symmetric matrix representing \(\mathbf{A}\).

Source code in singd/structures/dense.py
def __init__(self, mat: Tensor) -> None:
    r"""Store the dense matrix internally.

    Note:
        For performance reasons, symmetry is not checked internally and must
        be ensured by the caller.

    Args:
        mat: A symmetric matrix representing \(\mathbf{A}\).
    """
    super().__init__()
    self._mat: Tensor
    self.register_tensor(mat, "_mat")

singd.structures.hierarchical.Hierarchical15_15Matrix

Hierarchical15_15Matrix(A: Tensor, B: Tensor, C: Tensor, D: Tensor, E: Tensor)

Bases: HierarchicalMatrixTemplate

Hierarchical matrix with K1=15 and K2=15.

Note

See the template class HierarchicalMatrixTemplate for a mathematical description.

Store the structural components internally.

Parameters:

  • A (Tensor) –

    Dense symmetric matrix of shape [K1, K1] or smaller representing \(\mathbf{A}\).

  • B (Tensor) –

    Dense rectangular matrix of shape [K1, K - K1] representing \(\mathbf{B}\).

  • C (Tensor) –

    Vector of shape [K - K1 - K2] representing the diagonal of \(\mathbf{C}\).

  • D (Tensor) –

    Dense rectangular matrix of shape [K2, K - K1 - K2] representing \(\mathbf{D}\).

  • E (Tensor) –

    Dense symmetric matrix of shape [K2, K2] or smaller representing \(\mathbf{E}\).

Note

For performance reasons, symmetry is not checked internally and must be ensured by the caller.

Raises:

  • ValueError

    If the shapes of the arguments are invalid.

Source code in singd/structures/hierarchical.py
def __init__(self, A: Tensor, B: Tensor, C: Tensor, D: Tensor, E: Tensor):
    r"""Store the structural components internally.

    Args:
        A: Dense symmetric matrix of shape `[K1, K1]` or smaller representing
            \(\mathbf{A}\).
        B: Dense rectangular matrix of shape `[K1, K - K1]` representing
            \(\mathbf{B}\).
        C: Vector of shape `[K - K1 - K2]` representing the diagonal of
            \(\mathbf{C}\).
        D: Dense rectangular matrix of shape `[K2, K - K1 - K2]` representing
            \(\mathbf{D}\).
        E: Dense symmetric matrix of shape `[K2, K2]` or smaller representing
            \(\mathbf{E}\).

    Note:
        For performance reasons, symmetry is not checked internally and must
        be ensured by the caller.

    Raises:
        ValueError: If the shapes of the arguments are invalid.
    """
    super().__init__()
    if A.ndim != 2 or B.ndim != 2 or C.ndim != 1 or D.ndim != 2 or E.ndim != 2:
        raise ValueError(
            "Invalid tensor dimensions. Expected 2, 2, 1, 2, 2."
            + f" Got {A.ndim}, {B.ndim}, {C.ndim}, {D.ndim}, {E.ndim}."
        )
    self._check_square(A, name="A")
    self._check_square(E, name="E")

    self.K1 = A.shape[0]
    self.K2 = E.shape[0]
    self.diag_dim = C.shape[0]
    self.dim = self.K1 + self.K2 + self.diag_dim

    if A.shape[0] > self.MAX_K1 or E.shape[0] > self.MAX_K2:
        raise ValueError(
            f"Expected A, E to be smaller than {self.MAX_K1}, {self.MAX_K2}."
            + f" Got {A.shape}, {E.shape}."
        )
    if D.shape != (self.K2, self.diag_dim):
        raise ValueError(
            f"Expected D to have shape {self.K2, self.diag_dim}. Got {D.shape}."
        )
    if B.shape != (self.K1, self.diag_dim + self.K2):
        raise ValueError(
            f"Expected B to have shape {self.K1, self.diag_dim + self.K2}."
            + " Got {B.shape}."
        )

    self.A: Tensor
    self.register_tensor(A, "A")

    self.B: Tensor
    self.register_tensor(B, "B")

    self.C: Tensor
    self.register_tensor(C, "C")

    self.D: Tensor
    self.register_tensor(D, "D")

    self.E: Tensor
    self.register_tensor(E, "E")

DIAGONAL

singd.structures.diagonal.DiagonalMatrix

DiagonalMatrix(mat_diag: Tensor)

Bases: StructuredMatrix

Diagonal matrix implemented in the StructuredMatrix interface.

A diagonal matrix is defined as

\( \begin{pmatrix} d_1 & 0 & \cdots & 0 \\ 0 & d_2 & \ddots & \vdots \\ \vdots & \ddots & \ddots & 0 \\ 0 & \cdots & \ddots & d_K \\ \end{pmatrix} \in \mathbb{R}^{K \times K} \quad \text{with} \quad \mathbf{d} := \begin{pmatrix} d_1 \\ d_2 \\ \vdots \\ d_K \\ \end{pmatrix} \in \mathbb{R}^K \)

Store the dense matrix internally.

Parameters:

  • mat_diag (Tensor) –

    A 1d tensor representing the matrix diagonal \(\mathbf{d}\).

Source code in singd/structures/diagonal.py
def __init__(self, mat_diag: Tensor) -> None:
    r"""Store the dense matrix internally.

    Args:
        mat_diag: A 1d tensor representing the matrix diagonal \(\mathbf{d}\).
    """
    super().__init__()
    self._mat_diag: Tensor
    self.register_tensor(mat_diag, "_mat_diag")

singd.structures.blockdiagonal.Block30DiagonalMatrix

Block30DiagonalMatrix(blocks: Tensor, last: Tensor)

Bases: BlockDiagonalMatrixTemplate

Block-diagonal matrix with blocks of size 30.

Note

See the template class BlockDiagonalMatrixTemplate for a mathematical description.

Store the matrix internally.

Parameters:

  • blocks (Tensor) –

    The diagonal blocks \(\{\mathbf{A}_n = \mathbf{A}_n^\top\}_{n = 1}^N\), supplied as a tensor of shape [N, BLOCK_DIM, BLOCK_DIM]. If there are no blocks, this argument has shape [0, BLOCK_DIM, BLOCK_DIM].

  • last (Tensor) –

    The last block \(\mathbf{B} = \mathbf{B}^\top\) which contains the remaining matrix if BLOCK_DIM does not divide the matrix dimension. Has shape [last_dim, last_dim] where last_dim may be zero.

Note

For performance reasons, symmetry is not checked internally and must be ensured by the caller.

Raises:

  • ValueError

    If the passed tensors have incorrect shape.

Source code in singd/structures/blockdiagonal.py
def __init__(self, blocks: Tensor, last: Tensor) -> None:
    r"""Store the matrix internally.

    Args:
        blocks: The diagonal blocks
            \(\{\mathbf{A}_n = \mathbf{A}_n^\top\}_{n = 1}^N\),
            supplied as a tensor of shape `[N, BLOCK_DIM, BLOCK_DIM]`. If there are
            no blocks, this argument has shape `[0, BLOCK_DIM, BLOCK_DIM]`.
        last: The last block \(\mathbf{B} = \mathbf{B}^\top\) which contains the
            remaining matrix if `BLOCK_DIM` does not divide the matrix dimension.
            Has shape `[last_dim, last_dim]` where `last_dim` may be zero.

    Note:
        For performance reasons, symmetry is not checked internally and must
        be ensured by the caller.

    Raises:
        ValueError: If the passed tensors have incorrect shape.
    """
    super().__init__()
    if blocks.ndim != 3:
        raise ValueError(
            f"Diagonal blocks must be 3-dimensional, got {blocks.ndim}."
        )
    if blocks.shape[1] != blocks.shape[2] != self.BLOCK_DIM:
        raise ValueError(
            f"Diagonal blocks must be square with dimension {self.BLOCK_DIM},"
            f" got {blocks.shape[1:]} instead."
        )
    if last.ndim != 2 or last.shape[0] != last.shape[1]:
        raise ValueError(f"Last block must be square, got {last.shape}.")
    if last.shape[0] >= self.BLOCK_DIM or last.shape[1] >= self.BLOCK_DIM:
        raise ValueError(
            f"Last block must have dimension at most {self.BLOCK_DIM},"
            f" got {last.shape} instead."
        )

    self._blocks: Tensor
    self.register_tensor(blocks, "_blocks")

    self._last: Tensor
    self.register_tensor(last, "_last")

LOWER-TRIANGULAR

singd.structures.triltoeplitz.TrilToeplitzMatrix

TrilToeplitzMatrix(lower_diags: Tensor)

Bases: StructuredMatrix

Class for lower-triangular Toeplitz-structured matrices.

A lower-triangular Toeplitz matrix is defined by:

\( \begin{pmatrix} d_1 & 0 & \cdots & 0 \\ d_2 & d_1 & \ddots & \vdots \\ \vdots & \ddots & \ddots & 0 \\ d_K & \cdots & d_2 & d_1 \\ \end{pmatrix} \in \mathbb{R}^{K \times K} \quad \text{with} \quad \mathbf{d} := \begin{pmatrix} d_1 \\ d_2 \\ \vdots \\ d_K \\ \end{pmatrix} \in \mathbb{R}^K\,. \)

Store the lower-triangular Toeplitz matrix internally.

Parameters:

  • lower_diags (Tensor) –

    The vector \(\mathbf{d}\) containing the constants of all lower diagonals, starting with the value on the main diagonal.

Source code in singd/structures/triltoeplitz.py
def __init__(self, lower_diags: Tensor) -> None:
    r"""Store the lower-triangular Toeplitz matrix internally.

    Args:
        lower_diags: The vector \(\mathbf{d}\) containing the constants of all
            lower diagonals, starting with the value on the main diagonal.
    """
    super().__init__()
    self._lower_diags: Tensor
    self.register_tensor(lower_diags, "_lower_diags")

singd.structures.trilbottomrightdiag.TrilBottomRightDiagonalMatrix

TrilBottomRightDiagonalMatrix(A: StructuredMatrix, B: Tensor, C: StructuredMatrix)

Bases: RecursiveBottomLeftMatrixTemplate

Sparse lower-triangular matrix with bottom right diagonal.

This matrix is defined as follows:

\( \begin{pmatrix} a & \mathbf{0} \\ \mathbf{b} & \mathbf{C} \\ \end{pmatrix} \in \mathbb{R}^{K \times K} \)

where

  • \(a \in \mathbb{R}\) is a scalar, represented by a DenseMatrix
  • \(\mathbf{b} \in \mathbb{R}^{K-1}\) is a row vector, represented as PyTorch Tensor, and
  • \(\mathbf{C} \in \mathbb{R}^{(K-1)\times (K-1)}\) is a diagonal matrix represented as a DiagonalMatrix.

Store the matrix internally.

Parameters:

  • A (StructuredMatrix) –

    Structured matrix representing the top left block \(\mathbf{A}\).

  • B (Tensor) –

    Rectangular tensor representing the bottom left block \(\mathbf{B}\).

  • C (StructuredMatrix) –

    Structured matrix representing the bottom right block \(\mathbf{C}\).

Note

For performance reasons, symmetry is not checked internally and must be ensured by the caller.

Raises:

  • ValueError

    If the dimensions of the blocks do not match or the structured matrices are of wrong type.

Source code in singd/structures/recursive.py
def __init__(self, A: StructuredMatrix, B: Tensor, C: StructuredMatrix):
    r"""Store the matrix internally.

    Args:
        A: Structured matrix representing the top left block \(\mathbf{A}\).
        B: Rectangular tensor representing the bottom left block \(\mathbf{B}\).
        C: Structured matrix representing the bottom right block \(\mathbf{C}\).

    Note:
        For performance reasons, symmetry is not checked internally and must
        be ensured by the caller.

    Raises:
        ValueError: If the dimensions of the blocks do not match or the structured
            matrices are of wrong type.
    """
    super().__init__()
    if not isinstance(A, self.CLS_A) or not isinstance(C, self.CLS_C):
        raise ValueError(
            f"Matrices A and C must be of type {self.CLS_A} and "
            f"{self.CLS_C}, respectively. Got {type(A)} and {type(C)}."
        )

    # TODO Add a `dim` property to make this cheaper
    dim_A, dim_C = A.to_dense().shape[0], C.to_dense().shape[0]
    if B.shape != (dim_C, dim_A):
        raise ValueError(f"Shape of `B` ({B.shape}) should be ({(dim_A, dim_C)}).")

    max_dim_A, max_dim_C = self.MAX_DIMS
    if dim_A > max_dim_A:
        raise ValueError(f"Dim. of A ({dim_A}) exceeds max dim. ({max_dim_A}).")
    if dim_C > max_dim_C:
        raise ValueError(f"Dim. of C ({dim_A}) exceeds max dim. ({max_dim_C}).")

    self.A: StructuredMatrix
    self.register_substructure(A, "A")

    self.B: Tensor
    self.register_tensor(B, "B")

    self.C: StructuredMatrix
    self.register_substructure(C, "C")

singd.structures.triltopleftdiag.TrilTopLeftDiagonalMatrix

TrilTopLeftDiagonalMatrix(A: StructuredMatrix, B: Tensor, C: StructuredMatrix)

Bases: RecursiveBottomLeftMatrixTemplate

Sparse lower-triangular matrix with top left diagonal entries.

This matrix is defined as follows:

\( \begin{pmatrix} \mathbf{A} & \mathbf{0} \\ \mathbf{b} & c \\ \end{pmatrix} \in \mathbb{R}^{K \times K} \)

where

  • \(\mathbf{A} \in \mathbb{R}^{(K-1)\times (K-1)}\) is a diagonal matrix represented as a DiagonalMatrix.
  • \(\mathbf{b} \in \mathbb{R}^{K-1}\) is a row vector, represented as PyTorch Tensor, and
  • \(c \in \mathbb{R}\) is a scalar, represented by a DenseMatrix.

Store the matrix internally.

Parameters:

  • A (StructuredMatrix) –

    Structured matrix representing the top left block \(\mathbf{A}\).

  • B (Tensor) –

    Rectangular tensor representing the bottom left block \(\mathbf{B}\).

  • C (StructuredMatrix) –

    Structured matrix representing the bottom right block \(\mathbf{C}\).

Note

For performance reasons, symmetry is not checked internally and must be ensured by the caller.

Raises:

  • ValueError

    If the dimensions of the blocks do not match or the structured matrices are of wrong type.

Source code in singd/structures/recursive.py
def __init__(self, A: StructuredMatrix, B: Tensor, C: StructuredMatrix):
    r"""Store the matrix internally.

    Args:
        A: Structured matrix representing the top left block \(\mathbf{A}\).
        B: Rectangular tensor representing the bottom left block \(\mathbf{B}\).
        C: Structured matrix representing the bottom right block \(\mathbf{C}\).

    Note:
        For performance reasons, symmetry is not checked internally and must
        be ensured by the caller.

    Raises:
        ValueError: If the dimensions of the blocks do not match or the structured
            matrices are of wrong type.
    """
    super().__init__()
    if not isinstance(A, self.CLS_A) or not isinstance(C, self.CLS_C):
        raise ValueError(
            f"Matrices A and C must be of type {self.CLS_A} and "
            f"{self.CLS_C}, respectively. Got {type(A)} and {type(C)}."
        )

    # TODO Add a `dim` property to make this cheaper
    dim_A, dim_C = A.to_dense().shape[0], C.to_dense().shape[0]
    if B.shape != (dim_C, dim_A):
        raise ValueError(f"Shape of `B` ({B.shape}) should be ({(dim_A, dim_C)}).")

    max_dim_A, max_dim_C = self.MAX_DIMS
    if dim_A > max_dim_A:
        raise ValueError(f"Dim. of A ({dim_A}) exceeds max dim. ({max_dim_A}).")
    if dim_C > max_dim_C:
        raise ValueError(f"Dim. of C ({dim_A}) exceeds max dim. ({max_dim_C}).")

    self.A: StructuredMatrix
    self.register_substructure(A, "A")

    self.B: Tensor
    self.register_tensor(B, "B")

    self.C: StructuredMatrix
    self.register_substructure(C, "C")

UPPER-TRIANGULAR

singd.structures.triutoeplitz.TriuToeplitzMatrix

TriuToeplitzMatrix(upper_diags: Tensor)

Bases: StructuredMatrix

Class for upper-triangular Toeplitz-structured matrices.

An upper-triangular Toeplitz matrix is defined by:

\( \begin{pmatrix} d_1 & d_2 & \cdots & d_K \\ 0 & d_1 & \ddots & \vdots \\ \vdots & \ddots & \ddots & d_2 \\ 0 & \cdots & 0 & d_1 \\ \end{pmatrix} \in \mathbb{R}^{K \times K} \quad \text{with} \quad \mathbf{d} := \begin{pmatrix} d_1 \\ d_2 \\ \vdots \\ d_K \\ \end{pmatrix} \in \mathbb{R}^K\,. \)

Store the upper-triangular Toeplitz matrix internally.

Parameters:

  • upper_diags (Tensor) –

    A vector \(\mathbf{d}\) containing the constants of all upper diagonals, starting with the main diagonal.

Source code in singd/structures/triutoeplitz.py
def __init__(self, upper_diags: Tensor) -> None:
    r"""Store the upper-triangular Toeplitz matrix internally.

    Args:
        upper_diags: A vector \(\mathbf{d}\) containing the constants of all
            upper diagonals, starting with the main diagonal.
    """
    super().__init__()
    self._upper_diags: Tensor
    self.register_tensor(upper_diags, "_upper_diags")

singd.structures.triubottomrightdiag.TriuBottomRightDiagonalMatrix

TriuBottomRightDiagonalMatrix(A: StructuredMatrix, B: Tensor, C: StructuredMatrix)

Bases: RecursiveTopRightMatrixTemplate

Sparse upper-triangular matrix with bottom right diagonal entries.

This matrix is defined as follows:

\( \begin{pmatrix} a & \mathbf{b} \\ \mathbf{0} & \mathbf{C} \\ \end{pmatrix} \in \mathbb{R}^{K \times K} \)

where

  • \(a \in \mathbb{R}\) is a scalar, represented by a DenseMatrix
  • \(\mathbf{b} \in \mathbb{R}^{K-1}\) is a column vector, represented as PyTorch Tensor, and
  • \(\mathbf{C} \in \mathbb{R}^{(K-1)\times (K-1)}\) is a diagonal matrix represented as a DiagonalMatrix.

Store the matrix internally.

Parameters:

  • A (StructuredMatrix) –

    Structured matrix representing the top left block \(\mathbf{A}\).

  • B (Tensor) –

    Rectangular tensor representing the top right block \(\mathbf{B}\).

  • C (StructuredMatrix) –

    Structured matrix representing the bottom right block \(\mathbf{C}\).

Note

For performance reasons, symmetry is not checked internally and must be ensured by the caller.

Raises:

  • ValueError

    If the dimensions of the blocks do not match or the structured matrices are of wrong type.

Source code in singd/structures/recursive.py
def __init__(self, A: StructuredMatrix, B: Tensor, C: StructuredMatrix):
    r"""Store the matrix internally.

    Args:
        A: Structured matrix representing the top left block \(\mathbf{A}\).
        B: Rectangular tensor representing the top right block \(\mathbf{B}\).
        C: Structured matrix representing the bottom right block \(\mathbf{C}\).

    Note:
        For performance reasons, symmetry is not checked internally and must
        be ensured by the caller.

    Raises:
        ValueError: If the dimensions of the blocks do not match or the
            structured matrices are of wrong type.
    """
    super().__init__()
    if not isinstance(A, self.CLS_A) or not isinstance(C, self.CLS_C):
        raise ValueError(
            f"Matrices A and C must be of type {self.CLS_A} and "
            f"{self.CLS_C}, respectively. Got {type(A)} and {type(C)}."
        )

    # TODO Add a `dim` property to make this cheaper
    dim_A, dim_C = A.to_dense().shape[0], C.to_dense().shape[0]
    if B.shape != (dim_A, dim_C):
        raise ValueError(f"Shape of `B` ({B.shape}) should be ({(dim_A, dim_C)}).")

    max_dim_A, max_dim_C = self.MAX_DIMS
    if dim_A > max_dim_A:
        raise ValueError(f"Dim. of A ({dim_A}) exceeds max dim. ({max_dim_A}).")
    if dim_C > max_dim_C:
        raise ValueError(f"Dim. of C ({dim_A}) exceeds max dim. ({max_dim_C}).")

    self.A: StructuredMatrix
    self.register_substructure(A, "A")

    self.B: Tensor
    self.register_tensor(B, "B")

    self.C: StructuredMatrix
    self.register_substructure(C, "C")

singd.structures.triutopleftdiag.TriuTopLeftDiagonalMatrix

TriuTopLeftDiagonalMatrix(A: StructuredMatrix, B: Tensor, C: StructuredMatrix)

Bases: RecursiveTopRightMatrixTemplate

Sparse upper-triangular matrix with top left diagonal entries.

This matrix is defined as follows:

\( \begin{pmatrix} \mathbf{A} & \mathbf{b} \\ \mathbf{0} & c \\ \end{pmatrix} \in \mathbb{R}^{K \times K} \)

where

  • \(\mathbf{A} \in \mathbb{R}^{(K-1)\times (K-1)}\) is a diagonal matrix represented as a DiagonalMatrix.
  • \(\mathbf{b} \in \mathbb{R}^{K-1}\) is a column vector, represented as PyTorch Tensor, and
  • \(c \in \mathbb{R}\) is a scalar, represented by a DenseMatrix.

Store the matrix internally.

Parameters:

  • A (StructuredMatrix) –

    Structured matrix representing the top left block \(\mathbf{A}\).

  • B (Tensor) –

    Rectangular tensor representing the top right block \(\mathbf{B}\).

  • C (StructuredMatrix) –

    Structured matrix representing the bottom right block \(\mathbf{C}\).

Note

For performance reasons, symmetry is not checked internally and must be ensured by the caller.

Raises:

  • ValueError

    If the dimensions of the blocks do not match or the structured matrices are of wrong type.

Source code in singd/structures/recursive.py
def __init__(self, A: StructuredMatrix, B: Tensor, C: StructuredMatrix):
    r"""Store the matrix internally.

    Args:
        A: Structured matrix representing the top left block \(\mathbf{A}\).
        B: Rectangular tensor representing the top right block \(\mathbf{B}\).
        C: Structured matrix representing the bottom right block \(\mathbf{C}\).

    Note:
        For performance reasons, symmetry is not checked internally and must
        be ensured by the caller.

    Raises:
        ValueError: If the dimensions of the blocks do not match or the
            structured matrices are of wrong type.
    """
    super().__init__()
    if not isinstance(A, self.CLS_A) or not isinstance(C, self.CLS_C):
        raise ValueError(
            f"Matrices A and C must be of type {self.CLS_A} and "
            f"{self.CLS_C}, respectively. Got {type(A)} and {type(C)}."
        )

    # TODO Add a `dim` property to make this cheaper
    dim_A, dim_C = A.to_dense().shape[0], C.to_dense().shape[0]
    if B.shape != (dim_A, dim_C):
        raise ValueError(f"Shape of `B` ({B.shape}) should be ({(dim_A, dim_C)}).")

    max_dim_A, max_dim_C = self.MAX_DIMS
    if dim_A > max_dim_A:
        raise ValueError(f"Dim. of A ({dim_A}) exceeds max dim. ({max_dim_A}).")
    if dim_C > max_dim_C:
        raise ValueError(f"Dim. of C ({dim_A}) exceeds max dim. ({max_dim_C}).")

    self.A: StructuredMatrix
    self.register_substructure(A, "A")

    self.B: Tensor
    self.register_tensor(B, "B")

    self.C: StructuredMatrix
    self.register_substructure(C, "C")