问题描述
我正在使用Rcpp加速一些R代码(实际上这是我2014年待办事项"列表的项目之一),部分代码包括将矩阵列表乘以标量,我就是能够获得结果,但是矩阵不再是矩阵,而是矢量,我希望将矩阵列表作为最终输出.
I am using Rcpp to speed up some R codes (and actually this is one of the items of my 'to do' List for 2014), part of the code consists of multiplying a list of matrices by a scalar, I am able to get the results, nontheless the matrices are not longer matrices, they are vectors instead and I want a list of matrices as the final output.
这是我到目前为止的代码:
Here's the code I have so far:
// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>
using namespace Rcpp;
using namespace arma;
// I got this template from here: http://stackoverflow.com/a/18014655/1315767
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]]
List FooList(NumericVector fi1, ListOf<NumericMatrix> Ct){
List TempList(Ct.size());
NumericMatrix ct(2,2);
for(int i=0; i<Ct.size(); i++){
ct = Ct[i] ;
TempList[i] = ct * fi1[i] ; // multiply each matrix by each scalar in fi1
}
return TempList;
}
运行此代码时,我得到以下信息:
When running this code, I get the following:
> sourceCpp("FooList.cpp")
> A <- replicate(3,matrix(1:4, 2), simplify=FALSE) # a list of matrices
> vec <- 0.5 * c(1:3) # a vector
> FooList(vec, A) # dim are not preserved
[[1]]
[1] 0.5 1.0 1.5 2.0
[[2]]
[1] 1 2 3 4
[[3]]
[1] 1.5 3.0 4.5 6.0
FooList
给出的输出是可以的,但是格式不正确,我希望得到这样的东西:
The output given by FooList
is ok, but the format is not, I expected to get something like this:
[[1]]
[,1] [,2]
[1,] 0.5 1.5
[2,] 1.0 2.0
[[2]]
[,1] [,2]
[1,] 1 3
[2,] 2 4
[[3]]
[,1] [,2]
[1,] 1.5 4.5
[2,] 3.0 6.0
我不明白为什么要得到此输出,因为ct
是矩阵,如果我摆脱了fi1[i]
,则输出的确是矩阵列表,我什至尝试使用as_scalar(fi)
与以前一样.我也尝试在没有成功的情况下使用ct.attr("dim") = Dimension(2, 2);
.
I don't understand why I'm getting this output, because ct
is a matrix, if I get rid of fi1[i]
the output is indeed a list of matrices, I even tried using as_scalar(fi)
and I get the same as before. I also tried using ct.attr("dim") = Dimension(2, 2);
with no sucess.
推荐答案
关键问题是,当您在C ++中将矩阵乘以标量时,您将Rcpp
的语法糖用于*
,它是矢量化的.无论出于何种原因,它都不了解如何返回矩阵(我没有广泛阅读过文档).
The key problem is that when you are multiplying the matrix by a scalar in C++, you're using Rcpp
's syntactic sugar for *
, which is vectorized. For whatever reason, it doesn't understand how to return a matrix (I haven't looked at the documentation extensively).
如果我们改为将每个矩阵的每个元素乘以标量,则会得到预期的结果:
If we instead multiply each element of each matrix by the scalar, you get the expected results:
FooList.R
// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>
using namespace Rcpp;
using namespace arma;
// I got this template from here: http://stackoverflow.com/a/18014655/1315767
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]]
List FooList(NumericVector fi1, ListOf<NumericMatrix> Ct){
List TempList(Ct.size());
NumericMatrix ct(2,2);
for(int i=0; i<Ct.size(); i++){
ct = Ct[i] ;
for (int j=0; j < ct.nrow(); j++) {
for (int k=0; k < ct.ncol(); k++) {
ct(j, k) *= fi1[i]; // Multiply each element of the matrix by the scalar in fi1
}
}
TempList[i] = ct;
}
return TempList;
}
互动会话:
> sourceCpp("FooList.cpp")
> A <- replicate(3,matrix(1:4, 2), simplify=FALSE) # a list of matrices
> vec <- 0.5 * c(1:3) # a vector
> FooList(vec, A)
[[1]]
[,1] [,2]
[1,] 0.5 1.5
[2,] 1.0 2.0
[[2]]
[,1] [,2]
[1,] 1 3
[2,] 2 4
[[3]]
[,1] [,2]
[1,] 1.5 4.5
[2,] 3.0 6.0
这篇关于矩阵列表乘以标量后,维度属性未保留在Rcpp中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!