Skip to content

brahmap.base.BaseLinearOperator

Bases: object

Base class for defining the common interface shared by all linear operators within the BrahMap framework.

The linear operators abstract the large matrix operations into matrix-free functional mappings.

A linear operator is a linear mapping \(x \mapsto A(x)\) such that the size of the input vector \(x\) is nargin and the size of the output vector is nargout. The operator \(A\) acts equivalently to a dense matrix of shape (nargout, nargin), but computes products analytically or dynamically to maintain high performance and low memory footprints.

Parameters:

Name Type Description Default
nargin int

Size of the input vector \(x\), i.e. the number of columns of the operator

required
nargout int

Size of the output vector \(A(x)\), i.e. the number of rows of the operator

required
symmetric bool

A parameter to specify whether the linear operator is symmetric, by default False

False
dtype DTypeLike

Data type of the linear operator, by default np.float64

float64
**kwargs Any

Extra keywords arguments

{}

Attributes:

Name Type Description
dtype dtype

The data type of the operator

nargin int

Size of the input vector \(x\), i.e. the number of columns of the operator

nargout int

Size of the output vector \(A(x)\), i.e. the number of rows of the operator

symmetric bool

Indicates whether the operator is symmetric or not

shape tuple[int, int]

A tuple (nargout, nargin) representing the shape of the operator

nMatvec int

The number of matrix-vector multiplications computed so far

logger Logger

The logger instance for this operator

Methods:

Name Description
reset_counters

Resets matrix-vector product counter to zero.

dot

Numpy-like dot() method.

Source code in brahmap/base/linop.py
class BaseLinearOperator(object):
    """Base class for defining the common interface shared by all linear
    operators within the BrahMap framework.

    The linear operators abstract the large matrix operations into
    matrix-free functional mappings.

    A linear operator is a linear mapping $x \\mapsto A(x)$ such that
    the size of the input vector $x$ is `nargin` and the size of the
    output vector is `nargout`. The operator $A$ acts equivalently to a
    dense matrix of shape `(nargout, nargin)`, but computes products
    analytically or dynamically to maintain high performance and low
    memory footprints.

    Parameters
    ----------
    nargin : int
        Size of the input vector $x$, i.e. the number of columns of the operator
    nargout : int
        Size of the output vector $A(x)$, i.e. the number of rows of the operator
    symmetric : bool, optional
        A parameter to specify whether the linear operator is symmetric, by
        default `False`
    dtype : npt.DTypeLike, optional
        Data type of the linear operator, by default `np.float64`
    **kwargs : Any
        Extra keywords arguments

    Attributes
    ----------
    dtype : np.dtype
        The data type of the operator
    nargin : int
        Size of the input vector $x$, i.e. the number of columns of the operator
    nargout : int
        Size of the output vector $A(x)$, i.e. the number of rows of the operator
    symmetric : bool
        Indicates whether the operator is symmetric or not
    shape : tuple[int, int]
        A tuple `(nargout, nargin)` representing the shape of the operator
    nMatvec : int
        The number of matrix-vector multiplications computed so far
    logger : logging.Logger
        The logger instance for this operator
    """

    # A logger may be attached to the linear operator via the `logger` keyword
    # argument.

    def __init__(
        self,
        nargin: int,
        nargout: int,
        symmetric: bool = False,
        dtype: npt.DTypeLike = np.float64,
        **kwargs,
    ) -> None:
        self.__nargin = nargin
        self.__nargout = nargout
        self.__symmetric = symmetric
        self.__shape = (nargout, nargin)
        self.dtype = dtype
        self._nMatvec = 0

        # Log activity.
        self.logger = kwargs.get("logger", null_log)
        self.logger.info("New linear operator with shape " + str(self.shape))
        return

    @property
    def nargin(self) -> int:
        """Size of the input vector $x$, i.e. the number of columns of the operator

        Returns
        -------
        int
            The number of input columns
        """
        return self.__nargin

    @property
    def nargout(self) -> int:
        """Size of the output vector $A(x)$, i.e. the number of rows of the operator

        Returns
        -------
        int
            The number of output rows
        """
        return self.__nargout

    @property
    def symmetric(self) -> bool:
        """Indicates whether the operator is symmetric or not

        Returns
        -------
        bool
            `True` if symmetric, `False` otherwise
        """
        return self.__symmetric

    @property
    def shape(self) -> Tuple[int, int]:
        """A tuple `(nargout, nargin)` representing the shape of the operator

        Returns
        -------
        tuple[int, int]
            A tuple `(nrows, ncols)`
        """
        return self.__shape

    @property
    def dtype(self) -> npt.DTypeLike:
        """The data type of the operator.

        Returns
        -------
        npt.DTypeLike
            The NumPy data type of the operator
        """
        return self.__dtype

    @dtype.setter
    def dtype(self, dtype) -> None:
        self.__dtype = dtype

    @property
    def nMatvec(self) -> int:
        """The number of matrix-vector multiplications computed so far

        Returns
        -------
        int
            The number of matrix-vector multiplications performed
        """
        return self._nMatvec

    def reset_counters(self) -> None:
        """Resets matrix-vector product counter to zero."""
        self._nMatvec = 0

    def dot(self, x) -> npt.NDArray[np.number]:
        """Numpy-like dot() method.

        Parameters
        ----------
        x : Any
            The input vector or object to multiply with.
        Returns
        -------
        npt.NDArray[np.number]
            The result of the dot product.
        """
        return self.__mul__(x)

    def __call__(self, *args: Any, **kwargs: Any) -> Any:
        # An alias for __mul__.
        return self.__mul__(*args, **kwargs)

    def __mul__(self, x: Any) -> Any:
        raise NotImplementedError(
            f"{self.__class__.__name__}: Please subclass to implement __mul__."
        )

    def __repr__(self) -> str:
        if self.symmetric:
            s = "Symmetric"
        else:
            s = "Asymmetric"
        s += " <" + self.__class__.__name__ + ">"
        s += " of type %s" % self.dtype
        s += " with shape (%d,%d)" % (self.nargout, self.nargin)
        return s

