假设我在Rcpp中有一个List
,这里称为包含矩阵的x
。我可以使用x[0]
或其他东西提取其中一个元素。但是,如何提取该矩阵的特定元素?我的第一个想法是x[0](0,0)
,但这似乎不起作用。我尝试使用*
符号,但也无效。
下面是一些打印矩阵的示例代码(可以很容易地提取矩阵):
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] ));
以在第一行和第一列中打印元素?在我想用它的代码中,我需要提取这个元素来进行计算。
答案 0 :(得分:8)
快速的:
C ++中的复合表达有时会咬人;模板魔术挡路了。所以只需从List
对象分配给任何元素,例如NumericMatrix
。
然后根据您的需要从NumericMatrix
中选择。我们有row,col,element,... access。
使用Rcpp::Rcout << anElement
可以更轻松地进行打印,但请注意,我们目前无法打印整个矩阵或向量 - 但int
或double
类型正常。
编辑:
以下是一个示例实现。
#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))
sacha(L) # fix typo
*/
结果:
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>
答案 1 :(得分:6)
你必须在某些方面明确。 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