celestialgod

eigen decomposition in Rcpp and LAPACK

Jan 1st, 2017
118
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
R 1.36 KB | None | 0 0
  1. Sys.setenv("PKG_LIBS" = "$(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS)")
  2. Rcpp::sourceCpp("eigen_sym_cpp.cpp")
  3.  
  4. n_row <- 1e4L
  5. n_col <- 1e1L
  6. A <- matrix(rnorm(n_row * n_col), n_row, n_col)
  7. S <- cov(A)
  8.  
  9. eig_res_cpp1 <- eigen_sym_cpp(S)
  10. eig_res_cpp2 <- eigen_sym_cpp(S, 5L)
  11. eig_res_cpp3 <- eigen_sym_cpp(S, -1L, TRUE)
  12.  
  13. eig_res_r <- eigen(S)
  14.  
  15. # check eigenvalues
  16. all.equal(eig_res_cpp1$values, eig_res_r$values) # TRUE
  17. all.equal(eig_res_cpp2$values, eig_res_r$values[1L:5L]) # TRUE
  18. all.equal(eig_res_cpp3$values, eig_res_r$values) # TRUE
  19.  
  20. # check eigenvectors
  21. sign_vectors_cpp1 <- colSums(eig_res_r$vectors * eig_res_cpp1$vectors)
  22. eig_res_cpp1$vectors <- sweep(eig_res_cpp1$vectors, 2, sign_vectors_cpp1, '*')
  23. all.equal(eig_res_cpp1$vectors, eig_res_r$vectors) # TRUE
  24.  
  25. # check eigenvectors
  26. sign_vectors_cpp2 <- colSums(eig_res_r$vectors[ , 1L:5L] * eig_res_cpp2$vectors)
  27. eig_res_cpp2$vectors <- sweep(eig_res_cpp2$vectors, 2, sign_vectors_cpp2, '*')
  28. all.equal(eig_res_cpp2$vectors, eig_res_r$vectors[ , 1L:5L]) # TRUE
  29.  
  30. library(microbenchmark)
  31. microbenchmark(
  32.   Rcpp_BLAS = eigen_sym_cpp(S),
  33.   R = eigen(S),
  34.   times = 100L
  35. )
  36. # Unit: microseconds
  37. #       expr      min       lq      mean    median       uq      max neval
  38. #  Rcpp_BLAS  788.180  852.546  872.9262  860.4455  874.196 1000.293   100
  39. #          R 1203.336 1271.505 1363.7922 1281.4520 1391.457 2432.417   100
Add Comment
Please, Sign In to add comment