2013-07-31 38 views
7

Giả sử tôi có một số List trong Rcpp, ở đây được gọi là x chứa ma trận. Tôi có thể trích xuất một trong các thành phần bằng cách sử dụng x[0] hoặc thứ gì đó. Tuy nhiên, làm cách nào để trích xuất một phần tử cụ thể của ma trận đó? Suy nghĩ đầu tiên của tôi là x[0](0,0) nhưng điều đó dường như không hoạt động. Tôi đã thử sử dụng các dấu hiệu * nhưng cũng không hoạt động.Phần tử chỉ mục từ danh sách trong Rcpp

Dưới đây là một số mã ví dụ mà in ma trận (matrix cho thấy có thể dễ dàng được chiết xuất):

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() 

Làm thế nào tôi có thể thay đổi dòng Rf_PrintValue(wrap(x[0])); vào đây để in các phần tử trong hàng đầu tiên và cột? Trong mã tôi muốn sử dụng nó cho tôi cần phải trích xuất phần tử này để làm tính toán.

Trả lời

7

những Nhanh: biểu

  1. Compound trong C++ có thể cắn vào những thời điểm; ma thuật mẫu được cản đường. Vì vậy, chỉ cần gán từ đối tượng List cho bất kỳ phần tử nào, ví dụ: NumericMatrix.

  2. Sau đó chọn từ NumericMatrix khi bạn thấy vừa vặn. Chúng tôi có hàng, col, phần tử, ... truy cập.

  3. In ấn có thể được dễ dàng hơn bằng Rcpp::Rcout << anElement nhưng lưu ý rằng chúng tôi hiện không thể in toàn bộ ma trận hoặc vector - nhưng int hay double loại cũng tốt.

Edit:

Đây là một thực hiện mẫu.

#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) 
*/ 

Và kết quả của nó:

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

Bạn phải rõ ràng tại một số điểm. Các lớp List không có ý tưởng về các loại phần tử nó chứa, nó không biết nó là một danh sách các ma trận.

Dirk đã cho bạn thấy những gì chúng tôi thường làm, tìm nạp phần tử dưới dạng NumericMatrix và xử lý ma trận. Đây là một giải pháp thay thế giả định rằng tất cả các phần tử trong danh sách của bạn đều có cùng cấu trúc, sử dụng mẫu lớp mới: ListOf với đủ keo để làm cho mã người dùng liền mạch. Điều này chỉ di chuyển đến một nơi khác là nhân chứng.

#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) 
*/ 

Khi tôi sourceCpp tập tin này, tôi nhận được:

> L <- list(matrix(rnorm(9), 3), matrix(1:9, 3), matrix(sqrt(1:4), 2))  
> sacha(L) 
[1] 1.087057 
Các vấn đề liên quan