[Rd] double pointer matrix

Hin-Tak Leung
Wed, 08 Mar 2006 12:34:54 -0000

CC-ing r-devel for the direct e-mail.

Bernd Kriegstein wrote:
> Hi Hin-Tak,
>
> Thanks for the answer, but it's a little bit
> tangential. Mind you that y is a double pointer,
> commonly used in initialization of matrices. My
> problem is that I cannot eventually access the
> elements of this matrix from within R.

If you write the R code as (sorry, I make a mistake earlier -
you really mean a n*m matrix, not a n*1 one)

y <- double(n*m)
y <- .C("retMat", as.double(y) ....)[1],

y would *appear* to your C code as a double pointer,
and also would be allocated storage on the R side.
(you don't want to know how and why that is, it
is in the R-extension manual and not very clearly
explained, so you'll just have to try it out and see).

In fact
y <- .C("retMat", double(n*m), ...) [1]

probably would do the job just fine. (note it is
double(n*n), not as.double(...)) - this is allocating on
the way in.

>
> Put another way, do you have any idea about how to
> make a matrix in the C body and then pass it to R
> stack?

I do, but the only way of doing allocation and having it
interacting correctly with
R's garbage collector (i.e. having free() taken care of
automatically), is via the .Call/.External interfaces,
and it gets more complicated - basically you do something like

#include <R.h>
#include <Rinternals.h>

SEXP retMat(SEXP args)
{
...
PROTECT(y = allocMatrix(REALSXP,n,m)
...
}

and honestly, what I outlined earlier and again is the
simpliest way.

HTL

>
> Thanks for any answers,
>
> - b.
>
> --- Hin-Tak Leung <hin-tak.leung at cimr.cam.ac.uk>
> schrieb:
>
>
>>Please don't do malloc inside C code like this - it
>>won't interact too
>>well with the garbage collector in R, and your
>>program probably will
>>either leak or crash or both... and when are you
>>going to do your
>>free()?
>>
>>What you want is do is to delete that malloc line
>>and do the
>>allocation on the R side, something like this (the
>>first line does
>>the equivalent of your malloc allocation):
>>
>>y <- double(n)
>>y <- .C("retMat", as.double(y), as.double(n),
>>as.double(m),
>>as.double(a), as.double(b))[1]
>>
>>HTL
>>
>>Bernd Kriegstein wrote:
>>
>>>Hello,
>>>
>>>I'm having some difficulty to understand how I
>>
>>could
>>
>>>take the proper result from the following listing:
>>>
>>>-- cut ---
>>>#include <stdlib.h>
>>>#include <R.h>
>>>#include <Rmath.h>
>>>
>>>void retMat ( double **y, int *n, int *m, double
>>
>>*a,
>>
>>>double *b) {
>>>        int i, j;
>>>        y = malloc( (*n) * sizeof( double ) );
>>>        for (i=0; i<*n; i++) {
>>>                y[i] = malloc ( (*m) * sizeof(
>>
>>double
>>
>>>) );
>>>        }
>>>
>>>        GetRNGstate();
>>>
>>>        for (i=0; i<*n; i++) {
>>>                for (j=0; j<*m; j++) {
>>>                        y[i][j] >>
>>(i+1)*(j+1)*rbeta(
>>
>>>*a, *b );
>>>                }
>>>        }
>>>
>>>        PutRNGstate();
>>>}
>>>---
>>>I understand that I will have to make the matrix
>>>initialized in the double for loop above to be
>>
>>somehow
>>
>>>visible as a vector, because of the way that the
>>>matrix elements are passed in the argument when
>>
>>used
>>
>>>in the R space. Is there a way to accomplish this?
>>>
>>>Thanks for any answers,
>>>
>>>- b.