fast.svd {corpcor}R Documentation

Fast Singular Value Decomposition

Description

fast.svd returns the singular value decomposition of a rectangular real matrix

M=UDV,M = U D V^{'},

where UU and VV are orthogonal matrices with UU=IU' U = I and VV=IV' V = I, and DD is a diagonal matrix containing the singular values (see svd).

The main difference to the native version svd is that fast.svd is substantially faster for "fat" (small n, large p) and "thin" (large n, small p) matrices. In this case the decomposition of MM can be greatly sped up by first computing the SVD of either MMM M' (fat matrices) or MMM' M (thin matrices), rather than that of MM.

A second difference to svd is that fast.svd only returns the positive singular values (thus the dimension of DD always equals the rank of MM). Note that the singular vectors computed by fast.svd may differ in sign from those computed by svd.

Usage

fast.svd(m, tol)

Arguments

m

matrix

tol

tolerance - singular values larger than tol are considered non-zero (default value: tol = max(dim(m))*max(D)*.Machine$double.eps)

Details

For "fat" MM (small n, large p) the SVD decomposition of MMM M' yields

MM=UD2UM M^{'} = U D^2 U

As the matrix MMM M' has dimension n x n only, this is faster to compute than SVD of MM. The VV matrix is subsequently obtained by

V=MUD1V = M^{'} U D^{-1}

Similarly, for "thin" MM (large n, small p), the decomposition of MMM' M yields

MM=VD2VM^{'} M = V D^2 V^{'}

which is also quick to compute as MMM' M has only dimension p x p. The UU matrix is then computed via

U=MVD1U = M V D^{-1}

Value

A list with the following components:

d

a vector containing the positive singular values

u

a matrix with the corresponding left singular vectors

v

a matrix with the corresponding right singular vectors

Author(s)

Korbinian Strimmer (https://strimmerlab.github.io).

See Also

svd, solve.

Examples

# load corpcor library
library("corpcor")


# generate a "fat" data matrix
n = 50
p = 5000
X = matrix(rnorm(n*p), n, p)

# compute SVD
system.time( (s1 = svd(X)) ) 
system.time( (s2 = fast.svd(X)) )


eps = 1e-10
sum(abs(s1$d-s2$d) > eps)
sum(abs(abs(s1$u)-abs(s2$u)) > eps)
sum(abs(abs(s1$v)-abs(s2$v)) > eps)

[Package corpcor version 1.6.10 Index]