currently I am introducing myself to C to extend my R-functions. I wrote a function in C for some computations and they work fine. But as soon as I write a wrapper in R itself there seems to be some mistake. Consider my C-function as "colV" and "abc" as some arbitrary matrix.
The statement (R) .Call("colV", abc, ncol(abc), nrow(abc)) works totally fine (everytime, no matter how often I use it), whereas
colV = function(x){
nc = ncol(x)
nr = nrow(x)
.Call("colV", x, nc, nr)
}
delivers a wrong result at third use:
> colV(abc)
[1] 1.4274933 0.6254796 0.6774042 1.7094617 0.7250386
> colV(abc)
[1] 1.4274933 0.6254796 0.6774042 1.7094617 0.7250386
> colV(abc)
[1] -8.370087e+22 6.254796e-01 6.774042e-01 1.709462e+00 7.250386e-01
If I declare the wrapper again, the first two runs work fine and again at the third try the same result appears. Note, that besides the appearance only the first value actually changes!
Does somebody have an idea whats wrong with the wrapper? As said before, if I only use the .Call statement the correct result is returned always:
> .Call("colV", abc, ncol(abc), nrow(abc))
[1] 1.4274933 0.6254796 0.6774042 1.7094617 0.7250386
> .Call("colV", abc, ncol(abc), nrow(abc))
[1] 1.4274933 0.6254796 0.6774042 1.7094617 0.7250386
> .Call("colV", abc, ncol(abc), nrow(abc))
[1] 1.4274933 0.6254796 0.6774042 1.7094617 0.7250386
> .Call("colV", abc, ncol(abc), nrow(abc))
[1] 1.4274933 0.6254796 0.6774042 1.7094617 0.7250386
> .Call("colV", abc, ncol(abc), nrow(abc))
[1] 1.4274933 0.6254796 0.6774042 1.7094617 0.7250386
> .Call("colV", abc, ncol(abc), nrow(abc))
[1] 1.4274933 0.6254796 0.6774042 1.7094617 0.7250386
Also, I haven't had this problem using the .C-Interface, however that is not a solution to me due to speed and memory. Thanks in Advance Erin
Edit: Here is the C-Code:
#include <R.h>
#include <Rinternals.h>
#include <Rmath.h>
SEXP colV(SEXP y, SEXP n, SEXP r){
int *nc = INTEGER(n);
double *x = REAL(y);
int d = length(y);
int *nr = INTEGER(r);
int i, j, z;
//int d = nr * nc;
double colMean[(*nc)];
double xSq[(d)];
double colMsq[(*nc)];
double xSm[(*nc)];
SEXP result;
PROTECT(result = allocVector(REALSXP, (*nc)));
memset(REAL(result), 0, (*nc) * sizeof(double));
double *colVar = REAL(result);
//PROTECT(colVar = NEW_DOUBLE(nc));
int fr = ((*nr) - 1);
for(z = 0; z < (d); z++){
xSq[z] = x[z] * x[z];
}
for(i = 0; i < (*nc); i++){
for(j = 0; j < (*nr); j++){
colMean[i] += (x[(j + ((*nr) * i)) ]);
xSm[i] += (xSq[(j + (*nr * i))]);
}
colMean[i] = (colMean[i] / (*nr));
colMsq[i] = (*nr) * (colMean[i] * colMean[i]);
colVar[i] = ((xSm[i] - colMsq[i]) / fr);
}
UNPROTECT(1);
return(result);
}