Hello,
I use the simplest of examples that somebody can think
of in order to generate a matrix of random numbers
from within C, calling appropriate R functions. The
concrete example is below:
--- file pico.c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <R.h>
#include <Rmath.h>
#define COLM( i, j, m ) ( m*j + i)
void pico ( double *y, int n, int m ) {
int i, j;
GetRNGstate();
for ( i=0; i<n; i++ ) {
for ( j=0; j<m; j++ ) {
y[ COLM( i,j,m ) ] = rnorm( 0,
1 );
}
}
PutRNGstate();
}
---------
--- file pico.R
dyn.load("pico.so");
if( is.loaded( symbol.C( "pico" ) ) )
n<-10; m<-5;
y<-matrix( 0, n, m );
a<- .C( "pico", as.double(y), as.integer(n),
as.integer(m) );
-----
The code, when executed within R, gives a segmentation
fault. I looked at the writing R extensions, but not
much can be inferred from there on the subject. In
fact, I would be indebted if I could have a pointer to
a beginnner's guide to the R API.
Thank you for any answers,
- b.
PS. if this is not the appropriate section of R
maillists that this post should be in, I apologise in advance.
>>>>> "BK" == Bernd Kriegstein <kriegstn at yahoo.de> writes:BK> void pico ( double *y, int n, int m ) ^^^^^^^^^^^^^ Everything is passed from R to C as pointer, so these should be pointers. Hope this helps. Cheers, Berwin
On Tue, 21 Feb 2006, Bernd Kriegstein wrote:> I use the simplest of examples that somebody can think > of in order to generate a matrix of random numbers > from within C, calling appropriate R functions. The > concrete example is below: > [SNIP]------ pico.c -------- #include <stdio.h> #include <stdlib.h> #include <math.h> #include <R.h> #include <Rmath.h> #define COLM(i,j,m) ((m * j) + i) void pico(double *y, int *n, int *m) { register int i; GetRNGstate(); for (i = 0; i < *n; i++) { register int j; for (j = 0; j < *m; j++) { y[COLM(i,j,*m)] = rnorm(0.0, 1.0); } } PutRNGstate(); } ------ pico.R -------- dyn.load("pico.so") n <- 10 m <- 5 ans <- .C("pico", as.double(matrix(0, n, m)), as.integer(n), as.integer(m)) str(ans[[1]]) ---------------------- $ R CMD SHLIB pico.c $ R --vanilla < pico.R ---------------------------------------------------------- SIGSIG -- signature too long (core dumped)
Thank you very much for the answer. As a general principle, when and why should I register the counters? Should I do the same in matrices or other parameters that I pass and alter in the main body of the C function? Thanks again, - b. --- Paul Roebuck <roebuck at mdanderson.org> schrieb:> On Tue, 21 Feb 2006, Bernd Kriegstein wrote: > > > I use the simplest of examples that somebody can > think > > of in order to generate a matrix of random numbers > > from within C, calling appropriate R functions. > The > > concrete example is below: > > [SNIP] > > ------ pico.c -------- > #include <stdio.h> > #include <stdlib.h> > #include <math.h> > #include <R.h> > #include <Rmath.h> > > #define COLM(i,j,m) ((m * j) + i) > > void pico(double *y, int *n, int *m) { > register int i; > > GetRNGstate(); > for (i = 0; i < *n; i++) { > register int j; > > for (j = 0; j < *m; j++) { > y[COLM(i,j,*m)] = rnorm(0.0, 1.0); > } > } > PutRNGstate(); > } > > ------ pico.R -------- > dyn.load("pico.so") > n <- 10 > m <- 5 > ans <- .C("pico", > as.double(matrix(0, n, m)), > as.integer(n), > as.integer(m)) > str(ans[[1]]) > > ---------------------- > > $ R CMD SHLIB pico.c > $ R --vanilla < pico.R > >----------------------------------------------------------> SIGSIG -- signature too long (core dumped) > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel >
On Feb 21, 2006, at 2:48 PM, Bernd Kriegstein wrote:> Thank you very much for the answer. As a general principle, when > and why should I register the counters?"register int i" is merely an optimization, you can safely use "int i" instead. The "register" keyword only tells the compiler to store the variable in a CPU register where possible - it is not necessary at all (most modern compiler will optimize it correctly anyway). Crucial mistake in your example was the improper use of function parameters and pointers. Cheers, Simon