Skip to content

R-alpha: unif_rand() again

6 messages · Kurt Hornik, Peter Dalgaard

#
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
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
#
Kurt Hornik <Kurt.Hornik@ci.tuwien.ac.at> writes:
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:
...
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 (?)
#
Kurt Hornik <Kurt.Hornik@ci.tuwien.ac.at> writes:
...
Here's a model that does (seem to) work:
[[1]]
function (n, min = 0, max = 1) 
.Internal(runif(n, min, max))

[[1]]
[1] 0.126975
[[1]]
[1] 0.9233792
[[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];
}

--------------------------
5 days later
#
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
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-