numpy 1.22.4 Pypi GitHub Homepage
Other Docs
NotesParametersRaisesReturns
svd(a, full_matrices=True, compute_uv=True, hermitian=False)

When a is a 2D array, it is factorized as u @ np.diag(s) @ vh = (u * s) @ vh , where u and :None:None:`vh` are 2D unitary arrays and s is a 1D array of a's singular values. When a is higher-dimensional, SVD is applied in stacked mode as explained below.

Notes

versionchanged

Broadcasting rules apply, see the :None:None:`numpy.linalg` documentation for details.

The decomposition is performed using LAPACK routine _gesdd .

SVD is usually described for the factorization of a 2D matrix $A$ . The higher-dimensional case will be discussed below. In the 2D case, SVD is written as $A = U S V^H$ , where $A = a$ , $U= u$ , $S= \mathtt{np.diag}(s)$ and $V^H = vh$ . The 1D array s contains the singular values of a and u and :None:None:`vh` are unitary. The rows of :None:None:`vh` are the eigenvectors of $A^H A$ and the columns of u are the eigenvectors of $A A^H$ . In both cases the corresponding (possibly non-zero) eigenvalues are given by s**2 .

If a has more than two dimensions, then broadcasting rules apply, as explained in routines.linalg-broadcasting . This means that SVD is working in "stacked" mode: it iterates over all indices of the first a.ndim - 2 dimensions and for each combination SVD is applied to the last two indices. The matrix a can be reconstructed from the decomposition with either (u * s[..., None, :]) @ vh or u @ (s[..., None] * vh) . (The @ operator can be replaced by the function np.matmul for python versions below 3.5.)

If a is a matrix object (as opposed to an ndarray ), then so are all the return values.

Parameters

a : (..., M, N) array_like

A real or complex array with a.ndim >= 2 .

full_matrices : bool, optional

If True (default), u and :None:None:`vh` have the shapes (..., M, M) and (..., N, N) , respectively. Otherwise, the shapes are (..., M, K) and (..., K, N) , respectively, where K = min(M, N) .

compute_uv : bool, optional

Whether or not to compute u and :None:None:`vh` in addition to s. True by default.

hermitian : bool, optional

If True, a is assumed to be Hermitian (symmetric if real-valued), enabling a more efficient method for finding singular values. Defaults to False.

versionadded

Raises

LinAlgError

If SVD computation does not converge.

Returns

u : { (..., M, M), (..., M, K) } array

Unitary array(s). The first a.ndim - 2 dimensions have the same size as those of the input a. The size of the last two dimensions depends on the value of :None:None:`full_matrices`. Only returned when :None:None:`compute_uv` is True.

s : (..., K) array

Vector(s) with the singular values, within each vector sorted in descending order. The first a.ndim - 2 dimensions have the same size as those of the input a.

vh : { (..., N, N), (..., K, N) } array

Unitary array(s). The first a.ndim - 2 dimensions have the same size as those of the input a. The size of the last two dimensions depends on the value of :None:None:`full_matrices`. Only returned when :None:None:`compute_uv` is True.

Singular Value Decomposition.

See Also

scipy.linalg.svd

Similar function in SciPy.

scipy.linalg.svdvals

Compute singular values of a matrix.

Examples

>>> a = np.random.randn(9, 6) + 1j*np.random.randn(9, 6)
... b = np.random.randn(2, 7, 8, 3) + 1j*np.random.randn(2, 7, 8, 3)

Reconstruction based on full SVD, 2D case:

>>> u, s, vh = np.linalg.svd(a, full_matrices=True)
... u.shape, s.shape, vh.shape ((9, 9), (6,), (6, 6))
>>> np.allclose(a, np.dot(u[:, :6] * s, vh))
True
>>> smat = np.zeros((9, 6), dtype=complex)
... smat[:6, :6] = np.diag(s)
... np.allclose(a, np.dot(u, np.dot(smat, vh))) True

Reconstruction based on reduced SVD, 2D case:

>>> u, s, vh = np.linalg.svd(a, full_matrices=False)
... u.shape, s.shape, vh.shape ((9, 6), (6,), (6, 6))
>>> np.allclose(a, np.dot(u * s, vh))
True
>>> smat = np.diag(s)
... np.allclose(a, np.dot(u, np.dot(smat, vh))) True

Reconstruction based on full SVD, 4D case:

>>> u, s, vh = np.linalg.svd(b, full_matrices=True)
... u.shape, s.shape, vh.shape ((2, 7, 8, 8), (2, 7, 3), (2, 7, 3, 3))
>>> np.allclose(b, np.matmul(u[..., :3] * s[..., None, :], vh))
True
>>> np.allclose(b, np.matmul(u[..., :3], s[..., None] * vh))
True

Reconstruction based on reduced SVD, 4D case:

>>> u, s, vh = np.linalg.svd(b, full_matrices=False)
... u.shape, s.shape, vh.shape ((2, 7, 8, 3), (2, 7, 3), (2, 7, 3, 3))
>>> np.allclose(b, np.matmul(u * s[..., None, :], vh))
True
>>> np.allclose(b, np.matmul(u, s[..., None] * vh))
True
See :

Local connectivity graph

Hover to see nodes names; edges to Self not shown, Caped at 50 nodes.

Using a canvas is more power efficient and can get hundred of nodes ; but does not allow hyperlinks; , arrows or text (beyond on hover)

SVG is more flexible but power hungry; and does not scale well to 50 + nodes.

All aboves nodes referred to, (or are referred from) current nodes; Edges from Self to other have been omitted (or all nodes would be connected to the central node "self" which is not useful). Nodes are colored by the library they belong to, and scaled with the number of references pointing them


GitHub : /numpy/linalg/linalg.py#1470
type: <class 'function'>
Commit: