Function svd
pub fn svd<const D: usize, const D1: usize>(
tensor: Tensor<D>,
sweeps: usize,
) -> (Tensor<D>, Tensor<D1>, Tensor<D>)Expand description
Computes the singular value decomposition of a square or rectangular matrix.
This function decomposes the input tensor A into three tensors U, S, Vt
such that A = U @ diag(S) @ Vt, where:
Uhas orthonormal columns of shape[..., m, k]Scontains the singular values ofA, sorted in descending order, of shape[..., k]Vthas orthonormal rows of shape[..., k, n]
with k = min(m, n) (reduced decomposition, matching torch.linalg.svd).
§Algorithm
Two stages, mirroring the LAPACK gesvd / dbdsqr structure:
- Golub-Kahan bidiagonalization using Householder reflections (
A = U1 B V1^T). - Implicitly shifted bidiagonal QR iteration (LAPACK
dbdsqr) to diagonalizeB.
§Arguments
tensor- The input tensor of shape[..., m, n].sweeps- Upper bound on the number of QR sweeps per singular value.
§Returns
A tuple of three tensors (U, S, Vt):
U:[..., m, k]with orthonormal columnsS:[..., k]singular values in descending orderVt:[..., k, n]with orthonormal rows
§Generic Parameters
D: The number of dimensions of the input tensor.D1: Must be set toD - 1(the rank of the singular value tensor).
§Panics
This function will panic if the tensor checks fail:
- The input tensor has less than 2 dimensions (
D < 2). - The input is a quantized tensor with dtype
DType::QFloat. - The generic parameters do not satisfy
D - 1 == D1. - The input tensor requires gradients (SVD has no autodiff support yet; detach first).
sweepsis zero.- The QR iteration does not converge within the requested sweep budget.
§Performance Note
The computation is dispatched to the backend through
LinalgOps::svd, which backends may override with a native or
fused implementation (none ship one yet). The default implementation
runs the reference pipeline on the host over the tensor data
(into_data / from_data), which is deterministic and
backend-independent, but the bidiagonalization is O(m n^2) scalar math.
It is not competitive with tuned native libraries (e.g. cuSOLVER) for
large matrices.
§Numerical Behavior
- If the input tensor has dtype F16 or BF16, it is internally upcast to
F32 for the computation and cast back to the original dtype before
returning, like
detandlu. - Singular values are sorted in descending order.
- Internal norms, rotations, and shifts use scaled formulations to reduce overflow and underflow for extreme finite inputs.
§Example
use burn_linalg::svd;
use burn::Tensor;
fn example() {
let device = Default::default();
let tensor = Tensor::<2>::from_data([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]], &device);
// Compute the singular value decomposition
let (u, s, vt) = svd::<2, 1>(tensor, 10);
// A = U @ diag(S) @ Vt (within tolerance)
let recon = u.mul(s.unsqueeze_dim(0)).matmul(vt);
println!("{}", recon);
}