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