2011-03-01 96 views
6

由於昨晚我一直在嘗試Rcppinline,到目前爲止我非常享受它。但我一般對C有點新,只能做基本的東西,而且我很難在網上找到像函數這樣的東西。在Rcpp中查找最小矢量

我正在研究的是一個函數,它可以在全局環境中找到一個向量的最小值。我想出了:

library("inline") 
library("Rcpp") 

foo <- rnorm(100) 

bar <- cxxfunction(signature(), 
' 
Environment e = Environment::global_env(); 
NumericVector foo = e["foo"]; 
int min; 

for (int i = 0; i < foo.size(); i++) 
{ 
    if (foo[i] < foo[min]) min = i; 
} 
return wrap(min+1); 
', plugin = "Rcpp") 

bar() 

但好像應該有這樣做的更簡單的方法,它比which.max()

system.time(replicate(100000,bar())) 
    user system elapsed 
    0.27 0.00 0.26 
system.time(replicate(100000,which.min(foo))) 
    user system elapsed 
    0.2  0.0  0.2 

我俯瞰基本c++Rcpp功能相當慢於做這個?如果是這樣,我可以在哪裏找到這樣的功能列表?

我想這個問題是關於: Where can I learn how to write C code to speed up slow R functions?

,但在不同的我不是在如何R納入c++很感興趣,但更多的是如何以及在哪裏學習基本c++代碼是可用R

+1

我非常懷疑你會加快使用C++的最小和最大操作速度 - 這些可能已經在R中使用(快速)SSE指令來實現。另外,從C++到R的過渡並不是免費的。 – 2011-03-01 17:57:52

+0

我意識到,這更多是指概念,這是我試圖在R中實現的一個更大的C++函數的一部分。 – 2011-03-01 18:17:21

回答

9

很高興你發現Rcpp有用。

比利的第一條評論是非常正確的。在函數查找中有開銷,並且在每個元素的[]查找中都有開銷。

此外,更常用的方法是採用R中的矢量,將它傳遞給您通過編譯的函數創建內聯和Rcpp,並讓它返回結果。試試看。這個軟件包中有很多例子,它們遍佈在rcpp-devel郵件列表的檔案中。

編輯:我無法抗拒試圖設置一個非常C++/STL風格的答案。

R> src <- ' 
+ Rcpp::NumericVector x(xs); 
+ Rcpp::NumericVector::iterator it =  // iterator type 
+  std::min_element(x.begin(), x.end()); // STL algo 
+ return Rcpp::wrap(it - x.begin()); ' 
R> minfun <- cxxfunction(signature(xs="numeric"), body=src, plugin="Rcpp") 
R> minfun(c(7:20, 3:5)) 
[1] 14 
R> 

這不正是最簡單的答案,但它說明了如何使用什麼C++提供你甚至可以在C++水平沒有找到一個(明確)循環的最小單元。但內置函數min()仍然更快。

*編輯2:根據下面的羅曼的評論更正。

+0

但是,您的STL版本實現'min',這不是Sacha想要的:'which.min '。 – 2012-10-25 06:58:11

+1

看起來很好 - 但是由於'min_element()'返回一個迭代器,我們可以像我剛纔那樣簡單地修復它 - 在它現在(正確)返回14的示例上。 – 2012-10-25 13:26:40

+0

Rcpp 0.9.16將有'which_min' – 2012-11-03 08:19:41