Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ and R interface, getting output

Tags:

c++

r

rcpp

I just started learning R, thus getting stuck with trivial looking issues. I am trying to figure out how values are outputted in R. In C++ we simply use return variable, but that doesn't seem to be the case with R. Say I have a function that takes 4 input arguments, passes those arguments to a c++ function which does the required calculations, now if I want to load this myfun in R and get output from the c++ funciton, what do I need to do? Following is the template I am trying to use.

extern "C" {
   SEXP myfun(SEXP S, SEXP A, SEXP B, SEXP C) { //will call this function from R.
     SEXP rate, dir, list, list_names; //declare variables

     PROTECT( rate = allocMatrix(REALSXP, 10, 2) ); //allocate 10x2 matrix of double type?
     PROTECT( dir = allocVector(INTSXP, 10) ); //allocated vector(10) of int type?

     double* p_rate = REAL(rate); //why do I need pointers? 
     int* p_dir = INTEGER(dir);

//here I call a C++ function which calculates vector<vector<double> > someVal and vector<int> someVal2.

Now I want to pass those values to the rate and dir.

 for(int i =0; i < 10; i++){
      rate[i][0] = someVal1[i][0];
      rate[i][1] = someVal1[i][1];
      dir[i] = someVal2[i]; 
  }

but the compiler doesn't like it. I am not sure how to use the p_rate and p_dir pointers in this case.

Also, I am not quite understand why the following code is the way it is. It seems to be passing the strings, rate and dir to the list_names and values to the rate and dir. Why can't we simply do cout and print the desired values?

   char *tag[2] = {"rate","dir"};
   PROTECT(list_names = allocVector(STRSXP ,2));
   SET_STRING_ELT(list_names, 0, mkChar(tag[0]));
   SET_STRING_ELT(list_names, 1, mkChar(tag[1]));
   PROTECT(list = allocVector(VECSXP ,2));
   SET_VECTOR_ELT(list, 0, rate);
   SET_VECTOR_ELT(list, 1, dir);
   setAttrib(list, R_NamesSymbol , list_names);

   UNPROTECT(8);
   return (list);
}

I am not getting the basic idea behind returning the variables in R, it seems very confusing. I would really appreciate if someone could point me to the appropriate resources that explains these stuffs.

Thanks for your help in advance!

like image 802
intsymmetry Avatar asked Nov 11 '12 18:11

intsymmetry


People also ask

What is SEXP in R?

A SEXP is a variant type, with subtypes for all R's data structures. The most important types are: REALSXP : numeric vector. INTSXP : integer vector. LGLSXP : logical vector.


2 Answers

If you are already familiar with C++, you may find our Rcpp project for seamless R and C++ integrarion useful. It contains a lot of documentation and examples, plus CRAN has now over 80 packages using it which provides another large corpus of examples.

You could start with "Introduction" vignette which corresponds to our JSS paper, and also peruse the [rcpp] tag here.

Otherwise, you are back at the R API which is more bare-bones and based on C only.

like image 71
Dirk Eddelbuettel Avatar answered Sep 29 '22 04:09

Dirk Eddelbuettel


As we said while answering your previous question, give Rcpp a shot, and take away all the kludge in your code.

#include <Rcpp.h>
using namespace Rcpp ;

void yourCode( std::vector< std::vector<double> >& someVal, 
               std::vector<double>& someVal2 ){ ... }

extern "C" SEXP myfun() { 
    NumericMatrix rate(10, 2); 
    NumericVector dir(10) ;

    std::vector< std::vector<double> > someVal ;
    std::vector< double > someVal2 ;

    // call whatever function that fills someVal and someVal2
    yourCode( someVal, someVal2 ) ;

    // fills rate and dir
    for(int i =0; i < 10; i++){
      rate(i, 0) = someVal1[i][0];
      rate(i, 1) = someVal1[i][1];
      dir[i] = someVal2[i]; 
    }

    // structure the output
    List result = List::create( 
        _["rate"] = rate,
        _["dir"] = dir
    ) ;

    return result ;

}
like image 31
Romain Francois Avatar answered Sep 29 '22 05:09

Romain Francois