svd#

ivy.svd(x, /, *, compute_uv=True, full_matrices=True)[source]#

Return a singular value decomposition A = USVh of a matrix (or a stack of matrices) x, where U is a matrix (or a stack of matrices) with orthonormal columns, S is a vector of non-negative numbers (or stack of vectors), and Vh is a matrix (or a stack of matrices) with orthonormal rows.

Parameters:
  • x (Union[Array, NativeArray]) – input array having shape (..., M, N) and whose innermost two dimensions form matrices on which to perform singular value decomposition. Should have a floating-point data type.

  • full_matrices (bool, default: True) – If True, compute full-sized U and Vh, such that U has shape (..., M, M) and Vh has shape (..., N, N). If False, compute on the leading K singular vectors, such that U has shape (..., M, K) and Vh has shape (..., K, N) and where K = min(M, N). Default: True.

  • compute_uv (bool, default: True) – If True then left and right singular vectors will be computed and returned in U and Vh, respectively. Otherwise, only the singular values will be computed, which can be significantly faster.

  • note:: (..) – with backend set as torch, svd with still compute left and right singular vectors irrespective of the value of compute_uv, however Ivy will still only return the singular values.

Return type:

Union[Array, Tuple[Array, ...]]

Returns:

  • .. note:: – once complex numbers are supported, each square matrix must be Hermitian.

  • ret – a namedtuple (U, S, Vh) whose

    • first element must have the field name U and must be an array whose shape depends on the value of full_matrices and contain matrices with orthonormal columns (i.e., the columns are left singular vectors). If full_matrices is True, the array must have shape (..., M, M). If full_matrices is False, the array must have shape (..., M, K), where K = min(M, N). The first x.ndim-2 dimensions must have the same shape as those of the input x.

    • second element must have the field name S and must be an array with shape (..., K) that contains the vector(s) of singular values of length K, where K = min(M, N). For each vector, the singular values must be sorted in descending order by magnitude, such that s[..., 0] is the largest value, s[..., 1] is the second largest value, et cetera. The first x.ndim-2 dimensions must have the same shape as those of the input x. Must have a real-valued floating-point data type having the same precision as x (e.g., if x is complex64, S must have a float32 data type).

    • third element must have the field name Vh and must be an array whose shape depends on the value of full_matrices and contain orthonormal rows (i.e., the rows are the right singular vectors and the array is the adjoint). If full_matrices is True, the array must have shape (..., N, N). If full_matrices is False, the array must have shape (..., K, N) where K = min(M, N). The first x.ndim-2 dimensions must have the same shape as those of the input x. Must have the same data type as x.

    Each returned array must have the same floating-point data type as x.

This function conforms to the Array API Standard. This docstring is an extension of the docstring in the standard.

Both the description and the type hints above assumes an array input for simplicity, but this function is nestable, and therefore also accepts ivy.Container instances in place of any of the arguments.

Examples

With ivy.Array input:

>>> x = ivy.random_normal(shape = (9, 6))
>>> U, S, Vh = ivy.svd(x)
>>> print(U.shape, S.shape, Vh.shape)
(9, 9) (6,) (6, 6)

With reconstruction from SVD, result is numerically close to x

>>> reconstructed_x = ivy.matmul(U[:,:6] * S, Vh)
>>> print((reconstructed_x - x > 1e-3).sum())
ivy.array(0)
>>> U, S, Vh = ivy.svd(x, full_matrices = False)
>>> print(U.shape, S.shape, Vh.shape)
(9, 6) (6,) (6, 6)

With ivy.Container input:

>>> x = ivy.Container(a=ivy.array([[2.0, 3.0, 6.0], [5.0, 3.0, 4.0],
...                                [1.0, 7.0, 3.0], [3.0, 2.0, 5.0]]),
...                   b=ivy.array([[7.0, 1.0, 2.0, 3.0, 9.0],
...                                [2.0, 5.0, 3.0, 4.0, 10.0],
...                                [2.0, 11.0, 6.0, 1.0, 3.0],
...                                [8.0, 3.0, 4.0, 5.0, 9.0]]))
>>> U, S, Vh = ivy.svd(x)
>>> print(U.shape)
{
a: [
    4,
    4
],
b: [
    4,
    4
]
}
Array.svd(self, /, *, compute_uv=True, full_matrices=True)[source]#

