double pointer matrix

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

double pointer matrix

Bernd Kriegstein
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.

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: double pointer matrix

Hin-Tak Leung-2
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.
>
> ______________________________________________
> [hidden email] mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: double pointer matrix

Hin-Tak Leung-2
In reply to this post by Bernd Kriegstein
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 <[hidden email]>
> 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.

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel