% vecsqr.tex
% does:  calling C from R
%**************************************************;
\documentclass[12pt]{article}
\usepackage{times}

%height
\topmargin=0mm
\headheight=0mm
\headsep=0mm
\textheight=235mm

%width
\oddsidemargin=0mm
\evensidemargin=0mm
\textwidth=180mm

\begin{document}
\vspace{1cm}
\begin{center}
  {\bf
    Calling C code from R - an Example \\
    By Bahjat F. Qaqish \\
  }
\end{center}
%-----------------------------------------------------------------

This document describes a simple example of how to call
C code from within R.
It is assumed that  all the necessary software
(R itself, compiler and other tools) have been installed properly.


Our example is a function to which
we pass an array
$x_1, \cdots, x_n$
and it  computes
$y_1, \cdots, y_n$ defined by $y_i = x_i^2$.
The example shows
\begin{enumerate}
\item  How to pass arguments from R to C code
\item  How to receive computed values from  C code
\item  How to compile the C code
\item  How to load and run the C code from within R
\item  Some rules about writing C code to link to R
\end{enumerate}


The R function will be called \textsf{vecsqr}.
An example usage is
\textsf{y = vecsqr(x)},
assuming a vector \textsf{x} has been defined.
The C function will be called \textsf{vecsqr}
(other names will do as well)
and stored in a file called \textsf{vecsqr.c}.
Here is that file:
\begin{verbatim}
#include <R.h>

void vecsqr(double *y, double *x, int *n_p)
/* y[0:n-1] <- x[0:n-1]^2 */
{
  int i, n = *n_p;

  if (n < 1) Rprintf("vecsqr: error n = %d < 1\n", n);

  for (i=0; i < n; i++) y[i] = x[i]*x[i];
}
\end{verbatim}
Notice that there is no \textsf{main} function.
Also, \textsf{R.h} must be included.
Instead of \textsf{printf}, we use \textsf{Rprintf} to
send the output to the R console.
Functions that will be called from R must have type \textsf{void}.
All arguments are passed by reference including single numbers such as
\textsf{n}, the number of elements.

The next step is to compile the C code.
This is done with the command
\begin{verbatim}
R CMD SHLIB vecsqr.c
\end{verbatim}
The result is a file named \textsf{vecsqr.so}.

We are almost ready  to call our C function from R.
We can issue the call directly from R.
However, it is generally better  and more convenient
to write an R function
that takes care of dynamically loading the compiled code,
translating back and forth between R and C,
and making sure that the  arguments have the required type and are
passed in the proper order.
We put that function in a file named \textsf{vecsqr.r}.
Here is that file:
\begin{verbatim}
dyn.load("vecsqr.so")    # load the compiled code
vecsqr = function(x)     # our R interface to the compiled code
{
  n = length(x)
  result  = .C("vecsqr",
        y = double(n),
        as.double(x),
        as.integer(n) )
  result[["y"]]
}
\end{verbatim}
The function passes arguments in the proper order (y, x, n),
forces the correct type using \textsf{as.double} and \textsf{as.integer},
and allocates the required space for the result \textsf{y}.
The R function \textsf{.C} performs the actual call to  the C function,
and returns a list.
The  return
value from the R function \textsf{vecsqr} is the
vector \textsf{y} extracted from the list
returned by \textsf{.C} via \textsf{result[["y"]]}.


Now, in R, we source the R function
\begin{verbatim}
source("vecsqr.r")
\end{verbatim}
and we are ready to call the C function,
\begin{verbatim}
a1 = 1:10
a2 = vecsqr(a1)
a4 = vecsqr(a2)
a8 = vecsqr(a4)
cbind(a1, a2, a4, a8)
\end{verbatim}


To see the error message generated if \textsf{n} is less than 1 we call
the compiled code  directly via \textsf{.C}
\begin{verbatim}
x = 1:10
.C("vecsqr", y = double(length(x)), as.double(x), as.integer(-4))
\end{verbatim}


A lot more is possible.
Several functions can be defined in \textsf{vecsqr.c}
and in \textsf{vecsqr.r}.
It is possible to call R functions  from  C code.
Further, the \emph{package} mechanism
is especially convenient for distributing code to others.
See the \emph{Writing R Extensions} manual for further details.


%-----------------------------------------------------------------
\end{document}