ivy.Array instance method variant of ivy.svf. This method simply wraps the function, and so the docstring for ivy.svd also applies to this method with minimal changes.

Parameters:
  • self (Array) – input array having shape (..., M, N) and whose innermost two dimensions form matrices on which to perform singular value decomposition. Should have a floating-point data type.

  • full_matrices (bool, default: True) – If True, compute full-sized U and Vh, such that U has shape (..., M, M) and Vh has shape (..., N, N). If False, compute on the leading K singular vectors, such that U has shape (..., M, K) and Vh has shape (..., K, N) and where K = min(M, N). Default: True.

  • compute_uv (bool, default: True) – If True then left and right singular vectors will be computed and returned in U and Vh, respectively. Otherwise, only the singular values will be computed, which can be significantly faster.

  • note:: (..) – with backend set as torch, svd with still compute left and right singular vectors irrespective of the value of compute_uv, however Ivy will still only return the singular values.

Return type:

Union[Array, Tuple[Array, ...]]

Returns:

  • .. note:: – once complex numbers are supported, each square matrix must be Hermitian.

  • ret – a namedtuple (U, S, Vh). More details in ivy.svd.

    Each returned array must have the same floating-point data type as x.

Examples

With ivy.Array input:

>>> x = ivy.random_normal(shape = (9, 6))
>>> U, S, Vh = x.svd()
>>> print(U.shape, S.shape, Vh.shape)
(9, 9) (6,) (6, 6)

With reconstruction from SVD, result is numerically close to x

>>> reconstructed_x = ivy.matmul(U[:,:6] * S, Vh)
>>> print((reconstructed_x - x > 1e-3).sum())
ivy.array(0)
>>> U, S, Vh = x.svd(full_matrices = False)
>>> print(U.shape, S.shape, Vh.shape)
(9, 6) (6,) (6, 6)
Container.svd(self, /, *, compute_uv=True, full_matrices=True, key_chains=None, to_apply=True, prune_unapplied=False, map_sequences=False, out=None)[source]#

ivy.Container instance method variant of ivy.svd. This method simply wraps the function, and so the docstring for ivy.svd also applies to this method with minimal changes.

Parameters:
  • self (Container) – input container with array leaves having shape (..., M, N) and whose innermost two dimensions form matrices on which to perform singular value decomposition. Should have a floating-point data type.

  • full_matrices (Union[bool, Container], default: True) – If True, compute full-sized U and Vh, such that U has shape (..., M, M) and Vh has shape (..., N, N). If False, compute on the leading K singular vectors, such that U has shape (..., M, K) and Vh has shape (..., K, N) and where K = min(M, N). Default: True.

  • compute_uv (Union[bool, Container], default: True) – If True then left and right singular vectors will be computed and returned in U and Vh, respectively. Otherwise, only the singular values will be computed, which can be significantly faster.

  • note:: (..) – with backend set as torch, svd with still compute left and right singular vectors irrespective of the value of compute_uv, however Ivy will still only return the singular values.

Return type:

Container

Returns:

  • .. note:: – once complex numbers are supported, each square matrix must be Hermitian.

  • ret – A container of a namedtuples (U, S, Vh). More details in ivy.svd.

Examples

With ivy.Container input:

>>> x = ivy.random_normal(shape = (9, 6))
>>> y = ivy.random_normal(shape = (2, 4))
>>> z = ivy.Container(a=x, b=y)
>>> ret = z.svd()
>>> print(ret[0], ret[1], ret[2])
{
    a: (<class ivy.data_classes.array.array.Array> shape=[9, 9]),
    b: ivy.array([[-0.3475602, -0.93765765],
                  [-0.93765765, 0.3475602]])
} {
    a: ivy.array([3.58776021, 3.10416126, 2.80644298, 1.87024701, 1.48127627,
                  0.79101127]),
    b: ivy.array([1.98288572, 0.68917423])
} {
    a: (<class ivy.data_classes.array.array.Array> shape=[6, 6]),
    b: (<class ivy.data_classes.array.array.Array> shape=[4, 4])
}