I use a large real matrix, X, in C code that is passed from R and
transposed in place in the C code. I would like to conserve memory and,
if possible, allocate space for only one copy of X -- hence I would like
to pass a pointer to the data in the X object to the C code.
The Writing R Extensions manual says that neither .Call nor .External
copy their arguments. They also say that these arguments should be
treated as read only.
Fine, but in testing I seem to be able to transpose very large X's in
place, in C code without an error. This leads me to assume that the
manual was just giving good advice about treating arguments as read
only. However, I find that I have done nothing to the X in R. It seems
that a copy has been made after all. I may as well call the code with .C
and avoid the use of macros.
Could someone please point out the error in my thinking or suggest a way
to accomplish my goal?
My code follows:
"mListTest" <-
function(X,N,k) {
.Call("mList",as.double(X),as.integer(N),as.integer(k));
}
SEXP mList(
SEXP Xi,
SEXP Ni,
SEXP ki
)
{
double *pX=NUMERIC_POINTER(Xi);
int N=INTEGER_POINTER(Ni)[0];
int k=INTEGER_POINTER(ki)[0];
SEXP alist;
SEXP avector;
SEXP nvector;
SEXP rvector;
SEXP kvector;
int n;
int i;
transposeMatrix(pX,N,k);
n=4;
PROTECT(alist=NEW_LIST(n));
PROTECT(avector=NEW_NUMERIC(200));
for (i=0;i<200;i++) {
NUMERIC_POINTER(avector)[i]=pX[i];
}
SET_ELEMENT(alist,0,avector);
UNPROTECT(1);
PROTECT(nvector=NEW_INTEGER(1));
INTEGER_POINTER(nvector)[0]=N;
SET_ELEMENT(alist,1,nvector);
UNPROTECT(1);
PROTECT(rvector=NEW_NUMERIC(1));
NUMERIC_POINTER(rvector)[0]=0.5;
SET_ELEMENT(alist,2,rvector);
UNPROTECT(1);
PROTECT(kvector=NEW_INTEGER(1));
INTEGER_POINTER(kvector)[0]=k;
SET_ELEMENT(alist,3,kvector);
UNPROTECT(1);
UNPROTECT(1);
return alist;
}
--
Bob Wheeler --- http://www.bobwheeler.com/
ECHIP, Inc. ---
Randomness comes in bunches.