Return value from C ++ inline function in R

I have some R code that is somewhat slow, so I tried to write C ++ code directly in R code using the inline library.

This works well, and now I'm trying to configure it.

I managed to do this if I selected the data structures of the “results” in R and passed them as functional parameters to the c function. I am wondering if it is possible to use an odd c / C ++ function in R code such that memory is allocated and returned from c / C ++ rather than R.

See an example below:

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

thanks

+4
source share
1 answer

There are a few things that I would do differently, especially after just a casual look at the Rcpp documentation. So here is just a quick list:

  • Yes, we can make cycles faster. Often a lot.
  • Yes, we can return atomic types of C / C ++, as well as vectors. There are many examples. For these non-vector types, wrap() ; double vectors are returned automatically. But you never use new / delete . See Writing R Extensions for what.
  • Yes, you can use the built-in package. And we use it a lot. But we never use it with the .C() cfunction() from cfunction() . Always use cxxfunction() or at least include .Call() . I'm not sure how you missed it.
  • Since Rcpp is 0.10.0, we have Rcpp attributes that are even easier to use than inline and cxxfunction() . Look around, for example, on sourceCpp() or cppFunction() , or even read the vignette.
  • Finally, you really lack elementary things. Have you read the Rcpp-iintroduction PDF vignettes and / or the Rcpp-FAQ?

Edit: Ok, here is a complete example following the structure of your function (but we can do better, see below):

 #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) */ 

which, if you call it, also runs the R code below:

 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> 

But one of the key functions of Rcpp is that you can even perform a vector operation in 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> 

It just compiled a new single-line C ++ function that worked on the whole vector x and ran it.

+3
source

Source: https://habr.com/ru/post/1487704/


All Articles