4

私はいくつかの R コードを持っていますが、これはやや遅いので、「インライン」ライブラリを使用して R コードに直接 C++ コードを書き込もうとしています。

これはうまく機能し、私は今それを調整しようとしています。

Rで「結果」データ構造を割り当て、これらを関数パラメーターとしてc関数に渡す場合にのみ、機能させることができました。メモリが割り当てられ、R ではなく c/c++ から返されるように、R コードに非 void c/c++ 関数を含めることが可能かどうか疑問に思っています。

以下の例を参照してください。

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))$res


cfunWrap(x=rnorm(100))

ありがとう

4

1 に答える 1

3

特にRcpp のドキュメントをざっとただけでも、私が別の方法で実行したいことがいくつかあります。したがって、ここに簡単なリストを示します。

  1. はい、ループを高速化できます。多くの場合、たくさん。
  2. はい、アトミックな C/C++ 型とベクトルを返すことができます。たくさんの例があります。1 つはwrap()、これらの非ベクトル型を使用します。double のベクトルは自動的に返されます。しかし、それらに対して/を使用することは決してありません。理由を参照してください。newdeleteWriting R Extensions
  3. はい、インライン パッケージを使用できます。そして、私たちはそれをたくさん使います。しかし、 からの呼び出し規則では決して使用しません。常に使用するか、少なくとも有効にします。どうやってそれを見逃したのかわかりません。.C()cfunction()cxxfunction().Call()
  4. Rcpp 0.10.0 以降、インラインやその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 の重要な機能の1 つは、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> 

これは、ベクトル全体xを操作して実行する新しい 1 行の C++ 関数をコンパイルしたところです。

于 2013-06-23T12:33:41.690 に答える