R Under development (unstable) (2025-08-17 r88631 ucrt) -- "Unsuffered Consequences" Copyright (C) 2025 The R Foundation for Statistical Computing Platform: x86_64-w64-mingw32/x64 R is free software and comes with ABSOLUTELY NO WARRANTY. You are welcome to redistribute it under certain conditions. Type 'license()' or 'licence()' for distribution details. R is a collaborative project with many contributors. Type 'contributors()' for more information and 'citation()' on how to cite R or R packages in publications. Type 'demo()' for some demos, 'help()' for on-line help, or 'help.start()' for an HTML browser interface to help. Type 'q()' to quit R. > ## compute PCA of iris data set with svd() and sparsesvd() > library(sparsesvd) > library(Matrix) > > data(iris) > M <- scale(as.matrix(iris[, 1:4]), scale=FALSE) > Ms <- Matrix(M) # not sparse, but a dMatrix > > res1 <- svd(M) > res2 <- sparsesvd(Ms) > > ## check that eigenvalues are the same > print(res2$d, digits=3) [1] 25.10 6.01 3.41 1.88 > stopifnot(all.equal(res1$d, res2$d, tolerance=1e-12)) > > ## these should be diagonal unit matrices > UtU <- abs(crossprod(res2$u, res1$u)) # diagonal entries may be 1 or -1 > VtV <- abs(crossprod(res2$v, res1$v)) # (because sign of eigenvectors is arbitrary) > I1 <- diag(1, length(res1$d)) > > print(round(UtU, 12)) [,1] [,2] [,3] [,4] [1,] 1 0 0 0 [2,] 0 1 0 0 [3,] 0 0 1 0 [4,] 0 0 0 1 > stopifnot(all.equal(UtU, I1, tolerance=1e-12)) > > print(round(VtV, 12)) [,1] [,2] [,3] [,4] [1,] 1 0 0 0 [2,] 0 1 0 0 [3,] 0 0 1 0 [4,] 0 0 0 1 > stopifnot(all.equal(VtV, I1, tolerance=1e-12)) > > ## check that SVD is reproducible > ## (this is guaranteed by a deterministic RNG built into the SVDLIBC code) > for (i in 1:20) { + res <- sparsesvd(Ms) + if (!isTRUE(all.equal(res, res2))) stop("SVD not reproducible on iteration #", i) + } > > proc.time() user system elapsed 0.81 0.07 0.87