正确注册插件以通过 Rcpp 使用 Eigen

Tay*_*lor 3 c++ r rcpp c++11 eigen3

我试图能够c++R. 这是我第一次尝试一个可重复的小例子。

library(inline)
library(Rcpp)
inc <- 
"#include <Eigen/Dense>

template <size_t dim>
class SillyWrapper  
{
public:
  Eigen::Matrix<double,dim,1> m_vec;
  SillyWrapper(const Eigen::Matrix<int,dim,1>& vec) : m_vec(vec);
};"
src <- 
'SillyWrapper mything(Rcpp::as<Eigen::Map<Eigen::Matrix<double,dim,1>>>(x));'

library(inline)
fun <- cxxfunction(signature(x="numeric"),
                   body=src, 
                   includes=inc, 
                   plugin="Rcpp")
fun(rnorm(3))
Run Code Online (Sandbox Code Playgroud)

但是,如何访问 Eigen 标头呢?

在我的机器上,它们位于/usr/include/eigen3/. 我想我需要“注册一个插件”。我不确定这个文件路径在哪里。我尝试了一些命名参数,但没有成功。这是我尝试过但不起作用的一个示例:

library(inline)
library(Rcpp)
inc <- 
'template <size_t dim>
class SillyWrapper  
{
public:
  Eigen::Matrix<double,dim,1> m_vec;
  SillyWrapper(const Eigen::Matrix<int,dim,1>& vec) : m_vec(vec);
};'
src <- 
    'SillyWrapper mything(Rcpp::as<Eigen::Map<Eigen::Matrix<double,dim,1>>>(x));'
plug <- Rcpp.plugin.maker(include.before = "#include <Eigen/Dense>", 
                          LinkingTo = "-I/usr/include/eigen3/") # correct arg name?
inline::registerPlugin("eigenDemo", plug)
fun <- cxxfunction(signature(x="numeric"),
                   body=src, 
                   includes=inc, 
                   plugin="eigenDemo")
Run Code Online (Sandbox Code Playgroud)

我知道已经存在一个 RcppEigen 库,这将有助于此示例。如果可能的话,我希望看到一个不使用此信息的答案,因为该信息将更适用于不可用的其他情况。另外,你把 c++11 标志放在哪里?显然你只能使用cxxfunction显然,您一次

编辑:

谢谢@RalfStubner对于那些感兴趣的人,我在这里发布了一个后续问题。

Ral*_*ner 5

几点评论:

  1. 我会用Rcpp::cppFunction而不是inline::cxxfunction.
  2. 正如 Dirk 在评论中指出的,你为什么不使用 RcppEigen?特别是Rcpp::as<Eigen::...>你无论如何都需要那个包。
  3. 可以动态创建这样的插件,但设置包含路径有点复杂(请参见下面的示例)。
  4. 你想达到什么目的?R 不知道如何处理 的实例SillyWrapper

例如,由于上面第 4 点,我使用了 Eigen 文档中的一些代码:

src <- '
void foo() {
  Eigen::MatrixXd m(2,2);
  m(0,0) = 3;
  m(1,0) = 2.5;
  m(0,1) = -1;
  m(1,1) = m(1,0) + m(0,1);
  Rcpp::Rcout << "Here is the matrix m:\\n" << m << std::endl;
}'
Run Code Online (Sandbox Code Playgroud)

让我们使用 RcppEigen 提供的基础设施来编译并运行此代码:

Rcpp::cppFunction(code = src,
                  depends = "RcppEigen",
                  includes = "#include <Eigen/Dense>")

foo()
#> Here is the matrix m:
#>   3  -1
#> 2.5 1.5
Run Code Online (Sandbox Code Playgroud)

现在有了我们自己的插件:

Rcpp::registerPlugin(
    name = "Eigen3",
    plugin = function(x) {
        plug <- Rcpp::Rcpp.plugin.maker(include.before = "#include <Eigen/Dense>")
        settings <- plug()
        settings$env$PKG_CPPFLAGS = "-I/usr/include/eigen3"
        settings
    }
)

Rcpp::cppFunction(code = src,
                  plugins = "Eigen3")

foo()
#> Here is the matrix m:
#>   3  -1
#> 2.5 1.5
Run Code Online (Sandbox Code Playgroud)

由reprex 包(v0.3.0)于 2019-09-04 创建

因此,虽然原则上可以为系统安装的 Eigen 库编写一个即时插件,但我不确定考虑到 RcppEigen 的存在,这会有多大用处。