Attributes

dtype: npt.DTypeLike property writable

The data type of the operator.

Returns:

Type Description
DTypeLike

The NumPy data type of the operator

nargin: int property

Size of the input vector \(x\), i.e. the number of columns of the operator

Returns:

Type Description
int

The number of input columns

nargout: int property

Size of the output vector \(A(x)\), i.e. the number of rows of the operator

Returns:

Type Description
int

The number of output rows

symmetric: bool property

Indicates whether the operator is symmetric or not

Returns:

Type Description
bool

True if symmetric, False otherwise

shape: Tuple[int, int] property

A tuple (nargout, nargin) representing the shape of the operator

Returns:

Type Description
tuple[int, int]

A tuple (nrows, ncols)

nMatvec: int property

The number of matrix-vector multiplications computed so far

Returns:

Type Description
int

The number of matrix-vector multiplications performed

Functions

reset_counters() -> None

Resets matrix-vector product counter to zero.

Source code in brahmap/base/linop.py
def reset_counters(self) -> None:
    """Resets matrix-vector product counter to zero."""
    self._nMatvec = 0

dot(x) -> npt.NDArray[np.number]

Numpy-like dot() method.

Parameters:

Name Type Description Default
x Any

The input vector or object to multiply with.

required

Returns:

Type Description
NDArray[number]

The result of the dot product.

Source code in brahmap/base/linop.py
def dot(self, x) -> npt.NDArray[np.number]:
    """Numpy-like dot() method.

    Parameters
    ----------
    x : Any
        The input vector or object to multiply with.
    Returns
    -------
    npt.NDArray[np.number]
        The result of the dot product.
    """
    return self.__mul__(x)