mxnet.np.linalg.svd

svd(a)

Singular Value Decomposition.

When a is a 2D array, it is factorized as ut @ np.diag(s) @ v, where ut and v are 2D orthonormal 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.

Parameters

a ((.., M, N) ndarray) – A real array with a.ndim >= 2 and M <= N.

Returns

  • ut ((…, M, M) ndarray) – Orthonormal array(s). The first a.ndim - 2 dimensions have the same size as those of the input a.

  • s ((…, M) ndarray) – 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.

  • v ((…, M, N) ndarray) – Orthonormal array(s). The first a.ndim - 2 dimensions have the same size as those of the input a.

  • .. note:: – The decomposition is performed using LAPACK routine _gesvd.

    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^T S V\), where \(A = a\), \(U^T = ut\), \(S= \mathtt{np.diag}(s)\) and \(V = v\). The 1D array s contains the singular values of a and ut and v are orthonormal. The rows of v are the eigenvectors of \(A^T A\) and the columns of ut are the eigenvectors of \(A A^T\). In both cases the corresponding (possibly non-zero) eigenvalues are given by s**2.

    The sign of rows of u and v are determined as described in Auto-Differentiating Linear Algebra.

    If a has more than two dimensions, then broadcasting rules apply. 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 (ut * s[..., None, :]) @ v or ut @ (s[..., None] * v). (The @ operator denotes batch matrix multiplication)

    This function differs from the original numpy.linalg.svd in the following way(s): * The sign of rows of u and v may differ. * Does not support complex input.

Examples

>>> a = np.arange(54).reshape(6, 9)
>>> ut, s, v = np.linalg.svd(a)
>>> ut.shape, s.shape, v.shape
((6, 6), (6,), (6, 9))
>>> s = s.reshape(6, 1)
>>> ret = np.dot(ut, s * v)
>>> (ret - a > 1e-3).sum()
array(0.)
>>> (ret - a < -1e-3).sum()
array(0.)