开发者

Calling compiled C from R with .C()

开发者 https://www.devze.com 2023-02-05 11:51 出处:网络
I\'m trying to call a program (function getNBDensities in the C executable measurementDensities_out) from R. The function is passed several arrays and the variable double runsum. Right now, the getNBD

I'm trying to call a program (function getNBDensities in the C executable measurementDensities_out) from R. The function is passed several arrays and the variable double runsum. Right now, the getNBDensities function basically does nothing: it prints to screen the values of passed parameters. My problem is the syntax of calling the function:

array(.C("getNBDensities",
            hr = as.double(hosp.rate), # a vector (s x 1)
            sp = as.double(samplingProbabilities), # another vector (s x 1)
            odh = as.double(odh), # another vector (s x 1)
            simCases = as.integer(x[c("xC1","xC2","xC3")]), # another vector (s x 1)
            obsCases = as.integer(y[c("yC1","yC2","yC3")]), # another vector (s x 1)
            runsum = as.double(runsum), # double
            DUP = TRUE, NAOK = TRUE, PACKAGE = "measurementDensities_out")$f,
            dim = length(y[c("yC1","yC2","yC3")]),
            dimnames = c("yC1","yC2","yC3"))

The error I get, after proper 开发者_如何学Cexecution of the function (i.e., the right output is printed to screen), is

Error in dim(data) <- dim : attempt to set an attribute on NULL

I'm unclear what the dimensions are that I should be passing the function: should it be s x 5 + 1 (five vectors of length s and one double)? I've tried all sorts of combinations (including sx5+1) and have found only seemingly conflicting descriptions/examples online of what's supposed to happen here.

For those who are interested, the C code is below:

#include <R.h>
#include <Rmath.h>
#include <math.h>
#include <Rdefines.h>
#include <R_ext/PrtUtil.h>
#define NUM_STRAINS 3
#define DEBUG
void getNBDensities(  double *hr, double *sp, double *odh, int *simCases, int *obsCases, double *runsum );
void getNBDensities( double *hr, double *sp, double *odh, int *simCases, int *obsCases, double *runsum ) {
#ifdef DEBUG
  for ( int s = 0; s < NUM_STRAINS; s++ ) {
    Rprintf("\nFor strain %d",s); 
    Rprintf("\n\tHospitalization rate = %lg", hr[s]);
    Rprintf("\n\tSimulation probability = %lg",sp[s]);
    Rprintf("\n\tSimulated cases = %d",simCases[s]);
    Rprintf("\n\tObserved cases = %d",obsCases[s]);
    Rprintf("\n\tOverdispersion parameter = %lg",odh[s]);
}
  Rprintf("\nRunning sum = %lg",runsum[0]);
#endif
}


naive solution

While better (i.e., potentially faster or syntactically clearer) solutions may exist (see Dirk's answer below), the following simplification of the code works:

     out<-.C("getNBDensities",
            hr = as.double(hosp.rate),
            sp = as.double(samplingProbabilities),
            odh = as.double(odh),
            simCases = as.integer(x[c("xC1","xC2","xC3")]),
            obsCases = as.integer(y[c("yC1","yC2","yC3")]),
            runsum = as.double(runsum))

The variables can be accessed in >out.


You may want to look into the inline package which makes compiling, linking and loading of C, C++ or Fortran code an absolute breeze.

That said, and particularly if C++ is another option for you, also look at the Rcpp package which permits you transfer both R and C++ objects back and forth with ease.

0

精彩评论

暂无评论...
验证码 换一张
取 消