【问题标题】:Convert std::vector to Rcpp matrix将 std::vector 转换为 Rcpp 矩阵
【发布时间】:2013-11-08 16:42:11
【问题描述】:

这是一个与 Rcpp 转换相关的 Q。我希望将 long std::vector 转换为 Rcpp 矩阵对象,但想知道是否有简单的转换格式。自然地,您可以遍历每个元素并填充一个空的 Rcpp 矩阵,但这似乎容易出错并且如果可能有更方便的方法可能是不必要的。

我问的原因是我想在一些现有的 C++ 代码中使用 OpenMP,但是将元素直接存储在 OpenMP 循环中的 Rcpp 矩阵对象中似乎效果不佳(而加载 std::vector对象并在 OpenMP 循环完成后转换为矩阵似乎是解决问题的一种不错的方法)。

任何帮助将不胜感激!

【问题讨论】:

    标签: r rcpp


    【解决方案1】:

    扩展德克的答案; R 矩阵实际上只是具有dim 属性集的向量

    > x <- 1
    > y <- as.matrix(x)
    > .Internal( inspect(x) )
    @7f81a6c80568 14 REALSXP g0c1 [MARK,NAM(2)] (len=1, tl=0) 1 ## data
    > .Internal( inspect(y) )
    @7f81a3ea86c8 14 REALSXP g0c1 [NAM(2),ATT] (len=1, tl=0) 1 ## data
    ATTRIB:
      @7f81a3e68e08 02 LISTSXP g0c0 [] 
        TAG: @7f81a30013f8 01 SYMSXP g1c0 [MARK,LCK,gp=0x4000] "dim" (has value) 
        @7f81a3ea8668 13 INTSXP g0c1 [NAM(2)] (len=2, tl=0) 1,1
    

    请注意xy 的“数据”组件只是REALSXPs,但是矩阵上有这个额外的dim 组件。使用它,我们可以轻松地将NumericVector 转换为Rcpp 中的矩阵。

    (注意:在下面的示例中,我在属性中使用了SEXP,以便类型之间的转换是明确的):

    #include <Rcpp.h>
    using namespace Rcpp;
    
    // [[Rcpp::export]]
    SEXP vec_to_mat(SEXP x_) {
      std::vector<double> x = as< std::vector<double> >(x_);
      /* ... do something with x ... */
      NumericVector output = wrap(x);
      output.attr("dim") = Dimension(x.size(), 1);
      return output;
    }
    
    /*** R
    m <- c(1, 2, 3)
    vec_to_mat(m)
    */
    

    给我

    > m <- c(1, 2, 3)
    
    > vec_to_mat(m)
         [,1]
    [1,]    1
    [2,]    2
    [3,]    3
    

    因此,您可以使用 Dimension 类并将其分配给向量的 dim 属性,以在 Rcpp 中“手动”制作矩阵。

    【讨论】:

    • 非常有意义。谢谢!
    【解决方案2】:

    您选择了一个好方法。在 OpenMP 上下文中,你必须远离单线程 R。所以std::vector 很好。

    是的,我们有从std::vectorRcpp::NumericVectorRcpp::NumericMatrix 的构造函数(这毕竟只是一个具有维度属性的向量)以及Rcoo:Integer* 变体,以及通常的@987654327 @ 和 wrap 转换器。

    Rcpp 单元测试、Rcpp 示例,当然还有Rcpp Gallery 站点上应该有很多示例。

    编辑:这是一个过于简单的例子:

     R> cppFunction('NumericVector phil(int n) { std::vector<double> x(n);
     +              return wrap(x); }') 
     R> phil(4)  
     [1] 0 0 0 0    
     R>    
    

    【讨论】:

    • 太好了,非常感谢德克。我在 Rcpp 库或随包附带的示例中没有看到任何内容,但也许我只是看起来不够努力......
    • 我明白了。是的,我知道 std::vector 很容易转换为 Rcpp 向量,但我更想知道在给定 std::vector 和已知尺寸的情况下填充 NumericMatrix 的最佳方法(我猜更像NumericMatrix ret = vector2NumericMatrix(x, n, m);,其中@ 987654331@ 和 m 是行数和列数。当然,很容易编写一个函数来执行此操作,但我更想知道是否已经完成了类似的操作。谢谢!如果我在纠缠你,对不起琐碎的事情:)
    • 您还可以考虑 RcppArmadillo,它作为一个线性代数/矩阵库,具有大量子集、连接、组合等运算符。那可能是我的选择。我们可能缺少一两个转换器。欢迎投稿。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-14
    • 1970-01-01
    • 2016-12-10
    • 1970-01-01
    • 1970-01-01
    • 2017-04-26
    • 1970-01-01
    相关资源
    最近更新 更多