From hin-tak.leung at cimr.cam.ac.uk  Wed Mar  8 13:34:54 2006
From: hin-tak.leung at cimr.cam.ac.uk (Hin-Tak Leung)
Date: Wed, 08 Mar 2006 12:34:54 +0000
Subject: [Rd] double pointer matrix
In-Reply-To: <20060307194613.26687.qmail@web27409.mail.ukl.yahoo.com>
References: <20060307194613.26687.qmail@web27409.mail.ukl.yahoo.com>
Message-ID: <440ECF6E.3040201@cimr.cam.ac.uk>

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.



[Rd] double pointer matrix
Hin-Tak Leung