Linear algebra module

Linear algebra module#

lazylinop.linalg.svds(M, rank, backend=None)#

Partial singular value decomposition of M.

Args:
M: cp.array, np.ndarray, torch.Tensor, sparse array/tensor or LazyLinOp

Array or LazyLinOp to decompose.

rank: int

Compute the first rank largest magnitude singular values and associated singular vectors.

backend: str, optional

Determined how the SVD is computed: either via a full SVD followed by a truncation, or using specialized truncated SVD tools that can offer better efficiency. Possible choices are:

  • None (default) to choose SVD backend according to the nature of M (LazyLinOp or array) and, if applicable, its namespace and/or device.

    • If M is an array use the full SVD from its namespace (xp = array_namespace(M) followed by xp.linalg.svd(M)).

    • If M is a sparse array or tensor use partial SVD from its namespace.

    • If M is a LazyLinOp use SciPy partial SVD.

  • 'numpy_svd' to use NumPy full SVD,

  • 'scipy_svd' to use SciPy full SVD,

  • 'scipy_svds_<solver>' to use SciPy scipy.sparse.linalg.svds where '<solver>' is either 'arpack', 'lobpcg' or 'propack',

  • 'cupy_svd_x' to use CuPy full SVD where 'x' is the device id,

  • 'cupyx_svds_x' to use cupyx.scipy.sparse.linalg.svds where 'x' is the device id (see issue),

  • PyTorch 'pytorch_svd_cpu' or 'pytorch_svd_x' to use PyTorch full SVD where 'x' is the CUDA device id,

  • PyTorch 'pytorch_svds_cpu' or 'pytorch_svds_x' to use PyTorch partial SVD where 'x' is the CUDA device id.

Returns:

(U, S, Vh) arrays corresponding to the left singular vectors as columns, the singular values and the right singular vectors as rows.

Shape of U is (L.shape[0], rank).

Shape of S is (rank, ).

Shape of Vh is (rank, L.shape[1]).

The namespace and device of the singular values and vectors are determined as follows:

  • If A is an array (or aslazylinop(array)) then its namespace and device are used

  • otherwize, backend determines the namespace and device

Examples:
>>> from lazylinop.linalg import svds
>>> from lazylinop.signal import dft
>>> N = 16
>>> # Compute the first two largest magnitude singular values
>>> u, s, vh = svds(dft(16), rank=2, backend='scipy_svd')
>>> # Two left singular vectors
>>> u.shape[1] == 2
True
>>> # Two singular values
>>> s.shape[0] == 2
True
>>> # Two right singular vectors
>>> vh.shape[0] == 2
True
References: