Just out of curiosity, here is a question that might be embarrasingly stupid. Hmm ... What I need is to call runif() (more precisely, `runif(1, 0, 1)') from inside a C function. Is this possible using call_S? If so, how? -k =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- r-devel mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html Send "info", "help", or "[un]subscribe" (in the "body", not the subject !) To: r-devel-request@stat.math.ethz.ch =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
R-alpha: unif_rand() again
6 messages · Kurt Hornik, Peter Dalgaard
Kurt Hornik <Kurt.Hornik@ci.tuwien.ac.at> writes:
Just out of curiosity, here is a question that might be embarrasingly stupid. Hmm ... What I need is to call runif() (more precisely, `runif(1, 0, 1)') from inside a C function. Is this possible using call_S? If so, how?
Hmm ... Stupid counter-question: Did you study the zfun() function in $RHOME/demos/dynload/zero.c ? Looks pretty straightforward to me, except that I have no offhand guess what the 0L argument to call_S is good for. Peeking at the source should cure that.
O__ ---- Peter Dalgaard Blegdamsvej 3 c/ /'_ --- Dept. of Biostatistics 2200 Cph. N (*) \(*) -- University of Copenhagen Denmark Ph: (+45) 35327918 ~~~~~~~~~~ - (p.dalgaard@biostat.ku.dk) FAX: (+45) 35327907 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- r-devel mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html Send "info", "help", or "[un]subscribe" (in the "body", not the subject !) To: r-devel-request@stat.math.ethz.ch =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Peter Dalgaard BSA writes:
Kurt Hornik <Kurt.Hornik@ci.tuwien.ac.at> writes:
Just out of curiosity, here is a question that might be embarrasingly stupid. Hmm ... What I need is to call runif() (more precisely, `runif(1, 0, 1)') from inside a C function. Is this possible using call_S? If so, how?
Hmm ... Stupid counter-question: Did you study the zfun() function in $RHOME/demos/dynload/zero.c ? Looks pretty straightforward to me, except that I have no offhand guess what the 0L argument to call_S is good for. Peeking at the source should cure that.
I did. I hoped that something like
static char *func = "runif";
double unif_rand() {
void *in[3];
char *modes[] = { "integer", "integer", "integer" };
long lengths[] = { 1, 1, 1 };
void *out[1];
double *result;
in[0] = (void *)1L;
in[1] = (void *)0L;
in[2] = (void *)1L;
call_S((void *)func, 3L, in, modes, lengths, 0L, 1L, out);
result = (double *)out[0];
return(result[0]);
}
might work, but it does not ...
-k
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
r-devel mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !) To: r-devel-request@stat.math.ethz.ch
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Kurt Hornik <Kurt.Hornik@ci.tuwien.ac.at> writes:
What I need is to call runif() (more precisely, `runif(1, 0, 1)') from inside a C function. Is this possible using call_S? If so, how?
Hmm ... Stupid counter-question: Did you study the zfun() function in $RHOME/demos/dynload/zero.c ? Looks pretty straightforward to me, except that I have no offhand guess what the 0L argument to call_S is good for. Peeking at the source should cure that.
I did. I hoped that something like
static char *func = "runif";
double unif_rand() {
...
return(result[0]); } might work, but it does not ...
Aha. I see, call_R seems to want an SEXP parameter, not a character pointer. So some way of converting "runif" into the relevant SEXPREC seems to be needed. Something like mkChar() <um, no, that doesn't seem to be the way to make a "SEXPsymbol"..> followed by findFun(). Or just pass it as a parameter to .C This looks like a bug in the S compatibility, doesn't it? Nothing in the Splus examples indicate that the first argument should be a string, but I seem to recall seeing something to that effect in the blue book (?)
O__ ---- Peter Dalgaard Blegdamsvej 3 c/ /'_ --- Dept. of Biostatistics 2200 Cph. N (*) \(*) -- University of Copenhagen Denmark Ph: (+45) 35327918 ~~~~~~~~~~ - (p.dalgaard@biostat.ku.dk) FAX: (+45) 35327907 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- r-devel mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html Send "info", "help", or "[un]subscribe" (in the "body", not the subject !) To: r-devel-request@stat.math.ethz.ch =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Kurt Hornik <Kurt.Hornik@ci.tuwien.ac.at> writes:
I did. I hoped that something like
static char *func = "runif";
double unif_rand() {
...
might work, but it does not ...
Here's a model that does (seem to) work:
dyn.load("runif.so");.C("select_rand",runif); .C("unif_rand",3.3)
[[1]] function (n, min = 0, max = 1) .Internal(runif(n, min, max)) [[1]] [1] 0.126975
.C("unif_rand",3.3) # the 3.3 is just an arbitrary double...
[[1]] [1] 0.9233792
.C("unif_rand",3.3)
[[1]] [1] 0.03410953
with
runif.c:
-------------------------
static void * func;
double select_rand(void * f)
{
func = f;
}
static long one = 1L, zero = 0L;
unif_rand(double *x) {
void *in[3];
char *modes[] = { "integer", "integer", "integer" };
long lengths[] = { 1, 1, 1 };
double result;
double *values[1];
in[0] = (void *)&one;
in[1] = (void *)&zero;
in[2] = (void *)&one;
call_S((void *)func, 3L, in, modes, lengths, 0L, 1L, values);
x[0] = values[0][0];
}
--------------------------
O__ ---- Peter Dalgaard Blegdamsvej 3 c/ /'_ --- Dept. of Biostatistics 2200 Cph. N (*) \(*) -- University of Copenhagen Denmark Ph: (+45) 35327918 ~~~~~~~~~~ - (p.dalgaard@biostat.ku.dk) FAX: (+45) 35327907 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- r-devel mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html Send "info", "help", or "[un]subscribe" (in the "body", not the subject !) To: r-devel-request@stat.math.ethz.ch =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
5 days later
Peter Dalgaard BSA writes:
Kurt Hornik <Kurt.Hornik@ci.tuwien.ac.at> writes:
What I need is to call runif() (more precisely, `runif(1, 0, 1)') from inside a C function. Is this possible using call_S? If so, how?
Hmm ... Stupid counter-question: Did you study the zfun() function in $RHOME/demos/dynload/zero.c ? Looks pretty straightforward to me, except that I have no offhand guess what the 0L argument to call_S is good for. Peeking at the source should cure that.
I did. I hoped that something like
static char *func = "runif";
double unif_rand() {
...
return(result[0]); } might work, but it does not ...
Aha. I see, call_R seems to want an SEXP parameter, not a character pointer. So some way of converting "runif" into the relevant SEXPREC seems to be needed. Something like mkChar() <um, no, that doesn't seem to be the way to make a "SEXPsymbol"..> followed by findFun(). Or just pass it as a parameter to .C
I see. Thanks to all who helped. I now have a working example of unif_rand(), but I still hope for Ross to come up with something cleaner ... Trying to map a function name to the function in call_R would be very nice, in any case. -k =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- r-devel mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html Send "info", "help", or "[un]subscribe" (in the "body", not the subject !) To: r-devel-request@stat.math.ethz.ch =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-