Update: I did eventually discover an error in the C code which is probably ultimately responsible for the bug (the variable eff_size is allowed to get too large, and overrun the end of lev2[]). However the behaviour of R (or Rstudio) in response to this is still somewhat mystifying to me!
Robin On 21 May 2013 14:10, Robin Evans <rj...@cam.ac.uk> wrote: > Sure! C code is below if it helps. The gist is that the function > oneMargin forms two matrices M and C, mostly by repeatedly taking > Kronecker products. > > Robin > > void kronecker (int *A, int *B, int *dima, int *dimb, int *C) { > int k = 0; > int i1,i2,j1,j2; > > for (i2 = 0; i2 < dima[1]; i2++) { > for (j2 = 0; j2 < dimb[1]; j2++) { > for (i1 = 0; i1 < dima[0]; i1++) { > for (j1 = 0; j1 < dimb[0]; j1++) { > C[k] = A[i1 + dima[0]*i2]*B[j1 + dimb[0]*j2]; > k++; > }}}} > } > > void iterate (int *x, int *lev) { > bool ok = FALSE; > int i=0; > > do { > if(x[i] < lev[i]-1) { > x[i]++; > ok = TRUE; > } > else { > x[i] = 0; > } > i++; > } > while (!ok); > } > > void oneMargin(int *Mar, int *Eff, int *neff, int *lev, int *nvar, int > *M, int *C) { > > int *M2, *mult, *Cj, *Cj2; > int i,j=1,k,l,m; > > /* determine size of M to output */ > for (i = 0; i < nvar[0]; i++) { > j *= (Mar[i] == 1 ? lev[i]*lev[i] : lev[i]); > } > M2 = malloc(sizeof(int)*j); > mult = malloc(sizeof(int)*j); > > M[0] = 1; > int M_size[2] = {1,1}, mult_size[2], Cj_size[2], C_size[2] = {0,0}; > > for (i = nvar[0]-1; i >= 0; i--) { > if (Mar[i] == 1) { > for (j = 0; j < lev[i]*lev[i]; j++) { > mult[j] = ((j % (lev[i]+1)) == 0) ? 1 : 0; > } > mult_size[0] = mult_size[1] = lev[i]; > } > else { > for (j = 0; j < lev[i]; j++) { > mult[j] = 1; > } > mult_size[0] = 1; > mult_size[1] = lev[i]; > } > > kronecker(M, mult, M_size, mult_size, M2); > M_size[0] *= mult_size[0]; > M_size[1] *= mult_size[1]; > > /* copy M2 over to M */ > for (j=0; j < M_size[0]*M_size[1]; j++) { > M[j] = M2[j]; > } > } > > free(M2); > > /* Create C matrix */ > int index[nvar[0]]; > int prod; > int eff_size = 0; > /*swapped = 0; */ > mult_size[0] = 1; > > C_size[0] = 1; > for (j = 0; j < nvar[0]; j++) { > C_size[0] *= (Mar[j] == 1 ? lev[j] : 1); > } > > Cj = malloc(sizeof(int)*C_size[0]); > Cj2 = malloc(sizeof(int)*C_size[0]); > int *lev2; > lev2 = malloc(sizeof(int)*nvar[0]); > > /* loop over effects */ > for (i = 0; i < neff[0]; i++) { > prod = 1; > for (j = 0; j < nvar[0]; j++) { > if (Eff[j + i*nvar[0]]) { > prod *= lev[j]-1; > lev2[eff_size] = lev[j]-1; > index[eff_size] = 0; > eff_size++; > } > } > > /* loop over states of effect (excluding corner points) */ > for (j = 0; j < prod; j++) { > Cj[0] = 1; > Cj_size[0] = Cj_size[1] = 1; > > k = eff_size; > /* loop over variables */ > for (l = nvar[0]-1; l >= 0; l--) { > /* skip variables not in margin */ > if (Mar[l] == 0) continue; > mult_size[1] = lev[l]; > > /* kronecker factor depends on whether or not variable is in > effect */ > if (Eff[i*nvar[0]+l] == 0) { > /* for variables not in effect, just repeat matrix */ > for (m = 0; m < lev[l]; m++) { > mult[m] = 1; > } > } > else { > /* otherwise multiply based on state */ > k--; > for (m = 0; m < lev[l]; m++) { > mult[m] = (m == index[k]) ? lev[l] - 1 : -1; > } > } > kronecker(Cj, mult, Cj_size, mult_size, Cj2); > > Cj_size[1] *= mult_size[1]; > > /* copy Cj2 over to Cj */ > for (k=0; k < Cj_size[0]*Cj_size[1]; k++) { > Cj[k] = Cj2[k]; > } > if (Cj_size[0]*Cj_size[1] > C_size[0]) Rprintf("pointer screwup"); > } > > /* copy row over to C */ > for (m = 0; m < C_size[0]; m++) C[C_size[0]*C_size[1]+m] = Cj[m]; > C_size[1] += 1; > iterate(index, lev2); > } > } > > free(lev2); > free(Cj); > free(Cj2); > free(mult); > } > > > On 21 May 2013 14:04, R. Michael Weylandt <michael.weyla...@gmail.com> > wrote: > > > > It might also help if you can point us to the C code to help debug. > > > > MW > > > > On Tue, May 21, 2013 at 10:53 AM, Robin Evans <rj...@cam.ac.uk> wrote: > > > I should add to this that I'm running on Scientific Linux 6. I later > > > noticed that the bug only seems to occur when I run the code from > Rstudio, > > > and not if I use the terminal directly, so this may be the key to the > > > problem. > > > > > > Robin > > > > > > On 20 May 2013 16:12, Robin Evans <rj...@cam.ac.uk> wrote: > > > > > >> Hello, > > >> > > >> I've run into a problem which is both maddening and rather hard to > > >> replicate, therefore I wondered if someone might know of a plausible > > >> explanation for it. I couldn't find anything in the archives, though > > >> maybe I'm searching for the wrong thing. > > >> > > >> I'm calling some C code using .C, and get the vector I'm interested in > > >> back as the 7th location in the returned list. However I find that if > > >> I try to inspect the contents of this entry in the list in some ways, > > >> I get one answer, and if I look at it in others I get a different > > >> answer. It's quite possible that there's something wrong with the C > > >> code, but this doesn't seem to explain why this phenomenon would occur > > >> in R. > > >> > > >> The problem does not always occur - I have to run the code a few times > > >> and then call the console when it does, but the commands below show > > >> what can happen when it does. I apologise for not being able to get a > > >> cleaner example. Full code and output is below, but here is a > > >> stylised version: > > >> > > >> The following all give one answer (which is the wrong answer as far as > > >> I'm concerned) : > > >> * printing the whole list : > > >> .C(...) # and looking at the 7th entry > > >> * applying c() to the 7th element of the list > > >> c(.C(...)[[7]]) > > >> * assigning the 7th element to a vector: > > >> x = .C(...)[[7]]; > > >> x > > >> > > >> these give a different answer (which is the answer I would hope the C > > >> code returns): > > >> * using dput on the 7th entry: > > >> dput(.C(...)[[7]]) > > >> * applying c() and then dput() > > >> dput(c(.C(...)[[7]])) > > >> * just printing the 7th entry of the list > > >> .C(...)[[7]] > > >> > > >> The answers are consistent in the sense that I always get the same > > >> answers from running the same command in the console. I have tried > > >> inspecting the returned objects to see if the objects are somehow of a > > >> different class than I expect, or are just being printed oddly, but > > >> have not found anything untoward. > > >> > > >> Any suggestions would be much appreciated! > > >> > > >> Regards, > > >> > > >> Robin > > >> > > >> > > >> # THESE COMMANDS GIVE ONE ANSWER > > >> # [the correct answer always begins with 1, the incorrect with -1] > > >> > > >> > .C("oneMargin", c(1L,1L,1L,1L,1L), c(1L,1L,1L,1L,1L), 1L, > > >> c(2L,2L,2L,2L,2L), 5L, ptr1, ptr2)[[7]] > > >> [1] 1 -1 -1 1 -1 1 1 -1 -1 1 1 -1 1 -1 -1 1 -1 1 1 -1 1 -1 > > >> -1 1 1 -1 -1 1 -1 1 1 -1 > > >> > > >> > dput(.C("oneMargin", c(1L,1L,1L,1L,1L), c(1L,1L,1L,1L,1L), 1L, > > >> c(2L,2L,2L,2L,2L), 5L, ptr1, ptr2)[[7]]) > > >> c(1L, -1L, -1L, 1L, -1L, 1L, 1L, -1L, -1L, 1L, 1L, -1L, 1L, -1L, > > >> -1L, 1L, -1L, 1L, 1L, -1L, 1L, -1L, -1L, 1L, 1L, -1L, -1L, 1L, > > >> -1L, 1L, 1L, -1L) > > >> > > >> > x=dput(c(.C("oneMargin", c(1L,1L,1L,1L,1L), c(1L,1L,1L,1L,1L), 1L, > > >> c(2L,2L,2L,2L,2L), 5L, ptr1, ptr2)[[7]])) > > >> c(1L, -1L, -1L, 1L, -1L, 1L, 1L, -1L, -1L, 1L, 1L, -1L, 1L, -1L, > > >> -1L, 1L, -1L, 1L, 1L, -1L, 1L, -1L, -1L, 1L, 1L, -1L, -1L, 1L, > > >> -1L, 1L, 1L, -1L) > > >> > x > > >> [1] 1 -1 -1 1 -1 1 1 -1 -1 1 1 -1 1 -1 -1 1 -1 1 1 -1 1 -1 > > >> -1 1 1 -1 -1 1 -1 1 1 -1 > > >> > > >> # THESE ALL GIVE A DIFFERENT ONE! > > >> > > >> > .C("oneMargin", c(1L,1L,1L,1L,1L), c(1L,1L,1L,1L,1L), 1L, > > >> c(2L,2L,2L,2L,2L), 5L, ptr1, ptr2) > > >> > > >> # (OTHER ELEMENTS OF LIST REMOVED) > > >> [[7]] > > >> [1] -1 -1 1 1 1 1 -1 -1 1 1 -1 -1 -1 -1 1 1 1 1 -1 -1 -1 -1 > > >> 1 1 -1 -1 1 1 1 1 -1 -1 > > >> > > >> > c(.C("oneMargin", c(1L,1L,1L,1L,1L), c(1L,1L,1L,1L,1L), 1L, > > >> c(2L,2L,2L,2L,2L), 5L, ptr1, ptr2)[[7]]) > > >> [1] -1 -1 1 1 1 1 -1 -1 1 1 -1 -1 -1 -1 1 1 1 1 -1 -1 -1 -1 > > >> 1 1 -1 -1 1 1 1 1 -1 -1 > > >> > x = .C("oneMargin", c(1L,1L,1L,1L,1L), c(1L,1L,1L,1L,1L), 1L, > > >> c(2L,2L,2L,2L,2L), 5L, ptr1, ptr2)[[7]] > > >> > x > > >> [1] -1 -1 1 1 1 1 -1 -1 1 1 -1 -1 -1 -1 1 1 1 1 -1 -1 -1 -1 > > >> 1 1 -1 -1 1 1 1 1 -1 -1 > > >> > > >> > > >> -- > > >> Robin Evans > > >> Statistical Laboratory > > >> University of Cambridge > > >> blog: itsastatlife.blogspot.com > > >> web: www.statslab.cam.ac.uk/~rje42 > > >> > > >> Causal Inference Workshop July 15th: > > >> http://www.statslab.cam.ac.uk/~rje42/uai13/main.htm > > >> > > > > > > > > > > > > -- > > > Robin Evans > > > Statistical Laboratory > > > University of Cambridge > > > blog: itsastatlife.blogspot.com > > > web: www.statslab.cam.ac.uk/~rje42 < > http://www.stat.washington.edu/~rje42> > > > > > > Causal Inference Workshop July 15th: > > > http://www.statslab.cam.ac.uk/~rje42/uai13/main.htm > > > > > > [[alternative HTML version deleted]] > > > > > > ______________________________________________ > > > R-devel@r-project.org mailing list > > > https://stat.ethz.ch/mailman/listinfo/r-devel > [[alternative HTML version deleted]] ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel