У меня есть некоторый код 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))
Спасибо
Есть несколько вещей, которые я бы сделал по-другому, особенно после всего лишь случайный взгляд в документации Rcpp. Итак, вот лишь краткий список:
wrap()
для этих не векторных типов; векторы double возвращаются автоматически. Но ты никогда никогда использование new
/delete
на них. Увидеть Writing R Extensions
почему..C()
соглашение о вызовах от cfunction()
, Всегда использование cxxfunction()
или хотя бы включить .Call()
, Я не уверен, как ты это пропустил.cxxfunction()
, Посмотрите, например, для sourceCpp()
или же cppFunction()
или даже прочитать виньетку.Редактировать: Хорошо, вот полный пример, следующий структуре вашей функции (но мы можем сделать лучше, см. Ниже):
#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
и побежал.
Других решений пока нет …