C-within-R代码中的特征值计算

时间:2013-01-04 21:06:53

标签: c r eigenvalue

我正在编写使用已编译C代码的R代码。

从“编写R扩展”文档中,我了解到可以从C代码调用许多R可执行文件/ DLL。头文件'Rmath.h'列出了许多可用的功能,其源代码列在本网站上:http://svn.r-project.org/R/trunk/src/nmath/

我需要计算许多矩阵的奇异值分解,但我没有找到在上述网站上执行此操作的子程序。 (所以我假设Rmath.h不包含SVD子程序)是否有简单的方法在C-in-R代码中进行特征值计算?

非常感谢。

2 个答案:

答案 0 :(得分:4)

如果您愿意使用Rcpp及其相关软件包,fastLm()的现有示例将向您展示如何使用

  • Eigen via RcppEigen
  • 犰狳通过RcppArmadillo
  • GSL via RcppGSL

后两者将使用与R相同的BLAS,而Eigen具有内部通常更快的内容。所有软件包都使用语言提供的分解来实现lm()(通常使用求解或相关,但是一旦你有工具链为你工作,切换到SVD就很简单了。)

编辑:这是一个明确的例子。使用以下C ++代码:

#include <RcppArmadillo.h>   

// [[Rcpp::depends(RcppArmadillo)]] 

// [[Rcpp::export]]   
arma::vec getEigen(arma::mat M) { 
    return arma::eig_sym(M);      
}    

保存在文件“eigenEx.cpp”中。然后只需要这个R代码:

library(Rcpp)               ## recent version for sourceCpp()
sourceCpp("eigenEx.cpp")    ## converts source file into getEigen() we can call

这样我们就可以运行:

set.seed(42)        
X <- matrix(rnorm(3*3), 3, 3)
Z <- X %*% t(X)              

getEigen(Z)                 ## calls function created above

我得到了与R完全相同的特征向量。它真的没那么容易了。

它还让犰狳选择了用于特征分解的方法,正如大卫暗示的那样,这比完全成熟的SVD更快(参见犰狳文档)。

答案 1 :(得分:1)

您可以使用许多可用的线性代数(lapack)库中的一个。 Here是一个解释如何获取Windows的lapack库的链接。 GOTOBLAS和ACML都是免费的。 MKL也可以免费用于非商业用途。安装库后,您要查找的函数是sgesvd(浮点数)或dgesvd(表示double)。

以下是英特尔关于如何使用gesvd的几个例子。

  1. Row Major
  2. Col Major
  3. 如果您使用的是Linux,请查看GNU SLEigen。这些库通常可以从发行版的包管理器安装。