32 Interface com códigos compilados

O R pode utilizar códigos compilados em Fortran, C, C++ e Delphi.

Abaixo apresentamos um exemplo simples de como fazer tal interface. Maiores detalhes estão disponíveis no manual Wrinting R Extensions.

As instuções a seguir são direcionadas para o sistema operacional LINUX. Assume-se que exista um compilador C (por exemplo gcc disponível no sistema. O mesmo recurso também pode ser usado em outros sistemas operacionais tais como Windows.

Considere o seguinte código em C que gravaremos no arquivo test.c

=======================================================================  
#include <math.h>  
#include <R.h>  
#include <Rmath.h>  
 
void cormatern(int *n, double *uphi, double *kappa, double *ans)  
{  
 int register i;  
 double cte;  
 for (i=0; i<*n; i++){  
  if (uphi[i]==0) ans[i] = 1;  
  else{  
   if (*kappa==0.5)  
   ans[i] = exp(-uphi[i]);  
   else {  
    cte = R_pow(2, (-(*kappa-1)))/gammafn(*kappa);  
    ans[i] = cte * R_pow(uphi[i], *kappa) * bessel_k(uphi[i],*kappa,1);  
}}}}  
=======================================================================

Compilamos o código em C na linha de comando do LINUX com uma ferramenta do próprio R. O comando a seguir vai prodizir ambos: test.o e test.so

$ R CMD SHLIB teste.c  
$ R

Uma vez criado o objeto compartilhado test.so (seria um test.dll no Windows) vamos usar uma função do R para acessar função disponibilidadas por este objeto. No caso de código C mostrado a seguir usamos C(). Para código Fortran usa-se .Fortran() e para C++ .Call. A seguir iniciamos o R e vamos definir fazer uma função "wrapper" em R que vai chamar, passar dados e receber resultados da rotina em C.

"matern" <- function(u, kappa){  
  out <- .C("cormatern",  
            as.integer(length(u)),  
            as.double(u),  
            as.double(kappa),  
            res = as.double(rep(0,length(u))))$res  
  return(out)  
}

Depois basta carregar o objeto compartilhado ("shared object") e usar a sua função em R como no exemplo a seguir.

  > dyn.load('teste.so')
  > matern(0.1, 1)
  > matern(seq(0,1,l=11), 1)