C++ 是否可以将矩阵列表传递给vector<;本征::映射<;特征::矩阵xD>&燃气轮机;内联的?

C++ 是否可以将矩阵列表传递给vector<;本征::映射<;特征::矩阵xD>&燃气轮机;内联的?,c++,r,vector,stl,rcpp,C++,R,Vector,Stl,Rcpp,我试图以列表格式对矩阵行执行操作,以计算我正在编写的某些软件的Hessian矩阵(混合偏导数矩阵)的部分。我发现我只能在R中这么快地完成这项工作(即使是并行化),因此我已经切换到Rcpp以获得更快的速度,并切换到RcppEigen以获得提供的高级矩阵操作。当我依赖列表类型来表示从R传递来的矩阵/向量列表时,我的Cpp代码会随着列表长度(每个元素都是矩阵或向量)的增加而大大降低。我不知道确切的原因,但这可能是因为动态大小的对象?我的问题是:我是否可以使用RcppEigen通过如下方式将列表从R传递

我试图以列表格式对矩阵行执行操作,以计算我正在编写的某些软件的Hessian矩阵(混合偏导数矩阵)的部分。我发现我只能在R中这么快地完成这项工作(即使是并行化),因此我已经切换到Rcpp以获得更快的速度,并切换到RcppEigen以获得提供的高级矩阵操作。当我依赖列表类型来表示从R传递来的矩阵/向量列表时,我的Cpp代码会随着列表长度(每个元素都是矩阵或向量)的增加而大大降低。我不知道确切的原因,但这可能是因为动态大小的对象?我的问题是:我是否可以使用RcppEigen通过如下方式将列表从R传递到标准模板库(STL)的向量容器中

vector<Eigen::Map<Eigen::MatrixXd>> A(as<vector<Eigen::Map<Eigen::MatrixXd>> >(AA)) 
向量A(as(AA)) 我之所以想这样做,是因为我读到访问向量比访问列表快得多。然而,我可能误解了这一点,如果是这样,我道歉

其思想是传入向量列表(B2)和矩阵列表(A2)。在这些列表的每个索引中,我迭代当前索引A2中的矩阵(A)行和当前索引B2中的向量(b),计算:

b[j]*t(A[j,])%*%A[j,]

对于j,从0到第1行。我将得到一个列表,其大小等于该索引中矩阵的行数,然后转到外部限制的下一个索引,以此类推

下面是一个可复制的示例,说明了我可以使用列表执行的操作:

library(inline)
library(RcppEigen)
library(microbenchmark)    

## Create function which takes list into Rcpp and does all manipulations internally (no lapply outside)
A2 <- lapply(1:2, function(t) matrix(rnorm(10 * t), nrow = t, ncol = 10))
B2 <- lapply(1:2, function(t) rnorm(t))

## This becomes slower relative to R as the size increases.
## Something is not right in how I am programming this.
retLLMat <- "using Eigen::VectorXd;
         typedef Eigen::Map<Eigen::MatrixXd> MapMatd;
         typedef Eigen::Map<Eigen::VectorXd> MapVecd;
         List A(AA), B(BB);
         int listSize = A.size(), ncol, sublistSize;
         List outList;
         double sub;
         for (int i = 0; i < listSize; i++)
         {
           List subList;
           MapMatd subMat(as<MapMatd >(A[i]));
           MapVecd subVec(as<MapVecd >(B[i]));
           ncol = subMat.cols();
           VectorXd currRow(ncol);
           sublistSize = subMat.rows();
           for (int j = 0; j < sublistSize; j++)
           {
             currRow = subMat.row(j);
             sub = subVec[j];
             subList[String(j)] = (sub * currRow) * currRow.transpose();
           }
           outList[String(i)] = subList; 
         }
         return wrap(outList);"

## Compile Cpp code
retLLMatC <- cxxfunction(signature(AA = "List", BB = "List"), retLLMat, plugin = "RcppEigen")
## R version
retLLMat <- function(A, B) mapply(function(a, b) mapply(function(a, b) b * a, lapply(apply(a, 1, function(t) list(tcrossprod(t))), "[[", 1), b, SIMPLIFY = FALSE), A, B, SIMPLIFY = FALSE)

## Test R vs Rcpp version
microbenchmark(retLLMat(A2, B2), retLLMatC(A2, B2))
库(内联)
图书馆(RcppEigen)
图书馆(微基准)
##创建将列表纳入Rcpp并在内部执行所有操作的函数(外部无重叠)

A2你可以用另一种方法来做:使用一个标准的
列表(我们知道它是通过的),其中每个元素(无论如何必须是
SEXP
)通过一个本征
映射(我们也知道单独通过)


所以我会从简单开始,一步一步地让它变得更复杂,直到它崩溃。

嗨,德克!首先,我已经阅读了你们的文章和例子有一段时间了,所以我在这里有点震惊。很酷,你还是有时间在堆栈上响应!我将编辑我答案的底部,以显示我认为这是什么样子。我仍然有一个小问题,我认为我已经用迭代器解决了,但是,取消引用意味着类型丢失,或者类似的东西,我相信。
vector<Eigen::Map<Eigen::MatrixXd>> 
## Testing using a vector of Map<MatrixXd>
## Simplified by trying to return the list after reading it in
VectorMat <- "using Eigen::MatrixXd;
              using std::vector;
              typedef Eigen::Map<Eigen::MatrixXd> MapMatd;
              vector<MapMatd> A(as<vector<MapMatd> >(AA);
              return wrap(A);"

## This produces errors 
test <- cxxfunction(signature(AA = "List"), VectorMat, plugin = "RcppEigen")             
ListMat1 <- "using Eigen::MatrixXd;
typedef Eigen::Map<Eigen::MatrixXd> MapMatd;
ListOf<MapMatd> A(as<ListOf<MapMatd> >(AA));
return wrap(A);"
ListMat <- cxxfunction(signature(AA = "List"), ListMat1, plugin = "RcppEigen")
res <- ListMat(A2)
b2 <- lapply(1:5, function(t) numeric(t))

vecTest <- "ListOf<NumericVector> b(as<ListOf<NumericVector> >(bb)); 
NumericVector res = b[0];
return wrap(res);"   

vecTestfn <- cxxfunction(signature(bb = "List"), vecTest, plugin = "RcppEigen")
vecTestfn(b2)
ListMatInd <- "using Eigen::MatrixXd;
typedef Eigen::Map<Eigen::MatrixXd> MapMatd;
ListOf<MapMatd> A(as<ListOf<MapMatd> >(AA));
MatrixXd res = A[0];
return wrap(res);"
ListMatIndfn <- cxxfunction(signature(AA = "List"), ListMatInd, plugin = "RcppEigen")