Skip to contents

Computes the reduced ("economy") singular value decomposition of a matrix x of shape (m, n): $$A = u \, \mathrm{diag}(d) \, vt,$$ where u has orthonormal columns, vt has orthonormal rows, and d is the length-k (k = min(m, n)) vector of non-negative singular values in descending order.

Note: unlike base::svd(), which returns the right singular vectors as v of shape (n, k) (so that a = u %*% diag(d) %*% t(v)), this primitive returns them already transposed as vt of shape (k, n) (matching the underlying LAPACK / cuSOLVER output and avoiding an extra transpose).

Supports any matrix shape on both the host (LAPACK gesdd) and CUDA (cuSOLVER gesvd) backends. cuSOLVER's m >= n requirement is handled transparently via a layout flip for wide matrices.

Usage

nv_svd(x)

Arguments

x

(arrayish)
One input, with exactly 2 axes. Can be any numeric data type: a float keeps its own, and an integer one is converted to the default float data type (see default_dtypes()). An R value materializes at its default data type and is converted in the same way.

Value

(named list of three arrayish)
Elements d (length k), u (shape (m, k)), and vt (shape (k, n)). All have the input's data type – or the default float data type (see default_dtypes()) where the input was an integer one.

Examples

# all three outputs have the input's data type
x <- nv_matrix(c(1, 0, 0, 1, 0, 1), nrow = 3, dtype = "f64")
nv_svd(x)
#> $d
#> AnvlArray
#>  1.6180
#>  0.6180
#> [ CPUf64{2} ] 
#> 
#> $u
#> AnvlArray
#>   0.8507  0.5257
#>   0.0000  0.0000
#>   0.5257 -0.8507
#> [ CPUf64{3,2} ] 
#> 
#> $vt
#> AnvlArray
#>   0.5257  0.8507
#>   0.8507 -0.5257
#> [ CPUf64{2,2} ] 
#>