Hello, I try to write an extension in C, to get a faster functions. Therefore I have to add an element (vector) to a vector. The command in R is very simple: x = c(x,a) But in C I have the problem to reallocate my vector for getting more space. Everything I tried, I get a "Segmentation fault". So, how can I combine two vectors in C and give the result back to R (return(x))? Thanks Markus Schmidberger -- Dipl.-Tech. Math. Markus Schmidberger Ludwig-Maximilians-Universit?t M?nchen IBE - Institut f?r medizinische Informationsverarbeitung, Biometrie und Epidemiologie Marchioninistr. 15, D-81377 Muenchen URL: http://ibe.web.med.uni-muenchen.de Mail: Markus.Schmidberger [at] ibe.med.uni-muenchen.de Tel: +49 (089) 7095 - 4599
>>>>> "Markus" == Markus Schmidberger <schmidb at ibe.med.uni-muenchen.de> >>>>> on Fri, 19 Jan 2007 15:02:31 +0100 writes:Markus> Hello, Markus> I try to write an extension in C, to get a faster functions. Markus> Therefore I have to add an element (vector) to a vector. The command in Markus> R is very simple: x = c(x,a) aka x <- c(x,a) see that's why you'd probably rather stick with R a bit longer, and profile [-> help(Rprof)] your code and try to speedup quite a bit before thinking about using C ... Markus> But in C I have the problem to reallocate my vector for getting more Markus> space. Everything I tried, I get a "Segmentation fault". Markus> So, how can I combine two vectors in C and give the result back to R Markus> (return(x))? and you have a copy of "Writing R Extensions" right in front of you, electronically at least, I mean? To return the new vector via C's return() you'd definitely need to work with .Call() {which is a good thing but really not for C-beginners}, and that needs a bit time of reading the above manual "from cover to cover". Note that you probably should start with (5.8) on .Call. I'm also tending to recommend even starting to peek into R's own C source, notably the header files (src/include/...), and maybe src/main/* in order to see how R objects ("SEXP"s) are handled, how you add names(), dimnames() etc internally.. Hoping that helps, Martin Maechler, ETH Zurich Markus> Thanks Markus> Markus Schmidberger Markus> -- Markus> Dipl.-Tech. Math. Markus Schmidberger
This is a programming question, and I am sending a solution to R-devel (please see the posting guide). On Fri, 19 Jan 2007, Markus Schmidberger wrote:> Hello, > > I try to write an extension in C, to get a faster functions. > Therefore I have to add an element (vector) to a vector. The command in > R is very simple: x = c(x,a) > But in C I have the problem to reallocate my vector for getting more > space. Everything I tried, I get a "Segmentation fault". > > So, how can I combine two vectors in C and give the result back to R > (return(x))? > > Thanks > Markus Schmidberger > >-- Brian D. Ripley, ripley at stats.ox.ac.uk Professor of Applied Statistics, http://www.stats.ox.ac.uk/~ripley/ University of Oxford, Tel: +44 1865 272861 (self) 1 South Parks Road, +44 1865 272866 (PA) Oxford OX1 3TG, UK Fax: +44 1865 272595
[A programming question moved from R-help] On Fri, 19 Jan 2007, Markus Schmidberger wrote:> Hello, > > I try to write an extension in C, to get a faster functions. > Therefore I have to add an element (vector) to a vector. The command in > R is very simple: x = c(x,a)I don't see how you are going to code this in C appreciably faster than the R developers already have.> But in C I have the problem to reallocate my vector for getting more > space. Everything I tried, I get a "Segmentation fault".We have no idea how you are trying to do this, or even which interface (.C, .Call, .External) you are trying to use.> So, how can I combine two vectors in C and give the result back to R > (return(x))?The code below is just a beginning (it does no coercion, there are missing cases and it can be improved by caching e.g. REAL(a)), but can be used by> dyn.load("my_c.so") > my_c <- function(a, b) .Call("my_c", a, b)% cat my_c.c #include <R.h> #include <Rinternals.h> SEXP my_c(SEXP a, SEXP b) { SEXP ans; int i, na, nb; if(TYPEOF(a) != TYPEOF(b)) error("type mismatch"); switch(TYPEOF(a)) { case LGLSXP: case INTSXP: case REALSXP: case STRSXP: break; default: error("unimplemented type"); } na = LENGTH(a); nb = LENGTH(b); PROTECT(ans = allocVector(TYPEOF(a), na+nb)); switch(TYPEOF(a)) { case LGLSXP: case INTSXP: for(i = 0; i < na; i++) INTEGER(ans)[i] = INTEGER(a)[i]; for(i = 0; i < nb; i++) INTEGER(ans)[na+i] = INTEGER(a)[i]; break; case REALSXP: for(i = 0; i < na; i++) REAL(ans)[i] = REAL(a)[i]; for(i = 0; i < nb; i++) REAL(ans)[na+i] = REAL(a)[i]; break; case STRSXP: for(i = 0; i < na; i++) SET_STRING_ELT(ans, i, STRING_ELT(a, i)); for(i = 0; i < nb; i++) SET_STRING_ELT(ans, na+i, STRING_ELT(a, i)); break; } UNPROTECT(1); return ans; } -- Brian D. Ripley, ripley at stats.ox.ac.uk Professor of Applied Statistics, http://www.stats.ox.ac.uk/~ripley/ University of Oxford, Tel: +44 1865 272861 (self) 1 South Parks Road, +44 1865 272866 (PA) Oxford OX1 3TG, UK Fax: +44 1865 272595
Hello, thanks for help and code. We did a lot of work to speedup our function in R. We have a nested loop, vectorizing is the fastest way. But there we got a very big matrix and problems with memory. So we want to stay by loops an speedup with C. My code is similar to this. (my_c is code from Brian D. Ripley) SEXP test(SEXP a, SEXP b, SEXP in) { SEXP ans, new; int n=INTEGER(in)[0],i,j; PROTECT(ans = allocVector(REALSXP, 1)); REAL(ans)[0]=REAL(a)[0]; /* for(j = 0; i < m; j++)*/ for(i = 0; i < n; i++) { /* b= ... ^i ....*j*/ PROTECT(new = allocVector(REALSXP, i+2)); new = my_c(ans,b); PROTECT(ans = allocVector(REALSXP, i+2)); ans = new; UNPROTECT(2); } UNPROTECT(1); return ans; } We get an error by in=1300 > .Call("test",1,3,as.integer(1300)); Fehler: type mismatch > .Call("test",1,3,as.integer(1300)); Speicherzugriffsfehler Is there a possibility to free allocated memory? free(...) does not work. Is there a possibility to reallocate a vector? Thanks a lot Markus
On Mon, 22 Jan 2007, Markus Schmidberger wrote:> Hello, > thanks for help and code. > We did a lot of work to speedup our function in R. We have a nested loop, > vectorizing is the fastest way. But there we got a very big matrix and > problems with memory. So we want to stay by loops an speedup with C. > > My code is similar to this. (my_c is code from Brian D. Ripley)And not in many ways similar to mine, hence your error message. You really do have to handle all the types, as I did most.> > SEXP test(SEXP a, SEXP b, SEXP in) > { > SEXP ans, new; > int n=INTEGER(in)[0],i,j; > PROTECT(ans = allocVector(REALSXP, 1)); > REAL(ans)[0]=REAL(a)[0]; > /* for(j = 0; i < m; j++)*/ > for(i = 0; i < n; i++) > { > /* b= ... ^i ....*j*/ > PROTECT(new = allocVector(REALSXP, i+2)); > new = my_c(ans,b); > PROTECT(ans = allocVector(REALSXP, i+2)); > ans = new; > UNPROTECT(2); > } > UNPROTECT(1); > return ans; > } > > We get an error by in=1300 > >> .Call("test",1,3,as.integer(1300)); > Fehler: type mismatch >> .Call("test",1,3,as.integer(1300)); > Speicherzugriffsfehler > > Is there a possibility to free allocated memory? free(...) does not work.No, but garbage collection does.> Is there a possibility to reallocate a vector?Yes, sort of. See lengthgets(). -- Brian D. Ripley, ripley at stats.ox.ac.uk Professor of Applied Statistics, http://www.stats.ox.ac.uk/~ripley/ University of Oxford, Tel: +44 1865 272861 (self) 1 South Parks Road, +44 1865 272866 (PA) Oxford OX1 3TG, UK Fax: +44 1865 272595