2013-05-03 93 views
3

RcppEigen的JacobiSVD在升级到3.0时变慢了吗? 我的库使用RcppEigen现在工作得很快。RcppEigen svd很慢

> n<-1000 
> m<-matrix(rnorm(n*n),n,n) 

> unix.time(s1<-svd(m))  # R 
    user system elapsed 
10.376 0.028 10.407 

> unix.time(s2<-svdArma(m)) # RcppArmadillo 
    user system elapsed 
22.997 0.000 23.001 

> unix.time(s3<-svdEigen(m)) # RcppEigen 
    user system elapsed 
180.708 0.000 180.712 

这里是R上的测试代码:

library(inline) 

codeArma=' 
    arma::mat m = Rcpp::as<arma::mat>(m_); 

    arma::mat u; 
    arma::vec s; 
    arma::mat v; 

    arma::svd(u,s,v,m); 
    return List::create(Rcpp::Named("u")=u, 
         Rcpp::Named("d")=s, 
         Rcpp::Named("v")=v); 
' 
svdArma <- cxxfunction(signature(m_="matrix"),codeArma, plugin="RcppArmadillo") 

#----------------------------------------------------------------------- 

codeEigen=' 
    const Eigen::Map<Eigen::MatrixXd> m (as<Eigen::Map<Eigen::MatrixXd> >(m_)); 

    Eigen::JacobiSVD <Eigen::MatrixXd>svd(m, 
        Eigen::ComputeThinU|Eigen::ComputeThinV); 
    return List::create(Rcpp::Named("u")=svd.matrixU(), 
         Rcpp::Named("d")=svd.singularValues(), 
         Rcpp::Named("v")=svd.matrixV()); 
' 
svdEigen <- cxxfunction(signature(m_="matrix"), codeEigen, plugin="RcppEigen") 

#------------------------------------------------------------------------ 
n<-1000 
m<-matrix(rnorm(n*n),n,n) 

system.time(s1<-svd(m))  # R 
m1<-s1$u %*% diag(s1$d) %*% t(s1$v) 
all.equal(m,m1) 

system.time(s2<-svdArma(m)) # Armadillo 
m2<-s2$u %*% diag(array(s2$d)) %*% t(s2$v) 
all.equal(m,m2) 

system.time(s3<-svdEigen(m)) # Eigen 
m3<-s3$u %*% diag(s3$d) %*% t(s3$v) 
all.equal(m,m3) 

---------------------------- ------------------------------

+2

请不要破坏这样的帖子。一般来说,问题可能对其他人有价值。最好的办法是让你回答你自己的问题。如果你确实觉得没有附加价值,你可以简单地删除它。 – 2013-05-03 19:37:37

+0

OP是否有权删除/标记在当前声誉级别(〜80)内删除? – 2013-05-03 21:20:24

回答

5

切换到R 3.0.0应该不会看到如何影响包如RcppEigen执行。如果您看到表现出现回归,可能会出现其他情况。

你也可以尝试通过使用Armadillo和/或Eigen直接在C++中编译SVD(如果你将它们安装在R之外,和/或你可以从R包中获得头文件并使用一些修补程序)。