我無法在Rcpp或RcppArmadillo中找到很酷的which(x,arr.ind=T)
功能。所以我決定快速編寫代碼。RCPP中的(x,arr.ind = T)
// [[Rcpp::export]]
arma::umat whicha(arma::mat matrix, int what){
arma::uvec outp1;
int n = matrix.n_rows;
outp1 = find(matrix==what);
int nf = outp1.n_elem;
arma::mat out(nf,2);
arma::vec foo;
arma::uvec foo2;
foo = arma::conv_to<arma::colvec>::from(outp1) +1;
foo2 = arma::conv_to<arma::uvec>::from(foo);
for(int i=0; i<nf; i++){
out(i,0) = (foo2(i) %n);
out(i,1) = ceil(foo(i)/n);
if(out(i,0)==0) {
out(i,0)=n;
}
}
return(arma::conv_to<arma::umat>::from(out));
}
代碼似乎非常低效的,但microbenchmark
表明,它可以比的r which
功能更快。
問題:我可否進一步更改此功能以實際重現R的which
功能,即將MATRIX == something
傳遞給它?現在我需要第二個參數。我只是爲了方便有這個。
更新:修正了一個錯誤 - 需要的小區,而不是地板
如何檢查:
ma=floor(abs(rnorm(100,0,6)))
testf=function(k) {all(which(ma==k,arr.ind=T) == whicha(ma,k))} ; sapply(1:10,testf)
基準:
> microbenchmark(which(ma==k,arr.ind=T) , whicha(ma,k))
Unit: microseconds
expr min lq median uq max neval
which(ma == k, arr.ind = T) 10.264 11.170 11.774 12.377 51.317 100
whicha(ma, k) 3.623 4.227 4.830 5.133 36.224 100
那麼,如果你想要提高性能,直接的改進就是不要在arma類型中複製數據。在你的'whicha'函數中有一個'arma :: mat'對象作爲輸入意味着你正在將一個R對象的數據複製到一個犰狳對象中。這有成本。返回一個'arma :: umat'會將這個對象轉換爲R對象,這也意味着數據拷貝。 –