x <- as.numeric(1:10)
n <- as.integer(10)
## A simple Fortran example
code <- "
integer i
do 1 i=1, n(1)
1 x(i) = x(i)**3
"
cubefn <- cfunction(signature(n="integer", x="numeric"), code, convention=".Fortran")
cubefn(n, x)$x
## Use of .C convention with C code
## Defining two functions, one of which calls the other
sigSq <- signature(n="integer", x="numeric")
codeSq <- "for (int i=0; i < *n; i++) {
x[i] = x[i]*x[i];
}"
sigQd <- signature(n="integer", x="numeric")
codeQd <- "squarefn(n, x);
squarefn(n, x);
"
fns <- cfunction( list(squarefn=sigSq, quadfn=sigQd),
list(codeSq, codeQd),
convention=".C")
squarefn <- fns[["squarefn"]]
quadfn <- fns[["quadfn"]]
squarefn(n, x)$x
quadfn(n, x)$x
## Alternative declaration using 'setCMethod'
setCMethod(c("squarefn", "quadfn"), list(sigSq, sigQd),
list(codeSq, codeQd), convention=".C")
squarefn(n, x)$x
quadfn(n, x)$x
## Use of .Call convention with C code
## Multyplying each image in a stack with a 2D Gaussian at a given position
code <- "SEXP res;
int nprotect = 0, nx, ny, nz, x, y;
PROTECT(res = Rf_duplicate(a)); nprotect++;
nx = INTEGER(GET_DIM(a))[0];
ny = INTEGER(GET_DIM(a))[1];
nz = INTEGER(GET_DIM(a))[2];
double sigma2 = REAL(s)[0] * REAL(s)[0], d2 ;
double cx = REAL(centre)[0], cy = REAL(centre)[1], *data, *rdata;
for (int im = 0; im < nz; im++) {
data = &(REAL(a)[im*nx*ny]); rdata = &(REAL(res)[im*nx*ny]);
for (x = 0; x < nx; x++)
for (y = 0; y < ny; y++) {
d2 = (x-cx)*(x-cx) + (y-cy)*(y-cy);
rdata[x + y*nx] = data[x + y*nx] * exp(-d2/sigma2);
}
}
UNPROTECT(nprotect);
return res;
"
funx <- cfunction(signature(a="array", s="numeric", centre="numeric"), code)
x <- array(runif(50*50), c(50,50,1))
res <- funx(a=x, s=10, centre=c(25,15))
if (interactive()) image(res[,,1])
## Same but done by registering an S4 method
setCMethod("funy", signature(a="array", s="numeric", centre="numeric"), code, verbose=TRUE)
res <- funy(x, 10, c(35,35))
if (interactive()) { x11(); image(res[,,1]) }Run the code above in your browser using DataLab