r
  • rcpp
  • 2013-07-31 28 views 7 likes 
    7

    假设我在Rcpp中有一个List,这里叫做x包含矩阵。我可以使用x[0]或其他东西提取其中一个元素。但是,如何提取该矩阵的特定元素?我的第一个想法是x[0](0,0),但似乎并不奏效。我尝试使用*标志,但也不起作用。来自Rcpp中的列表的索引元素

    这里是打印矩阵一些示例代码(显示矩阵可以很容易地提取):

    library("Rcpp") 
    
    cppFunction(
    includes = ' 
    NumericMatrix RandMat(int nrow, int ncol) 
    { 
        int N = nrow * ncol; 
        NumericMatrix Res(nrow,ncol); 
        NumericVector Rands = runif(N); 
        for (int i = 0; i < N; i++) 
        { 
        Res[i] = Rands[i]; 
        } 
        return(Res); 
    }', 
    
    code = ' 
    void foo() 
    { 
        List x; 
        x[0] = RandMat(3,3); 
        Rf_PrintValue(wrap(x[0])); // Prints first matrix in list. 
    } 
    ') 
    
    
    foo() 
    

    我怎么能改线Rf_PrintValue(wrap(x[0]));这里打印的元素中的第一行和列?在我想要使用它的代码中,我需要提取这个元素来进行计算。

    回答

    7

    快速的:在C++有时可以咬

    1. 化合物表达;模板魔法会阻挡你。因此,只需将List对象分配给任何元素,例如NumericMatrix

    2. 然后从NumericMatrix中选择你认为合适的。我们有行,列,元素,...访问。

    3. 印刷可以使用Rcpp::Rcout << anElement更容易,但请注意,我们目前还不能打印整个矩阵或向量 - 但intdouble类型是罚款。

    编辑:

    这里是一个样本实现。

    #include <Rcpp.h> 
    
    // [[Rcpp::export]] 
    double sacha(Rcpp::List L) { 
        double sum = 0; 
        for (int i=0; i<L.size(); i++) { 
         Rcpp::NumericMatrix M = L[i]; 
         double topleft = M(0,0); 
         sum += topleft; 
         Rcpp::Rcout << "Element is " << topleft << std::endl; 
        } 
        return sum;  
    } 
    
    /*** R 
    set.seed(42) 
    L <- list(matrix(rnorm(9),3), matrix(1:9,3), matrix(sqrt(1:4),2)) 
    sasha(L) 
    */ 
    

    而其结果是:

    R> Rcpp::sourceCpp('/tmp/sacha.cpp') 
    
    R> set.seed(42) 
    
    R> L <- list(matrix(rnorm(9),3), matrix(1:9,3), matrix(sqrt(1:4),2)) 
    
    R> sacha(L) 
    Element is 1.37096 
    Element is 1 
    Element is 1 
    [1] 3.37096 
    R> 
    
    5

    你必须在某个时候明确。 List类不知道它包含的元素的类型,它不知道它是一个矩阵列表。

    Dirk向您展示了我们通常所做的工作,将元素作为NumericMatrix取回并处理矩阵。

    这是一种替代方法,假设您的列表中的所有元素具有相同的结构,并使用新的类模板:ListOf具有足够的粘合剂以使用户代码无缝。这只是明确的移动到一个不同的地方。

    #include <Rcpp.h> 
    using namespace Rcpp ; 
    
    template <typename WHAT> 
    class ListOf : public List { 
    public: 
        template <typename T> 
        ListOf(const T& x) : List(x){} 
    
        WHAT operator[](int i){ return as<WHAT>(((List*)this)->operator[](i)) ; } 
    
    } ; 
    
    // [[Rcpp::export]] 
    double sacha(ListOf<NumericMatrix> x){ 
        double sum = 0.0 ; 
        for(int i=0; i<x.size(); i++){ 
         sum += x[i](0,0) ;  
        } 
        return sum ; 
    } 
    
    /*** R 
        L <- list(matrix(rnorm(9),3), matrix(1:9,3), matrix(sqrt(1:4),2)) 
        sacha(L) 
    */ 
    

    当我sourceCpp这个文件,我得到:

    > L <- list(matrix(rnorm(9), 3), matrix(1:9, 3), matrix(sqrt(1:4), 2))  
    > sacha(L) 
    [1] 1.087057 
    
    相关问题