在MCMC算法的深处,我需要将用户提供的矩阵列表与向量相乘,即,每个MCMC迭代多次调用下面的Rcpp和RcppArmadillo代码:
List mat_vec1 (const List& Mats, const vec& y) {
int n_list = Mats.size();
Rcpp::List out(n_list);
for (int i = 0; i < n_list; ++i) {
out[i] = as<mat>(Mats[i]) * y;
}
return(out);
}
用户提供的列表Mats
在MCMC期间保持不变,每次迭代中的向量y
都会发生变化。效率是至关重要的,我试图看看我是否可以通过多次将Mats
的元素转换为arma :: mat来加速代码(它只需要执行一次)。我尝试了以下方法
List arma_Mats (const List& Mats) {
int n_list = Mats.size();
Rcpp::List res(n_list);
for (int i = 0; i < n_list; ++i) {
res[i] = as<mat>(Mats[i]);
}
return(res);
}
然后
List mat_vec2 (const List& Mats, const vec& y) {
int n_list = Mats.size();
Rcpp::List aMats = arma_Mats(Mats);
Rcpp::List out(n_list);
for (int i = 0; i < n_list; ++i) {
out[i] = aMats[i] * y;
}
return(out);
}
但这似乎不起作用。任何替代/更好解决方案的指针都非常受欢迎。
答案 0 :(得分:3)
好的,我基本上在评论中写了答案,但后来我发现我们已经在RcppArmadillo.package.skeleton()
创建的存根中提供了一个工作示例:
// [[Rcpp::export]]
Rcpp::List rcpparma_bothproducts(const arma::colvec & x) {
arma::mat op = x * x.t();
double ip = arma::as_scalar(x.t() * x);
return Rcpp::List::create(Rcpp::Named("outer")=op,
Rcpp::Named("inner")=ip);
}
这将返回给定向量的外积(矩阵)和内积(标量)的列表。
至于什么是快速的,什么不是:我建议不要猜测,而是 profile 并尽可能多地测量。我倾向于在Armadillo中做更多(独立的)C ++代码,并且最后只返回最小化转换。