Найти минимум вектора в Rcpp - PullRequest
7 голосов
/ 01 марта 2011

С прошлой ночи я пробовал Rcpp и inline, и до сих пор я действительно наслаждаюсь этим.Но я новичок в C в целом и пока могу заниматься только базовыми вещами, и мне трудно найти помощь в Интернете по таким вопросам, как функции.

Что-то, над чем я работал, было функцией, которая находитминимум вектора в глобальной среде.Я придумал:

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 функция, которая делает это?И если да, то где я могу найти список таких функций?

Я думаю, этот вопрос связан с: Где я могу научиться писать код на C, чтобы ускорить медленные функции R?

, но отличается тем, что меня не интересует, как включить c++ в R, а больше о том, как и где выучить базовый c++ код, который можно использовать в R.

1 Ответ

10 голосов
/ 01 марта 2011

Рад, что вы нашли Rcpp полезным.

Первый комментарий Билли совершенно прав.В поиске функции есть издержки, и в поиске [] для каждого элемента есть издержки.

Кроме того, гораздо более распространенный подход - взять вектор, который есть в R, передать его скомпилированному.Функция, которую вы создаете через inline и 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: исправлено в соответствии с комментарием Ромен ниже.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...