возвращаемое значение из встроенной функции c ++ в R

У меня есть некоторый код R, который несколько медленный, поэтому я пытался написать код на С ++ непосредственно в коде R, используя встроенную библиотеку.

Это хорошо работает, и я сейчас пытаюсь это настроить.

Я смог заставить его работать, только если я выделил структуры данных ‘results’ в R и передал их как параметры функции в функцию c. Мне интересно, возможно ли иметь в коде R функцию без void c / c ++, чтобы память выделялась и возвращалась из c / c ++, а не R.

Смотрите пример ниже:

library(inline)
cppSig <- signature(res="numeric",ary="numeric",len="integer")
cppBody <- "int lens=len[0];
res[0]=0;
for(int j=0;j<lens;j++)
res[0] += ary[j];
res[0] /= (double) lens;
#if 0 //Is something like this possible?
double *rary = new double[lens];
for(int i=0;i<lens;i++) rary[i] = ary[i]-res[0];
return rary;
#endif
"cfun <- cfunction( sig=list(myMean=cppSig),
body=list(cppBody),verbose=T,
convention=".C", cxxargs="-O3", cppargs="-O3",language="C++")
cfunWrap <- function(x)
cfun$myMean(res=0,ary=x,length(x))$rescfunWrap(x=rnorm(100))

Спасибо

4

Решение

Есть несколько вещей, которые я бы сделал по-другому, особенно после всего лишь случайный взгляд в документации Rcpp. Итак, вот лишь краткий список:

  1. Да, мы можем сделать петли быстрее. Часто очень много.
  2. Да, мы можем возвращать атомарные типы C / C ++, а также векторы. Есть много примеров. Один использует wrap() для этих не векторных типов; векторы double возвращаются автоматически. Но ты никогда никогда использование new/delete на них. Увидеть Writing R Extensions почему.
  3. Да, вы можете использовать встроенный пакет. И мы этим часто пользуемся. Но мы никогда использовать его с .C() соглашение о вызовах от cfunction(), Всегда использование cxxfunction()или хотя бы включить .Call(), Я не уверен, как ты это пропустил.
  4. Начиная с Rcpp 0.10.0, у нас есть «Атрибуты Rcpp», которые даже проще в использовании, чем inline и его cxxfunction(), Посмотрите, например, для sourceCpp() или же cppFunction()или даже прочитать виньетку.
  5. Наконец, вам действительно не хватает элементарных вещей. Вы читали pdf виньетки Rcpp-iintroduction и / или Rcpp-FAQ?

Редактировать: Хорошо, вот полный пример, следующий структуре вашей функции (но мы можем сделать лучше, см. Ниже):

#include <Rcpp.h>

using namespace Rcpp;

// [[Rcpp::export]]
NumericVector monkey(NumericVector ary) {
int lens = ary.length();   // objects can tell you about their length
double res=0;
for(int j=0;j<lens;j++) res += ary[j];
res /= (double) lens;

NumericVector rary(lens);
for(int i=0;i<lens;i++) rary[i] = ary[i]-res;
return rary;
}

// and we even include some R code to test automagically

/*** R
set.seed(42)
x <- rnorm(5)   # just five to keep printout short
monkey(x)
cat("Check:")
x - mean(x)
*/

который, если вы это называете, также запускает код R внизу:

R> Rcpp::sourceCpp('/tmp/monkey.cpp')

R> set.seed(42)

R> x <- rnorm(5)   # just five to keep printout short

R> monkey(x)
[1]  0.9296545 -1.0060021 -0.0781755  0.1915587 -0.0370356

R> cat("Check:")
Check:
R> x - mean(x)
[1]  0.9296545 -1.0060021 -0.0781755  0.1915587 -0.0370356
R>

Но один из ключевые особенности Rcpp является то, что вы можете даже сделать векторную операцию в C ++:

R> cppFunction('NumericVector monkey2(NumericVector x) { return x - mean(x); }')
R> monkey2(x)
[1]  0.9296545 -1.0060021 -0.0781755  0.1915587 -0.0370356
R>

Это только что скомпилировал новую однострочную функцию C ++, которая работала на весь вектор x и побежал.

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]